diff options
Diffstat (limited to 'drivers/net/ethernet/atheros/ag71xx.c')
-rw-r--r-- | drivers/net/ethernet/atheros/ag71xx.c | 153 |
1 files changed, 48 insertions, 105 deletions
diff --git a/drivers/net/ethernet/atheros/ag71xx.c b/drivers/net/ethernet/atheros/ag71xx.c index 88d2ab748399..cc932b3cf873 100644 --- a/drivers/net/ethernet/atheros/ag71xx.c +++ b/drivers/net/ethernet/atheros/ag71xx.c @@ -451,8 +451,8 @@ static void ag71xx_get_drvinfo(struct net_device *ndev, { struct ag71xx *ag = netdev_priv(ndev); - strlcpy(info->driver, "ag71xx", sizeof(info->driver)); - strlcpy(info->bus_info, of_node_full_name(ag->pdev->dev.of_node), + strscpy(info->driver, "ag71xx", sizeof(info->driver)); + strscpy(info->bus_info, of_node_full_name(ag->pdev->dev.of_node), sizeof(info->bus_info)); } @@ -766,7 +766,7 @@ static bool ag71xx_check_dma_stuck(struct ag71xx *ag) unsigned long timestamp; u32 rx_sm, tx_sm, rx_fd; - timestamp = netdev_get_tx_queue(ag->ndev, 0)->trans_start; + timestamp = READ_ONCE(netdev_get_tx_queue(ag->ndev, 0)->trans_start); if (likely(time_before(jiffies, timestamp + HZ / 10))) return false; @@ -786,7 +786,7 @@ static bool ag71xx_check_dma_stuck(struct ag71xx *ag) return false; } -static int ag71xx_tx_packets(struct ag71xx *ag, bool flush) +static int ag71xx_tx_packets(struct ag71xx *ag, bool flush, int budget) { struct ag71xx_ring *ring = &ag->tx_ring; int sent = 0, bytes_compl = 0, n = 0; @@ -825,7 +825,7 @@ static int ag71xx_tx_packets(struct ag71xx *ag, bool flush) if (!skb) continue; - dev_kfree_skb_any(skb); + napi_consume_skb(skb, budget); ring->buf[i].tx.skb = NULL; bytes_compl += ring->buf[i].tx.len; @@ -946,7 +946,7 @@ static unsigned int ag71xx_max_frame_len(unsigned int mtu) return ETH_HLEN + VLAN_HLEN + mtu + ETH_FCS_LEN; } -static void ag71xx_hw_set_macaddr(struct ag71xx *ag, unsigned char *mac) +static void ag71xx_hw_set_macaddr(struct ag71xx *ag, const unsigned char *mac) { u32 t; @@ -970,7 +970,7 @@ static void ag71xx_fast_reset(struct ag71xx *ag) mii_reg = ag71xx_rr(ag, AG71XX_REG_MII_CFG); rx_ds = ag71xx_rr(ag, AG71XX_REG_RX_DESC); - ag71xx_tx_packets(ag, true); + ag71xx_tx_packets(ag, true, 0); reset_control_assert(ag->mac_reset); usleep_range(10, 20); @@ -1024,83 +1024,6 @@ static void ag71xx_mac_config(struct phylink_config *config, unsigned int mode, ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, ag->fifodata[2]); } -static void ag71xx_mac_validate(struct phylink_config *config, - unsigned long *supported, - struct phylink_link_state *state) -{ - struct ag71xx *ag = netdev_priv(to_net_dev(config->dev)); - __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; - - switch (state->interface) { - case PHY_INTERFACE_MODE_NA: - break; - case PHY_INTERFACE_MODE_MII: - if ((ag71xx_is(ag, AR9330) && ag->mac_idx == 0) || - ag71xx_is(ag, AR9340) || - ag71xx_is(ag, QCA9530) || - (ag71xx_is(ag, QCA9550) && ag->mac_idx == 1)) - break; - goto unsupported; - case PHY_INTERFACE_MODE_GMII: - if ((ag71xx_is(ag, AR9330) && ag->mac_idx == 1) || - (ag71xx_is(ag, AR9340) && ag->mac_idx == 1) || - (ag71xx_is(ag, QCA9530) && ag->mac_idx == 1)) - break; - goto unsupported; - case PHY_INTERFACE_MODE_SGMII: - if (ag71xx_is(ag, QCA9550) && ag->mac_idx == 0) - break; - goto unsupported; - case PHY_INTERFACE_MODE_RMII: - if (ag71xx_is(ag, AR9340) && ag->mac_idx == 0) - break; - goto unsupported; - case PHY_INTERFACE_MODE_RGMII: - if ((ag71xx_is(ag, AR9340) && ag->mac_idx == 0) || - (ag71xx_is(ag, QCA9550) && ag->mac_idx == 1)) - break; - goto unsupported; - default: - goto unsupported; - } - - phylink_set(mask, MII); - - phylink_set(mask, Pause); - phylink_set(mask, Asym_Pause); - phylink_set(mask, Autoneg); - phylink_set(mask, 10baseT_Half); - phylink_set(mask, 10baseT_Full); - phylink_set(mask, 100baseT_Half); - phylink_set(mask, 100baseT_Full); - - if (state->interface == PHY_INTERFACE_MODE_NA || - state->interface == PHY_INTERFACE_MODE_SGMII || - state->interface == PHY_INTERFACE_MODE_RGMII || - state->interface == PHY_INTERFACE_MODE_GMII) { - phylink_set(mask, 1000baseT_Full); - phylink_set(mask, 1000baseX_Full); - } - - linkmode_and(supported, supported, mask); - linkmode_and(state->advertising, state->advertising, mask); - - return; -unsupported: - linkmode_zero(supported); -} - -static void ag71xx_mac_pcs_get_state(struct phylink_config *config, - struct phylink_link_state *state) -{ - state->link = 0; -} - -static void ag71xx_mac_an_restart(struct phylink_config *config) -{ - /* Not Supported */ -} - static void ag71xx_mac_link_down(struct phylink_config *config, unsigned int mode, phy_interface_t interface) { @@ -1163,9 +1086,7 @@ static void ag71xx_mac_link_up(struct phylink_config *config, } static const struct phylink_mac_ops ag71xx_phylink_mac_ops = { - .validate = ag71xx_mac_validate, - .mac_pcs_get_state = ag71xx_mac_pcs_get_state, - .mac_an_restart = ag71xx_mac_an_restart, + .validate = phylink_generic_validate, .mac_config = ag71xx_mac_config, .mac_link_down = ag71xx_mac_link_down, .mac_link_up = ag71xx_mac_link_up, @@ -1177,6 +1098,34 @@ static int ag71xx_phylink_setup(struct ag71xx *ag) ag->phylink_config.dev = &ag->ndev->dev; ag->phylink_config.type = PHYLINK_NETDEV; + ag->phylink_config.mac_capabilities = MAC_SYM_PAUSE | MAC_ASYM_PAUSE | + MAC_10 | MAC_100 | MAC_1000FD; + + if ((ag71xx_is(ag, AR9330) && ag->mac_idx == 0) || + ag71xx_is(ag, AR9340) || + ag71xx_is(ag, QCA9530) || + (ag71xx_is(ag, QCA9550) && ag->mac_idx == 1)) + __set_bit(PHY_INTERFACE_MODE_MII, + ag->phylink_config.supported_interfaces); + + if ((ag71xx_is(ag, AR9330) && ag->mac_idx == 1) || + (ag71xx_is(ag, AR9340) && ag->mac_idx == 1) || + (ag71xx_is(ag, QCA9530) && ag->mac_idx == 1)) + __set_bit(PHY_INTERFACE_MODE_GMII, + ag->phylink_config.supported_interfaces); + + if (ag71xx_is(ag, QCA9550) && ag->mac_idx == 0) + __set_bit(PHY_INTERFACE_MODE_SGMII, + ag->phylink_config.supported_interfaces); + + if (ag71xx_is(ag, AR9340) && ag->mac_idx == 0) + __set_bit(PHY_INTERFACE_MODE_RMII, + ag->phylink_config.supported_interfaces); + + if ((ag71xx_is(ag, AR9340) && ag->mac_idx == 0) || + (ag71xx_is(ag, QCA9550) && ag->mac_idx == 1)) + __set_bit(PHY_INTERFACE_MODE_RGMII, + ag->phylink_config.supported_interfaces); phylink = phylink_create(&ag->phylink_config, ag->pdev->dev.fwnode, ag->phy_if_mode, &ag71xx_phylink_mac_ops); @@ -1708,7 +1657,7 @@ static int ag71xx_rx_packets(struct ag71xx *ag, int limit) ndev->stats.rx_packets++; ndev->stats.rx_bytes += pktlen; - skb = build_skb(ring->buf[i].rx.rx_buf, ag71xx_buffer_size(ag)); + skb = napi_build_skb(ring->buf[i].rx.rx_buf, ag71xx_buffer_size(ag)); if (!skb) { skb_free_frag(ring->buf[i].rx.rx_buf); goto next; @@ -1754,7 +1703,7 @@ static int ag71xx_poll(struct napi_struct *napi, int limit) int tx_done, rx_done; u32 status; - tx_done = ag71xx_tx_packets(ag, false); + tx_done = ag71xx_tx_packets(ag, false, limit); netif_dbg(ag, rx_status, ndev, "processing RX ring\n"); rx_done = ag71xx_rx_packets(ag, limit); @@ -1913,15 +1862,12 @@ static int ag71xx_probe(struct platform_device *pdev) ag->mac_reset = devm_reset_control_get(&pdev->dev, "mac"); if (IS_ERR(ag->mac_reset)) { netif_err(ag, probe, ndev, "missing mac reset\n"); - err = PTR_ERR(ag->mac_reset); - goto err_free; + return PTR_ERR(ag->mac_reset); } ag->mac_base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); - if (!ag->mac_base) { - err = -ENOMEM; - goto err_free; - } + if (!ag->mac_base) + return -ENOMEM; ndev->irq = platform_get_irq(pdev, 0); err = devm_request_irq(&pdev->dev, ndev->irq, ag71xx_interrupt, @@ -1929,7 +1875,7 @@ static int ag71xx_probe(struct platform_device *pdev) if (err) { netif_err(ag, probe, ndev, "unable to request IRQ %d\n", ndev->irq); - goto err_free; + return err; } ndev->netdev_ops = &ag71xx_netdev_ops; @@ -1957,10 +1903,8 @@ static int ag71xx_probe(struct platform_device *pdev) ag->stop_desc = dmam_alloc_coherent(&pdev->dev, sizeof(struct ag71xx_desc), &ag->stop_desc_dma, GFP_KERNEL); - if (!ag->stop_desc) { - err = -ENOMEM; - goto err_free; - } + if (!ag->stop_desc) + return -ENOMEM; ag->stop_desc->data = 0; ag->stop_desc->ctrl = 0; @@ -1975,15 +1919,16 @@ static int ag71xx_probe(struct platform_device *pdev) err = of_get_phy_mode(np, &ag->phy_if_mode); if (err) { netif_err(ag, probe, ndev, "missing phy-mode property in DT\n"); - goto err_free; + return err; } - netif_napi_add(ndev, &ag->napi, ag71xx_poll, AG71XX_NAPI_WEIGHT); + netif_napi_add_weight(ndev, &ag->napi, ag71xx_poll, + AG71XX_NAPI_WEIGHT); err = clk_prepare_enable(ag->clk_eth); if (err) { netif_err(ag, probe, ndev, "Failed to enable eth clk.\n"); - goto err_free; + return err; } ag71xx_wr(ag, AG71XX_REG_MAC_CFG1, 0); @@ -2019,8 +1964,6 @@ err_mdio_remove: ag71xx_mdio_remove(ag); err_put_clk: clk_disable_unprepare(ag->clk_eth); -err_free: - free_netdev(ndev); return err; } |