| .. | .. |
|---|
| 44 | 44 | #include "gemini.h" |
|---|
| 45 | 45 | |
|---|
| 46 | 46 | #define DRV_NAME "gmac-gemini" |
|---|
| 47 | | -#define DRV_VERSION "1.0" |
|---|
| 48 | 47 | |
|---|
| 49 | 48 | #define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK) |
|---|
| 50 | 49 | static int debug = -1; |
|---|
| .. | .. |
|---|
| 86 | 85 | |
|---|
| 87 | 86 | /** |
|---|
| 88 | 87 | * struct gmac_queue_page - page buffer per-page info |
|---|
| 88 | + * @page: the page struct |
|---|
| 89 | + * @mapping: the dma address handle |
|---|
| 89 | 90 | */ |
|---|
| 90 | 91 | struct gmac_queue_page { |
|---|
| 91 | 92 | struct page *page; |
|---|
| .. | .. |
|---|
| 372 | 373 | return -ENODEV; |
|---|
| 373 | 374 | netdev->phydev = phy; |
|---|
| 374 | 375 | |
|---|
| 375 | | - phy->supported &= PHY_GBIT_FEATURES; |
|---|
| 376 | | - phy->supported |= SUPPORTED_Asym_Pause | SUPPORTED_Pause; |
|---|
| 377 | | - phy->advertising = phy->supported; |
|---|
| 376 | + phy_set_max_speed(phy, SPEED_1000); |
|---|
| 377 | + phy_support_asym_pause(phy); |
|---|
| 378 | 378 | |
|---|
| 379 | 379 | /* set PHY interface type */ |
|---|
| 380 | 380 | switch (phy->interface) { |
|---|
| .. | .. |
|---|
| 514 | 514 | .rel_threshold = 0, |
|---|
| 515 | 515 | } }; |
|---|
| 516 | 516 | union gmac_config0 tmp; |
|---|
| 517 | | - u32 val; |
|---|
| 518 | 517 | |
|---|
| 519 | 518 | config0.bits.max_len = gmac_pick_rx_max_len(netdev->mtu); |
|---|
| 520 | 519 | tmp.bits32 = readl(port->gmac_base + GMAC_CONFIG0); |
|---|
| .. | .. |
|---|
| 524 | 523 | writel(config2.bits32, port->gmac_base + GMAC_CONFIG2); |
|---|
| 525 | 524 | writel(config3.bits32, port->gmac_base + GMAC_CONFIG3); |
|---|
| 526 | 525 | |
|---|
| 527 | | - val = readl(port->dma_base + GMAC_AHB_WEIGHT_REG); |
|---|
| 526 | + readl(port->dma_base + GMAC_AHB_WEIGHT_REG); |
|---|
| 528 | 527 | writel(ahb_weight.bits32, port->dma_base + GMAC_AHB_WEIGHT_REG); |
|---|
| 529 | 528 | |
|---|
| 530 | 529 | writel(hw_weigh.bits32, |
|---|
| .. | .. |
|---|
| 542 | 541 | port->irq_every_tx_packets = 1 << (port->txq_order - 2); |
|---|
| 543 | 542 | |
|---|
| 544 | 543 | return 0; |
|---|
| 545 | | -} |
|---|
| 546 | | - |
|---|
| 547 | | -static void gmac_uninit(struct net_device *netdev) |
|---|
| 548 | | -{ |
|---|
| 549 | | - if (netdev->phydev) |
|---|
| 550 | | - phy_disconnect(netdev->phydev); |
|---|
| 551 | 544 | } |
|---|
| 552 | 545 | |
|---|
| 553 | 546 | static int gmac_setup_txqs(struct net_device *netdev) |
|---|
| .. | .. |
|---|
| 1188 | 1181 | buflen = skb_headlen(skb); |
|---|
| 1189 | 1182 | } else { |
|---|
| 1190 | 1183 | skb_frag = skb_si->frags + frag; |
|---|
| 1191 | | - buffer = page_address(skb_frag_page(skb_frag)) + |
|---|
| 1192 | | - skb_frag->page_offset; |
|---|
| 1193 | | - buflen = skb_frag->size; |
|---|
| 1184 | + buffer = skb_frag_address(skb_frag); |
|---|
| 1185 | + buflen = skb_frag_size(skb_frag); |
|---|
| 1194 | 1186 | } |
|---|
| 1195 | 1187 | |
|---|
| 1196 | 1188 | if (frag == last_frag) { |
|---|
| .. | .. |
|---|
| 1230 | 1222 | return -ENOMEM; |
|---|
| 1231 | 1223 | } |
|---|
| 1232 | 1224 | |
|---|
| 1233 | | -static int gmac_start_xmit(struct sk_buff *skb, struct net_device *netdev) |
|---|
| 1225 | +static netdev_tx_t gmac_start_xmit(struct sk_buff *skb, |
|---|
| 1226 | + struct net_device *netdev) |
|---|
| 1234 | 1227 | { |
|---|
| 1235 | 1228 | struct gemini_ethernet_port *port = netdev_priv(netdev); |
|---|
| 1236 | 1229 | unsigned short m = (1 << port->txq_order) - 1; |
|---|
| .. | .. |
|---|
| 1240 | 1233 | struct gmac_txq *txq; |
|---|
| 1241 | 1234 | int txq_num, nfrags; |
|---|
| 1242 | 1235 | union dma_rwptr rw; |
|---|
| 1243 | | - |
|---|
| 1244 | | - SKB_FRAG_ASSERT(skb); |
|---|
| 1245 | 1236 | |
|---|
| 1246 | 1237 | if (skb->len >= 0x10000) |
|---|
| 1247 | 1238 | goto out_drop_free; |
|---|
| .. | .. |
|---|
| 1305 | 1296 | return NETDEV_TX_OK; |
|---|
| 1306 | 1297 | } |
|---|
| 1307 | 1298 | |
|---|
| 1308 | | -static void gmac_tx_timeout(struct net_device *netdev) |
|---|
| 1299 | +static void gmac_tx_timeout(struct net_device *netdev, unsigned int txqueue) |
|---|
| 1309 | 1300 | { |
|---|
| 1310 | 1301 | netdev_err(netdev, "Tx timeout\n"); |
|---|
| 1311 | 1302 | gmac_dump_dma_state(netdev); |
|---|
| .. | .. |
|---|
| 1775 | 1766 | struct gemini_ethernet_port *port = netdev_priv(netdev); |
|---|
| 1776 | 1767 | int err; |
|---|
| 1777 | 1768 | |
|---|
| 1778 | | - if (!netdev->phydev) { |
|---|
| 1779 | | - err = gmac_setup_phy(netdev); |
|---|
| 1780 | | - if (err) { |
|---|
| 1781 | | - netif_err(port, ifup, netdev, |
|---|
| 1782 | | - "PHY init failed: %d\n", err); |
|---|
| 1783 | | - return err; |
|---|
| 1784 | | - } |
|---|
| 1785 | | - } |
|---|
| 1786 | | - |
|---|
| 1787 | 1769 | err = request_irq(netdev->irq, gmac_irq, |
|---|
| 1788 | 1770 | IRQF_SHARED, netdev->name, netdev); |
|---|
| 1789 | 1771 | if (err) { |
|---|
| .. | .. |
|---|
| 1938 | 1920 | |
|---|
| 1939 | 1921 | /* Racing with RX NAPI */ |
|---|
| 1940 | 1922 | do { |
|---|
| 1941 | | - start = u64_stats_fetch_begin(&port->rx_stats_syncp); |
|---|
| 1923 | + start = u64_stats_fetch_begin_irq(&port->rx_stats_syncp); |
|---|
| 1942 | 1924 | |
|---|
| 1943 | 1925 | stats->rx_packets = port->stats.rx_packets; |
|---|
| 1944 | 1926 | stats->rx_bytes = port->stats.rx_bytes; |
|---|
| .. | .. |
|---|
| 1950 | 1932 | stats->rx_crc_errors = port->stats.rx_crc_errors; |
|---|
| 1951 | 1933 | stats->rx_frame_errors = port->stats.rx_frame_errors; |
|---|
| 1952 | 1934 | |
|---|
| 1953 | | - } while (u64_stats_fetch_retry(&port->rx_stats_syncp, start)); |
|---|
| 1935 | + } while (u64_stats_fetch_retry_irq(&port->rx_stats_syncp, start)); |
|---|
| 1954 | 1936 | |
|---|
| 1955 | 1937 | /* Racing with MIB and TX completion interrupts */ |
|---|
| 1956 | 1938 | do { |
|---|
| 1957 | | - start = u64_stats_fetch_begin(&port->ir_stats_syncp); |
|---|
| 1939 | + start = u64_stats_fetch_begin_irq(&port->ir_stats_syncp); |
|---|
| 1958 | 1940 | |
|---|
| 1959 | 1941 | stats->tx_errors = port->stats.tx_errors; |
|---|
| 1960 | 1942 | stats->tx_packets = port->stats.tx_packets; |
|---|
| .. | .. |
|---|
| 1964 | 1946 | stats->rx_missed_errors = port->stats.rx_missed_errors; |
|---|
| 1965 | 1947 | stats->rx_fifo_errors = port->stats.rx_fifo_errors; |
|---|
| 1966 | 1948 | |
|---|
| 1967 | | - } while (u64_stats_fetch_retry(&port->ir_stats_syncp, start)); |
|---|
| 1949 | + } while (u64_stats_fetch_retry_irq(&port->ir_stats_syncp, start)); |
|---|
| 1968 | 1950 | |
|---|
| 1969 | 1951 | /* Racing with hard_start_xmit */ |
|---|
| 1970 | 1952 | do { |
|---|
| 1971 | | - start = u64_stats_fetch_begin(&port->tx_stats_syncp); |
|---|
| 1953 | + start = u64_stats_fetch_begin_irq(&port->tx_stats_syncp); |
|---|
| 1972 | 1954 | |
|---|
| 1973 | 1955 | stats->tx_dropped = port->stats.tx_dropped; |
|---|
| 1974 | 1956 | |
|---|
| 1975 | | - } while (u64_stats_fetch_retry(&port->tx_stats_syncp, start)); |
|---|
| 1957 | + } while (u64_stats_fetch_retry_irq(&port->tx_stats_syncp, start)); |
|---|
| 1976 | 1958 | |
|---|
| 1977 | 1959 | stats->rx_dropped += stats->rx_missed_errors; |
|---|
| 1978 | 1960 | } |
|---|
| .. | .. |
|---|
| 2050 | 2032 | /* Racing with MIB interrupt */ |
|---|
| 2051 | 2033 | do { |
|---|
| 2052 | 2034 | p = values; |
|---|
| 2053 | | - start = u64_stats_fetch_begin(&port->ir_stats_syncp); |
|---|
| 2035 | + start = u64_stats_fetch_begin_irq(&port->ir_stats_syncp); |
|---|
| 2054 | 2036 | |
|---|
| 2055 | 2037 | for (i = 0; i < RX_STATS_NUM; i++) |
|---|
| 2056 | 2038 | *p++ = port->hw_stats[i]; |
|---|
| 2057 | 2039 | |
|---|
| 2058 | | - } while (u64_stats_fetch_retry(&port->ir_stats_syncp, start)); |
|---|
| 2040 | + } while (u64_stats_fetch_retry_irq(&port->ir_stats_syncp, start)); |
|---|
| 2059 | 2041 | values = p; |
|---|
| 2060 | 2042 | |
|---|
| 2061 | 2043 | /* Racing with RX NAPI */ |
|---|
| 2062 | 2044 | do { |
|---|
| 2063 | 2045 | p = values; |
|---|
| 2064 | | - start = u64_stats_fetch_begin(&port->rx_stats_syncp); |
|---|
| 2046 | + start = u64_stats_fetch_begin_irq(&port->rx_stats_syncp); |
|---|
| 2065 | 2047 | |
|---|
| 2066 | 2048 | for (i = 0; i < RX_STATUS_NUM; i++) |
|---|
| 2067 | 2049 | *p++ = port->rx_stats[i]; |
|---|
| .. | .. |
|---|
| 2069 | 2051 | *p++ = port->rx_csum_stats[i]; |
|---|
| 2070 | 2052 | *p++ = port->rx_napi_exits; |
|---|
| 2071 | 2053 | |
|---|
| 2072 | | - } while (u64_stats_fetch_retry(&port->rx_stats_syncp, start)); |
|---|
| 2054 | + } while (u64_stats_fetch_retry_irq(&port->rx_stats_syncp, start)); |
|---|
| 2073 | 2055 | values = p; |
|---|
| 2074 | 2056 | |
|---|
| 2075 | 2057 | /* Racing with TX start_xmit */ |
|---|
| 2076 | 2058 | do { |
|---|
| 2077 | 2059 | p = values; |
|---|
| 2078 | | - start = u64_stats_fetch_begin(&port->tx_stats_syncp); |
|---|
| 2060 | + start = u64_stats_fetch_begin_irq(&port->tx_stats_syncp); |
|---|
| 2079 | 2061 | |
|---|
| 2080 | 2062 | for (i = 0; i < TX_MAX_FRAGS; i++) { |
|---|
| 2081 | 2063 | *values++ = port->tx_frag_stats[i]; |
|---|
| .. | .. |
|---|
| 2084 | 2066 | *values++ = port->tx_frags_linearized; |
|---|
| 2085 | 2067 | *values++ = port->tx_hw_csummed; |
|---|
| 2086 | 2068 | |
|---|
| 2087 | | - } while (u64_stats_fetch_retry(&port->tx_stats_syncp, start)); |
|---|
| 2069 | + } while (u64_stats_fetch_retry_irq(&port->tx_stats_syncp, start)); |
|---|
| 2088 | 2070 | } |
|---|
| 2089 | 2071 | |
|---|
| 2090 | 2072 | static int gmac_get_ksettings(struct net_device *netdev, |
|---|
| .. | .. |
|---|
| 2129 | 2111 | struct ethtool_ringparam *rp) |
|---|
| 2130 | 2112 | { |
|---|
| 2131 | 2113 | struct gemini_ethernet_port *port = netdev_priv(netdev); |
|---|
| 2132 | | - union gmac_config0 config0; |
|---|
| 2133 | 2114 | |
|---|
| 2134 | | - config0.bits32 = readl(port->gmac_base + GMAC_CONFIG0); |
|---|
| 2115 | + readl(port->gmac_base + GMAC_CONFIG0); |
|---|
| 2135 | 2116 | |
|---|
| 2136 | 2117 | rp->rx_max_pending = 1 << 15; |
|---|
| 2137 | 2118 | rp->rx_mini_max_pending = 0; |
|---|
| .. | .. |
|---|
| 2211 | 2192 | struct ethtool_drvinfo *info) |
|---|
| 2212 | 2193 | { |
|---|
| 2213 | 2194 | strcpy(info->driver, DRV_NAME); |
|---|
| 2214 | | - strcpy(info->version, DRV_VERSION); |
|---|
| 2215 | 2195 | strcpy(info->bus_info, netdev->dev_id ? "1" : "0"); |
|---|
| 2216 | 2196 | } |
|---|
| 2217 | 2197 | |
|---|
| 2218 | 2198 | static const struct net_device_ops gmac_351x_ops = { |
|---|
| 2219 | 2199 | .ndo_init = gmac_init, |
|---|
| 2220 | | - .ndo_uninit = gmac_uninit, |
|---|
| 2221 | 2200 | .ndo_open = gmac_open, |
|---|
| 2222 | 2201 | .ndo_stop = gmac_stop, |
|---|
| 2223 | 2202 | .ndo_start_xmit = gmac_start_xmit, |
|---|
| .. | .. |
|---|
| 2231 | 2210 | }; |
|---|
| 2232 | 2211 | |
|---|
| 2233 | 2212 | static const struct ethtool_ops gmac_351x_ethtool_ops = { |
|---|
| 2213 | + .supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS | |
|---|
| 2214 | + ETHTOOL_COALESCE_MAX_FRAMES, |
|---|
| 2234 | 2215 | .get_sset_count = gmac_get_sset_count, |
|---|
| 2235 | 2216 | .get_strings = gmac_get_strings, |
|---|
| 2236 | 2217 | .get_ethtool_stats = gmac_get_ethtool_stats, |
|---|
| .. | .. |
|---|
| 2301 | 2282 | |
|---|
| 2302 | 2283 | static void gemini_port_remove(struct gemini_ethernet_port *port) |
|---|
| 2303 | 2284 | { |
|---|
| 2304 | | - if (port->netdev) |
|---|
| 2285 | + if (port->netdev) { |
|---|
| 2286 | + phy_disconnect(port->netdev->phydev); |
|---|
| 2305 | 2287 | unregister_netdev(port->netdev); |
|---|
| 2288 | + } |
|---|
| 2306 | 2289 | clk_disable_unprepare(port->pclk); |
|---|
| 2307 | 2290 | geth_cleanup_freeq(port->geth); |
|---|
| 2308 | 2291 | } |
|---|
| .. | .. |
|---|
| 2431 | 2414 | |
|---|
| 2432 | 2415 | /* Interrupt */ |
|---|
| 2433 | 2416 | irq = platform_get_irq(pdev, 0); |
|---|
| 2434 | | - if (irq <= 0) { |
|---|
| 2435 | | - dev_err(dev, "no IRQ\n"); |
|---|
| 2417 | + if (irq <= 0) |
|---|
| 2436 | 2418 | return irq ? irq : -ENODEV; |
|---|
| 2437 | | - } |
|---|
| 2438 | 2419 | port->irq = irq; |
|---|
| 2439 | 2420 | |
|---|
| 2440 | 2421 | /* Clock the port */ |
|---|
| .. | .. |
|---|
| 2513 | 2494 | if (ret) |
|---|
| 2514 | 2495 | goto unprepare; |
|---|
| 2515 | 2496 | |
|---|
| 2497 | + ret = gmac_setup_phy(netdev); |
|---|
| 2498 | + if (ret) { |
|---|
| 2499 | + netdev_err(netdev, |
|---|
| 2500 | + "PHY init failed\n"); |
|---|
| 2501 | + goto unprepare; |
|---|
| 2502 | + } |
|---|
| 2503 | + |
|---|
| 2516 | 2504 | ret = register_netdev(netdev); |
|---|
| 2517 | 2505 | if (ret) |
|---|
| 2518 | 2506 | goto unprepare; |
|---|
| .. | .. |
|---|
| 2521 | 2509 | "irq %d, DMA @ 0x%pap, GMAC @ 0x%pap\n", |
|---|
| 2522 | 2510 | port->irq, &dmares->start, |
|---|
| 2523 | 2511 | &gmacres->start); |
|---|
| 2524 | | - ret = gmac_setup_phy(netdev); |
|---|
| 2525 | | - if (ret) |
|---|
| 2526 | | - netdev_info(netdev, |
|---|
| 2527 | | - "PHY init failed, deferring to ifup time\n"); |
|---|
| 2528 | 2512 | return 0; |
|---|
| 2529 | 2513 | |
|---|
| 2530 | 2514 | unprepare: |
|---|
| .. | .. |
|---|
| 2537 | 2521 | struct gemini_ethernet_port *port = platform_get_drvdata(pdev); |
|---|
| 2538 | 2522 | |
|---|
| 2539 | 2523 | gemini_port_remove(port); |
|---|
| 2524 | + |
|---|
| 2540 | 2525 | return 0; |
|---|
| 2541 | 2526 | } |
|---|
| 2542 | 2527 | |
|---|