From 27e9e10391259cbe2e52d6f0ac5b16b1d898d901 Mon Sep 17 00:00:00 2001 From: Ivan Khoronzhuk Date: Wed, 10 Aug 2016 02:22:32 +0300 Subject: [PATCH 01/13] net: ethernet: ti: cpsw: simplify submit routine As second net dev is created only in case of dual_emac mode, port number can be figured out in simpler way. Also no need to pass redundant ndev struct. Reviewed-by: Mugunthan V N Reviewed-by: Grygorii Strashko Signed-off-by: Ivan Khoronzhuk Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/cpsw.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index c51f34693eae..8972bf6870ed 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -1065,19 +1065,11 @@ static int cpsw_common_res_usage_state(struct cpsw_priv *priv) return usage_count; } -static inline int cpsw_tx_packet_submit(struct net_device *ndev, - struct cpsw_priv *priv, struct sk_buff *skb) +static inline int cpsw_tx_packet_submit(struct cpsw_priv *priv, + struct sk_buff *skb) { - if (!priv->data.dual_emac) - return cpdma_chan_submit(priv->txch, skb, skb->data, - skb->len, 0); - - if (ndev == cpsw_get_slave_ndev(priv, 0)) - return cpdma_chan_submit(priv->txch, skb, skb->data, - skb->len, 1); - else - return cpdma_chan_submit(priv->txch, skb, skb->data, - skb->len, 2); + return cpdma_chan_submit(priv->txch, skb, skb->data, skb->len, + priv->emac_port + priv->data.dual_emac); } static inline void cpsw_add_dual_emac_def_ale_entries( @@ -1406,7 +1398,7 @@ static netdev_tx_t cpsw_ndo_start_xmit(struct sk_buff *skb, skb_tx_timestamp(skb); - ret = cpsw_tx_packet_submit(ndev, priv, skb); + ret = cpsw_tx_packet_submit(priv, skb); if (unlikely(ret != 0)) { cpsw_err(priv, tx_err, "desc submit failed\n"); goto fail; From 0a440f8f4f75598235a71a365fb0dbe0056ad75c Mon Sep 17 00:00:00 2001 From: Ivan Khoronzhuk Date: Wed, 10 Aug 2016 02:22:33 +0300 Subject: [PATCH 02/13] net: ethernet: ti: cpsw: remove intr dbg msg from poll handlers At poll handler no possibility to figure out which network device is handling packets, as cpdma channels are common for both network devices in dual_emac mode. Currently, the messages are printed only for one device, in fact, there is two. This print msg is incorrect and seems is not very useful, so drop it from poll handler. Reviewed-by: Mugunthan V N Signed-off-by: Ivan Khoronzhuk Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/cpsw.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 8972bf6870ed..21cf3671c79e 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -793,9 +793,6 @@ static int cpsw_tx_poll(struct napi_struct *napi_tx, int budget) } } - if (num_tx) - cpsw_dbg(priv, intr, "poll %d tx pkts\n", num_tx); - return num_tx; } @@ -814,9 +811,6 @@ static int cpsw_rx_poll(struct napi_struct *napi_rx, int budget) } } - if (num_rx) - cpsw_dbg(priv, intr, "poll %d rx pkts\n", num_rx); - return num_rx; } From 6f1f58361fa249ce10ca14256e473e6881e4efee Mon Sep 17 00:00:00 2001 From: Ivan Khoronzhuk Date: Wed, 10 Aug 2016 02:22:34 +0300 Subject: [PATCH 03/13] net: ethernet: ti: cpsw: remove priv from cpsw_get_slave_port() parameters list There is no need in priv here. Reviewed-by: Mugunthan V N Reviewed-by: Grygorii Strashko Signed-off-by: Ivan Khoronzhuk Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/cpsw.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 21cf3671c79e..4f6a4c100810 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -525,7 +525,7 @@ static const struct cpsw_stats cpsw_gstrings_stats[] = { if (priv->data.dual_emac) { \ struct cpsw_slave *slave = priv->slaves + \ priv->emac_port; \ - int slave_port = cpsw_get_slave_port(priv, \ + int slave_port = cpsw_get_slave_port( \ slave->slave_num); \ cpsw_ale_add_mcast(priv->ale, addr, \ 1 << slave_port | ALE_PORT_HOST, \ @@ -537,7 +537,7 @@ static const struct cpsw_stats cpsw_gstrings_stats[] = { } \ } while (0) -static inline int cpsw_get_slave_port(struct cpsw_priv *priv, u32 slave_num) +static inline int cpsw_get_slave_port(u32 slave_num) { return slave_num + 1; } @@ -847,7 +847,7 @@ static void _cpsw_adjust_link(struct cpsw_slave *slave, if (!phy) return; - slave_port = cpsw_get_slave_port(priv, slave->slave_num); + slave_port = cpsw_get_slave_port(slave->slave_num); if (phy->link) { mac_control = priv->data.mac_control; @@ -1118,7 +1118,7 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv) slave->mac_control = 0; /* no link yet */ - slave_port = cpsw_get_slave_port(priv, slave->slave_num); + slave_port = cpsw_get_slave_port(slave->slave_num); if (priv->data.dual_emac) cpsw_add_dual_emac_def_ale_entries(priv, slave, slave_port); @@ -1220,7 +1220,7 @@ static void cpsw_slave_stop(struct cpsw_slave *slave, struct cpsw_priv *priv) { u32 slave_port; - slave_port = cpsw_get_slave_port(priv, slave->slave_num); + slave_port = cpsw_get_slave_port(slave->slave_num); if (!slave->phy) return; From ef4183a1d75b15c3bbd6e7f2b14fc5480d740bff Mon Sep 17 00:00:00 2001 From: Ivan Khoronzhuk Date: Wed, 10 Aug 2016 02:22:35 +0300 Subject: [PATCH 04/13] net: ethernet: ti: cpsw: remove clk var from priv There is no need to hold link to clk, it's used only once while probe. Reviewed-by: Mugunthan V N Reviewed-by: Grygorii Strashko Signed-off-by: Ivan Khoronzhuk Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/cpsw.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 4f6a4c100810..0b6958d6834e 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -379,7 +379,6 @@ struct cpsw_priv { u32 coal_intvl; u32 bus_freq_mhz; int rx_packet_max; - struct clk *clk; u8 mac_addr[ETH_ALEN]; struct cpsw_slave *slaves; struct cpdma_ctlr *dma; @@ -2177,8 +2176,6 @@ static int cpsw_probe_dual_emac(struct platform_device *pdev, memcpy(ndev->dev_addr, priv_sl2->mac_addr, ETH_ALEN); priv_sl2->slaves = priv->slaves; - priv_sl2->clk = priv->clk; - priv_sl2->coal_intvl = 0; priv_sl2->bus_freq_mhz = priv->bus_freq_mhz; @@ -2256,6 +2253,7 @@ MODULE_DEVICE_TABLE(of, cpsw_of_mtable); static int cpsw_probe(struct platform_device *pdev) { + struct clk *clk; struct cpsw_platform_data *data; struct net_device *ndev; struct cpsw_priv *priv; @@ -2334,14 +2332,14 @@ static int cpsw_probe(struct platform_device *pdev) priv->slaves[0].ndev = ndev; priv->emac_port = 0; - priv->clk = devm_clk_get(&pdev->dev, "fck"); - if (IS_ERR(priv->clk)) { + clk = devm_clk_get(&pdev->dev, "fck"); + if (IS_ERR(clk)) { dev_err(priv->dev, "fck is not found\n"); ret = -ENODEV; goto clean_runtime_disable_ret; } priv->coal_intvl = 0; - priv->bus_freq_mhz = clk_get_rate(priv->clk) / 1000000; + priv->bus_freq_mhz = clk_get_rate(clk) / 1000000; ss_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ss_regs = devm_ioremap_resource(&pdev->dev, ss_res); From 82b52104a31a96689fe1931180c66dd699ad5fc1 Mon Sep 17 00:00:00 2001 From: Ivan Khoronzhuk Date: Wed, 10 Aug 2016 02:22:36 +0300 Subject: [PATCH 05/13] net: ethernet: ti: cpsw: don't check slave num in runtime No need to check const slave num in runtime for every packet, and ndev for slaves w/o ndev is anyway NULL. So remove redundant check and macro. Reviewed-by: Mugunthan V N Signed-off-by: Ivan Khoronzhuk Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/cpsw.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 0b6958d6834e..cfbb1f2becdd 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -497,9 +497,6 @@ static const struct cpsw_stats cpsw_gstrings_stats[] = { n; n--) \ (func)(slave++, ##arg); \ } while (0) -#define cpsw_get_slave_ndev(priv, __slave_no__) \ - ((__slave_no__ < priv->data.slaves) ? \ - priv->slaves[__slave_no__].ndev : NULL) #define cpsw_get_slave_priv(priv, __slave_no__) \ (((__slave_no__ < priv->data.slaves) && \ (priv->slaves[__slave_no__].ndev)) ? \ @@ -510,11 +507,11 @@ static const struct cpsw_stats cpsw_gstrings_stats[] = { if (!priv->data.dual_emac) \ break; \ if (CPDMA_RX_SOURCE_PORT(status) == 1) { \ - ndev = cpsw_get_slave_ndev(priv, 0); \ + ndev = priv->slaves[0].ndev; \ priv = netdev_priv(ndev); \ skb->dev = ndev; \ } else if (CPDMA_RX_SOURCE_PORT(status) == 2) { \ - ndev = cpsw_get_slave_ndev(priv, 1); \ + ndev = priv->slaves[1].ndev; \ priv = netdev_priv(ndev); \ skb->dev = ndev; \ } \ @@ -2561,7 +2558,7 @@ static int cpsw_remove(struct platform_device *pdev) } if (priv->data.dual_emac) - unregister_netdev(cpsw_get_slave_ndev(priv, 1)); + unregister_netdev(priv->slaves[1].ndev); unregister_netdev(ndev); cpsw_ale_destroy(priv->ale); @@ -2570,7 +2567,7 @@ static int cpsw_remove(struct platform_device *pdev) pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); if (priv->data.dual_emac) - free_netdev(cpsw_get_slave_ndev(priv, 1)); + free_netdev(priv->slaves[1].ndev); free_netdev(ndev); return 0; } From 649a1688c96098a702e827a073542b29739b4f88 Mon Sep 17 00:00:00 2001 From: Ivan Khoronzhuk Date: Wed, 10 Aug 2016 02:22:37 +0300 Subject: [PATCH 06/13] net: ethernet: ti: cpsw: create common struct to hold shared driver data This patch simply create holder for common data and as a start moves pdev var to it. Signed-off-by: Ivan Khoronzhuk Reviewed-by: Mugunthan V N Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/cpsw.c | 62 +++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 23 deletions(-) diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index cfbb1f2becdd..3ccf577dd46d 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -363,8 +363,11 @@ static inline void slave_write(struct cpsw_slave *slave, u32 val, u32 offset) __raw_writel(val, slave->regs + offset); } -struct cpsw_priv { +struct cpsw_common { struct platform_device *pdev; +}; + +struct cpsw_priv { struct net_device *ndev; struct napi_struct napi_rx; struct napi_struct napi_tx; @@ -394,6 +397,7 @@ struct cpsw_priv { u32 num_irqs; struct cpts *cpts; u32 emac_port; + struct cpsw_common *cpsw; }; struct cpsw_stats { @@ -484,6 +488,7 @@ static const struct cpsw_stats cpsw_gstrings_stats[] = { #define CPSW_STATS_LEN ARRAY_SIZE(cpsw_gstrings_stats) +#define ndev_to_cpsw(ndev) (((struct cpsw_priv *)netdev_priv(ndev))->cpsw) #define napi_to_priv(napi) container_of(napi, struct cpsw_priv, napi) #define for_each_slave(priv, func, arg...) \ do { \ @@ -1091,6 +1096,7 @@ static void soft_reset_slave(struct cpsw_slave *slave) static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv) { u32 slave_port; + struct cpsw_common *cpsw = priv->cpsw; soft_reset_slave(slave); @@ -1149,7 +1155,7 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv) phy_start(slave->phy); /* Configure GMII_SEL register */ - cpsw_phy_sel(&priv->pdev->dev, slave->phy->interface, slave->slave_num); + cpsw_phy_sel(&cpsw->pdev->dev, slave->phy->interface, slave->slave_num); } static inline void cpsw_add_default_vlan(struct cpsw_priv *priv) @@ -1231,12 +1237,13 @@ static void cpsw_slave_stop(struct cpsw_slave *slave, struct cpsw_priv *priv) static int cpsw_ndo_open(struct net_device *ndev) { struct cpsw_priv *priv = netdev_priv(ndev); + struct cpsw_common *cpsw = priv->cpsw; int i, ret; u32 reg; - ret = pm_runtime_get_sync(&priv->pdev->dev); + ret = pm_runtime_get_sync(&cpsw->pdev->dev); if (ret < 0) { - pm_runtime_put_noidle(&priv->pdev->dev); + pm_runtime_put_noidle(&cpsw->pdev->dev); return ret; } @@ -1313,7 +1320,7 @@ static int cpsw_ndo_open(struct net_device *ndev) */ cpsw_info(priv, ifup, "submitted %d rx descriptors\n", i); - if (cpts_register(&priv->pdev->dev, priv->cpts, + if (cpts_register(&cpsw->pdev->dev, priv->cpts, priv->data.cpts_clock_mult, priv->data.cpts_clock_shift)) dev_err(priv->dev, "error registering cpts device\n"); @@ -1338,7 +1345,7 @@ static int cpsw_ndo_open(struct net_device *ndev) err_cleanup: cpdma_ctlr_stop(priv->dma); for_each_slave(priv, cpsw_slave_stop, priv); - pm_runtime_put_sync(&priv->pdev->dev); + pm_runtime_put_sync(&cpsw->pdev->dev); netif_carrier_off(priv->ndev); return ret; } @@ -1346,6 +1353,7 @@ static int cpsw_ndo_open(struct net_device *ndev) static int cpsw_ndo_stop(struct net_device *ndev) { struct cpsw_priv *priv = netdev_priv(ndev); + struct cpsw_common *cpsw = priv->cpsw; cpsw_info(priv, ifdown, "shutting down cpsw device\n"); netif_stop_queue(priv->ndev); @@ -1362,7 +1370,7 @@ static int cpsw_ndo_stop(struct net_device *ndev) cpsw_ale_stop(priv->ale); } for_each_slave(priv, cpsw_slave_stop, priv); - pm_runtime_put_sync(&priv->pdev->dev); + pm_runtime_put_sync(&cpsw->pdev->dev); if (priv->data.dual_emac) priv->slaves[priv->emac_port].open_stat = false; return 0; @@ -1594,6 +1602,7 @@ static int cpsw_ndo_set_mac_address(struct net_device *ndev, void *p) { struct cpsw_priv *priv = netdev_priv(ndev); struct sockaddr *addr = (struct sockaddr *)p; + struct cpsw_common *cpsw = priv->cpsw; int flags = 0; u16 vid = 0; int ret; @@ -1601,9 +1610,9 @@ static int cpsw_ndo_set_mac_address(struct net_device *ndev, void *p) if (!is_valid_ether_addr(addr->sa_data)) return -EADDRNOTAVAIL; - ret = pm_runtime_get_sync(&priv->pdev->dev); + ret = pm_runtime_get_sync(&cpsw->pdev->dev); if (ret < 0) { - pm_runtime_put_noidle(&priv->pdev->dev); + pm_runtime_put_noidle(&cpsw->pdev->dev); return ret; } @@ -1621,7 +1630,7 @@ static int cpsw_ndo_set_mac_address(struct net_device *ndev, void *p) memcpy(ndev->dev_addr, priv->mac_addr, ETH_ALEN); for_each_slave(priv, cpsw_set_slave_mac, priv); - pm_runtime_put(&priv->pdev->dev); + pm_runtime_put(&cpsw->pdev->dev); return 0; } @@ -1687,14 +1696,15 @@ static int cpsw_ndo_vlan_rx_add_vid(struct net_device *ndev, __be16 proto, u16 vid) { struct cpsw_priv *priv = netdev_priv(ndev); + struct cpsw_common *cpsw = priv->cpsw; int ret; if (vid == priv->data.default_vlan) return 0; - ret = pm_runtime_get_sync(&priv->pdev->dev); + ret = pm_runtime_get_sync(&cpsw->pdev->dev); if (ret < 0) { - pm_runtime_put_noidle(&priv->pdev->dev); + pm_runtime_put_noidle(&cpsw->pdev->dev); return ret; } @@ -1714,7 +1724,7 @@ static int cpsw_ndo_vlan_rx_add_vid(struct net_device *ndev, dev_info(priv->dev, "Adding vlanid %d to vlan filter\n", vid); ret = cpsw_add_vlan_ale_entry(priv, vid); - pm_runtime_put(&priv->pdev->dev); + pm_runtime_put(&cpsw->pdev->dev); return ret; } @@ -1722,14 +1732,15 @@ static int cpsw_ndo_vlan_rx_kill_vid(struct net_device *ndev, __be16 proto, u16 vid) { struct cpsw_priv *priv = netdev_priv(ndev); + struct cpsw_common *cpsw = priv->cpsw; int ret; if (vid == priv->data.default_vlan) return 0; - ret = pm_runtime_get_sync(&priv->pdev->dev); + ret = pm_runtime_get_sync(&cpsw->pdev->dev); if (ret < 0) { - pm_runtime_put_noidle(&priv->pdev->dev); + pm_runtime_put_noidle(&cpsw->pdev->dev); return ret; } @@ -1754,7 +1765,7 @@ static int cpsw_ndo_vlan_rx_kill_vid(struct net_device *ndev, ret = cpsw_ale_del_mcast(priv->ale, priv->ndev->broadcast, 0, ALE_VLAN, vid); - pm_runtime_put(&priv->pdev->dev); + pm_runtime_put(&cpsw->pdev->dev); return ret; } @@ -1797,11 +1808,11 @@ static void cpsw_get_regs(struct net_device *ndev, static void cpsw_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info) { - struct cpsw_priv *priv = netdev_priv(ndev); + struct cpsw_common *cpsw = ndev_to_cpsw(ndev); strlcpy(info->driver, "cpsw", sizeof(info->driver)); strlcpy(info->version, "1.0", sizeof(info->version)); - strlcpy(info->bus_info, priv->pdev->name, sizeof(info->bus_info)); + strlcpy(info->bus_info, cpsw->pdev->name, sizeof(info->bus_info)); } static u32 cpsw_get_msglevel(struct net_device *ndev) @@ -1920,12 +1931,13 @@ static int cpsw_set_pauseparam(struct net_device *ndev, static int cpsw_ethtool_op_begin(struct net_device *ndev) { struct cpsw_priv *priv = netdev_priv(ndev); + struct cpsw_common *cpsw = priv->cpsw; int ret; - ret = pm_runtime_get_sync(&priv->pdev->dev); + ret = pm_runtime_get_sync(&cpsw->pdev->dev); if (ret < 0) { cpsw_err(priv, drv, "ethtool begin failed %d\n", ret); - pm_runtime_put_noidle(&priv->pdev->dev); + pm_runtime_put_noidle(&cpsw->pdev->dev); } return ret; @@ -1936,7 +1948,7 @@ static void cpsw_ethtool_op_complete(struct net_device *ndev) struct cpsw_priv *priv = netdev_priv(ndev); int ret; - ret = pm_runtime_put(&priv->pdev->dev); + ret = pm_runtime_put(&priv->cpsw->pdev->dev); if (ret < 0) cpsw_err(priv, drv, "ethtool complete failed %d\n", ret); } @@ -2155,8 +2167,8 @@ static int cpsw_probe_dual_emac(struct platform_device *pdev, } priv_sl2 = netdev_priv(ndev); + priv_sl2->cpsw = priv->cpsw; priv_sl2->data = *data; - priv_sl2->pdev = pdev; priv_sl2->ndev = ndev; priv_sl2->dev = &ndev->dev; priv_sl2->msg_enable = netif_msg_init(debug_level, CPSW_DEBUG); @@ -2261,9 +2273,13 @@ static int cpsw_probe(struct platform_device *pdev) const struct of_device_id *of_id; struct gpio_descs *mode; u32 slave_offset, sliver_offset, slave_size; + struct cpsw_common *cpsw; int ret = 0, i; int irq; + cpsw = devm_kzalloc(&pdev->dev, sizeof(struct cpsw_common), GFP_KERNEL); + cpsw->pdev = pdev; + ndev = alloc_etherdev(sizeof(struct cpsw_priv)); if (!ndev) { dev_err(&pdev->dev, "error allocating net_device\n"); @@ -2272,7 +2288,7 @@ static int cpsw_probe(struct platform_device *pdev) platform_set_drvdata(pdev, ndev); priv = netdev_priv(ndev); - priv->pdev = pdev; + priv->cpsw = cpsw; priv->ndev = ndev; priv->dev = &ndev->dev; priv->msg_enable = netif_msg_init(debug_level, CPSW_DEBUG); From 56e31bd89334325f918e4b9f4d91f07157400169 Mon Sep 17 00:00:00 2001 From: Ivan Khoronzhuk Date: Wed, 10 Aug 2016 02:22:38 +0300 Subject: [PATCH 07/13] net: ethernet: ti: cpsw: replace pdev on dev No need to hold pdev link when only dev is needed. This allows to simplify a bunch of cpsw->pdev->dev now and farther. Signed-off-by: Ivan Khoronzhuk Reviewed-by: Mugunthan V N Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/cpsw.c | 65 ++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 3ccf577dd46d..c21cc38834d0 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -364,7 +364,7 @@ static inline void slave_write(struct cpsw_slave *slave, u32 val, u32 offset) } struct cpsw_common { - struct platform_device *pdev; + struct device *dev; }; struct cpsw_priv { @@ -1155,7 +1155,7 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv) phy_start(slave->phy); /* Configure GMII_SEL register */ - cpsw_phy_sel(&cpsw->pdev->dev, slave->phy->interface, slave->slave_num); + cpsw_phy_sel(cpsw->dev, slave->phy->interface, slave->slave_num); } static inline void cpsw_add_default_vlan(struct cpsw_priv *priv) @@ -1241,9 +1241,9 @@ static int cpsw_ndo_open(struct net_device *ndev) int i, ret; u32 reg; - ret = pm_runtime_get_sync(&cpsw->pdev->dev); + ret = pm_runtime_get_sync(cpsw->dev); if (ret < 0) { - pm_runtime_put_noidle(&cpsw->pdev->dev); + pm_runtime_put_noidle(cpsw->dev); return ret; } @@ -1320,7 +1320,7 @@ static int cpsw_ndo_open(struct net_device *ndev) */ cpsw_info(priv, ifup, "submitted %d rx descriptors\n", i); - if (cpts_register(&cpsw->pdev->dev, priv->cpts, + if (cpts_register(cpsw->dev, priv->cpts, priv->data.cpts_clock_mult, priv->data.cpts_clock_shift)) dev_err(priv->dev, "error registering cpts device\n"); @@ -1345,7 +1345,7 @@ static int cpsw_ndo_open(struct net_device *ndev) err_cleanup: cpdma_ctlr_stop(priv->dma); for_each_slave(priv, cpsw_slave_stop, priv); - pm_runtime_put_sync(&cpsw->pdev->dev); + pm_runtime_put_sync(cpsw->dev); netif_carrier_off(priv->ndev); return ret; } @@ -1370,7 +1370,7 @@ static int cpsw_ndo_stop(struct net_device *ndev) cpsw_ale_stop(priv->ale); } for_each_slave(priv, cpsw_slave_stop, priv); - pm_runtime_put_sync(&cpsw->pdev->dev); + pm_runtime_put_sync(cpsw->dev); if (priv->data.dual_emac) priv->slaves[priv->emac_port].open_stat = false; return 0; @@ -1610,9 +1610,9 @@ static int cpsw_ndo_set_mac_address(struct net_device *ndev, void *p) if (!is_valid_ether_addr(addr->sa_data)) return -EADDRNOTAVAIL; - ret = pm_runtime_get_sync(&cpsw->pdev->dev); + ret = pm_runtime_get_sync(cpsw->dev); if (ret < 0) { - pm_runtime_put_noidle(&cpsw->pdev->dev); + pm_runtime_put_noidle(cpsw->dev); return ret; } @@ -1630,7 +1630,7 @@ static int cpsw_ndo_set_mac_address(struct net_device *ndev, void *p) memcpy(ndev->dev_addr, priv->mac_addr, ETH_ALEN); for_each_slave(priv, cpsw_set_slave_mac, priv); - pm_runtime_put(&cpsw->pdev->dev); + pm_runtime_put(cpsw->dev); return 0; } @@ -1702,9 +1702,9 @@ static int cpsw_ndo_vlan_rx_add_vid(struct net_device *ndev, if (vid == priv->data.default_vlan) return 0; - ret = pm_runtime_get_sync(&cpsw->pdev->dev); + ret = pm_runtime_get_sync(cpsw->dev); if (ret < 0) { - pm_runtime_put_noidle(&cpsw->pdev->dev); + pm_runtime_put_noidle(cpsw->dev); return ret; } @@ -1724,7 +1724,7 @@ static int cpsw_ndo_vlan_rx_add_vid(struct net_device *ndev, dev_info(priv->dev, "Adding vlanid %d to vlan filter\n", vid); ret = cpsw_add_vlan_ale_entry(priv, vid); - pm_runtime_put(&cpsw->pdev->dev); + pm_runtime_put(cpsw->dev); return ret; } @@ -1738,9 +1738,9 @@ static int cpsw_ndo_vlan_rx_kill_vid(struct net_device *ndev, if (vid == priv->data.default_vlan) return 0; - ret = pm_runtime_get_sync(&cpsw->pdev->dev); + ret = pm_runtime_get_sync(cpsw->dev); if (ret < 0) { - pm_runtime_put_noidle(&cpsw->pdev->dev); + pm_runtime_put_noidle(cpsw->dev); return ret; } @@ -1765,7 +1765,7 @@ static int cpsw_ndo_vlan_rx_kill_vid(struct net_device *ndev, ret = cpsw_ale_del_mcast(priv->ale, priv->ndev->broadcast, 0, ALE_VLAN, vid); - pm_runtime_put(&cpsw->pdev->dev); + pm_runtime_put(cpsw->dev); return ret; } @@ -1809,10 +1809,11 @@ static void cpsw_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info) { struct cpsw_common *cpsw = ndev_to_cpsw(ndev); + struct platform_device *pdev = to_platform_device(cpsw->dev); strlcpy(info->driver, "cpsw", sizeof(info->driver)); strlcpy(info->version, "1.0", sizeof(info->version)); - strlcpy(info->bus_info, cpsw->pdev->name, sizeof(info->bus_info)); + strlcpy(info->bus_info, pdev->name, sizeof(info->bus_info)); } static u32 cpsw_get_msglevel(struct net_device *ndev) @@ -1934,10 +1935,10 @@ static int cpsw_ethtool_op_begin(struct net_device *ndev) struct cpsw_common *cpsw = priv->cpsw; int ret; - ret = pm_runtime_get_sync(&cpsw->pdev->dev); + ret = pm_runtime_get_sync(cpsw->dev); if (ret < 0) { cpsw_err(priv, drv, "ethtool begin failed %d\n", ret); - pm_runtime_put_noidle(&cpsw->pdev->dev); + pm_runtime_put_noidle(cpsw->dev); } return ret; @@ -1948,7 +1949,7 @@ static void cpsw_ethtool_op_complete(struct net_device *ndev) struct cpsw_priv *priv = netdev_priv(ndev); int ret; - ret = pm_runtime_put(&priv->cpsw->pdev->dev); + ret = pm_runtime_put(priv->cpsw->dev); if (ret < 0) cpsw_err(priv, drv, "ethtool complete failed %d\n", ret); } @@ -2152,17 +2153,17 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data, return 0; } -static int cpsw_probe_dual_emac(struct platform_device *pdev, - struct cpsw_priv *priv) +static int cpsw_probe_dual_emac(struct cpsw_priv *priv) { struct cpsw_platform_data *data = &priv->data; struct net_device *ndev; struct cpsw_priv *priv_sl2; int ret = 0, i; + struct cpsw_common *cpsw = priv->cpsw; ndev = alloc_etherdev(sizeof(struct cpsw_priv)); if (!ndev) { - dev_err(&pdev->dev, "cpsw: error allocating net_device\n"); + dev_err(cpsw->dev, "cpsw: error allocating net_device\n"); return -ENOMEM; } @@ -2177,10 +2178,12 @@ static int cpsw_probe_dual_emac(struct platform_device *pdev, if (is_valid_ether_addr(data->slave_data[1].mac_addr)) { memcpy(priv_sl2->mac_addr, data->slave_data[1].mac_addr, ETH_ALEN); - dev_info(&pdev->dev, "cpsw: Detected MACID = %pM\n", priv_sl2->mac_addr); + dev_info(cpsw->dev, "cpsw: Detected MACID = %pM\n", + priv_sl2->mac_addr); } else { random_ether_addr(priv_sl2->mac_addr); - dev_info(&pdev->dev, "cpsw: Random MACID = %pM\n", priv_sl2->mac_addr); + dev_info(cpsw->dev, "cpsw: Random MACID = %pM\n", + priv_sl2->mac_addr); } memcpy(ndev->dev_addr, priv_sl2->mac_addr, ETH_ALEN); @@ -2211,10 +2214,10 @@ static int cpsw_probe_dual_emac(struct platform_device *pdev, ndev->ethtool_ops = &cpsw_ethtool_ops; /* register the network device */ - SET_NETDEV_DEV(ndev, &pdev->dev); + SET_NETDEV_DEV(ndev, cpsw->dev); ret = register_netdev(ndev); if (ret) { - dev_err(&pdev->dev, "cpsw: error registering net device\n"); + dev_err(cpsw->dev, "cpsw: error registering net device\n"); free_netdev(ndev); ret = -ENODEV; } @@ -2278,7 +2281,7 @@ static int cpsw_probe(struct platform_device *pdev) int irq; cpsw = devm_kzalloc(&pdev->dev, sizeof(struct cpsw_common), GFP_KERNEL); - cpsw->pdev = pdev; + cpsw->dev = &pdev->dev; ndev = alloc_etherdev(sizeof(struct cpsw_priv)); if (!ndev) { @@ -2541,7 +2544,7 @@ static int cpsw_probe(struct platform_device *pdev) &ss_res->start, ndev->irq); if (priv->data.dual_emac) { - ret = cpsw_probe_dual_emac(pdev, priv); + ret = cpsw_probe_dual_emac(priv); if (ret) { cpsw_err(priv, probe, "error probe slave 2 emac interface\n"); goto clean_ale_ret; @@ -2608,7 +2611,7 @@ static int cpsw_suspend(struct device *dev) } /* Select sleep pin state */ - pinctrl_pm_select_sleep_state(&pdev->dev); + pinctrl_pm_select_sleep_state(dev); return 0; } @@ -2620,7 +2623,7 @@ static int cpsw_resume(struct device *dev) struct cpsw_priv *priv = netdev_priv(ndev); /* Select default pin state */ - pinctrl_pm_select_default_state(&pdev->dev); + pinctrl_pm_select_default_state(dev); if (priv->data.dual_emac) { int i; From 5d8d0d4d46ed7bc0cf3e3ccb6c8b6ad7676335bc Mon Sep 17 00:00:00 2001 From: Ivan Khoronzhuk Date: Wed, 10 Aug 2016 02:22:39 +0300 Subject: [PATCH 08/13] net: ethernet: ti: cpsw: move links on h/w registers to cpsw_common The pointers on h/w registers are common for every cpsw_private instance, so no need to hold them for every ndev. Signed-off-by: Ivan Khoronzhuk Reviewed-by: Mugunthan V N Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/cpsw.c | 97 +++++++++++++++++++--------------- 1 file changed, 53 insertions(+), 44 deletions(-) diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index c21cc38834d0..5db2a554fc2c 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -365,6 +365,10 @@ static inline void slave_write(struct cpsw_slave *slave, u32 val, u32 offset) struct cpsw_common { struct device *dev; + struct cpsw_ss_regs __iomem *regs; + struct cpsw_wr_regs __iomem *wr_regs; + u8 __iomem *hw_stats; + struct cpsw_host_regs __iomem *host_port_regs; }; struct cpsw_priv { @@ -373,10 +377,6 @@ struct cpsw_priv { struct napi_struct napi_tx; struct device *dev; struct cpsw_platform_data data; - struct cpsw_ss_regs __iomem *regs; - struct cpsw_wr_regs __iomem *wr_regs; - u8 __iomem *hw_stats; - struct cpsw_host_regs __iomem *host_port_regs; u32 msg_enable; u32 version; u32 coal_intvl; @@ -656,8 +656,10 @@ static void cpsw_ndo_set_rx_mode(struct net_device *ndev) static void cpsw_intr_enable(struct cpsw_priv *priv) { - __raw_writel(0xFF, &priv->wr_regs->tx_en); - __raw_writel(0xFF, &priv->wr_regs->rx_en); + struct cpsw_common *cpsw = priv->cpsw; + + __raw_writel(0xFF, &cpsw->wr_regs->tx_en); + __raw_writel(0xFF, &cpsw->wr_regs->rx_en); cpdma_ctlr_int_ctrl(priv->dma, true); return; @@ -665,8 +667,10 @@ static void cpsw_intr_enable(struct cpsw_priv *priv) static void cpsw_intr_disable(struct cpsw_priv *priv) { - __raw_writel(0, &priv->wr_regs->tx_en); - __raw_writel(0, &priv->wr_regs->rx_en); + struct cpsw_common *cpsw = priv->cpsw; + + __raw_writel(0, &cpsw->wr_regs->tx_en); + __raw_writel(0, &cpsw->wr_regs->rx_en); cpdma_ctlr_int_ctrl(priv->dma, false); return; @@ -750,8 +754,9 @@ static void cpsw_rx_handler(void *token, int len, int status) static irqreturn_t cpsw_tx_interrupt(int irq, void *dev_id) { struct cpsw_priv *priv = dev_id; + struct cpsw_common *cpsw = priv->cpsw; - writel(0, &priv->wr_regs->tx_en); + writel(0, &cpsw->wr_regs->tx_en); cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX); if (priv->quirk_irq) { @@ -766,9 +771,10 @@ static irqreturn_t cpsw_tx_interrupt(int irq, void *dev_id) static irqreturn_t cpsw_rx_interrupt(int irq, void *dev_id) { struct cpsw_priv *priv = dev_id; + struct cpsw_common *cpsw = priv->cpsw; cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX); - writel(0, &priv->wr_regs->rx_en); + writel(0, &cpsw->wr_regs->rx_en); if (priv->quirk_irq) { disable_irq_nosync(priv->irqs_table[0]); @@ -783,11 +789,12 @@ static int cpsw_tx_poll(struct napi_struct *napi_tx, int budget) { struct cpsw_priv *priv = napi_to_priv(napi_tx); int num_tx; + struct cpsw_common *cpsw = priv->cpsw; num_tx = cpdma_chan_process(priv->txch, budget); if (num_tx < budget) { napi_complete(napi_tx); - writel(0xff, &priv->wr_regs->tx_en); + writel(0xff, &cpsw->wr_regs->tx_en); if (priv->quirk_irq && priv->tx_irq_disabled) { priv->tx_irq_disabled = false; enable_irq(priv->irqs_table[1]); @@ -801,11 +808,12 @@ static int cpsw_rx_poll(struct napi_struct *napi_rx, int budget) { struct cpsw_priv *priv = napi_to_priv(napi_rx); int num_rx; + struct cpsw_common *cpsw = priv->cpsw; num_rx = cpdma_chan_process(priv->rxch, budget); if (num_rx < budget) { napi_complete(napi_rx); - writel(0xff, &priv->wr_regs->rx_en); + writel(0xff, &cpsw->wr_regs->rx_en); if (priv->quirk_irq && priv->rx_irq_disabled) { priv->rx_irq_disabled = false; enable_irq(priv->irqs_table[0]); @@ -925,10 +933,11 @@ static int cpsw_set_coalesce(struct net_device *ndev, u32 prescale = 0; u32 addnl_dvdr = 1; u32 coal_intvl = 0; + struct cpsw_common *cpsw = priv->cpsw; coal_intvl = coal->rx_coalesce_usecs; - int_ctrl = readl(&priv->wr_regs->int_control); + int_ctrl = readl(&cpsw->wr_regs->int_control); prescale = priv->bus_freq_mhz * 4; if (!coal->rx_coalesce_usecs) { @@ -957,15 +966,15 @@ static int cpsw_set_coalesce(struct net_device *ndev, } num_interrupts = (1000 * addnl_dvdr) / coal_intvl; - writel(num_interrupts, &priv->wr_regs->rx_imax); - writel(num_interrupts, &priv->wr_regs->tx_imax); + writel(num_interrupts, &cpsw->wr_regs->rx_imax); + writel(num_interrupts, &cpsw->wr_regs->tx_imax); int_ctrl |= CPSW_INTPACEEN; int_ctrl &= (~CPSW_INTPRESCALE_MASK); int_ctrl |= (prescale & CPSW_INTPRESCALE_MASK); update_return: - writel(int_ctrl, &priv->wr_regs->int_control); + writel(int_ctrl, &cpsw->wr_regs->int_control); cpsw_notice(priv, timer, "Set coalesce to %d usecs.\n", coal_intvl); if (priv->data.dual_emac) { @@ -1017,6 +1026,7 @@ static void cpsw_get_ethtool_stats(struct net_device *ndev, u32 val; u8 *p; int i; + struct cpsw_common *cpsw = priv->cpsw; /* Collect Davinci CPDMA stats for Rx and Tx Channel */ cpdma_chan_get_stats(priv->rxch, &rx_stats); @@ -1025,7 +1035,7 @@ static void cpsw_get_ethtool_stats(struct net_device *ndev, for (i = 0; i < CPSW_STATS_LEN; i++) { switch (cpsw_gstrings_stats[i].type) { case CPSW_STATS: - val = readl(priv->hw_stats + + val = readl(cpsw->hw_stats + cpsw_gstrings_stats[i].stat_offset); data[i] = val; break; @@ -1164,11 +1174,12 @@ static inline void cpsw_add_default_vlan(struct cpsw_priv *priv) u32 reg; int i; int unreg_mcast_mask; + struct cpsw_common *cpsw = priv->cpsw; reg = (priv->version == CPSW_VERSION_1) ? CPSW1_PORT_VLAN : CPSW2_PORT_VLAN; - writel(vlan, &priv->host_port_regs->port_vlan); + writel(vlan, &cpsw->host_port_regs->port_vlan); for (i = 0; i < priv->data.slaves; i++) slave_write(priv->slaves + i, vlan, reg); @@ -1185,27 +1196,28 @@ static inline void cpsw_add_default_vlan(struct cpsw_priv *priv) static void cpsw_init_host_port(struct cpsw_priv *priv) { - u32 control_reg; u32 fifo_mode; + u32 control_reg; + struct cpsw_common *cpsw = priv->cpsw; /* soft reset the controller and initialize ale */ - soft_reset("cpsw", &priv->regs->soft_reset); + soft_reset("cpsw", &cpsw->regs->soft_reset); cpsw_ale_start(priv->ale); /* switch to vlan unaware mode */ cpsw_ale_control_set(priv->ale, HOST_PORT_NUM, ALE_VLAN_AWARE, CPSW_ALE_VLAN_AWARE); - control_reg = readl(&priv->regs->control); + control_reg = readl(&cpsw->regs->control); control_reg |= CPSW_VLAN_AWARE; - writel(control_reg, &priv->regs->control); + writel(control_reg, &cpsw->regs->control); fifo_mode = (priv->data.dual_emac) ? CPSW_FIFO_DUAL_MAC_MODE : CPSW_FIFO_NORMAL_MODE; - writel(fifo_mode, &priv->host_port_regs->tx_in_ctl); + writel(fifo_mode, &cpsw->host_port_regs->tx_in_ctl); /* setup host port priority mapping */ __raw_writel(CPDMA_TX_PRIORITY_MAP, - &priv->host_port_regs->cpdma_tx_pri_map); - __raw_writel(0, &priv->host_port_regs->cpdma_rx_chan_map); + &cpsw->host_port_regs->cpdma_tx_pri_map); + __raw_writel(0, &cpsw->host_port_regs->cpdma_rx_chan_map); cpsw_ale_control_set(priv->ale, HOST_PORT_NUM, ALE_PORT_STATE, ALE_PORT_STATE_FORWARD); @@ -1278,13 +1290,13 @@ static int cpsw_ndo_open(struct net_device *ndev) cpdma_control_set(priv->dma, CPDMA_RX_BUFFER_OFFSET, 0); /* disable priority elevation */ - __raw_writel(0, &priv->regs->ptype); + __raw_writel(0, &cpsw->regs->ptype); /* enable statistics collection only on all ports */ - __raw_writel(0x7, &priv->regs->stat_port_en); + __raw_writel(0x7, &cpsw->regs->stat_port_en); /* Enable internal fifo flow control */ - writel(0x7, &priv->regs->flow_control); + writel(0x7, &cpsw->regs->flow_control); napi_enable(&priv_sl0->napi_rx); napi_enable(&priv_sl0->napi_tx); @@ -1443,6 +1455,7 @@ static void cpsw_hwtstamp_v1(struct cpsw_priv *priv) static void cpsw_hwtstamp_v2(struct cpsw_priv *priv) { struct cpsw_slave *slave; + struct cpsw_common *cpsw = priv->cpsw; u32 ctrl, mtype; if (priv->data.dual_emac) @@ -1477,7 +1490,7 @@ static void cpsw_hwtstamp_v2(struct cpsw_priv *priv) slave_write(slave, mtype, CPSW2_TS_SEQ_MTYPE); slave_write(slave, ctrl, CPSW2_CONTROL); - __raw_writel(ETH_P_1588, &priv->regs->ts_ltype); + __raw_writel(ETH_P_1588, &cpsw->regs->ts_ltype); } static int cpsw_hwtstamp_set(struct net_device *dev, struct ifreq *ifr) @@ -1980,7 +1993,8 @@ static const struct ethtool_ops cpsw_ethtool_ops = { static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv, u32 slave_reg_ofs, u32 sliver_reg_ofs) { - void __iomem *regs = priv->regs; + struct cpsw_common *cpsw = priv->cpsw; + void __iomem *regs = cpsw->regs; int slave_num = slave->slave_num; struct cpsw_slave_data *data = priv->data.slave_data + slave_num; @@ -2190,11 +2204,6 @@ static int cpsw_probe_dual_emac(struct cpsw_priv *priv) priv_sl2->slaves = priv->slaves; priv_sl2->coal_intvl = 0; priv_sl2->bus_freq_mhz = priv->bus_freq_mhz; - - priv_sl2->regs = priv->regs; - priv_sl2->host_port_regs = priv->host_port_regs; - priv_sl2->wr_regs = priv->wr_regs; - priv_sl2->hw_stats = priv->hw_stats; priv_sl2->dma = priv->dma; priv_sl2->txch = priv->txch; priv_sl2->rxch = priv->rxch; @@ -2363,7 +2372,7 @@ static int cpsw_probe(struct platform_device *pdev) ret = PTR_ERR(ss_regs); goto clean_runtime_disable_ret; } - priv->regs = ss_regs; + cpsw->regs = ss_regs; /* Need to enable clocks with runtime PM api to access module * registers @@ -2373,13 +2382,13 @@ static int cpsw_probe(struct platform_device *pdev) pm_runtime_put_noidle(&pdev->dev); goto clean_runtime_disable_ret; } - priv->version = readl(&priv->regs->id_ver); + priv->version = readl(&cpsw->regs->id_ver); pm_runtime_put_sync(&pdev->dev); res = platform_get_resource(pdev, IORESOURCE_MEM, 1); - priv->wr_regs = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(priv->wr_regs)) { - ret = PTR_ERR(priv->wr_regs); + cpsw->wr_regs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(cpsw->wr_regs)) { + ret = PTR_ERR(cpsw->wr_regs); goto clean_runtime_disable_ret; } @@ -2388,9 +2397,9 @@ static int cpsw_probe(struct platform_device *pdev) switch (priv->version) { case CPSW_VERSION_1: - priv->host_port_regs = ss_regs + CPSW1_HOST_PORT_OFFSET; + cpsw->host_port_regs = ss_regs + CPSW1_HOST_PORT_OFFSET; priv->cpts->reg = ss_regs + CPSW1_CPTS_OFFSET; - priv->hw_stats = ss_regs + CPSW1_HW_STATS; + cpsw->hw_stats = ss_regs + CPSW1_HW_STATS; dma_params.dmaregs = ss_regs + CPSW1_CPDMA_OFFSET; dma_params.txhdp = ss_regs + CPSW1_STATERAM_OFFSET; ale_params.ale_regs = ss_regs + CPSW1_ALE_OFFSET; @@ -2402,9 +2411,9 @@ static int cpsw_probe(struct platform_device *pdev) case CPSW_VERSION_2: case CPSW_VERSION_3: case CPSW_VERSION_4: - priv->host_port_regs = ss_regs + CPSW2_HOST_PORT_OFFSET; + cpsw->host_port_regs = ss_regs + CPSW2_HOST_PORT_OFFSET; priv->cpts->reg = ss_regs + CPSW2_CPTS_OFFSET; - priv->hw_stats = ss_regs + CPSW2_HW_STATS; + cpsw->hw_stats = ss_regs + CPSW2_HW_STATS; dma_params.dmaregs = ss_regs + CPSW2_CPDMA_OFFSET; dma_params.txhdp = ss_regs + CPSW2_STATERAM_OFFSET; ale_params.ale_regs = ss_regs + CPSW2_ALE_OFFSET; From 2c836bd9a247132ff478857ec7b41a740df5ab64 Mon Sep 17 00:00:00 2001 From: Ivan Khoronzhuk Date: Wed, 10 Aug 2016 02:22:40 +0300 Subject: [PATCH 09/13] net: ethernet: ti: cpsw: move cpdma resources to cpsw_common Every net device private struct holds links to shared cpdma resources. No need to save and every time synchronize these resources per net dev. So, move it to common driver struct. Signed-off-by: Ivan Khoronzhuk Reviewed-by: Mugunthan V N Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/cpsw.c | 97 +++++++++++++++++----------------- 1 file changed, 48 insertions(+), 49 deletions(-) diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 5db2a554fc2c..6d99d1e614f5 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -369,6 +369,8 @@ struct cpsw_common { struct cpsw_wr_regs __iomem *wr_regs; u8 __iomem *hw_stats; struct cpsw_host_regs __iomem *host_port_regs; + struct cpdma_ctlr *dma; + struct cpdma_chan *txch, *rxch; }; struct cpsw_priv { @@ -384,8 +386,6 @@ struct cpsw_priv { int rx_packet_max; u8 mac_addr[ETH_ALEN]; struct cpsw_slave *slaves; - struct cpdma_ctlr *dma; - struct cpdma_chan *txch, *rxch; struct cpsw_ale *ale; bool rx_pause; bool tx_pause; @@ -654,25 +654,21 @@ static void cpsw_ndo_set_rx_mode(struct net_device *ndev) } } -static void cpsw_intr_enable(struct cpsw_priv *priv) +static void cpsw_intr_enable(struct cpsw_common *cpsw) { - struct cpsw_common *cpsw = priv->cpsw; - __raw_writel(0xFF, &cpsw->wr_regs->tx_en); __raw_writel(0xFF, &cpsw->wr_regs->rx_en); - cpdma_ctlr_int_ctrl(priv->dma, true); + cpdma_ctlr_int_ctrl(cpsw->dma, true); return; } -static void cpsw_intr_disable(struct cpsw_priv *priv) +static void cpsw_intr_disable(struct cpsw_common *cpsw) { - struct cpsw_common *cpsw = priv->cpsw; - __raw_writel(0, &cpsw->wr_regs->tx_en); __raw_writel(0, &cpsw->wr_regs->rx_en); - cpdma_ctlr_int_ctrl(priv->dma, false); + cpdma_ctlr_int_ctrl(cpsw->dma, false); return; } @@ -700,6 +696,7 @@ static void cpsw_rx_handler(void *token, int len, int status) struct net_device *ndev = skb->dev; struct cpsw_priv *priv = netdev_priv(ndev); int ret = 0; + struct cpsw_common *cpsw = priv->cpsw; cpsw_dual_emac_src_port_detect(status, priv, ndev, skb); @@ -745,8 +742,8 @@ static void cpsw_rx_handler(void *token, int len, int status) } requeue: - ret = cpdma_chan_submit(priv->rxch, new_skb, new_skb->data, - skb_tailroom(new_skb), 0); + ret = cpdma_chan_submit(cpsw->rxch, new_skb, new_skb->data, + skb_tailroom(new_skb), 0); if (WARN_ON(ret < 0)) dev_kfree_skb_any(new_skb); } @@ -757,7 +754,7 @@ static irqreturn_t cpsw_tx_interrupt(int irq, void *dev_id) struct cpsw_common *cpsw = priv->cpsw; writel(0, &cpsw->wr_regs->tx_en); - cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_TX); + cpdma_ctlr_eoi(cpsw->dma, CPDMA_EOI_TX); if (priv->quirk_irq) { disable_irq_nosync(priv->irqs_table[1]); @@ -773,7 +770,7 @@ static irqreturn_t cpsw_rx_interrupt(int irq, void *dev_id) struct cpsw_priv *priv = dev_id; struct cpsw_common *cpsw = priv->cpsw; - cpdma_ctlr_eoi(priv->dma, CPDMA_EOI_RX); + cpdma_ctlr_eoi(cpsw->dma, CPDMA_EOI_RX); writel(0, &cpsw->wr_regs->rx_en); if (priv->quirk_irq) { @@ -791,7 +788,7 @@ static int cpsw_tx_poll(struct napi_struct *napi_tx, int budget) int num_tx; struct cpsw_common *cpsw = priv->cpsw; - num_tx = cpdma_chan_process(priv->txch, budget); + num_tx = cpdma_chan_process(cpsw->txch, budget); if (num_tx < budget) { napi_complete(napi_tx); writel(0xff, &cpsw->wr_regs->tx_en); @@ -810,7 +807,7 @@ static int cpsw_rx_poll(struct napi_struct *napi_rx, int budget) int num_rx; struct cpsw_common *cpsw = priv->cpsw; - num_rx = cpdma_chan_process(priv->rxch, budget); + num_rx = cpdma_chan_process(cpsw->rxch, budget); if (num_rx < budget) { napi_complete(napi_rx); writel(0xff, &cpsw->wr_regs->rx_en); @@ -1020,17 +1017,16 @@ static void cpsw_get_strings(struct net_device *ndev, u32 stringset, u8 *data) static void cpsw_get_ethtool_stats(struct net_device *ndev, struct ethtool_stats *stats, u64 *data) { - struct cpsw_priv *priv = netdev_priv(ndev); struct cpdma_chan_stats rx_stats; struct cpdma_chan_stats tx_stats; u32 val; u8 *p; int i; - struct cpsw_common *cpsw = priv->cpsw; + struct cpsw_common *cpsw = ndev_to_cpsw(ndev); /* Collect Davinci CPDMA stats for Rx and Tx Channel */ - cpdma_chan_get_stats(priv->rxch, &rx_stats); - cpdma_chan_get_stats(priv->txch, &tx_stats); + cpdma_chan_get_stats(cpsw->rxch, &rx_stats); + cpdma_chan_get_stats(cpsw->txch, &tx_stats); for (i = 0; i < CPSW_STATS_LEN; i++) { switch (cpsw_gstrings_stats[i].type) { @@ -1073,7 +1069,9 @@ static int cpsw_common_res_usage_state(struct cpsw_priv *priv) static inline int cpsw_tx_packet_submit(struct cpsw_priv *priv, struct sk_buff *skb) { - return cpdma_chan_submit(priv->txch, skb, skb->data, skb->len, + struct cpsw_common *cpsw = priv->cpsw; + + return cpdma_chan_submit(cpsw->txch, skb, skb->data, skb->len, priv->emac_port + priv->data.dual_emac); } @@ -1260,7 +1258,7 @@ static int cpsw_ndo_open(struct net_device *ndev) } if (!cpsw_common_res_usage_state(priv)) - cpsw_intr_disable(priv); + cpsw_intr_disable(cpsw); netif_carrier_off(ndev); reg = priv->version; @@ -1286,8 +1284,8 @@ static int cpsw_ndo_open(struct net_device *ndev) int buf_num; /* setup tx dma to fixed prio and zero offset */ - cpdma_control_set(priv->dma, CPDMA_TX_PRIO_FIXED, 1); - cpdma_control_set(priv->dma, CPDMA_RX_BUFFER_OFFSET, 0); + cpdma_control_set(cpsw->dma, CPDMA_TX_PRIO_FIXED, 1); + cpdma_control_set(cpsw->dma, CPDMA_RX_BUFFER_OFFSET, 0); /* disable priority elevation */ __raw_writel(0, &cpsw->regs->ptype); @@ -1311,7 +1309,7 @@ static int cpsw_ndo_open(struct net_device *ndev) enable_irq(priv->irqs_table[0]); } - buf_num = cpdma_chan_get_rx_buf_num(priv->dma); + buf_num = cpdma_chan_get_rx_buf_num(cpsw->dma); for (i = 0; i < buf_num; i++) { struct sk_buff *skb; @@ -1320,8 +1318,8 @@ static int cpsw_ndo_open(struct net_device *ndev) priv->rx_packet_max, GFP_KERNEL); if (!skb) goto err_cleanup; - ret = cpdma_chan_submit(priv->rxch, skb, skb->data, - skb_tailroom(skb), 0); + ret = cpdma_chan_submit(cpsw->rxch, skb, skb->data, + skb_tailroom(skb), 0); if (ret < 0) { kfree_skb(skb); goto err_cleanup; @@ -1347,15 +1345,15 @@ static int cpsw_ndo_open(struct net_device *ndev) cpsw_set_coalesce(ndev, &coal); } - cpdma_ctlr_start(priv->dma); - cpsw_intr_enable(priv); + cpdma_ctlr_start(cpsw->dma); + cpsw_intr_enable(cpsw); if (priv->data.dual_emac) priv->slaves[priv->emac_port].open_stat = true; return 0; err_cleanup: - cpdma_ctlr_stop(priv->dma); + cpdma_ctlr_stop(cpsw->dma); for_each_slave(priv, cpsw_slave_stop, priv); pm_runtime_put_sync(cpsw->dev); netif_carrier_off(priv->ndev); @@ -1377,8 +1375,8 @@ static int cpsw_ndo_stop(struct net_device *ndev) napi_disable(&priv_sl0->napi_rx); napi_disable(&priv_sl0->napi_tx); cpts_unregister(priv->cpts); - cpsw_intr_disable(priv); - cpdma_ctlr_stop(priv->dma); + cpsw_intr_disable(cpsw); + cpdma_ctlr_stop(cpsw->dma); cpsw_ale_stop(priv->ale); } for_each_slave(priv, cpsw_slave_stop, priv); @@ -1393,6 +1391,7 @@ static netdev_tx_t cpsw_ndo_start_xmit(struct sk_buff *skb, { struct cpsw_priv *priv = netdev_priv(ndev); int ret; + struct cpsw_common *cpsw = priv->cpsw; netif_trans_update(ndev); @@ -1417,7 +1416,7 @@ static netdev_tx_t cpsw_ndo_start_xmit(struct sk_buff *skb, /* If there is no more tx desc left free then we need to * tell the kernel to stop sending us tx frames. */ - if (unlikely(!cpdma_check_free_tx_desc(priv->txch))) + if (unlikely(!cpdma_check_free_tx_desc(cpsw->txch))) netif_stop_queue(ndev); return NETDEV_TX_OK; @@ -1602,13 +1601,14 @@ static int cpsw_ndo_ioctl(struct net_device *dev, struct ifreq *req, int cmd) static void cpsw_ndo_tx_timeout(struct net_device *ndev) { struct cpsw_priv *priv = netdev_priv(ndev); + struct cpsw_common *cpsw = priv->cpsw; cpsw_err(priv, tx_err, "transmit timeout, restarting dma\n"); ndev->stats.tx_errors++; - cpsw_intr_disable(priv); - cpdma_chan_stop(priv->txch); - cpdma_chan_start(priv->txch); - cpsw_intr_enable(priv); + cpsw_intr_disable(cpsw); + cpdma_chan_stop(cpsw->txch); + cpdma_chan_start(cpsw->txch); + cpsw_intr_enable(cpsw); } static int cpsw_ndo_set_mac_address(struct net_device *ndev, void *p) @@ -1652,11 +1652,12 @@ static int cpsw_ndo_set_mac_address(struct net_device *ndev, void *p) static void cpsw_ndo_poll_controller(struct net_device *ndev) { struct cpsw_priv *priv = netdev_priv(ndev); + struct cpsw_common *cpsw = priv->cpsw; - cpsw_intr_disable(priv); + cpsw_intr_disable(priv->cpsw); cpsw_rx_interrupt(priv->irqs_table[0], priv); cpsw_tx_interrupt(priv->irqs_table[1], priv); - cpsw_intr_enable(priv); + cpsw_intr_enable(priv->cpsw); } #endif @@ -2204,9 +2205,6 @@ static int cpsw_probe_dual_emac(struct cpsw_priv *priv) priv_sl2->slaves = priv->slaves; priv_sl2->coal_intvl = 0; priv_sl2->bus_freq_mhz = priv->bus_freq_mhz; - priv_sl2->dma = priv->dma; - priv_sl2->txch = priv->txch; - priv_sl2->rxch = priv->rxch; priv_sl2->ale = priv->ale; priv_sl2->emac_port = 1; priv->slaves[1].ndev = ndev; @@ -2450,19 +2448,19 @@ static int cpsw_probe(struct platform_device *pdev) dma_params.has_ext_regs = true; dma_params.desc_hw_addr = dma_params.desc_mem_phys; - priv->dma = cpdma_ctlr_create(&dma_params); - if (!priv->dma) { + cpsw->dma = cpdma_ctlr_create(&dma_params); + if (!cpsw->dma) { dev_err(priv->dev, "error initializing dma\n"); ret = -ENOMEM; goto clean_runtime_disable_ret; } - priv->txch = cpdma_chan_create(priv->dma, tx_chan_num(0), + cpsw->txch = cpdma_chan_create(cpsw->dma, tx_chan_num(0), cpsw_tx_handler); - priv->rxch = cpdma_chan_create(priv->dma, rx_chan_num(0), + cpsw->rxch = cpdma_chan_create(cpsw->dma, rx_chan_num(0), cpsw_rx_handler); - if (WARN_ON(!priv->txch || !priv->rxch)) { + if (WARN_ON(!cpsw->txch || !cpsw->rxch)) { dev_err(priv->dev, "error initializing dma channels\n"); ret = -ENOMEM; goto clean_dma_ret; @@ -2565,7 +2563,7 @@ static int cpsw_probe(struct platform_device *pdev) clean_ale_ret: cpsw_ale_destroy(priv->ale); clean_dma_ret: - cpdma_ctlr_destroy(priv->dma); + cpdma_ctlr_destroy(cpsw->dma); clean_runtime_disable_ret: pm_runtime_disable(&pdev->dev); clean_ndev_ret: @@ -2577,6 +2575,7 @@ static int cpsw_remove(struct platform_device *pdev) { struct net_device *ndev = platform_get_drvdata(pdev); struct cpsw_priv *priv = netdev_priv(ndev); + struct cpsw_common *cpsw = priv->cpsw; int ret; ret = pm_runtime_get_sync(&pdev->dev); @@ -2590,7 +2589,7 @@ static int cpsw_remove(struct platform_device *pdev) unregister_netdev(ndev); cpsw_ale_destroy(priv->ale); - cpdma_ctlr_destroy(priv->dma); + cpdma_ctlr_destroy(cpsw->dma); of_platform_depopulate(&pdev->dev); pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); From e38b5a3db84c75c418d8c08863e005bda077f382 Mon Sep 17 00:00:00 2001 From: Ivan Khoronzhuk Date: Wed, 10 Aug 2016 02:22:41 +0300 Subject: [PATCH 10/13] net; ethernet: ti: cpsw: move irq stuff under cpsw_common The irq data are common for net devs in dual_emac mode. So no need to hold these data in every priv struct, move them under cpsw_common. Also delete irq_num var, as after optimization it's not needed. Correct number of irqs to 2, as anyway, driver is using only 2, at least for now. Signed-off-by: Ivan Khoronzhuk Reviewed-by: Mugunthan V N Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/cpsw.c | 65 +++++++++++++++------------------- 1 file changed, 29 insertions(+), 36 deletions(-) diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 6d99d1e614f5..b2482b668044 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -143,6 +143,7 @@ do { \ #define cpsw_slave_index(priv) \ ((priv->data.dual_emac) ? priv->emac_port : \ priv->data.active_slave) +#define IRQ_NUM 2 static int debug_level; module_param(debug_level, int, 0); @@ -371,6 +372,10 @@ struct cpsw_common { struct cpsw_host_regs __iomem *host_port_regs; struct cpdma_ctlr *dma; struct cpdma_chan *txch, *rxch; + bool quirk_irq; + bool rx_irq_disabled; + bool tx_irq_disabled; + u32 irqs_table[IRQ_NUM]; }; struct cpsw_priv { @@ -389,12 +394,6 @@ struct cpsw_priv { struct cpsw_ale *ale; bool rx_pause; bool tx_pause; - bool quirk_irq; - bool rx_irq_disabled; - bool tx_irq_disabled; - /* snapshot of IRQ numbers */ - u32 irqs_table[4]; - u32 num_irqs; struct cpts *cpts; u32 emac_port; struct cpsw_common *cpsw; @@ -756,9 +755,9 @@ static irqreturn_t cpsw_tx_interrupt(int irq, void *dev_id) writel(0, &cpsw->wr_regs->tx_en); cpdma_ctlr_eoi(cpsw->dma, CPDMA_EOI_TX); - if (priv->quirk_irq) { - disable_irq_nosync(priv->irqs_table[1]); - priv->tx_irq_disabled = true; + if (cpsw->quirk_irq) { + disable_irq_nosync(cpsw->irqs_table[1]); + cpsw->tx_irq_disabled = true; } napi_schedule(&priv->napi_tx); @@ -773,9 +772,9 @@ static irqreturn_t cpsw_rx_interrupt(int irq, void *dev_id) cpdma_ctlr_eoi(cpsw->dma, CPDMA_EOI_RX); writel(0, &cpsw->wr_regs->rx_en); - if (priv->quirk_irq) { - disable_irq_nosync(priv->irqs_table[0]); - priv->rx_irq_disabled = true; + if (cpsw->quirk_irq) { + disable_irq_nosync(cpsw->irqs_table[0]); + cpsw->rx_irq_disabled = true; } napi_schedule(&priv->napi_rx); @@ -792,9 +791,9 @@ static int cpsw_tx_poll(struct napi_struct *napi_tx, int budget) if (num_tx < budget) { napi_complete(napi_tx); writel(0xff, &cpsw->wr_regs->tx_en); - if (priv->quirk_irq && priv->tx_irq_disabled) { - priv->tx_irq_disabled = false; - enable_irq(priv->irqs_table[1]); + if (cpsw->quirk_irq && cpsw->tx_irq_disabled) { + cpsw->tx_irq_disabled = false; + enable_irq(cpsw->irqs_table[1]); } } @@ -811,9 +810,9 @@ static int cpsw_rx_poll(struct napi_struct *napi_rx, int budget) if (num_rx < budget) { napi_complete(napi_rx); writel(0xff, &cpsw->wr_regs->rx_en); - if (priv->quirk_irq && priv->rx_irq_disabled) { - priv->rx_irq_disabled = false; - enable_irq(priv->irqs_table[0]); + if (cpsw->quirk_irq && cpsw->rx_irq_disabled) { + cpsw->rx_irq_disabled = false; + enable_irq(cpsw->irqs_table[0]); } } @@ -1299,14 +1298,14 @@ static int cpsw_ndo_open(struct net_device *ndev) napi_enable(&priv_sl0->napi_rx); napi_enable(&priv_sl0->napi_tx); - if (priv_sl0->tx_irq_disabled) { - priv_sl0->tx_irq_disabled = false; - enable_irq(priv->irqs_table[1]); + if (cpsw->tx_irq_disabled) { + cpsw->tx_irq_disabled = false; + enable_irq(cpsw->irqs_table[1]); } - if (priv_sl0->rx_irq_disabled) { - priv_sl0->rx_irq_disabled = false; - enable_irq(priv->irqs_table[0]); + if (cpsw->rx_irq_disabled) { + cpsw->rx_irq_disabled = false; + enable_irq(cpsw->irqs_table[0]); } buf_num = cpdma_chan_get_rx_buf_num(cpsw->dma); @@ -1655,8 +1654,8 @@ static void cpsw_ndo_poll_controller(struct net_device *ndev) struct cpsw_common *cpsw = priv->cpsw; cpsw_intr_disable(priv->cpsw); - cpsw_rx_interrupt(priv->irqs_table[0], priv); - cpsw_tx_interrupt(priv->irqs_table[1], priv); + cpsw_rx_interrupt(cpsw->irqs_table[0], priv); + cpsw_tx_interrupt(cpsw->irqs_table[1], priv); cpsw_intr_enable(priv->cpsw); } #endif @@ -2173,7 +2172,7 @@ static int cpsw_probe_dual_emac(struct cpsw_priv *priv) struct cpsw_platform_data *data = &priv->data; struct net_device *ndev; struct cpsw_priv *priv_sl2; - int ret = 0, i; + int ret = 0; struct cpsw_common *cpsw = priv->cpsw; ndev = alloc_etherdev(sizeof(struct cpsw_priv)); @@ -2210,11 +2209,6 @@ static int cpsw_probe_dual_emac(struct cpsw_priv *priv) priv->slaves[1].ndev = ndev; priv_sl2->cpts = priv->cpts; priv_sl2->version = priv->version; - - for (i = 0; i < priv->num_irqs; i++) { - priv_sl2->irqs_table[i] = priv->irqs_table[i]; - priv_sl2->num_irqs = priv->num_irqs; - } ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER; ndev->netdev_ops = &cpsw_netdev_ops; @@ -2489,7 +2483,7 @@ static int cpsw_probe(struct platform_device *pdev) if (of_id) { pdev->id_entry = of_id->data; if (pdev->id_entry->driver_data) - priv->quirk_irq = true; + cpsw->quirk_irq = true; } /* Grab RX and TX IRQs. Note that we also have RX_THRESHOLD and @@ -2507,7 +2501,7 @@ static int cpsw_probe(struct platform_device *pdev) goto clean_ale_ret; } - priv->irqs_table[0] = irq; + cpsw->irqs_table[0] = irq; ret = devm_request_irq(&pdev->dev, irq, cpsw_rx_interrupt, 0, dev_name(&pdev->dev), priv); if (ret < 0) { @@ -2522,14 +2516,13 @@ static int cpsw_probe(struct platform_device *pdev) goto clean_ale_ret; } - priv->irqs_table[1] = irq; + cpsw->irqs_table[1] = irq; ret = devm_request_irq(&pdev->dev, irq, cpsw_tx_interrupt, 0, dev_name(&pdev->dev), priv); if (ret < 0) { dev_err(priv->dev, "error attaching irq (%d)\n", ret); goto clean_ale_ret; } - priv->num_irqs = 2; ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER; From 606f39939595a4d4540406bfc11f265b2036af6d Mon Sep 17 00:00:00 2001 From: Ivan Khoronzhuk Date: Wed, 10 Aug 2016 02:22:42 +0300 Subject: [PATCH 11/13] net: ethernet: ti: cpsw: move platform data and slaves info to cpsw_common These data are common for net devs in dual_emac mode. No need to hold it for every priv instance, so move them under cpsw_common. Signed-off-by: Ivan Khoronzhuk Reviewed-by: Mugunthan V N Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/cpsw.c | 265 +++++++++++++++++---------------- 1 file changed, 137 insertions(+), 128 deletions(-) diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index b2482b668044..ab5488b0cbae 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -140,9 +140,9 @@ do { \ #define CPSW_CMINTMAX_INTVL (1000 / CPSW_CMINTMIN_CNT) #define CPSW_CMINTMIN_INTVL ((1000 / CPSW_CMINTMAX_CNT) + 1) -#define cpsw_slave_index(priv) \ - ((priv->data.dual_emac) ? priv->emac_port : \ - priv->data.active_slave) +#define cpsw_slave_index(cpsw, priv) \ + ((cpsw->data.dual_emac) ? priv->emac_port : \ + cpsw->data.active_slave) #define IRQ_NUM 2 static int debug_level; @@ -366,10 +366,12 @@ static inline void slave_write(struct cpsw_slave *slave, u32 val, u32 offset) struct cpsw_common { struct device *dev; + struct cpsw_platform_data data; struct cpsw_ss_regs __iomem *regs; struct cpsw_wr_regs __iomem *wr_regs; u8 __iomem *hw_stats; struct cpsw_host_regs __iomem *host_port_regs; + struct cpsw_slave *slaves; struct cpdma_ctlr *dma; struct cpdma_chan *txch, *rxch; bool quirk_irq; @@ -383,14 +385,12 @@ struct cpsw_priv { struct napi_struct napi_rx; struct napi_struct napi_tx; struct device *dev; - struct cpsw_platform_data data; u32 msg_enable; u32 version; u32 coal_intvl; u32 bus_freq_mhz; int rx_packet_max; u8 mac_addr[ETH_ALEN]; - struct cpsw_slave *slaves; struct cpsw_ale *ale; bool rx_pause; bool tx_pause; @@ -492,38 +492,39 @@ static const struct cpsw_stats cpsw_gstrings_stats[] = { #define for_each_slave(priv, func, arg...) \ do { \ struct cpsw_slave *slave; \ + struct cpsw_common *cpsw = (priv)->cpsw; \ int n; \ - if (priv->data.dual_emac) \ - (func)((priv)->slaves + priv->emac_port, ##arg);\ + if (cpsw->data.dual_emac) \ + (func)((cpsw)->slaves + priv->emac_port, ##arg);\ else \ - for (n = (priv)->data.slaves, \ - slave = (priv)->slaves; \ + for (n = cpsw->data.slaves, \ + slave = cpsw->slaves; \ n; n--) \ (func)(slave++, ##arg); \ } while (0) -#define cpsw_get_slave_priv(priv, __slave_no__) \ - (((__slave_no__ < priv->data.slaves) && \ - (priv->slaves[__slave_no__].ndev)) ? \ - netdev_priv(priv->slaves[__slave_no__].ndev) : NULL) \ +#define cpsw_get_slave_priv(cpsw, __slave_no__) \ + (((__slave_no__ < cpsw->data.slaves) && \ + (cpsw->slaves[__slave_no__].ndev)) ? \ + netdev_priv(cpsw->slaves[__slave_no__].ndev) : NULL) \ -#define cpsw_dual_emac_src_port_detect(status, priv, ndev, skb) \ +#define cpsw_dual_emac_src_port_detect(cpsw, status, priv, ndev, skb) \ do { \ - if (!priv->data.dual_emac) \ + if (!cpsw->data.dual_emac) \ break; \ if (CPDMA_RX_SOURCE_PORT(status) == 1) { \ - ndev = priv->slaves[0].ndev; \ + ndev = cpsw->slaves[0].ndev; \ priv = netdev_priv(ndev); \ skb->dev = ndev; \ } else if (CPDMA_RX_SOURCE_PORT(status) == 2) { \ - ndev = priv->slaves[1].ndev; \ + ndev = cpsw->slaves[1].ndev; \ priv = netdev_priv(ndev); \ skb->dev = ndev; \ } \ } while (0) -#define cpsw_add_mcast(priv, addr) \ +#define cpsw_add_mcast(cpsw, priv, addr) \ do { \ - if (priv->data.dual_emac) { \ - struct cpsw_slave *slave = priv->slaves + \ + if (cpsw->data.dual_emac) { \ + struct cpsw_slave *slave = cpsw->slaves + \ priv->emac_port; \ int slave_port = cpsw_get_slave_port( \ slave->slave_num); \ @@ -545,18 +546,19 @@ static inline int cpsw_get_slave_port(u32 slave_num) static void cpsw_set_promiscious(struct net_device *ndev, bool enable) { struct cpsw_priv *priv = netdev_priv(ndev); + struct cpsw_common *cpsw = priv->cpsw; struct cpsw_ale *ale = priv->ale; int i; - if (priv->data.dual_emac) { + if (cpsw->data.dual_emac) { bool flag = false; /* Enabling promiscuous mode for one interface will be * common for both the interface as the interface shares * the same hardware resource. */ - for (i = 0; i < priv->data.slaves; i++) - if (priv->slaves[i].ndev->flags & IFF_PROMISC) + for (i = 0; i < cpsw->data.slaves; i++) + if (cpsw->slaves[i].ndev->flags & IFF_PROMISC) flag = true; if (!enable && flag) { @@ -579,7 +581,7 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable) unsigned long timeout = jiffies + HZ; /* Disable Learn for all ports (host is port 0 and slaves are port 1 and up */ - for (i = 0; i <= priv->data.slaves; i++) { + for (i = 0; i <= cpsw->data.slaves; i++) { cpsw_ale_control_set(ale, i, ALE_PORT_NOLEARN, 1); cpsw_ale_control_set(ale, i, @@ -606,7 +608,7 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable) cpsw_ale_control_set(ale, 0, ALE_P0_UNI_FLOOD, 0); /* Enable Learn for all ports (host is port 0 and slaves are port 1 and up */ - for (i = 0; i <= priv->data.slaves; i++) { + for (i = 0; i <= cpsw->data.slaves; i++) { cpsw_ale_control_set(ale, i, ALE_PORT_NOLEARN, 0); cpsw_ale_control_set(ale, i, @@ -620,12 +622,13 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable) static void cpsw_ndo_set_rx_mode(struct net_device *ndev) { struct cpsw_priv *priv = netdev_priv(ndev); + struct cpsw_common *cpsw = priv->cpsw; int vid; - if (priv->data.dual_emac) - vid = priv->slaves[priv->emac_port].port_vlan; + if (cpsw->data.dual_emac) + vid = cpsw->slaves[priv->emac_port].port_vlan; else - vid = priv->data.default_vlan; + vid = cpsw->data.default_vlan; if (ndev->flags & IFF_PROMISC) { /* Enable promiscuous mode */ @@ -648,7 +651,7 @@ static void cpsw_ndo_set_rx_mode(struct net_device *ndev) /* program multicast address list into ALE register */ netdev_for_each_mc_addr(ha, ndev) { - cpsw_add_mcast(priv, (u8 *)ha->addr); + cpsw_add_mcast(cpsw, priv, (u8 *)ha->addr); } } } @@ -697,16 +700,16 @@ static void cpsw_rx_handler(void *token, int len, int status) int ret = 0; struct cpsw_common *cpsw = priv->cpsw; - cpsw_dual_emac_src_port_detect(status, priv, ndev, skb); + cpsw_dual_emac_src_port_detect(cpsw, status, priv, ndev, skb); if (unlikely(status < 0) || unlikely(!netif_running(ndev))) { bool ndev_status = false; - struct cpsw_slave *slave = priv->slaves; + struct cpsw_slave *slave = cpsw->slaves; int n; - if (priv->data.dual_emac) { + if (cpsw->data.dual_emac) { /* In dual emac mode check for all interfaces */ - for (n = priv->data.slaves; n; n--, slave++) + for (n = cpsw->data.slaves; n; n--, slave++) if (netif_running(slave->ndev)) ndev_status = true; } @@ -848,6 +851,7 @@ static void _cpsw_adjust_link(struct cpsw_slave *slave, struct phy_device *phy = slave->phy; u32 mac_control = 0; u32 slave_port; + struct cpsw_common *cpsw = priv->cpsw; if (!phy) return; @@ -855,7 +859,7 @@ static void _cpsw_adjust_link(struct cpsw_slave *slave, slave_port = cpsw_get_slave_port(slave->slave_num); if (phy->link) { - mac_control = priv->data.mac_control; + mac_control = cpsw->data.mac_control; /* enable forwarding */ cpsw_ale_control_set(priv->ale, slave_port, @@ -973,11 +977,11 @@ static int cpsw_set_coalesce(struct net_device *ndev, writel(int_ctrl, &cpsw->wr_regs->int_control); cpsw_notice(priv, timer, "Set coalesce to %d usecs.\n", coal_intvl); - if (priv->data.dual_emac) { + if (cpsw->data.dual_emac) { int i; - for (i = 0; i < priv->data.slaves; i++) { - priv = netdev_priv(priv->slaves[i].ndev); + for (i = 0; i < cpsw->data.slaves; i++) { + priv = netdev_priv(cpsw->slaves[i].ndev); priv->coal_intvl = coal_intvl; } } else { @@ -1050,16 +1054,16 @@ static void cpsw_get_ethtool_stats(struct net_device *ndev, } } -static int cpsw_common_res_usage_state(struct cpsw_priv *priv) +static int cpsw_common_res_usage_state(struct cpsw_common *cpsw) { u32 i; u32 usage_count = 0; - if (!priv->data.dual_emac) + if (!cpsw->data.dual_emac) return 0; - for (i = 0; i < priv->data.slaves; i++) - if (priv->slaves[i].open_stat) + for (i = 0; i < cpsw->data.slaves; i++) + if (cpsw->slaves[i].open_stat) usage_count++; return usage_count; @@ -1071,7 +1075,7 @@ static inline int cpsw_tx_packet_submit(struct cpsw_priv *priv, struct cpsw_common *cpsw = priv->cpsw; return cpdma_chan_submit(cpsw->txch, skb, skb->data, skb->len, - priv->emac_port + priv->data.dual_emac); + priv->emac_port + cpsw->data.dual_emac); } static inline void cpsw_add_dual_emac_def_ale_entries( @@ -1129,7 +1133,7 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv) slave_port = cpsw_get_slave_port(slave->slave_num); - if (priv->data.dual_emac) + if (cpsw->data.dual_emac) cpsw_add_dual_emac_def_ale_entries(priv, slave, slave_port); else cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast, @@ -1167,19 +1171,19 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv) static inline void cpsw_add_default_vlan(struct cpsw_priv *priv) { - const int vlan = priv->data.default_vlan; + struct cpsw_common *cpsw = priv->cpsw; + const int vlan = cpsw->data.default_vlan; u32 reg; int i; int unreg_mcast_mask; - struct cpsw_common *cpsw = priv->cpsw; reg = (priv->version == CPSW_VERSION_1) ? CPSW1_PORT_VLAN : CPSW2_PORT_VLAN; writel(vlan, &cpsw->host_port_regs->port_vlan); - for (i = 0; i < priv->data.slaves; i++) - slave_write(priv->slaves + i, vlan, reg); + for (i = 0; i < cpsw->data.slaves; i++) + slave_write(cpsw->slaves + i, vlan, reg); if (priv->ndev->flags & IFF_ALLMULTI) unreg_mcast_mask = ALE_ALL_PORTS; @@ -1207,7 +1211,7 @@ static void cpsw_init_host_port(struct cpsw_priv *priv) control_reg = readl(&cpsw->regs->control); control_reg |= CPSW_VLAN_AWARE; writel(control_reg, &cpsw->regs->control); - fifo_mode = (priv->data.dual_emac) ? CPSW_FIFO_DUAL_MAC_MODE : + fifo_mode = (cpsw->data.dual_emac) ? CPSW_FIFO_DUAL_MAC_MODE : CPSW_FIFO_NORMAL_MODE; writel(fifo_mode, &cpsw->host_port_regs->tx_in_ctl); @@ -1219,7 +1223,7 @@ static void cpsw_init_host_port(struct cpsw_priv *priv) cpsw_ale_control_set(priv->ale, HOST_PORT_NUM, ALE_PORT_STATE, ALE_PORT_STATE_FORWARD); - if (!priv->data.dual_emac) { + if (!cpsw->data.dual_emac) { cpsw_ale_add_ucast(priv->ale, priv->mac_addr, HOST_PORT_NUM, 0, 0); cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast, @@ -1256,7 +1260,7 @@ static int cpsw_ndo_open(struct net_device *ndev) return ret; } - if (!cpsw_common_res_usage_state(priv)) + if (!cpsw_common_res_usage_state(cpsw)) cpsw_intr_disable(cpsw); netif_carrier_off(ndev); @@ -1267,19 +1271,19 @@ static int cpsw_ndo_open(struct net_device *ndev) CPSW_RTL_VERSION(reg)); /* initialize host and slave ports */ - if (!cpsw_common_res_usage_state(priv)) + if (!cpsw_common_res_usage_state(cpsw)) cpsw_init_host_port(priv); for_each_slave(priv, cpsw_slave_open, priv); /* Add default VLAN */ - if (!priv->data.dual_emac) + if (!cpsw->data.dual_emac) cpsw_add_default_vlan(priv); else - cpsw_ale_add_vlan(priv->ale, priv->data.default_vlan, + cpsw_ale_add_vlan(priv->ale, cpsw->data.default_vlan, ALE_ALL_PORTS, ALE_ALL_PORTS, 0, 0); - if (!cpsw_common_res_usage_state(priv)) { - struct cpsw_priv *priv_sl0 = cpsw_get_slave_priv(priv, 0); + if (!cpsw_common_res_usage_state(cpsw)) { + struct cpsw_priv *priv_sl0 = cpsw_get_slave_priv(cpsw, 0); int buf_num; /* setup tx dma to fixed prio and zero offset */ @@ -1330,8 +1334,8 @@ static int cpsw_ndo_open(struct net_device *ndev) cpsw_info(priv, ifup, "submitted %d rx descriptors\n", i); if (cpts_register(cpsw->dev, priv->cpts, - priv->data.cpts_clock_mult, - priv->data.cpts_clock_shift)) + cpsw->data.cpts_clock_mult, + cpsw->data.cpts_clock_shift)) dev_err(priv->dev, "error registering cpts device\n"); } @@ -1347,8 +1351,8 @@ static int cpsw_ndo_open(struct net_device *ndev) cpdma_ctlr_start(cpsw->dma); cpsw_intr_enable(cpsw); - if (priv->data.dual_emac) - priv->slaves[priv->emac_port].open_stat = true; + if (cpsw->data.dual_emac) + cpsw->slaves[priv->emac_port].open_stat = true; return 0; err_cleanup: @@ -1368,8 +1372,8 @@ static int cpsw_ndo_stop(struct net_device *ndev) netif_stop_queue(priv->ndev); netif_carrier_off(priv->ndev); - if (cpsw_common_res_usage_state(priv) <= 1) { - struct cpsw_priv *priv_sl0 = cpsw_get_slave_priv(priv, 0); + if (cpsw_common_res_usage_state(cpsw) <= 1) { + struct cpsw_priv *priv_sl0 = cpsw_get_slave_priv(cpsw, 0); napi_disable(&priv_sl0->napi_rx); napi_disable(&priv_sl0->napi_tx); @@ -1380,8 +1384,8 @@ static int cpsw_ndo_stop(struct net_device *ndev) } for_each_slave(priv, cpsw_slave_stop, priv); pm_runtime_put_sync(cpsw->dev); - if (priv->data.dual_emac) - priv->slaves[priv->emac_port].open_stat = false; + if (cpsw->data.dual_emac) + cpsw->slaves[priv->emac_port].open_stat = false; return 0; } @@ -1429,7 +1433,8 @@ static netdev_tx_t cpsw_ndo_start_xmit(struct sk_buff *skb, static void cpsw_hwtstamp_v1(struct cpsw_priv *priv) { - struct cpsw_slave *slave = &priv->slaves[priv->data.active_slave]; + struct cpsw_common *cpsw = priv->cpsw; + struct cpsw_slave *slave = &cpsw->slaves[cpsw->data.active_slave]; u32 ts_en, seq_id; if (!priv->cpts->tx_enable && !priv->cpts->rx_enable) { @@ -1456,10 +1461,10 @@ static void cpsw_hwtstamp_v2(struct cpsw_priv *priv) struct cpsw_common *cpsw = priv->cpsw; u32 ctrl, mtype; - if (priv->data.dual_emac) - slave = &priv->slaves[priv->emac_port]; + if (cpsw->data.dual_emac) + slave = &cpsw->slaves[priv->emac_port]; else - slave = &priv->slaves[priv->data.active_slave]; + slave = &cpsw->slaves[cpsw->data.active_slave]; ctrl = slave_read(slave, CPSW2_CONTROL); switch (priv->version) { @@ -1578,7 +1583,8 @@ static int cpsw_hwtstamp_get(struct net_device *dev, struct ifreq *ifr) static int cpsw_ndo_ioctl(struct net_device *dev, struct ifreq *req, int cmd) { struct cpsw_priv *priv = netdev_priv(dev); - int slave_no = cpsw_slave_index(priv); + struct cpsw_common *cpsw = priv->cpsw; + int slave_no = cpsw_slave_index(cpsw, priv); if (!netif_running(dev)) return -EINVAL; @@ -1592,9 +1598,9 @@ static int cpsw_ndo_ioctl(struct net_device *dev, struct ifreq *req, int cmd) #endif } - if (!priv->slaves[slave_no].phy) + if (!cpsw->slaves[slave_no].phy) return -EOPNOTSUPP; - return phy_mii_ioctl(priv->slaves[slave_no].phy, req, cmd); + return phy_mii_ioctl(cpsw->slaves[slave_no].phy, req, cmd); } static void cpsw_ndo_tx_timeout(struct net_device *ndev) @@ -1628,8 +1634,8 @@ static int cpsw_ndo_set_mac_address(struct net_device *ndev, void *p) return ret; } - if (priv->data.dual_emac) { - vid = priv->slaves[priv->emac_port].port_vlan; + if (cpsw->data.dual_emac) { + vid = cpsw->slaves[priv->emac_port].port_vlan; flags = ALE_VLAN; } @@ -1666,8 +1672,9 @@ static inline int cpsw_add_vlan_ale_entry(struct cpsw_priv *priv, int ret; int unreg_mcast_mask = 0; u32 port_mask; + struct cpsw_common *cpsw = priv->cpsw; - if (priv->data.dual_emac) { + if (cpsw->data.dual_emac) { port_mask = (1 << (priv->emac_port + 1)) | ALE_PORT_HOST; if (priv->ndev->flags & IFF_ALLMULTI) @@ -1712,7 +1719,7 @@ static int cpsw_ndo_vlan_rx_add_vid(struct net_device *ndev, struct cpsw_common *cpsw = priv->cpsw; int ret; - if (vid == priv->data.default_vlan) + if (vid == cpsw->data.default_vlan) return 0; ret = pm_runtime_get_sync(cpsw->dev); @@ -1721,15 +1728,15 @@ static int cpsw_ndo_vlan_rx_add_vid(struct net_device *ndev, return ret; } - if (priv->data.dual_emac) { + if (cpsw->data.dual_emac) { /* In dual EMAC, reserved VLAN id should not be used for * creating VLAN interfaces as this can break the dual * EMAC port separation */ int i; - for (i = 0; i < priv->data.slaves; i++) { - if (vid == priv->slaves[i].port_vlan) + for (i = 0; i < cpsw->data.slaves; i++) { + if (vid == cpsw->slaves[i].port_vlan) return -EINVAL; } } @@ -1748,7 +1755,7 @@ static int cpsw_ndo_vlan_rx_kill_vid(struct net_device *ndev, struct cpsw_common *cpsw = priv->cpsw; int ret; - if (vid == priv->data.default_vlan) + if (vid == cpsw->data.default_vlan) return 0; ret = pm_runtime_get_sync(cpsw->dev); @@ -1757,11 +1764,11 @@ static int cpsw_ndo_vlan_rx_kill_vid(struct net_device *ndev, return ret; } - if (priv->data.dual_emac) { + if (cpsw->data.dual_emac) { int i; - for (i = 0; i < priv->data.slaves; i++) { - if (vid == priv->slaves[i].port_vlan) + for (i = 0; i < cpsw->data.slaves; i++) { + if (vid == cpsw->slaves[i].port_vlan) return -EINVAL; } } @@ -1801,9 +1808,9 @@ static const struct net_device_ops cpsw_netdev_ops = { static int cpsw_get_regs_len(struct net_device *ndev) { - struct cpsw_priv *priv = netdev_priv(ndev); + struct cpsw_common *cpsw = ndev_to_cpsw(ndev); - return priv->data.ale_entries * ALE_ENTRY_WORDS * sizeof(u32); + return cpsw->data.ale_entries * ALE_ENTRY_WORDS * sizeof(u32); } static void cpsw_get_regs(struct net_device *ndev, @@ -1877,10 +1884,11 @@ static int cpsw_get_settings(struct net_device *ndev, struct ethtool_cmd *ecmd) { struct cpsw_priv *priv = netdev_priv(ndev); - int slave_no = cpsw_slave_index(priv); + struct cpsw_common *cpsw = priv->cpsw; + int slave_no = cpsw_slave_index(cpsw, priv); - if (priv->slaves[slave_no].phy) - return phy_ethtool_gset(priv->slaves[slave_no].phy, ecmd); + if (cpsw->slaves[slave_no].phy) + return phy_ethtool_gset(cpsw->slaves[slave_no].phy, ecmd); else return -EOPNOTSUPP; } @@ -1888,10 +1896,11 @@ static int cpsw_get_settings(struct net_device *ndev, static int cpsw_set_settings(struct net_device *ndev, struct ethtool_cmd *ecmd) { struct cpsw_priv *priv = netdev_priv(ndev); - int slave_no = cpsw_slave_index(priv); + struct cpsw_common *cpsw = priv->cpsw; + int slave_no = cpsw_slave_index(cpsw, priv); - if (priv->slaves[slave_no].phy) - return phy_ethtool_sset(priv->slaves[slave_no].phy, ecmd); + if (cpsw->slaves[slave_no].phy) + return phy_ethtool_sset(cpsw->slaves[slave_no].phy, ecmd); else return -EOPNOTSUPP; } @@ -1899,22 +1908,24 @@ static int cpsw_set_settings(struct net_device *ndev, struct ethtool_cmd *ecmd) static void cpsw_get_wol(struct net_device *ndev, struct ethtool_wolinfo *wol) { struct cpsw_priv *priv = netdev_priv(ndev); - int slave_no = cpsw_slave_index(priv); + struct cpsw_common *cpsw = priv->cpsw; + int slave_no = cpsw_slave_index(cpsw, priv); wol->supported = 0; wol->wolopts = 0; - if (priv->slaves[slave_no].phy) - phy_ethtool_get_wol(priv->slaves[slave_no].phy, wol); + if (cpsw->slaves[slave_no].phy) + phy_ethtool_get_wol(cpsw->slaves[slave_no].phy, wol); } static int cpsw_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol) { struct cpsw_priv *priv = netdev_priv(ndev); - int slave_no = cpsw_slave_index(priv); + struct cpsw_common *cpsw = priv->cpsw; + int slave_no = cpsw_slave_index(cpsw, priv); - if (priv->slaves[slave_no].phy) - return phy_ethtool_set_wol(priv->slaves[slave_no].phy, wol); + if (cpsw->slaves[slave_no].phy) + return phy_ethtool_set_wol(cpsw->slaves[slave_no].phy, wol); else return -EOPNOTSUPP; } @@ -1990,13 +2001,12 @@ static const struct ethtool_ops cpsw_ethtool_ops = { .complete = cpsw_ethtool_op_complete, }; -static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv, +static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_common *cpsw, u32 slave_reg_ofs, u32 sliver_reg_ofs) { - struct cpsw_common *cpsw = priv->cpsw; void __iomem *regs = cpsw->regs; int slave_num = slave->slave_num; - struct cpsw_slave_data *data = priv->data.slave_data + slave_num; + struct cpsw_slave_data *data = cpsw->data.slave_data + slave_num; slave->data = data; slave->regs = regs + slave_reg_ofs; @@ -2169,11 +2179,11 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data, static int cpsw_probe_dual_emac(struct cpsw_priv *priv) { - struct cpsw_platform_data *data = &priv->data; + struct cpsw_common *cpsw = priv->cpsw; + struct cpsw_platform_data *data = &cpsw->data; struct net_device *ndev; struct cpsw_priv *priv_sl2; int ret = 0; - struct cpsw_common *cpsw = priv->cpsw; ndev = alloc_etherdev(sizeof(struct cpsw_priv)); if (!ndev) { @@ -2182,8 +2192,7 @@ static int cpsw_probe_dual_emac(struct cpsw_priv *priv) } priv_sl2 = netdev_priv(ndev); - priv_sl2->cpsw = priv->cpsw; - priv_sl2->data = *data; + priv_sl2->cpsw = cpsw; priv_sl2->ndev = ndev; priv_sl2->dev = &ndev->dev; priv_sl2->msg_enable = netif_msg_init(debug_level, CPSW_DEBUG); @@ -2201,12 +2210,11 @@ static int cpsw_probe_dual_emac(struct cpsw_priv *priv) } memcpy(ndev->dev_addr, priv_sl2->mac_addr, ETH_ALEN); - priv_sl2->slaves = priv->slaves; priv_sl2->coal_intvl = 0; priv_sl2->bus_freq_mhz = priv->bus_freq_mhz; priv_sl2->ale = priv->ale; priv_sl2->emac_port = 1; - priv->slaves[1].ndev = ndev; + cpsw->slaves[1].ndev = ndev; priv_sl2->cpts = priv->cpts; priv_sl2->version = priv->version; ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER; @@ -2319,12 +2327,12 @@ static int cpsw_probe(struct platform_device *pdev) /* Select default pin state */ pinctrl_pm_select_default_state(&pdev->dev); - if (cpsw_probe_dt(&priv->data, pdev)) { + if (cpsw_probe_dt(&cpsw->data, pdev)) { dev_err(&pdev->dev, "cpsw: platform data missing\n"); ret = -ENODEV; goto clean_runtime_disable_ret; } - data = &priv->data; + data = &cpsw->data; if (is_valid_ether_addr(data->slave_data[0].mac_addr)) { memcpy(priv->mac_addr, data->slave_data[0].mac_addr, ETH_ALEN); @@ -2336,17 +2344,17 @@ static int cpsw_probe(struct platform_device *pdev) memcpy(ndev->dev_addr, priv->mac_addr, ETH_ALEN); - priv->slaves = devm_kzalloc(&pdev->dev, + cpsw->slaves = devm_kzalloc(&pdev->dev, sizeof(struct cpsw_slave) * data->slaves, GFP_KERNEL); - if (!priv->slaves) { + if (!cpsw->slaves) { ret = -ENOMEM; goto clean_runtime_disable_ret; } for (i = 0; i < data->slaves; i++) - priv->slaves[i].slave_num = i; + cpsw->slaves[i].slave_num = i; - priv->slaves[0].ndev = ndev; + cpsw->slaves[0].ndev = ndev; priv->emac_port = 0; clk = devm_clk_get(&pdev->dev, "fck"); @@ -2420,9 +2428,10 @@ static int cpsw_probe(struct platform_device *pdev) ret = -ENODEV; goto clean_runtime_disable_ret; } - for (i = 0; i < priv->data.slaves; i++) { - struct cpsw_slave *slave = &priv->slaves[i]; - cpsw_slave_init(slave, priv, slave_offset, sliver_offset); + for (i = 0; i < cpsw->data.slaves; i++) { + struct cpsw_slave *slave = &cpsw->slaves[i]; + + cpsw_slave_init(slave, cpsw, slave_offset, sliver_offset); slave_offset += slave_size; sliver_offset += SLIVER_SIZE; } @@ -2543,7 +2552,7 @@ static int cpsw_probe(struct platform_device *pdev) cpsw_notice(priv, probe, "initialized device (regs %pa, irq %d)\n", &ss_res->start, ndev->irq); - if (priv->data.dual_emac) { + if (cpsw->data.dual_emac) { ret = cpsw_probe_dual_emac(priv); if (ret) { cpsw_err(priv, probe, "error probe slave 2 emac interface\n"); @@ -2577,8 +2586,8 @@ static int cpsw_remove(struct platform_device *pdev) return ret; } - if (priv->data.dual_emac) - unregister_netdev(priv->slaves[1].ndev); + if (cpsw->data.dual_emac) + unregister_netdev(cpsw->slaves[1].ndev); unregister_netdev(ndev); cpsw_ale_destroy(priv->ale); @@ -2586,8 +2595,8 @@ static int cpsw_remove(struct platform_device *pdev) of_platform_depopulate(&pdev->dev); pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); - if (priv->data.dual_emac) - free_netdev(priv->slaves[1].ndev); + if (cpsw->data.dual_emac) + free_netdev(cpsw->slaves[1].ndev); free_netdev(ndev); return 0; } @@ -2597,14 +2606,14 @@ static int cpsw_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct net_device *ndev = platform_get_drvdata(pdev); - struct cpsw_priv *priv = netdev_priv(ndev); + struct cpsw_common *cpsw = ndev_to_cpsw(ndev); - if (priv->data.dual_emac) { + if (cpsw->data.dual_emac) { int i; - for (i = 0; i < priv->data.slaves; i++) { - if (netif_running(priv->slaves[i].ndev)) - cpsw_ndo_stop(priv->slaves[i].ndev); + for (i = 0; i < cpsw->data.slaves; i++) { + if (netif_running(cpsw->slaves[i].ndev)) + cpsw_ndo_stop(cpsw->slaves[i].ndev); } } else { if (netif_running(ndev)) @@ -2621,17 +2630,17 @@ static int cpsw_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct net_device *ndev = platform_get_drvdata(pdev); - struct cpsw_priv *priv = netdev_priv(ndev); + struct cpsw_common *cpsw = netdev_priv(ndev); /* Select default pin state */ pinctrl_pm_select_default_state(dev); - if (priv->data.dual_emac) { + if (cpsw->data.dual_emac) { int i; - for (i = 0; i < priv->data.slaves; i++) { - if (netif_running(priv->slaves[i].ndev)) - cpsw_ndo_open(priv->slaves[i].ndev); + for (i = 0; i < cpsw->data.slaves; i++) { + if (netif_running(cpsw->slaves[i].ndev)) + cpsw_ndo_open(cpsw->slaves[i].ndev); } } else { if (netif_running(ndev)) From dbc4ec522d2ee2b3fa24d329a7a63594aba3b069 Mon Sep 17 00:00:00 2001 From: Ivan Khoronzhuk Date: Wed, 10 Aug 2016 02:22:43 +0300 Subject: [PATCH 12/13] net: ethernet: ti: cpsw: move napi struct to cpsw_common The napi structs are common for both net devices in dual_emac mode, In order to not hold duplicate links to them, move to cpsw_common. Signed-off-by: Ivan Khoronzhuk Reviewed-by: Mugunthan V N Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/cpsw.c | 52 ++++++++++++++-------------------- 1 file changed, 22 insertions(+), 30 deletions(-) diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index ab5488b0cbae..2c2e36a416c1 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -367,6 +367,8 @@ static inline void slave_write(struct cpsw_slave *slave, u32 val, u32 offset) struct cpsw_common { struct device *dev; struct cpsw_platform_data data; + struct napi_struct napi_rx; + struct napi_struct napi_tx; struct cpsw_ss_regs __iomem *regs; struct cpsw_wr_regs __iomem *wr_regs; u8 __iomem *hw_stats; @@ -382,8 +384,6 @@ struct cpsw_common { struct cpsw_priv { struct net_device *ndev; - struct napi_struct napi_rx; - struct napi_struct napi_tx; struct device *dev; u32 msg_enable; u32 version; @@ -488,7 +488,7 @@ static const struct cpsw_stats cpsw_gstrings_stats[] = { #define CPSW_STATS_LEN ARRAY_SIZE(cpsw_gstrings_stats) #define ndev_to_cpsw(ndev) (((struct cpsw_priv *)netdev_priv(ndev))->cpsw) -#define napi_to_priv(napi) container_of(napi, struct cpsw_priv, napi) +#define napi_to_cpsw(napi) container_of(napi, struct cpsw_common, napi) #define for_each_slave(priv, func, arg...) \ do { \ struct cpsw_slave *slave; \ @@ -752,8 +752,7 @@ static void cpsw_rx_handler(void *token, int len, int status) static irqreturn_t cpsw_tx_interrupt(int irq, void *dev_id) { - struct cpsw_priv *priv = dev_id; - struct cpsw_common *cpsw = priv->cpsw; + struct cpsw_common *cpsw = dev_id; writel(0, &cpsw->wr_regs->tx_en); cpdma_ctlr_eoi(cpsw->dma, CPDMA_EOI_TX); @@ -763,14 +762,13 @@ static irqreturn_t cpsw_tx_interrupt(int irq, void *dev_id) cpsw->tx_irq_disabled = true; } - napi_schedule(&priv->napi_tx); + napi_schedule(&cpsw->napi_tx); return IRQ_HANDLED; } static irqreturn_t cpsw_rx_interrupt(int irq, void *dev_id) { - struct cpsw_priv *priv = dev_id; - struct cpsw_common *cpsw = priv->cpsw; + struct cpsw_common *cpsw = dev_id; cpdma_ctlr_eoi(cpsw->dma, CPDMA_EOI_RX); writel(0, &cpsw->wr_regs->rx_en); @@ -780,15 +778,14 @@ static irqreturn_t cpsw_rx_interrupt(int irq, void *dev_id) cpsw->rx_irq_disabled = true; } - napi_schedule(&priv->napi_rx); + napi_schedule(&cpsw->napi_rx); return IRQ_HANDLED; } static int cpsw_tx_poll(struct napi_struct *napi_tx, int budget) { - struct cpsw_priv *priv = napi_to_priv(napi_tx); + struct cpsw_common *cpsw = napi_to_cpsw(napi_tx); int num_tx; - struct cpsw_common *cpsw = priv->cpsw; num_tx = cpdma_chan_process(cpsw->txch, budget); if (num_tx < budget) { @@ -805,9 +802,8 @@ static int cpsw_tx_poll(struct napi_struct *napi_tx, int budget) static int cpsw_rx_poll(struct napi_struct *napi_rx, int budget) { - struct cpsw_priv *priv = napi_to_priv(napi_rx); + struct cpsw_common *cpsw = napi_to_cpsw(napi_rx); int num_rx; - struct cpsw_common *cpsw = priv->cpsw; num_rx = cpdma_chan_process(cpsw->rxch, budget); if (num_rx < budget) { @@ -1283,7 +1279,6 @@ static int cpsw_ndo_open(struct net_device *ndev) ALE_ALL_PORTS, ALE_ALL_PORTS, 0, 0); if (!cpsw_common_res_usage_state(cpsw)) { - struct cpsw_priv *priv_sl0 = cpsw_get_slave_priv(cpsw, 0); int buf_num; /* setup tx dma to fixed prio and zero offset */ @@ -1299,8 +1294,8 @@ static int cpsw_ndo_open(struct net_device *ndev) /* Enable internal fifo flow control */ writel(0x7, &cpsw->regs->flow_control); - napi_enable(&priv_sl0->napi_rx); - napi_enable(&priv_sl0->napi_tx); + napi_enable(&cpsw->napi_rx); + napi_enable(&cpsw->napi_tx); if (cpsw->tx_irq_disabled) { cpsw->tx_irq_disabled = false; @@ -1373,10 +1368,8 @@ static int cpsw_ndo_stop(struct net_device *ndev) netif_carrier_off(priv->ndev); if (cpsw_common_res_usage_state(cpsw) <= 1) { - struct cpsw_priv *priv_sl0 = cpsw_get_slave_priv(cpsw, 0); - - napi_disable(&priv_sl0->napi_rx); - napi_disable(&priv_sl0->napi_tx); + napi_disable(&cpsw->napi_rx); + napi_disable(&cpsw->napi_tx); cpts_unregister(priv->cpts); cpsw_intr_disable(cpsw); cpdma_ctlr_stop(cpsw->dma); @@ -1656,13 +1649,12 @@ static int cpsw_ndo_set_mac_address(struct net_device *ndev, void *p) #ifdef CONFIG_NET_POLL_CONTROLLER static void cpsw_ndo_poll_controller(struct net_device *ndev) { - struct cpsw_priv *priv = netdev_priv(ndev); - struct cpsw_common *cpsw = priv->cpsw; + struct cpsw_common *cpsw = ndev_to_cpsw(ndev); - cpsw_intr_disable(priv->cpsw); - cpsw_rx_interrupt(cpsw->irqs_table[0], priv); - cpsw_tx_interrupt(cpsw->irqs_table[1], priv); - cpsw_intr_enable(priv->cpsw); + cpsw_intr_disable(cpsw); + cpsw_rx_interrupt(cpsw->irqs_table[0], cpsw); + cpsw_tx_interrupt(cpsw->irqs_table[1], cpsw); + cpsw_intr_enable(cpsw); } #endif @@ -2512,7 +2504,7 @@ static int cpsw_probe(struct platform_device *pdev) cpsw->irqs_table[0] = irq; ret = devm_request_irq(&pdev->dev, irq, cpsw_rx_interrupt, - 0, dev_name(&pdev->dev), priv); + 0, dev_name(&pdev->dev), cpsw); if (ret < 0) { dev_err(priv->dev, "error attaching irq (%d)\n", ret); goto clean_ale_ret; @@ -2527,7 +2519,7 @@ static int cpsw_probe(struct platform_device *pdev) cpsw->irqs_table[1] = irq; ret = devm_request_irq(&pdev->dev, irq, cpsw_tx_interrupt, - 0, dev_name(&pdev->dev), priv); + 0, dev_name(&pdev->dev), cpsw); if (ret < 0) { dev_err(priv->dev, "error attaching irq (%d)\n", ret); goto clean_ale_ret; @@ -2537,8 +2529,8 @@ static int cpsw_probe(struct platform_device *pdev) ndev->netdev_ops = &cpsw_netdev_ops; ndev->ethtool_ops = &cpsw_ethtool_ops; - netif_napi_add(ndev, &priv->napi_rx, cpsw_rx_poll, CPSW_POLL_WEIGHT); - netif_tx_napi_add(ndev, &priv->napi_tx, cpsw_tx_poll, CPSW_POLL_WEIGHT); + netif_napi_add(ndev, &cpsw->napi_rx, cpsw_rx_poll, CPSW_POLL_WEIGHT); + netif_tx_napi_add(ndev, &cpsw->napi_tx, cpsw_tx_poll, CPSW_POLL_WEIGHT); /* register the network device */ SET_NETDEV_DEV(ndev, &pdev->dev); From 2a05a622d88a8e195adaab3ab83aaba317a2e5cf Mon Sep 17 00:00:00 2001 From: Ivan Khoronzhuk Date: Wed, 10 Aug 2016 02:22:44 +0300 Subject: [PATCH 13/13] net: ethernet: ti: cpsw: move ale, cpts and drivers params under cpsw_common The ale, cpts, version, rx_packet_max, bus_freq, interrupt pacing parameters are common per net device that uses the same h/w. So, move them to common driver structure. Signed-off-by: Ivan Khoronzhuk Reviewed-by: Mugunthan V N Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/cpsw.c | 235 +++++++++++++++------------------ 1 file changed, 106 insertions(+), 129 deletions(-) diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 2c2e36a416c1..b4d3b410c32a 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -373,28 +373,28 @@ struct cpsw_common { struct cpsw_wr_regs __iomem *wr_regs; u8 __iomem *hw_stats; struct cpsw_host_regs __iomem *host_port_regs; + u32 version; + u32 coal_intvl; + u32 bus_freq_mhz; + int rx_packet_max; struct cpsw_slave *slaves; struct cpdma_ctlr *dma; struct cpdma_chan *txch, *rxch; + struct cpsw_ale *ale; bool quirk_irq; bool rx_irq_disabled; bool tx_irq_disabled; u32 irqs_table[IRQ_NUM]; + struct cpts *cpts; }; struct cpsw_priv { struct net_device *ndev; struct device *dev; u32 msg_enable; - u32 version; - u32 coal_intvl; - u32 bus_freq_mhz; - int rx_packet_max; u8 mac_addr[ETH_ALEN]; - struct cpsw_ale *ale; bool rx_pause; bool tx_pause; - struct cpts *cpts; u32 emac_port; struct cpsw_common *cpsw; }; @@ -502,22 +502,16 @@ static const struct cpsw_stats cpsw_gstrings_stats[] = { n; n--) \ (func)(slave++, ##arg); \ } while (0) -#define cpsw_get_slave_priv(cpsw, __slave_no__) \ - (((__slave_no__ < cpsw->data.slaves) && \ - (cpsw->slaves[__slave_no__].ndev)) ? \ - netdev_priv(cpsw->slaves[__slave_no__].ndev) : NULL) \ -#define cpsw_dual_emac_src_port_detect(cpsw, status, priv, ndev, skb) \ +#define cpsw_dual_emac_src_port_detect(cpsw, status, ndev, skb) \ do { \ if (!cpsw->data.dual_emac) \ break; \ if (CPDMA_RX_SOURCE_PORT(status) == 1) { \ ndev = cpsw->slaves[0].ndev; \ - priv = netdev_priv(ndev); \ skb->dev = ndev; \ } else if (CPDMA_RX_SOURCE_PORT(status) == 2) { \ ndev = cpsw->slaves[1].ndev; \ - priv = netdev_priv(ndev); \ skb->dev = ndev; \ } \ } while (0) @@ -528,11 +522,11 @@ static const struct cpsw_stats cpsw_gstrings_stats[] = { priv->emac_port; \ int slave_port = cpsw_get_slave_port( \ slave->slave_num); \ - cpsw_ale_add_mcast(priv->ale, addr, \ + cpsw_ale_add_mcast(cpsw->ale, addr, \ 1 << slave_port | ALE_PORT_HOST, \ ALE_VLAN, slave->port_vlan, 0); \ } else { \ - cpsw_ale_add_mcast(priv->ale, addr, \ + cpsw_ale_add_mcast(cpsw->ale, addr, \ ALE_ALL_PORTS, \ 0, 0, 0); \ } \ @@ -545,9 +539,8 @@ static inline int cpsw_get_slave_port(u32 slave_num) static void cpsw_set_promiscious(struct net_device *ndev, bool enable) { - struct cpsw_priv *priv = netdev_priv(ndev); - struct cpsw_common *cpsw = priv->cpsw; - struct cpsw_ale *ale = priv->ale; + struct cpsw_common *cpsw = ndev_to_cpsw(ndev); + struct cpsw_ale *ale = cpsw->ale; int i; if (cpsw->data.dual_emac) { @@ -633,7 +626,7 @@ static void cpsw_ndo_set_rx_mode(struct net_device *ndev) if (ndev->flags & IFF_PROMISC) { /* Enable promiscuous mode */ cpsw_set_promiscious(ndev, true); - cpsw_ale_set_allmulti(priv->ale, IFF_ALLMULTI); + cpsw_ale_set_allmulti(cpsw->ale, IFF_ALLMULTI); return; } else { /* Disable promiscuous mode */ @@ -641,10 +634,10 @@ static void cpsw_ndo_set_rx_mode(struct net_device *ndev) } /* Restore allmulti on vlans if necessary */ - cpsw_ale_set_allmulti(priv->ale, priv->ndev->flags & IFF_ALLMULTI); + cpsw_ale_set_allmulti(cpsw->ale, priv->ndev->flags & IFF_ALLMULTI); /* Clear all mcast from ALE */ - cpsw_ale_flush_multicast(priv->ale, ALE_ALL_PORTS, vid); + cpsw_ale_flush_multicast(cpsw->ale, ALE_ALL_PORTS, vid); if (!netdev_mc_empty(ndev)) { struct netdev_hw_addr *ha; @@ -678,14 +671,14 @@ static void cpsw_tx_handler(void *token, int len, int status) { struct sk_buff *skb = token; struct net_device *ndev = skb->dev; - struct cpsw_priv *priv = netdev_priv(ndev); + struct cpsw_common *cpsw = ndev_to_cpsw(ndev); /* Check whether the queue is stopped due to stalled tx dma, if the * queue is stopped then start the queue as we have free desc for tx */ if (unlikely(netif_queue_stopped(ndev))) netif_wake_queue(ndev); - cpts_tx_timestamp(priv->cpts, skb); + cpts_tx_timestamp(cpsw->cpts, skb); ndev->stats.tx_packets++; ndev->stats.tx_bytes += len; dev_kfree_skb_any(skb); @@ -696,11 +689,10 @@ static void cpsw_rx_handler(void *token, int len, int status) struct sk_buff *skb = token; struct sk_buff *new_skb; struct net_device *ndev = skb->dev; - struct cpsw_priv *priv = netdev_priv(ndev); int ret = 0; - struct cpsw_common *cpsw = priv->cpsw; + struct cpsw_common *cpsw = ndev_to_cpsw(ndev); - cpsw_dual_emac_src_port_detect(cpsw, status, priv, ndev, skb); + cpsw_dual_emac_src_port_detect(cpsw, status, ndev, skb); if (unlikely(status < 0) || unlikely(!netif_running(ndev))) { bool ndev_status = false; @@ -730,10 +722,10 @@ static void cpsw_rx_handler(void *token, int len, int status) return; } - new_skb = netdev_alloc_skb_ip_align(ndev, priv->rx_packet_max); + new_skb = netdev_alloc_skb_ip_align(ndev, cpsw->rx_packet_max); if (new_skb) { skb_put(skb, len); - cpts_rx_timestamp(priv->cpts, skb); + cpts_rx_timestamp(cpsw->cpts, skb); skb->protocol = eth_type_trans(skb, ndev); netif_receive_skb(skb); ndev->stats.rx_bytes += len; @@ -858,7 +850,7 @@ static void _cpsw_adjust_link(struct cpsw_slave *slave, mac_control = cpsw->data.mac_control; /* enable forwarding */ - cpsw_ale_control_set(priv->ale, slave_port, + cpsw_ale_control_set(cpsw->ale, slave_port, ALE_PORT_STATE, ALE_PORT_STATE_FORWARD); if (phy->speed == 1000) @@ -882,7 +874,7 @@ static void _cpsw_adjust_link(struct cpsw_slave *slave, } else { mac_control = 0; /* disable forwarding */ - cpsw_ale_control_set(priv->ale, slave_port, + cpsw_ale_control_set(cpsw->ale, slave_port, ALE_PORT_STATE, ALE_PORT_STATE_DISABLE); } @@ -914,9 +906,9 @@ static void cpsw_adjust_link(struct net_device *ndev) static int cpsw_get_coalesce(struct net_device *ndev, struct ethtool_coalesce *coal) { - struct cpsw_priv *priv = netdev_priv(ndev); + struct cpsw_common *cpsw = ndev_to_cpsw(ndev); - coal->rx_coalesce_usecs = priv->coal_intvl; + coal->rx_coalesce_usecs = cpsw->coal_intvl; return 0; } @@ -934,7 +926,7 @@ static int cpsw_set_coalesce(struct net_device *ndev, coal_intvl = coal->rx_coalesce_usecs; int_ctrl = readl(&cpsw->wr_regs->int_control); - prescale = priv->bus_freq_mhz * 4; + prescale = cpsw->bus_freq_mhz * 4; if (!coal->rx_coalesce_usecs) { int_ctrl &= ~(CPSW_INTPRESCALE_MASK | CPSW_INTPACEEN); @@ -973,16 +965,7 @@ static int cpsw_set_coalesce(struct net_device *ndev, writel(int_ctrl, &cpsw->wr_regs->int_control); cpsw_notice(priv, timer, "Set coalesce to %d usecs.\n", coal_intvl); - if (cpsw->data.dual_emac) { - int i; - - for (i = 0; i < cpsw->data.slaves; i++) { - priv = netdev_priv(cpsw->slaves[i].ndev); - priv->coal_intvl = coal_intvl; - } - } else { - priv->coal_intvl = coal_intvl; - } + cpsw->coal_intvl = coal_intvl; return 0; } @@ -1078,18 +1061,20 @@ static inline void cpsw_add_dual_emac_def_ale_entries( struct cpsw_priv *priv, struct cpsw_slave *slave, u32 slave_port) { + struct cpsw_common *cpsw = priv->cpsw; u32 port_mask = 1 << slave_port | ALE_PORT_HOST; - if (priv->version == CPSW_VERSION_1) + if (cpsw->version == CPSW_VERSION_1) slave_write(slave, slave->port_vlan, CPSW1_PORT_VLAN); else slave_write(slave, slave->port_vlan, CPSW2_PORT_VLAN); - cpsw_ale_add_vlan(priv->ale, slave->port_vlan, port_mask, + cpsw_ale_add_vlan(cpsw->ale, slave->port_vlan, port_mask, port_mask, port_mask, 0); - cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast, + cpsw_ale_add_mcast(cpsw->ale, priv->ndev->broadcast, port_mask, ALE_VLAN, slave->port_vlan, 0); - cpsw_ale_add_ucast(priv->ale, priv->mac_addr, - HOST_PORT_NUM, ALE_VLAN | ALE_SECURE, slave->port_vlan); + cpsw_ale_add_ucast(cpsw->ale, priv->mac_addr, + HOST_PORT_NUM, ALE_VLAN | + ALE_SECURE, slave->port_vlan); } static void soft_reset_slave(struct cpsw_slave *slave) @@ -1110,7 +1095,7 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv) /* setup priority mapping */ __raw_writel(RX_PRIORITY_MAPPING, &slave->sliver->rx_pri_map); - switch (priv->version) { + switch (cpsw->version) { case CPSW_VERSION_1: slave_write(slave, TX_PRIORITY_MAPPING, CPSW1_TX_PRI_MAP); break; @@ -1122,7 +1107,7 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv) } /* setup max packet size, and mac address */ - __raw_writel(priv->rx_packet_max, &slave->sliver->rx_maxlen); + __raw_writel(cpsw->rx_packet_max, &slave->sliver->rx_maxlen); cpsw_set_slave_mac(slave, priv); slave->mac_control = 0; /* no link yet */ @@ -1132,7 +1117,7 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv) if (cpsw->data.dual_emac) cpsw_add_dual_emac_def_ale_entries(priv, slave, slave_port); else - cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast, + cpsw_ale_add_mcast(cpsw->ale, priv->ndev->broadcast, 1 << slave_port, 0, 0, ALE_MCAST_FWD_2); if (slave->data->phy_node) { @@ -1173,7 +1158,7 @@ static inline void cpsw_add_default_vlan(struct cpsw_priv *priv) int i; int unreg_mcast_mask; - reg = (priv->version == CPSW_VERSION_1) ? CPSW1_PORT_VLAN : + reg = (cpsw->version == CPSW_VERSION_1) ? CPSW1_PORT_VLAN : CPSW2_PORT_VLAN; writel(vlan, &cpsw->host_port_regs->port_vlan); @@ -1186,7 +1171,7 @@ static inline void cpsw_add_default_vlan(struct cpsw_priv *priv) else unreg_mcast_mask = ALE_PORT_1 | ALE_PORT_2; - cpsw_ale_add_vlan(priv->ale, vlan, ALE_ALL_PORTS, + cpsw_ale_add_vlan(cpsw->ale, vlan, ALE_ALL_PORTS, ALE_ALL_PORTS, ALE_ALL_PORTS, unreg_mcast_mask); } @@ -1199,10 +1184,10 @@ static void cpsw_init_host_port(struct cpsw_priv *priv) /* soft reset the controller and initialize ale */ soft_reset("cpsw", &cpsw->regs->soft_reset); - cpsw_ale_start(priv->ale); + cpsw_ale_start(cpsw->ale); /* switch to vlan unaware mode */ - cpsw_ale_control_set(priv->ale, HOST_PORT_NUM, ALE_VLAN_AWARE, + cpsw_ale_control_set(cpsw->ale, HOST_PORT_NUM, ALE_VLAN_AWARE, CPSW_ALE_VLAN_AWARE); control_reg = readl(&cpsw->regs->control); control_reg |= CPSW_VLAN_AWARE; @@ -1216,18 +1201,18 @@ static void cpsw_init_host_port(struct cpsw_priv *priv) &cpsw->host_port_regs->cpdma_tx_pri_map); __raw_writel(0, &cpsw->host_port_regs->cpdma_rx_chan_map); - cpsw_ale_control_set(priv->ale, HOST_PORT_NUM, + cpsw_ale_control_set(cpsw->ale, HOST_PORT_NUM, ALE_PORT_STATE, ALE_PORT_STATE_FORWARD); if (!cpsw->data.dual_emac) { - cpsw_ale_add_ucast(priv->ale, priv->mac_addr, HOST_PORT_NUM, + cpsw_ale_add_ucast(cpsw->ale, priv->mac_addr, HOST_PORT_NUM, 0, 0); - cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast, + cpsw_ale_add_mcast(cpsw->ale, priv->ndev->broadcast, ALE_PORT_HOST, 0, 0, ALE_MCAST_FWD_2); } } -static void cpsw_slave_stop(struct cpsw_slave *slave, struct cpsw_priv *priv) +static void cpsw_slave_stop(struct cpsw_slave *slave, struct cpsw_common *cpsw) { u32 slave_port; @@ -1238,7 +1223,7 @@ static void cpsw_slave_stop(struct cpsw_slave *slave, struct cpsw_priv *priv) phy_stop(slave->phy); phy_disconnect(slave->phy); slave->phy = NULL; - cpsw_ale_control_set(priv->ale, slave_port, + cpsw_ale_control_set(cpsw->ale, slave_port, ALE_PORT_STATE, ALE_PORT_STATE_DISABLE); soft_reset_slave(slave); } @@ -1260,7 +1245,7 @@ static int cpsw_ndo_open(struct net_device *ndev) cpsw_intr_disable(cpsw); netif_carrier_off(ndev); - reg = priv->version; + reg = cpsw->version; dev_info(priv->dev, "initializing cpsw version %d.%d (%d)\n", CPSW_MAJOR_VERSION(reg), CPSW_MINOR_VERSION(reg), @@ -1275,7 +1260,7 @@ static int cpsw_ndo_open(struct net_device *ndev) if (!cpsw->data.dual_emac) cpsw_add_default_vlan(priv); else - cpsw_ale_add_vlan(priv->ale, cpsw->data.default_vlan, + cpsw_ale_add_vlan(cpsw->ale, cpsw->data.default_vlan, ALE_ALL_PORTS, ALE_ALL_PORTS, 0, 0); if (!cpsw_common_res_usage_state(cpsw)) { @@ -1313,7 +1298,7 @@ static int cpsw_ndo_open(struct net_device *ndev) ret = -ENOMEM; skb = __netdev_alloc_skb_ip_align(priv->ndev, - priv->rx_packet_max, GFP_KERNEL); + cpsw->rx_packet_max, GFP_KERNEL); if (!skb) goto err_cleanup; ret = cpdma_chan_submit(cpsw->rxch, skb, skb->data, @@ -1328,7 +1313,7 @@ static int cpsw_ndo_open(struct net_device *ndev) */ cpsw_info(priv, ifup, "submitted %d rx descriptors\n", i); - if (cpts_register(cpsw->dev, priv->cpts, + if (cpts_register(cpsw->dev, cpsw->cpts, cpsw->data.cpts_clock_mult, cpsw->data.cpts_clock_shift)) dev_err(priv->dev, "error registering cpts device\n"); @@ -1336,10 +1321,10 @@ static int cpsw_ndo_open(struct net_device *ndev) } /* Enable Interrupt pacing if configured */ - if (priv->coal_intvl != 0) { + if (cpsw->coal_intvl != 0) { struct ethtool_coalesce coal; - coal.rx_coalesce_usecs = priv->coal_intvl; + coal.rx_coalesce_usecs = cpsw->coal_intvl; cpsw_set_coalesce(ndev, &coal); } @@ -1352,7 +1337,7 @@ static int cpsw_ndo_open(struct net_device *ndev) err_cleanup: cpdma_ctlr_stop(cpsw->dma); - for_each_slave(priv, cpsw_slave_stop, priv); + for_each_slave(priv, cpsw_slave_stop, cpsw); pm_runtime_put_sync(cpsw->dev); netif_carrier_off(priv->ndev); return ret; @@ -1370,12 +1355,12 @@ static int cpsw_ndo_stop(struct net_device *ndev) if (cpsw_common_res_usage_state(cpsw) <= 1) { napi_disable(&cpsw->napi_rx); napi_disable(&cpsw->napi_tx); - cpts_unregister(priv->cpts); + cpts_unregister(cpsw->cpts); cpsw_intr_disable(cpsw); cpdma_ctlr_stop(cpsw->dma); - cpsw_ale_stop(priv->ale); + cpsw_ale_stop(cpsw->ale); } - for_each_slave(priv, cpsw_slave_stop, priv); + for_each_slave(priv, cpsw_slave_stop, cpsw); pm_runtime_put_sync(cpsw->dev); if (cpsw->data.dual_emac) cpsw->slaves[priv->emac_port].open_stat = false; @@ -1398,7 +1383,7 @@ static netdev_tx_t cpsw_ndo_start_xmit(struct sk_buff *skb, } if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP && - priv->cpts->tx_enable) + cpsw->cpts->tx_enable) skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; skb_tx_timestamp(skb); @@ -1424,13 +1409,12 @@ static netdev_tx_t cpsw_ndo_start_xmit(struct sk_buff *skb, #ifdef CONFIG_TI_CPTS -static void cpsw_hwtstamp_v1(struct cpsw_priv *priv) +static void cpsw_hwtstamp_v1(struct cpsw_common *cpsw) { - struct cpsw_common *cpsw = priv->cpsw; struct cpsw_slave *slave = &cpsw->slaves[cpsw->data.active_slave]; u32 ts_en, seq_id; - if (!priv->cpts->tx_enable && !priv->cpts->rx_enable) { + if (!cpsw->cpts->tx_enable && !cpsw->cpts->rx_enable) { slave_write(slave, 0, CPSW1_TS_CTL); return; } @@ -1438,10 +1422,10 @@ static void cpsw_hwtstamp_v1(struct cpsw_priv *priv) seq_id = (30 << CPSW_V1_SEQ_ID_OFS_SHIFT) | ETH_P_1588; ts_en = EVENT_MSG_BITS << CPSW_V1_MSG_TYPE_OFS; - if (priv->cpts->tx_enable) + if (cpsw->cpts->tx_enable) ts_en |= CPSW_V1_TS_TX_EN; - if (priv->cpts->rx_enable) + if (cpsw->cpts->rx_enable) ts_en |= CPSW_V1_TS_RX_EN; slave_write(slave, ts_en, CPSW1_TS_CTL); @@ -1460,24 +1444,24 @@ static void cpsw_hwtstamp_v2(struct cpsw_priv *priv) slave = &cpsw->slaves[cpsw->data.active_slave]; ctrl = slave_read(slave, CPSW2_CONTROL); - switch (priv->version) { + switch (cpsw->version) { case CPSW_VERSION_2: ctrl &= ~CTRL_V2_ALL_TS_MASK; - if (priv->cpts->tx_enable) + if (cpsw->cpts->tx_enable) ctrl |= CTRL_V2_TX_TS_BITS; - if (priv->cpts->rx_enable) + if (cpsw->cpts->rx_enable) ctrl |= CTRL_V2_RX_TS_BITS; break; case CPSW_VERSION_3: default: ctrl &= ~CTRL_V3_ALL_TS_MASK; - if (priv->cpts->tx_enable) + if (cpsw->cpts->tx_enable) ctrl |= CTRL_V3_TX_TS_BITS; - if (priv->cpts->rx_enable) + if (cpsw->cpts->rx_enable) ctrl |= CTRL_V3_RX_TS_BITS; break; } @@ -1492,12 +1476,13 @@ static void cpsw_hwtstamp_v2(struct cpsw_priv *priv) static int cpsw_hwtstamp_set(struct net_device *dev, struct ifreq *ifr) { struct cpsw_priv *priv = netdev_priv(dev); - struct cpts *cpts = priv->cpts; struct hwtstamp_config cfg; + struct cpsw_common *cpsw = priv->cpsw; + struct cpts *cpts = cpsw->cpts; - if (priv->version != CPSW_VERSION_1 && - priv->version != CPSW_VERSION_2 && - priv->version != CPSW_VERSION_3) + if (cpsw->version != CPSW_VERSION_1 && + cpsw->version != CPSW_VERSION_2 && + cpsw->version != CPSW_VERSION_3) return -EOPNOTSUPP; if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg))) @@ -1537,9 +1522,9 @@ static int cpsw_hwtstamp_set(struct net_device *dev, struct ifreq *ifr) cpts->tx_enable = cfg.tx_type == HWTSTAMP_TX_ON; - switch (priv->version) { + switch (cpsw->version) { case CPSW_VERSION_1: - cpsw_hwtstamp_v1(priv); + cpsw_hwtstamp_v1(cpsw); break; case CPSW_VERSION_2: case CPSW_VERSION_3: @@ -1554,13 +1539,13 @@ static int cpsw_hwtstamp_set(struct net_device *dev, struct ifreq *ifr) static int cpsw_hwtstamp_get(struct net_device *dev, struct ifreq *ifr) { - struct cpsw_priv *priv = netdev_priv(dev); - struct cpts *cpts = priv->cpts; + struct cpsw_common *cpsw = ndev_to_cpsw(dev); + struct cpts *cpts = cpsw->cpts; struct hwtstamp_config cfg; - if (priv->version != CPSW_VERSION_1 && - priv->version != CPSW_VERSION_2 && - priv->version != CPSW_VERSION_3) + if (cpsw->version != CPSW_VERSION_1 && + cpsw->version != CPSW_VERSION_2 && + cpsw->version != CPSW_VERSION_3) return -EOPNOTSUPP; cfg.flags = 0; @@ -1632,9 +1617,9 @@ static int cpsw_ndo_set_mac_address(struct net_device *ndev, void *p) flags = ALE_VLAN; } - cpsw_ale_del_ucast(priv->ale, priv->mac_addr, HOST_PORT_NUM, + cpsw_ale_del_ucast(cpsw->ale, priv->mac_addr, HOST_PORT_NUM, flags, vid); - cpsw_ale_add_ucast(priv->ale, addr->sa_data, HOST_PORT_NUM, + cpsw_ale_add_ucast(cpsw->ale, addr->sa_data, HOST_PORT_NUM, flags, vid); memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN); @@ -1680,27 +1665,27 @@ static inline int cpsw_add_vlan_ale_entry(struct cpsw_priv *priv, unreg_mcast_mask = ALE_PORT_1 | ALE_PORT_2; } - ret = cpsw_ale_add_vlan(priv->ale, vid, port_mask, 0, port_mask, + ret = cpsw_ale_add_vlan(cpsw->ale, vid, port_mask, 0, port_mask, unreg_mcast_mask); if (ret != 0) return ret; - ret = cpsw_ale_add_ucast(priv->ale, priv->mac_addr, + ret = cpsw_ale_add_ucast(cpsw->ale, priv->mac_addr, HOST_PORT_NUM, ALE_VLAN, vid); if (ret != 0) goto clean_vid; - ret = cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast, + ret = cpsw_ale_add_mcast(cpsw->ale, priv->ndev->broadcast, port_mask, ALE_VLAN, vid, 0); if (ret != 0) goto clean_vlan_ucast; return 0; clean_vlan_ucast: - cpsw_ale_del_ucast(priv->ale, priv->mac_addr, + cpsw_ale_del_ucast(cpsw->ale, priv->mac_addr, HOST_PORT_NUM, ALE_VLAN, vid); clean_vid: - cpsw_ale_del_vlan(priv->ale, vid, 0); + cpsw_ale_del_vlan(cpsw->ale, vid, 0); return ret; } @@ -1766,16 +1751,16 @@ static int cpsw_ndo_vlan_rx_kill_vid(struct net_device *ndev, } dev_info(priv->dev, "removing vlanid %d from vlan filter\n", vid); - ret = cpsw_ale_del_vlan(priv->ale, vid, 0); + ret = cpsw_ale_del_vlan(cpsw->ale, vid, 0); if (ret != 0) return ret; - ret = cpsw_ale_del_ucast(priv->ale, priv->mac_addr, + ret = cpsw_ale_del_ucast(cpsw->ale, priv->mac_addr, HOST_PORT_NUM, ALE_VLAN, vid); if (ret != 0) return ret; - ret = cpsw_ale_del_mcast(priv->ale, priv->ndev->broadcast, + ret = cpsw_ale_del_mcast(cpsw->ale, priv->ndev->broadcast, 0, ALE_VLAN, vid); pm_runtime_put(cpsw->dev); return ret; @@ -1808,13 +1793,13 @@ static int cpsw_get_regs_len(struct net_device *ndev) static void cpsw_get_regs(struct net_device *ndev, struct ethtool_regs *regs, void *p) { - struct cpsw_priv *priv = netdev_priv(ndev); u32 *reg = p; + struct cpsw_common *cpsw = ndev_to_cpsw(ndev); /* update CPSW IP version */ - regs->version = priv->version; + regs->version = cpsw->version; - cpsw_ale_dump(priv->ale, reg); + cpsw_ale_dump(cpsw->ale, reg); } static void cpsw_get_drvinfo(struct net_device *ndev, @@ -1844,7 +1829,7 @@ static int cpsw_get_ts_info(struct net_device *ndev, struct ethtool_ts_info *info) { #ifdef CONFIG_TI_CPTS - struct cpsw_priv *priv = netdev_priv(ndev); + struct cpsw_common *cpsw = ndev_to_cpsw(ndev); info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE | @@ -1853,7 +1838,7 @@ static int cpsw_get_ts_info(struct net_device *ndev, SOF_TIMESTAMPING_RX_SOFTWARE | SOF_TIMESTAMPING_SOFTWARE | SOF_TIMESTAMPING_RAW_HARDWARE; - info->phc_index = priv->cpts->phc_index; + info->phc_index = cpsw->cpts->phc_index; info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON); @@ -2188,7 +2173,6 @@ static int cpsw_probe_dual_emac(struct cpsw_priv *priv) priv_sl2->ndev = ndev; priv_sl2->dev = &ndev->dev; priv_sl2->msg_enable = netif_msg_init(debug_level, CPSW_DEBUG); - priv_sl2->rx_packet_max = max(rx_packet_max, 128); if (is_valid_ether_addr(data->slave_data[1].mac_addr)) { memcpy(priv_sl2->mac_addr, data->slave_data[1].mac_addr, @@ -2202,13 +2186,8 @@ static int cpsw_probe_dual_emac(struct cpsw_priv *priv) } memcpy(ndev->dev_addr, priv_sl2->mac_addr, ETH_ALEN); - priv_sl2->coal_intvl = 0; - priv_sl2->bus_freq_mhz = priv->bus_freq_mhz; - priv_sl2->ale = priv->ale; priv_sl2->emac_port = 1; cpsw->slaves[1].ndev = ndev; - priv_sl2->cpts = priv->cpts; - priv_sl2->version = priv->version; ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER; ndev->netdev_ops = &cpsw_netdev_ops; @@ -2296,9 +2275,9 @@ static int cpsw_probe(struct platform_device *pdev) priv->ndev = ndev; priv->dev = &ndev->dev; priv->msg_enable = netif_msg_init(debug_level, CPSW_DEBUG); - priv->rx_packet_max = max(rx_packet_max, 128); - priv->cpts = devm_kzalloc(&pdev->dev, sizeof(struct cpts), GFP_KERNEL); - if (!priv->cpts) { + cpsw->rx_packet_max = max(rx_packet_max, 128); + cpsw->cpts = devm_kzalloc(&pdev->dev, sizeof(struct cpts), GFP_KERNEL); + if (!cpsw->cpts) { dev_err(&pdev->dev, "error allocating cpts\n"); ret = -ENOMEM; goto clean_ndev_ret; @@ -2355,8 +2334,7 @@ static int cpsw_probe(struct platform_device *pdev) ret = -ENODEV; goto clean_runtime_disable_ret; } - priv->coal_intvl = 0; - priv->bus_freq_mhz = clk_get_rate(clk) / 1000000; + cpsw->bus_freq_mhz = clk_get_rate(clk) / 1000000; ss_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ss_regs = devm_ioremap_resource(&pdev->dev, ss_res); @@ -2374,7 +2352,7 @@ static int cpsw_probe(struct platform_device *pdev) pm_runtime_put_noidle(&pdev->dev); goto clean_runtime_disable_ret; } - priv->version = readl(&cpsw->regs->id_ver); + cpsw->version = readl(&cpsw->regs->id_ver); pm_runtime_put_sync(&pdev->dev); res = platform_get_resource(pdev, IORESOURCE_MEM, 1); @@ -2387,10 +2365,10 @@ static int cpsw_probe(struct platform_device *pdev) memset(&dma_params, 0, sizeof(dma_params)); memset(&ale_params, 0, sizeof(ale_params)); - switch (priv->version) { + switch (cpsw->version) { case CPSW_VERSION_1: cpsw->host_port_regs = ss_regs + CPSW1_HOST_PORT_OFFSET; - priv->cpts->reg = ss_regs + CPSW1_CPTS_OFFSET; + cpsw->cpts->reg = ss_regs + CPSW1_CPTS_OFFSET; cpsw->hw_stats = ss_regs + CPSW1_HW_STATS; dma_params.dmaregs = ss_regs + CPSW1_CPDMA_OFFSET; dma_params.txhdp = ss_regs + CPSW1_STATERAM_OFFSET; @@ -2404,7 +2382,7 @@ static int cpsw_probe(struct platform_device *pdev) case CPSW_VERSION_3: case CPSW_VERSION_4: cpsw->host_port_regs = ss_regs + CPSW2_HOST_PORT_OFFSET; - priv->cpts->reg = ss_regs + CPSW2_CPTS_OFFSET; + cpsw->cpts->reg = ss_regs + CPSW2_CPTS_OFFSET; cpsw->hw_stats = ss_regs + CPSW2_HW_STATS; dma_params.dmaregs = ss_regs + CPSW2_CPDMA_OFFSET; dma_params.txhdp = ss_regs + CPSW2_STATERAM_OFFSET; @@ -2416,7 +2394,7 @@ static int cpsw_probe(struct platform_device *pdev) (u32 __force) ss_res->start + CPSW2_BD_OFFSET; break; default: - dev_err(priv->dev, "unknown version 0x%08x\n", priv->version); + dev_err(priv->dev, "unknown version 0x%08x\n", cpsw->version); ret = -ENODEV; goto clean_runtime_disable_ret; } @@ -2466,8 +2444,8 @@ static int cpsw_probe(struct platform_device *pdev) ale_params.ale_entries = data->ale_entries; ale_params.ale_ports = data->slaves; - priv->ale = cpsw_ale_create(&ale_params); - if (!priv->ale) { + cpsw->ale = cpsw_ale_create(&ale_params); + if (!cpsw->ale) { dev_err(priv->dev, "error initializing ale engine\n"); ret = -ENODEV; goto clean_dma_ret; @@ -2555,7 +2533,7 @@ static int cpsw_probe(struct platform_device *pdev) return 0; clean_ale_ret: - cpsw_ale_destroy(priv->ale); + cpsw_ale_destroy(cpsw->ale); clean_dma_ret: cpdma_ctlr_destroy(cpsw->dma); clean_runtime_disable_ret: @@ -2568,8 +2546,7 @@ static int cpsw_probe(struct platform_device *pdev) static int cpsw_remove(struct platform_device *pdev) { struct net_device *ndev = platform_get_drvdata(pdev); - struct cpsw_priv *priv = netdev_priv(ndev); - struct cpsw_common *cpsw = priv->cpsw; + struct cpsw_common *cpsw = ndev_to_cpsw(ndev); int ret; ret = pm_runtime_get_sync(&pdev->dev); @@ -2582,7 +2559,7 @@ static int cpsw_remove(struct platform_device *pdev) unregister_netdev(cpsw->slaves[1].ndev); unregister_netdev(ndev); - cpsw_ale_destroy(priv->ale); + cpsw_ale_destroy(cpsw->ale); cpdma_ctlr_destroy(cpsw->dma); of_platform_depopulate(&pdev->dev); pm_runtime_put_sync(&pdev->dev);