From e55b702ba52b4e43073cb33a7a4a95c1d55ddb53 Mon Sep 17 00:00:00 2001 From: WingMan Kwok Date: Mon, 9 Mar 2015 13:12:20 -0400 Subject: net: keystone: clean up slave port configurations In multi-if mode: When MDIO/PHY is enabled, carrier on/off is reported to upper layer by the phy state machine, hence cpsw driver needs to report carrier on/off when the link interface type is other than MAC-to-PHY. Also, in the MAC-to-PHY case, in addition to checking the sgmii link status register, cpsw driver needs to check the bit that corresponds to the phy connected to the slave port in the phy link state variable in netcp in order to conclude the sgmii link status. Only when both of these two statuses show an up state can the cpsw driver conclude the link is up. Before this patch, it checks the aggregated value of the phy link state variable. In the case of MAC-to-MAC, the cpsw driver is responsible to report the carrier on/off status to upper layers. Signed-off-by: WingMan Kwok --- drivers/net/ethernet/ti/keystone_ethss.c | 71 ++++++++++++++++----------- drivers/net/ethernet/ti/keystone_ethss2.c | 72 ++++++++++++++++------------ drivers/net/ethernet/ti/keystone_net.h | 2 +- drivers/net/ethernet/ti/keystone_xgess.c | 79 ++++++++++++++++++------------- 4 files changed, 134 insertions(+), 90 deletions(-) (limited to 'drivers/net/ethernet') diff --git a/drivers/net/ethernet/ti/keystone_ethss.c b/drivers/net/ethernet/ti/keystone_ethss.c index e2aebf708dc..1e18fa4d27e 100644 --- a/drivers/net/ethernet/ti/keystone_ethss.c +++ b/drivers/net/ethernet/ti/keystone_ethss.c @@ -63,6 +63,9 @@ #define MACSL_RX_ENABLE_CSF BIT(23) #define MACSL_RX_ENABLE_EXT_CTL BIT(18) #define MACSL_ENABLE BIT(5) +#define MACSL_DEFAULT_CONFIG (MACSL_ENABLE |\ + MACSL_RX_ENABLE_EXT_CTL |\ + MACSL_RX_ENABLE_CSF) #define GMACSL_RET_WARN_RESET_INCOMPLETE -2 #define CPSW_NUM_PORTS 5 @@ -154,7 +157,7 @@ #define MAX_SLAVES 4 -/* s: 0-based slave_port */ +/* s: 0-based slave_num */ #define SGMII_BASE(s) \ (((s) < 2) ? cpsw_dev->sgmii_port_regs : cpsw_dev->sgmii_port34_regs) @@ -169,6 +172,9 @@ struct cpts_port_ts_ctl { u8 ts_mcast_type; }; +/* slave_num: 0-based + * port_num: 1-based + */ struct cpsw_slave { struct cpsw_slave_regs __iomem *regs; struct cpsw_sliver_regs __iomem *sliver; @@ -549,6 +555,8 @@ struct cpsw_priv { struct serdes serdes; }; +/* slave_port: 0-based (currently relevant only in multi_if mode) +*/ struct cpsw_intf { struct net_device *ndev; struct device *dev; @@ -564,7 +572,7 @@ struct cpsw_intf { u32 multi_if; struct list_head cpsw_intf_list; struct timer_list timer; - u32 sgmii_link; + u32 link_state; }; static struct cpsw_priv *global_priv; /* FIXME: REMOVE THIS!! */ @@ -2101,8 +2109,7 @@ static void _cpsw_adjust_link(struct cpsw_slave *slave, bool *link) if (phy->link) { mac_control = slave->mac_control; - mac_control |= MACSL_ENABLE | MACSL_RX_ENABLE_EXT_CTL | - MACSL_RX_ENABLE_CSF; + mac_control |= MACSL_DEFAULT_CONFIG; /* enable forwarding */ cpsw_ale_control_set(slave->ale, slave_port, ALE_PORT_STATE, ALE_PORT_STATE_FORWARD); @@ -2137,9 +2144,9 @@ static void cpsw_adjust_link(struct net_device *n_dev, void *context) _cpsw_adjust_link(slave, &link); if (link) - netcp->link_state |= BIT(slave->slave_num); + netcp->phy_link_state_mask |= BIT(slave->slave_num); else - netcp->link_state &= ~BIT(slave->slave_num); + netcp->phy_link_state_mask &= ~BIT(slave->slave_num); } /* @@ -2174,11 +2181,12 @@ static void cpsw_port_config(struct cpsw_slave *slave, int max_rx_len) if (max_rx_len > MAX_SIZE_STREAM_BUFFER) max_rx_len = MAX_SIZE_STREAM_BUFFER; + slave->mac_control = MACSL_DEFAULT_CONFIG; + __raw_writel(max_rx_len, &slave->sliver->rx_maxlen); __iowmb(); - __raw_writel(MACSL_ENABLE | MACSL_RX_ENABLE_EXT_CTL | - MACSL_RX_ENABLE_CSF, &slave->sliver->mac_control); + __raw_writel(slave->mac_control, &slave->sliver->mac_control); } static void cpsw_slave_stop(struct cpsw_slave *slave, @@ -2213,12 +2221,14 @@ static void cpsw_slave_link(struct cpsw_slave *slave, struct cpsw_intf *cpsw_intf) { struct netcp_priv *netcp = netdev_priv(cpsw_intf->ndev); + int sn = slave->slave_num; if (slave->link_interface == SGMII_LINK_MAC_PHY) { - if (netcp->link_state) - cpsw_intf->sgmii_link |= BIT(slave->slave_num); - else - cpsw_intf->sgmii_link &= ~BIT(slave->slave_num); + /* check only the bit in phy_link_state_mask + * that corresponds to the slave + */ + if (!(netcp->phy_link_state_mask & BIT(sn))) + cpsw_intf->link_state &= ~BIT(sn); } } @@ -2247,9 +2257,6 @@ static void cpsw_slave_open(struct cpsw_slave *slave, cpsw_set_slave_mac(slave, cpsw_intf); - slave->mac_control = MACSL_ENABLE | MACSL_RX_ENABLE_EXT_CTL | - MACSL_RX_ENABLE_CSF; - /* this slave port here is 1 based */ slave_port = cpsw_get_slave_port(priv, slave->slave_num); @@ -2639,10 +2646,10 @@ static void cpsw_timer(unsigned long arg) struct cpsw_priv *cpsw_dev = cpsw_intf->cpsw_priv; u32 sp = cpsw_intf->slave_port; u32 ns = cpsw_intf->num_slaves; - u32 sgmii_link; + u32 link_state; if (cpsw_dev->multi_if) - sgmii_link = keystone_sgmii_get_port_link(SGMII_BASE(sp), sp); + link_state = keystone_sgmii_get_port_link(SGMII_BASE(sp), sp); else { /* Single interface mode. Link is up if any one slave * port is up. It assumes slave port always starts from @@ -2650,28 +2657,36 @@ static void cpsw_timer(unsigned long arg) */ /* slave port 2, 3 status */ - sgmii_link = keystone_sgmii_link_status(SGMII_BASE(2), + link_state = keystone_sgmii_link_status(SGMII_BASE(2), max_t(u32, ns, 2) - 2); - sgmii_link <<= 2; + link_state <<= 2; /* slave port 0, 1 status */ - sgmii_link |= keystone_sgmii_link_status(SGMII_BASE(0), + link_state |= keystone_sgmii_link_status(SGMII_BASE(0), min_t(u32, ns, 2)); } - cpsw_intf->sgmii_link = sgmii_link; + cpsw_intf->link_state = link_state; + /* if MAC-to-PHY, check phy link status also + * to conclude the intf link's status + */ for_each_slave(cpsw_intf, cpsw_slave_link, cpsw_intf); - /* FIXME: Don't aggregate link statuses in multi-interface case */ - if (cpsw_intf->sgmii_link) { - /* link ON */ - if (!netif_carrier_ok(cpsw_intf->ndev)) + /* Is this the right logic? + * multi_if & MAC_PHY: phy state machine already reported carrier + * multi_if & !MAC_PHY: report carrier + * !multi_if: any one slave up means intf is up, reporting carrier + * here corrects what phy state machine (if it exists) + * might have reported. + */ + if (!cpsw_dev->multi_if || + (cpsw_dev->multi_if && + cpsw_intf->slaves->link_interface != SGMII_LINK_MAC_PHY)) { + if (cpsw_intf->link_state) netif_carrier_on(cpsw_intf->ndev); - } else { - /* link OFF */ - if (netif_carrier_ok(cpsw_intf->ndev)) + else netif_carrier_off(cpsw_intf->ndev); } diff --git a/drivers/net/ethernet/ti/keystone_ethss2.c b/drivers/net/ethernet/ti/keystone_ethss2.c index 5f2c64f56c4..b0f701f5289 100644 --- a/drivers/net/ethernet/ti/keystone_ethss2.c +++ b/drivers/net/ethernet/ti/keystone_ethss2.c @@ -60,6 +60,9 @@ #define MACSL_RX_ENABLE_CSF BIT(23) #define MACSL_RX_ENABLE_EXT_CTL BIT(18) #define MACSL_ENABLE BIT(5) +#define MACSL_DEFAULT_CONFIG (MACSL_ENABLE |\ + MACSL_RX_ENABLE_EXT_CTL |\ + MACSL_RX_ENABLE_CSF) #define GMACSL_RET_WARN_RESET_INCOMPLETE -2 #define CPSW2_NUM_PORTS 9 @@ -157,7 +160,7 @@ #define MAX_SLAVES (CPSW2_NUM_PORTS - 1) -/* s: 0-based slave_port */ +/* s: 0-based slave_num */ #define SGMII2_BASE(s) (((s) < 2) ? cpsw_dev->sgmii_port_regs : \ cpsw_dev->sgmii_port_regs + SGMII_REGS_SIZE * 2) @@ -179,6 +182,9 @@ struct cpts2_port_ts_ctl { u8 ts_mcast_type; }; +/* slave_num: 0-based + * port_num: 1-based + */ struct cpsw2_slave { struct cpsw2_slave_regs __iomem *regs; int slave_num; @@ -897,6 +903,8 @@ struct cpsw2_priv { struct serdes serdes; }; +/* slave_port: 0-based (currently relevant only in multi_if mode) + */ struct cpsw2_intf { struct net_device *ndev; struct device *dev; @@ -912,7 +920,7 @@ struct cpsw2_intf { u32 multi_if; struct list_head cpsw_intf_list; struct timer_list timer; - u32 sgmii_link; + u32 link_state; }; struct cpsw2_attribute { @@ -2484,8 +2492,7 @@ static void _cpsw2_adjust_link(struct cpsw2_slave *slave, bool *link) if (phy->link) { mac_control = slave->mac_control; - mac_control |= MACSL_ENABLE | MACSL_RX_ENABLE_EXT_CTL | - MACSL_RX_ENABLE_CSF; + mac_control |= MACSL_DEFAULT_CONFIG; /* enable forwarding */ cpsw_ale_control_set(slave->ale, slave_port, ALE_PORT_STATE, ALE_PORT_STATE_FORWARD); @@ -2520,9 +2527,9 @@ static void cpsw2_adjust_link(struct net_device *n_dev, void *context) _cpsw2_adjust_link(slave, &link); if (link) - netcp->link_state |= BIT(slave->slave_num); + netcp->phy_link_state_mask |= BIT(slave->slave_num); else - netcp->link_state &= ~BIT(slave->slave_num); + netcp->phy_link_state_mask &= ~BIT(slave->slave_num); } /* @@ -2555,10 +2562,10 @@ static void cpsw2_port_config(struct cpsw2_slave *slave, int max_rx_len) if (max_rx_len > MAX_SIZE_STREAM_BUFFER) max_rx_len = MAX_SIZE_STREAM_BUFFER; - writel(max_rx_len, &slave->regs->rx_maxlen); + slave->mac_control = MACSL_DEFAULT_CONFIG; - writel(MACSL_ENABLE | MACSL_RX_ENABLE_EXT_CTL | MACSL_RX_ENABLE_CSF, - &slave->regs->mac_control); + writel(max_rx_len, &slave->regs->rx_maxlen); + writel(slave->mac_control, &slave->regs->mac_control); } static void cpsw2_slave_stop(struct cpsw2_slave *slave, @@ -2588,12 +2595,14 @@ static void cpsw2_slave_link(struct cpsw2_slave *slave, struct cpsw2_intf *cpsw_intf) { struct netcp_priv *netcp = netdev_priv(cpsw_intf->ndev); + int sn = slave->slave_num; if (slave->link_interface == SGMII_LINK_MAC_PHY) { - if (netcp->link_state) - cpsw_intf->sgmii_link |= BIT(slave->slave_num); - else - cpsw_intf->sgmii_link &= ~BIT(slave->slave_num); + /* check only the bit in phy_link_state_mask + * that corresponds to the slave + */ + if (!(netcp->phy_link_state_mask & BIT(sn))) + cpsw_intf->link_state &= ~BIT(sn); } } @@ -2617,9 +2626,6 @@ static void cpsw2_slave_open(struct cpsw2_slave *slave, cpsw2_set_slave_mac(slave, cpsw_intf); - slave->mac_control = MACSL_ENABLE | MACSL_RX_ENABLE_EXT_CTL | - MACSL_RX_ENABLE_CSF; - /* this slave port here is 1 based */ slave_port = cpsw2_get_slave_port(cpsw_dev, slave->slave_num); @@ -3002,10 +3008,10 @@ static void cpsw2_timer(unsigned long arg) struct cpsw2_priv *cpsw_dev = cpsw_intf->cpsw_priv; u32 sp = cpsw_intf->slave_port; u32 ns = cpsw_intf->num_slaves; - u32 sgmii_link; + u32 link_state; if (cpsw_dev->multi_if) - sgmii_link = keystone_sgmii_get_port_link(SGMII2_BASE(sp), sp); + link_state = keystone_sgmii_get_port_link(SGMII2_BASE(sp), sp); else { /* Single interface mode. Link is up if any one slave * port is up. It assumes slave port always starts from @@ -3013,27 +3019,35 @@ static void cpsw2_timer(unsigned long arg) */ /* slave port (port > 2) status */ - sgmii_link = keystone_sgmii_link_status(SGMII2_BASE(2), + link_state = keystone_sgmii_link_status(SGMII2_BASE(2), max_t(u32, ns, 2) - 2); - sgmii_link <<= 2; + link_state <<= 2; /* slave port 0, 1 status */ - sgmii_link |= keystone_sgmii_link_status(SGMII2_BASE(0), + link_state |= keystone_sgmii_link_status(SGMII2_BASE(0), min_t(u32, ns, 2)); } - cpsw_intf->sgmii_link = sgmii_link; + cpsw_intf->link_state = link_state; + /* if MAC-to-PHY, check phy link status also + * to conclude the intf link's status + */ for_each_slave(cpsw_intf, cpsw2_slave_link, cpsw_intf); - /* FIXME: Don't aggregate link statuses in multi-interface case */ - if (cpsw_intf->sgmii_link) { - /* link ON */ - if (!netif_carrier_ok(cpsw_intf->ndev)) + /* Is this the right logic? + * multi_if & MAC_PHY: phy state machine already reported carrier + * multi_if & !MAC_PHY: report carrier + * !multi_if: any one slave up means intf is up, reporting carrier + * here corrects what phy state machine (if it exists) + * might have reported. + */ + if (!cpsw_dev->multi_if || + (cpsw_dev->multi_if && + cpsw_intf->slaves->link_interface != SGMII_LINK_MAC_PHY)) { + if (cpsw_intf->link_state) netif_carrier_on(cpsw_intf->ndev); - } else { - /* link OFF */ - if (netif_carrier_ok(cpsw_intf->ndev)) + else netif_carrier_off(cpsw_intf->ndev); } diff --git a/drivers/net/ethernet/ti/keystone_net.h b/drivers/net/ethernet/ti/keystone_net.h index 050b7e81260..307db180a23 100644 --- a/drivers/net/ethernet/ti/keystone_net.h +++ b/drivers/net/ethernet/ti/keystone_net.h @@ -131,7 +131,7 @@ struct netcp_priv { spinlock_t lock; int rx_packet_max; const char *rx_chan_name; - u32 link_state; + u32 phy_link_state_mask; struct list_head module_head; struct list_head interface_list; struct list_head addr_list; diff --git a/drivers/net/ethernet/ti/keystone_xgess.c b/drivers/net/ethernet/ti/keystone_xgess.c index a09de9044d2..0af8126a11e 100644 --- a/drivers/net/ethernet/ti/keystone_xgess.c +++ b/drivers/net/ethernet/ti/keystone_xgess.c @@ -69,6 +69,11 @@ (MACSL_XGMII_ENABLE | MACSL_XGIG_MODE) : \ MACSL_GMII_ENABLE) +#define MACSL_DEFAULT_CONFIG(s) \ + (MACSL_SIG_ENABLE((s)) | \ + MACSL_RX_ENABLE_EXT_CTL | \ + MACSL_RX_ENABLE_CSF) + #define CPSW_NUM_PORTS 3 #define CPSW_CTL_P0_ENABLE BIT(2) #define CPSW_CTL_VLAN_AWARE BIT(1) @@ -85,6 +90,9 @@ #define HOST_TX_PRI_MAP_DEFAULT 0x00000000 #define MAX_SIZE_STREAM_BUFFER 9504 +/* slave_num: 0-based + * port_num: 1-based + */ struct cpswx_slave { struct cpswx_slave_regs __iomem *regs; struct cpswx_sliver_regs __iomem *sliver; @@ -303,6 +311,8 @@ struct cpswx_priv { struct device_node *serdes; }; +/* slave_port: 0-based (currently relevant only in multi_if mode) +*/ struct cpswx_intf { struct net_device *ndev; struct device *dev; @@ -318,7 +328,7 @@ struct cpswx_intf { u32 multi_if; struct list_head cpsw_intf_list; struct timer_list timer; - u32 sgmii_link; + u32 link_state; }; /* @@ -1524,9 +1534,7 @@ static void _cpsw_adjust_link(struct cpswx_slave *slave, bool *link) if (phy->link) { mac_control = slave->mac_control; - mac_control |= MACSL_SIG_ENABLE(slave) | - MACSL_RX_ENABLE_EXT_CTL | - MACSL_RX_ENABLE_CSF; + mac_control |= MACSL_DEFAULT_CONFIG(slave); /* enable forwarding */ cpsw_ale_control_set(slave->ale, slave_port, ALE_PORT_STATE, ALE_PORT_STATE_FORWARD); @@ -1561,9 +1569,9 @@ static void cpsw_adjust_link(struct net_device *n_dev, void *context) _cpsw_adjust_link(slave, &link); if (link) - netcp->link_state |= BIT(slave->slave_num); + netcp->phy_link_state_mask |= BIT(slave->slave_num); else - netcp->link_state &= ~BIT(slave->slave_num); + netcp->phy_link_state_mask &= ~BIT(slave->slave_num); } /* @@ -1595,17 +1603,15 @@ static int cpsw_port_reset(struct cpswx_slave *slave) */ static void cpsw_port_config(struct cpswx_slave *slave, int max_rx_len) { - u32 mac_control; - if (max_rx_len > MAX_SIZE_STREAM_BUFFER) max_rx_len = MAX_SIZE_STREAM_BUFFER; + slave->mac_control = MACSL_DEFAULT_CONFIG(slave); + __raw_writel(max_rx_len, &slave->sliver->rx_maxlen); - mac_control = (MACSL_SIG_ENABLE(slave) | - MACSL_RX_ENABLE_EXT_CTL | - MACSL_RX_ENABLE_CSF); - __raw_writel(mac_control, &slave->sliver->mac_control); + __iowmb(); + __raw_writel(slave->mac_control, &slave->sliver->mac_control); } static void cpsw_slave_stop(struct cpswx_slave *slave, struct cpswx_priv *priv) @@ -1624,15 +1630,17 @@ static void cpsw_slave_link(struct cpswx_slave *slave, struct cpswx_intf *cpsw_intf) { struct netcp_priv *netcp = netdev_priv(cpsw_intf->ndev); + int sn = slave->slave_num; if ((slave->link_interface == SGMII_LINK_MAC_PHY) || (slave->link_interface == XGMII_LINK_MAC_PHY)) { - if (netcp->link_state) - cpsw_intf->sgmii_link |= BIT(slave->slave_num); - else - cpsw_intf->sgmii_link &= ~BIT(slave->slave_num); + /* check only the bit in phy_link_state_mask + * that corresponds to the slave + */ + if (!(netcp->phy_link_state_mask & BIT(sn))) + cpsw_intf->link_state &= ~BIT(sn); } else if (slave->link_interface == XGMII_LINK_MAC_MAC_FORCED) - cpsw_intf->sgmii_link |= BIT(slave->slave_num); + cpsw_intf->link_state |= BIT(slave->slave_num); } static void cpsw_slave_open(struct cpswx_slave *slave, @@ -1661,9 +1669,6 @@ static void cpsw_slave_open(struct cpswx_slave *slave, cpsw_set_slave_mac(slave, cpsw_intf); - slave->mac_control = MACSL_SIG_ENABLE(slave) | MACSL_RX_ENABLE_EXT_CTL | - MACSL_RX_ENABLE_CSF; - slave_port = cpsw_get_slave_port(priv, slave->slave_num); slave->port_num = slave_port; @@ -1884,34 +1889,44 @@ static void cpswx_timer(unsigned long arg) struct cpswx_priv *cpsw_dev = cpsw_intf->cpsw_priv; /* - * if the slave's link_interface is not XGMII, sgmii_link bit + * if the slave's link_interface is not XGMII, link_state bit * will not be set */ if (cpsw_dev->multi_if) - cpsw_intf->sgmii_link = + cpsw_intf->link_state = keystone_sgmii_get_port_link(cpsw_dev->sgmii_port_regs, cpsw_intf->slave_port); else - cpsw_intf->sgmii_link = + cpsw_intf->link_state = keystone_sgmii_link_status(cpsw_dev->sgmii_port_regs, cpsw_intf->num_slaves); + /* if MAC-to-PHY, check phy link status also + * to conclude the intf link's status + */ for_each_slave(cpsw_intf, cpsw_slave_link, cpsw_intf); - /* FIXME: Don't aggregate link statuses in multi-interface case */ - if (cpsw_intf->sgmii_link) { - /* link ON */ - if (!netif_carrier_ok(cpsw_intf->ndev)) + /* Is this the right logic? + * multi_if & MAC_PHY: phy state machine already reported carrier + * multi_if & !MAC_PHY: report carrier + * !multi_if: any one slave up means intf is up, reporting carrier + * here corrects what phy state machine (if it exists) + * might have reported. + */ + if (!cpsw_dev->multi_if || + (cpsw_dev->multi_if && + (cpsw_intf->slaves->link_interface != SGMII_LINK_MAC_PHY) && + (cpsw_intf->slaves->link_interface != XGMII_LINK_MAC_PHY))) { + if (cpsw_intf->link_state) netif_carrier_on(cpsw_intf->ndev); - } else { - /* link OFF */ - if (netif_carrier_ok(cpsw_intf->ndev)) + else netif_carrier_off(cpsw_intf->ndev); } - spin_lock_bh(&cpsw_dev->hw_stats_lock); + /* A timer runs as a BH, no need to block them */ + spin_lock(&cpsw_dev->hw_stats_lock); cpswx_update_stats(cpsw_dev, NULL); - spin_unlock_bh(&cpsw_dev->hw_stats_lock); + spin_unlock(&cpsw_dev->hw_stats_lock); cpsw_intf->timer.expires = jiffies + (HZ/10); add_timer(&cpsw_intf->timer); -- cgit v1.2.3-54-g00ecf From efd468cfeeb35dbb843540d6bcc8c61231a054a7 Mon Sep 17 00:00:00 2001 From: WingMan Kwok Date: Fri, 27 Feb 2015 16:18:33 -0500 Subject: net: keystone: add support of additional 1G sgmii mode configurations This patch adds support of 3 1G sgmii mode configurations 1. MAC-to-PHY master (SGMII_LINK_MAC_PHY_MASTER) 2. MAC-to-PHY master NO MDIO (SGMII_LINK_MAC_PHY_MASTER_NO_MDIO) - SGMII is in master mode and auto-nego enabled - use this mode to work around link down/up issue observed on K2E/L. - these 2 modes supports only gigabit fullduplex connections. 3. MAC-to-MAC Auto-negotiation Slave (SGMII_LINK_MAC_MAC_AN_SLAVE) - When connected 2 EVMs back-to-back and one side is configured as MAC-to-MAC Auto-negotiation master the other side needs to be configured as auto-nego slave. Signed-off-by: WingMan Kwok --- drivers/net/ethernet/ti/keystone_ethss.c | 9 ++++++--- drivers/net/ethernet/ti/keystone_ethss2.c | 8 +++++--- drivers/net/ethernet/ti/keystone_net.h | 3 +++ drivers/net/ethernet/ti/keystone_sgmii.c | 3 +++ 4 files changed, 17 insertions(+), 6 deletions(-) (limited to 'drivers/net/ethernet') diff --git a/drivers/net/ethernet/ti/keystone_ethss.c b/drivers/net/ethernet/ti/keystone_ethss.c index 1e18fa4d27e..51a5bd7038e 100644 --- a/drivers/net/ethernet/ti/keystone_ethss.c +++ b/drivers/net/ethernet/ti/keystone_ethss.c @@ -161,6 +161,9 @@ #define SGMII_BASE(s) \ (((s) < 2) ? cpsw_dev->sgmii_port_regs : cpsw_dev->sgmii_port34_regs) +#define IS_SGMII_MAC_PHY(i) \ + (((i) == SGMII_LINK_MAC_PHY) || ((i) == SGMII_LINK_MAC_PHY_MASTER)) + /* CPSW SERDES */ #define CPSW_SERDES_MAX_NUM 1 #define CPSW_LANE_NUM_PER_SERDES 4 @@ -2223,7 +2226,7 @@ static void cpsw_slave_link(struct cpsw_slave *slave, struct netcp_priv *netcp = netdev_priv(cpsw_intf->ndev); int sn = slave->slave_num; - if (slave->link_interface == SGMII_LINK_MAC_PHY) { + if (IS_SGMII_MAC_PHY(slave->link_interface)) { /* check only the bit in phy_link_state_mask * that corresponds to the slave */ @@ -2271,7 +2274,7 @@ static void cpsw_slave_open(struct cpsw_slave *slave, cpsw_ale_add_mcast(priv->ale, cpsw_intf->ndev->broadcast, 1 << slave_port, 0, 0, ALE_MCAST_FWD_2); - if (slave->link_interface == SGMII_LINK_MAC_PHY) { + if (IS_SGMII_MAC_PHY(slave->link_interface)) { slave->phy = of_phy_connect(cpsw_intf->ndev, cpsw_intf->phy_node, &cpsw_adjust_link, 0, @@ -2683,7 +2686,7 @@ static void cpsw_timer(unsigned long arg) */ if (!cpsw_dev->multi_if || (cpsw_dev->multi_if && - cpsw_intf->slaves->link_interface != SGMII_LINK_MAC_PHY)) { + !IS_SGMII_MAC_PHY(cpsw_intf->slaves->link_interface))) { if (cpsw_intf->link_state) netif_carrier_on(cpsw_intf->ndev); else diff --git a/drivers/net/ethernet/ti/keystone_ethss2.c b/drivers/net/ethernet/ti/keystone_ethss2.c index b0f701f5289..e5fadee8c0f 100644 --- a/drivers/net/ethernet/ti/keystone_ethss2.c +++ b/drivers/net/ethernet/ti/keystone_ethss2.c @@ -164,6 +164,8 @@ #define SGMII2_BASE(s) (((s) < 2) ? cpsw_dev->sgmii_port_regs : \ cpsw_dev->sgmii_port_regs + SGMII_REGS_SIZE * 2) +#define IS_SGMII_MAC_PHY(i) \ + (((i) == SGMII_LINK_MAC_PHY) || ((i) == SGMII_LINK_MAC_PHY_MASTER)) /* CPSW Statistics register map size */ #define CPSW2_STATS_REGS_SIZE 0x200 @@ -2597,7 +2599,7 @@ static void cpsw2_slave_link(struct cpsw2_slave *slave, struct netcp_priv *netcp = netdev_priv(cpsw_intf->ndev); int sn = slave->slave_num; - if (slave->link_interface == SGMII_LINK_MAC_PHY) { + if (IS_SGMII_MAC_PHY(slave->link_interface)) { /* check only the bit in phy_link_state_mask * that corresponds to the slave */ @@ -2640,7 +2642,7 @@ static void cpsw2_slave_open(struct cpsw2_slave *slave, cpsw_ale_add_mcast(cpsw_dev->ale, cpsw_intf->ndev->broadcast, 1 << slave_port, 0, 0, ALE_MCAST_FWD_2); - if (slave->link_interface == SGMII_LINK_MAC_PHY) { + if (IS_SGMII_MAC_PHY(slave->link_interface)) { slave->phy = of_phy_connect(cpsw_intf->ndev, cpsw_intf->phy_node, &cpsw2_adjust_link, 0, @@ -3044,7 +3046,7 @@ static void cpsw2_timer(unsigned long arg) */ if (!cpsw_dev->multi_if || (cpsw_dev->multi_if && - cpsw_intf->slaves->link_interface != SGMII_LINK_MAC_PHY)) { + !IS_SGMII_MAC_PHY(cpsw_intf->slaves->link_interface))) { if (cpsw_intf->link_state) netif_carrier_on(cpsw_intf->ndev); else diff --git a/drivers/net/ethernet/ti/keystone_net.h b/drivers/net/ethernet/ti/keystone_net.h index 307db180a23..c6f62687da8 100644 --- a/drivers/net/ethernet/ti/keystone_net.h +++ b/drivers/net/ethernet/ti/keystone_net.h @@ -34,6 +34,9 @@ #define SGMII_LINK_MAC_MAC_FORCED 2 #define SGMII_LINK_MAC_FIBER 3 #define SGMII_LINK_MAC_PHY_NO_MDIO 4 +#define SGMII_LINK_MAC_PHY_MASTER 5 +#define SGMII_LINK_MAC_PHY_MASTER_NO_MDIO 6 +#define SGMII_LINK_MAC_MAC_AN_SLAVE 7 #define XGMII_LINK_MAC_PHY 10 #define XGMII_LINK_MAC_MAC_FORCED 11 diff --git a/drivers/net/ethernet/ti/keystone_sgmii.c b/drivers/net/ethernet/ti/keystone_sgmii.c index 5591ea55d81..8d0538fb503 100644 --- a/drivers/net/ethernet/ti/keystone_sgmii.c +++ b/drivers/net/ethernet/ti/keystone_sgmii.c @@ -137,6 +137,8 @@ int keystone_sgmii_config(void __iomem *sgmii_ofs, u32 control; switch (interface) { + case SGMII_LINK_MAC_PHY_MASTER: + case SGMII_LINK_MAC_PHY_MASTER_NO_MDIO: case SGMII_LINK_MAC_MAC_AUTONEG: mr_adv_ability = 0x9801; control = 0x21; @@ -144,6 +146,7 @@ int keystone_sgmii_config(void __iomem *sgmii_ofs, case SGMII_LINK_MAC_PHY: case SGMII_LINK_MAC_PHY_NO_MDIO: + case SGMII_LINK_MAC_MAC_AN_SLAVE: mr_adv_ability = 1; control = 1; break; -- cgit v1.2.3-54-g00ecf From c376febd9ff9c0bc205cd4c9a719f5578ae4bd15 Mon Sep 17 00:00:00 2001 From: WingMan Kwok Date: Fri, 27 Feb 2015 16:53:19 -0500 Subject: net: keystone: add support of setting hw address live This patch adds support of setting hw address live. When doing so, the netcp needs to update the lower modules cpsw and pa to update their database accordingly, i.e. setting up their receive filters. Signed-off-by: WingMan Kwok --- drivers/net/ethernet/ti/keystone_ethss.c | 9 +++ drivers/net/ethernet/ti/keystone_ethss2.c | 10 +++ drivers/net/ethernet/ti/keystone_net_core.c | 110 +++++++++++++++++++++------- drivers/net/ethernet/ti/keystone_pa.c | 9 +++ drivers/net/ethernet/ti/keystone_pa2.c | 9 +++ drivers/net/ethernet/ti/keystone_xgess.c | 9 +++ 6 files changed, 128 insertions(+), 28 deletions(-) (limited to 'drivers/net/ethernet') diff --git a/drivers/net/ethernet/ti/keystone_ethss.c b/drivers/net/ethernet/ti/keystone_ethss.c index 51a5bd7038e..dc0ed03df54 100644 --- a/drivers/net/ethernet/ti/keystone_ethss.c +++ b/drivers/net/ethernet/ti/keystone_ethss.c @@ -556,6 +556,7 @@ struct cpsw_priv { u32 num_serdes; u32 serdes_lanes; struct serdes serdes; + u32 opened; }; /* slave_port: 0-based (currently relevant only in multi_if mode) @@ -2403,6 +2404,9 @@ int cpsw_add_addr(void *intf_priv, struct netcp_addr *naddr) struct cpsw_intf *cpsw_intf = intf_priv; struct cpsw_priv *cpsw_dev = cpsw_intf->cpsw_priv; + if (!cpsw_dev->opened) + return -ENXIO; + dev_dbg(cpsw_dev->dev, "ethss adding address %pM, type %d\n", naddr->addr, naddr->type); @@ -2429,6 +2433,9 @@ int cpsw_del_addr(void *intf_priv, struct netcp_addr *naddr) struct cpsw_intf *cpsw_intf = intf_priv; struct cpsw_priv *cpsw_dev = cpsw_intf->cpsw_priv; + if (!cpsw_dev->opened) + return -ENXIO; + dev_dbg(cpsw_dev->dev, "ethss deleting address %pM, type %d\n", naddr->addr, naddr->type); @@ -3096,6 +3103,7 @@ static int cpsw_open(void *intf_priv, struct net_device *ndev) PSTREAM_ROUTE_DMA); cpsw_register_cpts(cpsw_dev); + cpsw_dev->opened = 1; return 0; ale_fail: @@ -3135,6 +3143,7 @@ static int cpsw_close(void *intf_priv, struct net_device *ndev) clk_put(cpsw_dev->cpgmac); cpsw_unregister_cpts(cpsw_dev); + cpsw_dev->opened = 0; return 0; } diff --git a/drivers/net/ethernet/ti/keystone_ethss2.c b/drivers/net/ethernet/ti/keystone_ethss2.c index e5fadee8c0f..feaf3b82840 100644 --- a/drivers/net/ethernet/ti/keystone_ethss2.c +++ b/drivers/net/ethernet/ti/keystone_ethss2.c @@ -167,6 +167,7 @@ #define IS_SGMII_MAC_PHY(i) \ (((i) == SGMII_LINK_MAC_PHY) || ((i) == SGMII_LINK_MAC_PHY_MASTER)) + /* CPSW Statistics register map size */ #define CPSW2_STATS_REGS_SIZE 0x200 @@ -903,6 +904,7 @@ struct cpsw2_priv { u32 num_serdes; u32 serdes_lanes; struct serdes serdes; + u32 opened; }; /* slave_port: 0-based (currently relevant only in multi_if mode) @@ -2764,6 +2766,9 @@ static int cpsw2_add_addr(void *intf_priv, struct netcp_addr *naddr) struct cpsw2_intf *cpsw_intf = intf_priv; struct cpsw2_priv *cpsw_dev = cpsw_intf->cpsw_priv; + if (!cpsw_dev->opened) + return -ENXIO; + dev_dbg(cpsw_dev->dev, "ethss adding address %pM, type %d\n", naddr->addr, naddr->type); @@ -2790,6 +2795,9 @@ static int cpsw2_del_addr(void *intf_priv, struct netcp_addr *naddr) struct cpsw2_intf *cpsw_intf = intf_priv; struct cpsw2_priv *cpsw_dev = cpsw_intf->cpsw_priv; + if (!cpsw_dev->opened) + return -ENXIO; + dev_dbg(cpsw_dev->dev, "ethss deleting address %pM, type %d\n", naddr->addr, naddr->type); @@ -3455,6 +3463,7 @@ static int cpsw2_open(void *intf_priv, struct net_device *ndev) PSTREAM_ROUTE_GLOBAL_DMA); cpsw2_register_cpts(cpsw_dev); + cpsw_dev->opened = 1; return 0; ale_fail: @@ -3494,6 +3503,7 @@ static int cpsw2_close(void *intf_priv, struct net_device *ndev) clk_put(cpsw_dev->cpgmac); cpsw2_unregister_cpts(cpsw_dev); + cpsw_dev->opened = 0; return 0; } diff --git a/drivers/net/ethernet/ti/keystone_net_core.c b/drivers/net/ethernet/ti/keystone_net_core.c index ae5098aa09c..4d53d59ef8a 100644 --- a/drivers/net/ethernet/ti/keystone_net_core.c +++ b/drivers/net/ethernet/ti/keystone_net_core.c @@ -1464,65 +1464,85 @@ static void netcp_addr_clear_mark(struct netcp_priv *netcp) naddr->flags = 0; } -static void netcp_addr_add_mark(struct netcp_priv *netcp, const u8 *addr, - enum netcp_addr_type type) +static struct netcp_addr * +netcp_addr_add_mark(struct netcp_priv *netcp, const u8 *addr, + enum netcp_addr_type type) { struct netcp_addr *naddr; naddr = netcp_addr_find(netcp, addr, type); if (naddr) { naddr->flags |= ADDR_VALID; - return; + return naddr; } naddr = netcp_addr_add(netcp, addr, type); if (!WARN_ON(!naddr)) naddr->flags |= ADDR_NEW; + + return naddr; } -static void netcp_addr_sweep_del(struct netcp_priv *netcp) +static void netcp_mod_del_addr(struct netcp_priv *netcp, + struct netcp_addr *naddr) { - struct netcp_addr *naddr, *tmp; struct netcp_intf_modpriv *priv; struct netcp_module *module; - int error; + + dev_dbg(netcp->dev, "deleting address %pM, type %x\n", + naddr->addr, naddr->type); + for_each_module(netcp, priv) { + module = priv->netcp_module; + if (!module->del_addr) + continue; + module->del_addr(priv->module_priv, naddr); + } +} + +static void netcp_addr_sweep_del(struct netcp_priv *netcp) +{ + struct netcp_addr *naddr, *tmp; list_for_each_entry_safe(naddr, tmp, &netcp->addr_list, node) { if (naddr->flags & (ADDR_VALID | ADDR_NEW)) continue; - dev_dbg(netcp->dev, "deleting address %pM, type %x\n", - naddr->addr, naddr->type); - for_each_module(netcp, priv) { - module = priv->netcp_module; - if (!module->del_addr) - continue; - error = module->del_addr(priv->module_priv, - naddr); - WARN_ON(error); - } + netcp_mod_del_addr(netcp, naddr); netcp_addr_del(naddr); } } -static void netcp_addr_sweep_add(struct netcp_priv *netcp) +static int netcp_mod_add_addr(struct netcp_priv *netcp, + struct netcp_addr *naddr) { - struct netcp_addr *naddr, *tmp; struct netcp_intf_modpriv *priv; struct netcp_module *module; int error; + dev_dbg(netcp->dev, "adding address %pM, type %x\n", + naddr->addr, naddr->type); + for_each_module(netcp, priv) { + module = priv->netcp_module; + if (!module->add_addr) + continue; + error = module->add_addr(priv->module_priv, naddr); + if (error) + break; + } + + if (error) + netcp_mod_del_addr(netcp, naddr); + + return error; +} + +static void netcp_addr_sweep_add(struct netcp_priv *netcp) +{ + struct netcp_addr *naddr, *tmp; + list_for_each_entry_safe(naddr, tmp, &netcp->addr_list, node) { if (!(naddr->flags & ADDR_NEW)) continue; - dev_dbg(netcp->dev, "adding address %pM, type %x\n", - naddr->addr, naddr->type); - for_each_module(netcp, priv) { - module = priv->netcp_module; - if (!module->add_addr) - continue; - error = module->add_addr(priv->module_priv, naddr); - WARN_ON(error); - } + netcp_mod_add_addr(netcp, naddr); } } @@ -1772,6 +1792,38 @@ static int netcp_ndo_change_mtu(struct net_device *ndev, int new_mtu) return 0; } +static int netcp_ndo_set_mac_address(struct net_device *ndev, void *p) +{ + struct netcp_priv *netcp = netdev_priv(ndev); + struct netcp_addr *naddr; + int ret; + + ret = eth_mac_addr(ndev, p); + if (ret) { + dev_info(netcp->dev, "set mac addr %pM failed (%d).\n", + ((struct sockaddr *)p)->sa_data, ret); + goto done; + } + + naddr = netcp_addr_add_mark(netcp, ndev->dev_addr, ADDR_DEV); + if (!naddr) { + ret = -ENOMEM; + goto done; + } + if (naddr->flags & ADDR_VALID) + goto done; + + ret = netcp_mod_add_addr(netcp, naddr); + if (ret) { + /* lower modules are not ready yet */ + netcp_addr_del(naddr); + ret = 0; + } + +done: + return ret; +} + static void netcp_ndo_tx_timeout(struct net_device *ndev) { struct netcp_priv *netcp = netdev_priv(ndev); @@ -1948,7 +2000,7 @@ static const struct net_device_ops netcp_netdev_ops = { .ndo_do_ioctl = netcp_ndo_ioctl, .ndo_get_stats64 = netcp_get_stats, .ndo_change_mtu = netcp_ndo_change_mtu, - .ndo_set_mac_address = eth_mac_addr, + .ndo_set_mac_address = netcp_ndo_set_mac_address, .ndo_validate_addr = eth_validate_addr, .ndo_vlan_rx_add_vid = netcp_rx_add_vid, .ndo_vlan_rx_kill_vid = netcp_rx_kill_vid, @@ -2000,6 +2052,8 @@ int netcp_create_interface(struct netcp_device *netcp_device, NETIF_F_SG| NETIF_F_FRAGLIST; + ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE; + netcp = netdev_priv(ndev); spin_lock_init(&netcp->lock); INIT_LIST_HEAD(&netcp->module_head); diff --git a/drivers/net/ethernet/ti/keystone_pa.c b/drivers/net/ethernet/ti/keystone_pa.c index 5b4875f3e78..620ed16a053 100644 --- a/drivers/net/ethernet/ti/keystone_pa.c +++ b/drivers/net/ethernet/ti/keystone_pa.c @@ -301,6 +301,7 @@ struct pa_device { u32 ip_lut_size; netdev_features_t netif_features; const char *pdsp_fw[DEVICE_PA_NUM_PDSPS]; + u32 opened; }; #define pa_from_module(data) container_of(data, struct pa_device, module) @@ -2095,6 +2096,7 @@ static int pa_close(void *intf_priv, struct net_device *ndev) pa_dev->clk = NULL; } + pa_dev->opened = 0; mutex_unlock(&pa_modules_lock); return 0; } @@ -2336,6 +2338,7 @@ static int pa_open(void *intf_priv, struct net_device *ndev) netcp_register_rxhook(netcp_priv, pa_dev->rxhook_order, pa_rx_hook, intf_priv); + pa_dev->opened = 1; return 0; fail: @@ -2355,6 +2358,9 @@ int pa_add_addr(void *intf_priv, struct netcp_addr *naddr) int idx, error; const u8 *addr; + if (!pa_dev->opened) + return -ENXIO; + for (idx = 0; idx < count; idx++) { entries[idx] = pa_lut_alloc(pa_dev, PA_LUT_MAC, naddr->type == ADDR_ANY); @@ -2409,6 +2415,9 @@ static int pa_del_addr(void *intf_priv, struct netcp_addr *naddr) struct pa_lut_entry *entry; int idx; + if (!pa_dev->opened) + return -ENXIO; + for (idx = 0; idx < pa_dev->lut_size; idx++) { entry = pa_dev->lut + idx; if (!entry->valid || !entry->in_use || entry->u.naddr != naddr) diff --git a/drivers/net/ethernet/ti/keystone_pa2.c b/drivers/net/ethernet/ti/keystone_pa2.c index caca6ff3006..3d642714ec9 100644 --- a/drivers/net/ethernet/ti/keystone_pa2.c +++ b/drivers/net/ethernet/ti/keystone_pa2.c @@ -1065,6 +1065,7 @@ struct pa2_device { u32 lut_size; const char *pdsp_fw[PA2_NUM_PDSPS]; + u32 opened; }; #define pa2_from_module(data) container_of(data, struct pa2_device, module) @@ -2413,6 +2414,7 @@ static int pa2_close(void *intf_priv, struct net_device *ndev) pa_dev->clk = NULL; } + pa_dev->opened = 0; mutex_unlock(&pa2_modules_lock); return 0; } @@ -2611,6 +2613,7 @@ static int pa2_open(void *intf_priv, struct net_device *ndev) netcp_register_txhook(netcp_priv, pa_dev->txhook_softcsum, pa2_txhook_softcsum, intf_priv); + pa_dev->opened = 1; return 0; fail: @@ -2662,6 +2665,9 @@ static int pa2_add_addr(void *intf_priv, struct netcp_addr *naddr) int idx, error; const u8 *addr; + if (!pa_dev->opened) + return -ENXIO; + for (idx = 0; idx < count; idx++) { entries[idx] = pa2_lut_alloc(pa_dev, naddr->type == ADDR_ANY); if (!entries[idx]) @@ -2715,6 +2721,9 @@ static int pa2_del_addr(void *intf_priv, struct netcp_addr *naddr) struct pa2_lut_entry *entry; int idx; + if (!pa_dev->opened) + return -ENXIO; + for (idx = 0; idx < pa_dev->lut_size; idx++) { entry = pa_dev->lut + idx; if (!entry->valid || !entry->in_use || entry->naddr != naddr) diff --git a/drivers/net/ethernet/ti/keystone_xgess.c b/drivers/net/ethernet/ti/keystone_xgess.c index 0af8126a11e..a84d5d78623 100644 --- a/drivers/net/ethernet/ti/keystone_xgess.c +++ b/drivers/net/ethernet/ti/keystone_xgess.c @@ -309,6 +309,7 @@ struct cpswx_priv { struct kobject stats_kobj; spinlock_t hw_stats_lock; struct device_node *serdes; + u32 opened; }; /* slave_port: 0-based (currently relevant only in multi_if mode) @@ -1819,6 +1820,9 @@ static int cpswx_add_addr(void *intf_priv, struct netcp_addr *naddr) struct cpswx_intf *cpsw_intf = intf_priv; struct cpswx_priv *cpsw_dev = cpsw_intf->cpsw_priv; + if (!cpsw_dev->opened) + return -ENXIO; + dev_dbg(cpsw_dev->dev, "xgess adding address %pM, type %d\n", naddr->addr, naddr->type); @@ -1845,6 +1849,9 @@ static int cpswx_del_addr(void *intf_priv, struct netcp_addr *naddr) struct cpswx_intf *cpsw_intf = intf_priv; struct cpswx_priv *cpsw_dev = cpsw_intf->cpsw_priv; + if (!cpsw_dev->opened) + return -ENXIO; + dev_dbg(cpsw_dev->dev, "xgess deleting address %pM, type %d\n", naddr->addr, naddr->type); @@ -2032,6 +2039,7 @@ static int cpswx_open(void *intf_mod_priv, struct net_device *ndev) PSTREAM_ROUTE_DMA); #endif + cpsw_dev->opened = 1; return 0; ale_fail: @@ -2066,6 +2074,7 @@ static int cpswx_close(void *intf_modpriv, struct net_device *ndev) clk_disable_unprepare(cpsw_dev->clk); clk_put(cpsw_dev->clk); + cpsw_dev->opened = 0; return 0; } -- cgit v1.2.3-54-g00ecf From 3e81277598fad80c185a1c2aa52952047409046e Mon Sep 17 00:00:00 2001 From: WingMan Kwok Date: Wed, 25 Feb 2015 16:12:06 -0500 Subject: net: keystone: add missing statistics for k2l and k2e This patch adds the missing statistics for k2l and k2e. It also removes the ones that are not defined for these platforms. Signed-off-by: WingMan Kwok --- drivers/net/ethernet/ti/keystone_ethss2.c | 308 +++++++++++++++++++++++++++--- 1 file changed, 278 insertions(+), 30 deletions(-) (limited to 'drivers/net/ethernet') diff --git a/drivers/net/ethernet/ti/keystone_ethss2.c b/drivers/net/ethernet/ti/keystone_ethss2.c index feaf3b82840..77cf57c5512 100644 --- a/drivers/net/ethernet/ti/keystone_ethss2.c +++ b/drivers/net/ethernet/ti/keystone_ethss2.c @@ -357,9 +357,50 @@ struct cpsw2_hw_stats { u32 ale_rate_limit_drop; u32 ale_vid_ingress_drop; u32 ale_da_eq_sa_drop; - u32 ale_block_drop; - u32 ale_secure_drop; - u32 ale_auth_drop; + u32 rsvd0[3]; + u32 ale_unknown_ucast; + u32 ale_unknown_ucast_bytes; + u32 ale_unknown_mcast; + u32 ale_unknown_mcast_bytes; + u32 ale_unknown_bcast; + u32 ale_unknown_bcast_bytes; + u32 ale_pol_match; + u32 ale_pol_match_red; + u32 ale_pol_match_yellow; + u32 rsvd1[44]; + u32 tx_mem_protect_err; + u32 tx_pri0; + u32 tx_pri1; + u32 tx_pri2; + u32 tx_pri3; + u32 tx_pri4; + u32 tx_pri5; + u32 tx_pri6; + u32 tx_pri7; + u32 tx_pri0_bcnt; + u32 tx_pri1_bcnt; + u32 tx_pri2_bcnt; + u32 tx_pri3_bcnt; + u32 tx_pri4_bcnt; + u32 tx_pri5_bcnt; + u32 tx_pri6_bcnt; + u32 tx_pri7_bcnt; + u32 tx_pri0_drop; + u32 tx_pri1_drop; + u32 tx_pri2_drop; + u32 tx_pri3_drop; + u32 tx_pri4_drop; + u32 tx_pri5_drop; + u32 tx_pri6_drop; + u32 tx_pri7_drop; + u32 tx_pri0_drop_bcnt; + u32 tx_pri1_drop_bcnt; + u32 tx_pri2_drop_bcnt; + u32 tx_pri3_drop_bcnt; + u32 tx_pri4_drop_bcnt; + u32 tx_pri5_drop_bcnt; + u32 tx_pri6_drop_bcnt; + u32 tx_pri7_drop_bcnt; }; /* Offset 0x3e000 */ @@ -495,9 +536,32 @@ static const struct netcp2_ethtool_stat et_stats[] = { {CPSW2_STATS0_INFO(ale_rate_limit_drop)}, {CPSW2_STATS0_INFO(ale_vid_ingress_drop)}, {CPSW2_STATS0_INFO(ale_da_eq_sa_drop)}, - {CPSW2_STATS0_INFO(ale_block_drop)}, - {CPSW2_STATS0_INFO(ale_secure_drop)}, - {CPSW2_STATS0_INFO(ale_auth_drop)}, + {CPSW2_STATS0_INFO(ale_unknown_ucast)}, + {CPSW2_STATS0_INFO(ale_unknown_ucast_bytes)}, + {CPSW2_STATS0_INFO(ale_unknown_mcast)}, + {CPSW2_STATS0_INFO(ale_unknown_mcast_bytes)}, + {CPSW2_STATS0_INFO(ale_unknown_bcast)}, + {CPSW2_STATS0_INFO(ale_unknown_bcast_bytes)}, + {CPSW2_STATS0_INFO(ale_pol_match)}, + {CPSW2_STATS0_INFO(ale_pol_match_red)}, + {CPSW2_STATS0_INFO(ale_pol_match_yellow)}, + {CPSW2_STATS0_INFO(tx_mem_protect_err)}, + {CPSW2_STATS0_INFO(tx_pri0_drop)}, + {CPSW2_STATS0_INFO(tx_pri1_drop)}, + {CPSW2_STATS0_INFO(tx_pri2_drop)}, + {CPSW2_STATS0_INFO(tx_pri3_drop)}, + {CPSW2_STATS0_INFO(tx_pri4_drop)}, + {CPSW2_STATS0_INFO(tx_pri5_drop)}, + {CPSW2_STATS0_INFO(tx_pri6_drop)}, + {CPSW2_STATS0_INFO(tx_pri7_drop)}, + {CPSW2_STATS0_INFO(tx_pri0_drop_bcnt)}, + {CPSW2_STATS0_INFO(tx_pri1_drop_bcnt)}, + {CPSW2_STATS0_INFO(tx_pri2_drop_bcnt)}, + {CPSW2_STATS0_INFO(tx_pri3_drop_bcnt)}, + {CPSW2_STATS0_INFO(tx_pri4_drop_bcnt)}, + {CPSW2_STATS0_INFO(tx_pri5_drop_bcnt)}, + {CPSW2_STATS0_INFO(tx_pri6_drop_bcnt)}, + {CPSW2_STATS0_INFO(tx_pri7_drop_bcnt)}, /* CPSW module 1 */ {CPSW2_STATS1_INFO(rx_good_frames)}, {CPSW2_STATS1_INFO(rx_broadcast_frames)}, @@ -538,9 +602,32 @@ static const struct netcp2_ethtool_stat et_stats[] = { {CPSW2_STATS1_INFO(ale_rate_limit_drop)}, {CPSW2_STATS1_INFO(ale_vid_ingress_drop)}, {CPSW2_STATS1_INFO(ale_da_eq_sa_drop)}, - {CPSW2_STATS1_INFO(ale_block_drop)}, - {CPSW2_STATS1_INFO(ale_secure_drop)}, - {CPSW2_STATS1_INFO(ale_auth_drop)}, + {CPSW2_STATS1_INFO(ale_unknown_ucast)}, + {CPSW2_STATS1_INFO(ale_unknown_ucast_bytes)}, + {CPSW2_STATS1_INFO(ale_unknown_mcast)}, + {CPSW2_STATS1_INFO(ale_unknown_mcast_bytes)}, + {CPSW2_STATS1_INFO(ale_unknown_bcast)}, + {CPSW2_STATS1_INFO(ale_unknown_bcast_bytes)}, + {CPSW2_STATS1_INFO(ale_pol_match)}, + {CPSW2_STATS1_INFO(ale_pol_match_red)}, + {CPSW2_STATS1_INFO(ale_pol_match_yellow)}, + {CPSW2_STATS1_INFO(tx_mem_protect_err)}, + {CPSW2_STATS1_INFO(tx_pri0_drop)}, + {CPSW2_STATS1_INFO(tx_pri1_drop)}, + {CPSW2_STATS1_INFO(tx_pri2_drop)}, + {CPSW2_STATS1_INFO(tx_pri3_drop)}, + {CPSW2_STATS1_INFO(tx_pri4_drop)}, + {CPSW2_STATS1_INFO(tx_pri5_drop)}, + {CPSW2_STATS1_INFO(tx_pri6_drop)}, + {CPSW2_STATS1_INFO(tx_pri7_drop)}, + {CPSW2_STATS1_INFO(tx_pri0_drop_bcnt)}, + {CPSW2_STATS1_INFO(tx_pri1_drop_bcnt)}, + {CPSW2_STATS1_INFO(tx_pri2_drop_bcnt)}, + {CPSW2_STATS1_INFO(tx_pri3_drop_bcnt)}, + {CPSW2_STATS1_INFO(tx_pri4_drop_bcnt)}, + {CPSW2_STATS1_INFO(tx_pri5_drop_bcnt)}, + {CPSW2_STATS1_INFO(tx_pri6_drop_bcnt)}, + {CPSW2_STATS1_INFO(tx_pri7_drop_bcnt)}, /* CPSW module 2 */ {CPSW2_STATS2_INFO(rx_good_frames)}, {CPSW2_STATS2_INFO(rx_broadcast_frames)}, @@ -581,9 +668,32 @@ static const struct netcp2_ethtool_stat et_stats[] = { {CPSW2_STATS2_INFO(ale_rate_limit_drop)}, {CPSW2_STATS2_INFO(ale_vid_ingress_drop)}, {CPSW2_STATS2_INFO(ale_da_eq_sa_drop)}, - {CPSW2_STATS2_INFO(ale_block_drop)}, - {CPSW2_STATS2_INFO(ale_secure_drop)}, - {CPSW2_STATS2_INFO(ale_auth_drop)}, + {CPSW2_STATS2_INFO(ale_unknown_ucast)}, + {CPSW2_STATS2_INFO(ale_unknown_ucast_bytes)}, + {CPSW2_STATS2_INFO(ale_unknown_mcast)}, + {CPSW2_STATS2_INFO(ale_unknown_mcast_bytes)}, + {CPSW2_STATS2_INFO(ale_unknown_bcast)}, + {CPSW2_STATS2_INFO(ale_unknown_bcast_bytes)}, + {CPSW2_STATS2_INFO(ale_pol_match)}, + {CPSW2_STATS2_INFO(ale_pol_match_red)}, + {CPSW2_STATS2_INFO(ale_pol_match_yellow)}, + {CPSW2_STATS2_INFO(tx_mem_protect_err)}, + {CPSW2_STATS2_INFO(tx_pri0_drop)}, + {CPSW2_STATS2_INFO(tx_pri1_drop)}, + {CPSW2_STATS2_INFO(tx_pri2_drop)}, + {CPSW2_STATS2_INFO(tx_pri3_drop)}, + {CPSW2_STATS2_INFO(tx_pri4_drop)}, + {CPSW2_STATS2_INFO(tx_pri5_drop)}, + {CPSW2_STATS2_INFO(tx_pri6_drop)}, + {CPSW2_STATS2_INFO(tx_pri7_drop)}, + {CPSW2_STATS2_INFO(tx_pri0_drop_bcnt)}, + {CPSW2_STATS2_INFO(tx_pri1_drop_bcnt)}, + {CPSW2_STATS2_INFO(tx_pri2_drop_bcnt)}, + {CPSW2_STATS2_INFO(tx_pri3_drop_bcnt)}, + {CPSW2_STATS2_INFO(tx_pri4_drop_bcnt)}, + {CPSW2_STATS2_INFO(tx_pri5_drop_bcnt)}, + {CPSW2_STATS2_INFO(tx_pri6_drop_bcnt)}, + {CPSW2_STATS2_INFO(tx_pri7_drop_bcnt)}, /* CPSW module 3 */ {CPSW2_STATS3_INFO(rx_good_frames)}, {CPSW2_STATS3_INFO(rx_broadcast_frames)}, @@ -624,9 +734,32 @@ static const struct netcp2_ethtool_stat et_stats[] = { {CPSW2_STATS3_INFO(ale_rate_limit_drop)}, {CPSW2_STATS3_INFO(ale_vid_ingress_drop)}, {CPSW2_STATS3_INFO(ale_da_eq_sa_drop)}, - {CPSW2_STATS3_INFO(ale_block_drop)}, - {CPSW2_STATS3_INFO(ale_secure_drop)}, - {CPSW2_STATS3_INFO(ale_auth_drop)}, + {CPSW2_STATS3_INFO(ale_unknown_ucast)}, + {CPSW2_STATS3_INFO(ale_unknown_ucast_bytes)}, + {CPSW2_STATS3_INFO(ale_unknown_mcast)}, + {CPSW2_STATS3_INFO(ale_unknown_mcast_bytes)}, + {CPSW2_STATS3_INFO(ale_unknown_bcast)}, + {CPSW2_STATS3_INFO(ale_unknown_bcast_bytes)}, + {CPSW2_STATS3_INFO(ale_pol_match)}, + {CPSW2_STATS3_INFO(ale_pol_match_red)}, + {CPSW2_STATS3_INFO(ale_pol_match_yellow)}, + {CPSW2_STATS3_INFO(tx_mem_protect_err)}, + {CPSW2_STATS3_INFO(tx_pri0_drop)}, + {CPSW2_STATS3_INFO(tx_pri1_drop)}, + {CPSW2_STATS3_INFO(tx_pri2_drop)}, + {CPSW2_STATS3_INFO(tx_pri3_drop)}, + {CPSW2_STATS3_INFO(tx_pri4_drop)}, + {CPSW2_STATS3_INFO(tx_pri5_drop)}, + {CPSW2_STATS3_INFO(tx_pri6_drop)}, + {CPSW2_STATS3_INFO(tx_pri7_drop)}, + {CPSW2_STATS3_INFO(tx_pri0_drop_bcnt)}, + {CPSW2_STATS3_INFO(tx_pri1_drop_bcnt)}, + {CPSW2_STATS3_INFO(tx_pri2_drop_bcnt)}, + {CPSW2_STATS3_INFO(tx_pri3_drop_bcnt)}, + {CPSW2_STATS3_INFO(tx_pri4_drop_bcnt)}, + {CPSW2_STATS3_INFO(tx_pri5_drop_bcnt)}, + {CPSW2_STATS3_INFO(tx_pri6_drop_bcnt)}, + {CPSW2_STATS3_INFO(tx_pri7_drop_bcnt)}, /* CPSW module 4 */ {CPSW2_STATS4_INFO(rx_good_frames)}, {CPSW2_STATS4_INFO(rx_broadcast_frames)}, @@ -667,9 +800,32 @@ static const struct netcp2_ethtool_stat et_stats[] = { {CPSW2_STATS4_INFO(ale_rate_limit_drop)}, {CPSW2_STATS4_INFO(ale_vid_ingress_drop)}, {CPSW2_STATS4_INFO(ale_da_eq_sa_drop)}, - {CPSW2_STATS4_INFO(ale_block_drop)}, - {CPSW2_STATS4_INFO(ale_secure_drop)}, - {CPSW2_STATS4_INFO(ale_auth_drop)}, + {CPSW2_STATS4_INFO(ale_unknown_ucast)}, + {CPSW2_STATS4_INFO(ale_unknown_ucast_bytes)}, + {CPSW2_STATS4_INFO(ale_unknown_mcast)}, + {CPSW2_STATS4_INFO(ale_unknown_mcast_bytes)}, + {CPSW2_STATS4_INFO(ale_unknown_bcast)}, + {CPSW2_STATS4_INFO(ale_unknown_bcast_bytes)}, + {CPSW2_STATS4_INFO(ale_pol_match)}, + {CPSW2_STATS4_INFO(ale_pol_match_red)}, + {CPSW2_STATS4_INFO(ale_pol_match_yellow)}, + {CPSW2_STATS4_INFO(tx_mem_protect_err)}, + {CPSW2_STATS4_INFO(tx_pri0_drop)}, + {CPSW2_STATS4_INFO(tx_pri1_drop)}, + {CPSW2_STATS4_INFO(tx_pri2_drop)}, + {CPSW2_STATS4_INFO(tx_pri3_drop)}, + {CPSW2_STATS4_INFO(tx_pri4_drop)}, + {CPSW2_STATS4_INFO(tx_pri5_drop)}, + {CPSW2_STATS4_INFO(tx_pri6_drop)}, + {CPSW2_STATS4_INFO(tx_pri7_drop)}, + {CPSW2_STATS4_INFO(tx_pri0_drop_bcnt)}, + {CPSW2_STATS4_INFO(tx_pri1_drop_bcnt)}, + {CPSW2_STATS4_INFO(tx_pri2_drop_bcnt)}, + {CPSW2_STATS4_INFO(tx_pri3_drop_bcnt)}, + {CPSW2_STATS4_INFO(tx_pri4_drop_bcnt)}, + {CPSW2_STATS4_INFO(tx_pri5_drop_bcnt)}, + {CPSW2_STATS4_INFO(tx_pri6_drop_bcnt)}, + {CPSW2_STATS4_INFO(tx_pri7_drop_bcnt)}, /* CPSW module 5 */ {CPSW2_STATS5_INFO(rx_good_frames)}, {CPSW2_STATS5_INFO(rx_broadcast_frames)}, @@ -710,9 +866,32 @@ static const struct netcp2_ethtool_stat et_stats[] = { {CPSW2_STATS5_INFO(ale_rate_limit_drop)}, {CPSW2_STATS5_INFO(ale_vid_ingress_drop)}, {CPSW2_STATS5_INFO(ale_da_eq_sa_drop)}, - {CPSW2_STATS5_INFO(ale_block_drop)}, - {CPSW2_STATS5_INFO(ale_secure_drop)}, - {CPSW2_STATS5_INFO(ale_auth_drop)}, + {CPSW2_STATS5_INFO(ale_unknown_ucast)}, + {CPSW2_STATS5_INFO(ale_unknown_ucast_bytes)}, + {CPSW2_STATS5_INFO(ale_unknown_mcast)}, + {CPSW2_STATS5_INFO(ale_unknown_mcast_bytes)}, + {CPSW2_STATS5_INFO(ale_unknown_bcast)}, + {CPSW2_STATS5_INFO(ale_unknown_bcast_bytes)}, + {CPSW2_STATS5_INFO(ale_pol_match)}, + {CPSW2_STATS5_INFO(ale_pol_match_red)}, + {CPSW2_STATS5_INFO(ale_pol_match_yellow)}, + {CPSW2_STATS5_INFO(tx_mem_protect_err)}, + {CPSW2_STATS5_INFO(tx_pri0_drop)}, + {CPSW2_STATS5_INFO(tx_pri1_drop)}, + {CPSW2_STATS5_INFO(tx_pri2_drop)}, + {CPSW2_STATS5_INFO(tx_pri3_drop)}, + {CPSW2_STATS5_INFO(tx_pri4_drop)}, + {CPSW2_STATS5_INFO(tx_pri5_drop)}, + {CPSW2_STATS5_INFO(tx_pri6_drop)}, + {CPSW2_STATS5_INFO(tx_pri7_drop)}, + {CPSW2_STATS5_INFO(tx_pri0_drop_bcnt)}, + {CPSW2_STATS5_INFO(tx_pri1_drop_bcnt)}, + {CPSW2_STATS5_INFO(tx_pri2_drop_bcnt)}, + {CPSW2_STATS5_INFO(tx_pri3_drop_bcnt)}, + {CPSW2_STATS5_INFO(tx_pri4_drop_bcnt)}, + {CPSW2_STATS5_INFO(tx_pri5_drop_bcnt)}, + {CPSW2_STATS5_INFO(tx_pri6_drop_bcnt)}, + {CPSW2_STATS5_INFO(tx_pri7_drop_bcnt)}, /* CPSW module 6 */ {CPSW2_STATS6_INFO(rx_good_frames)}, {CPSW2_STATS6_INFO(rx_broadcast_frames)}, @@ -753,9 +932,32 @@ static const struct netcp2_ethtool_stat et_stats[] = { {CPSW2_STATS6_INFO(ale_rate_limit_drop)}, {CPSW2_STATS6_INFO(ale_vid_ingress_drop)}, {CPSW2_STATS6_INFO(ale_da_eq_sa_drop)}, - {CPSW2_STATS6_INFO(ale_block_drop)}, - {CPSW2_STATS6_INFO(ale_secure_drop)}, - {CPSW2_STATS6_INFO(ale_auth_drop)}, + {CPSW2_STATS6_INFO(ale_unknown_ucast)}, + {CPSW2_STATS6_INFO(ale_unknown_ucast_bytes)}, + {CPSW2_STATS6_INFO(ale_unknown_mcast)}, + {CPSW2_STATS6_INFO(ale_unknown_mcast_bytes)}, + {CPSW2_STATS6_INFO(ale_unknown_bcast)}, + {CPSW2_STATS6_INFO(ale_unknown_bcast_bytes)}, + {CPSW2_STATS6_INFO(ale_pol_match)}, + {CPSW2_STATS6_INFO(ale_pol_match_red)}, + {CPSW2_STATS6_INFO(ale_pol_match_yellow)}, + {CPSW2_STATS6_INFO(tx_mem_protect_err)}, + {CPSW2_STATS6_INFO(tx_pri0_drop)}, + {CPSW2_STATS6_INFO(tx_pri1_drop)}, + {CPSW2_STATS6_INFO(tx_pri2_drop)}, + {CPSW2_STATS6_INFO(tx_pri3_drop)}, + {CPSW2_STATS6_INFO(tx_pri4_drop)}, + {CPSW2_STATS6_INFO(tx_pri5_drop)}, + {CPSW2_STATS6_INFO(tx_pri6_drop)}, + {CPSW2_STATS6_INFO(tx_pri7_drop)}, + {CPSW2_STATS6_INFO(tx_pri0_drop_bcnt)}, + {CPSW2_STATS6_INFO(tx_pri1_drop_bcnt)}, + {CPSW2_STATS6_INFO(tx_pri2_drop_bcnt)}, + {CPSW2_STATS6_INFO(tx_pri3_drop_bcnt)}, + {CPSW2_STATS6_INFO(tx_pri4_drop_bcnt)}, + {CPSW2_STATS6_INFO(tx_pri5_drop_bcnt)}, + {CPSW2_STATS6_INFO(tx_pri6_drop_bcnt)}, + {CPSW2_STATS6_INFO(tx_pri7_drop_bcnt)}, /* CPSW module 7 */ {CPSW2_STATS7_INFO(rx_good_frames)}, {CPSW2_STATS7_INFO(rx_broadcast_frames)}, @@ -796,9 +998,32 @@ static const struct netcp2_ethtool_stat et_stats[] = { {CPSW2_STATS7_INFO(ale_rate_limit_drop)}, {CPSW2_STATS7_INFO(ale_vid_ingress_drop)}, {CPSW2_STATS7_INFO(ale_da_eq_sa_drop)}, - {CPSW2_STATS7_INFO(ale_block_drop)}, - {CPSW2_STATS7_INFO(ale_secure_drop)}, - {CPSW2_STATS7_INFO(ale_auth_drop)}, + {CPSW2_STATS7_INFO(ale_unknown_ucast)}, + {CPSW2_STATS7_INFO(ale_unknown_ucast_bytes)}, + {CPSW2_STATS7_INFO(ale_unknown_mcast)}, + {CPSW2_STATS7_INFO(ale_unknown_mcast_bytes)}, + {CPSW2_STATS7_INFO(ale_unknown_bcast)}, + {CPSW2_STATS7_INFO(ale_unknown_bcast_bytes)}, + {CPSW2_STATS7_INFO(ale_pol_match)}, + {CPSW2_STATS7_INFO(ale_pol_match_red)}, + {CPSW2_STATS7_INFO(ale_pol_match_yellow)}, + {CPSW2_STATS7_INFO(tx_mem_protect_err)}, + {CPSW2_STATS7_INFO(tx_pri0_drop)}, + {CPSW2_STATS7_INFO(tx_pri1_drop)}, + {CPSW2_STATS7_INFO(tx_pri2_drop)}, + {CPSW2_STATS7_INFO(tx_pri3_drop)}, + {CPSW2_STATS7_INFO(tx_pri4_drop)}, + {CPSW2_STATS7_INFO(tx_pri5_drop)}, + {CPSW2_STATS7_INFO(tx_pri6_drop)}, + {CPSW2_STATS7_INFO(tx_pri7_drop)}, + {CPSW2_STATS7_INFO(tx_pri0_drop_bcnt)}, + {CPSW2_STATS7_INFO(tx_pri1_drop_bcnt)}, + {CPSW2_STATS7_INFO(tx_pri2_drop_bcnt)}, + {CPSW2_STATS7_INFO(tx_pri3_drop_bcnt)}, + {CPSW2_STATS7_INFO(tx_pri4_drop_bcnt)}, + {CPSW2_STATS7_INFO(tx_pri5_drop_bcnt)}, + {CPSW2_STATS7_INFO(tx_pri6_drop_bcnt)}, + {CPSW2_STATS7_INFO(tx_pri7_drop_bcnt)}, /* CPSW module 8 */ {CPSW2_STATS8_INFO(rx_good_frames)}, {CPSW2_STATS8_INFO(rx_broadcast_frames)}, @@ -839,9 +1064,32 @@ static const struct netcp2_ethtool_stat et_stats[] = { {CPSW2_STATS8_INFO(ale_rate_limit_drop)}, {CPSW2_STATS8_INFO(ale_vid_ingress_drop)}, {CPSW2_STATS8_INFO(ale_da_eq_sa_drop)}, - {CPSW2_STATS8_INFO(ale_block_drop)}, - {CPSW2_STATS8_INFO(ale_secure_drop)}, - {CPSW2_STATS8_INFO(ale_auth_drop)}, + {CPSW2_STATS8_INFO(ale_unknown_ucast)}, + {CPSW2_STATS8_INFO(ale_unknown_ucast_bytes)}, + {CPSW2_STATS8_INFO(ale_unknown_mcast)}, + {CPSW2_STATS8_INFO(ale_unknown_mcast_bytes)}, + {CPSW2_STATS8_INFO(ale_unknown_bcast)}, + {CPSW2_STATS8_INFO(ale_unknown_bcast_bytes)}, + {CPSW2_STATS8_INFO(ale_pol_match)}, + {CPSW2_STATS8_INFO(ale_pol_match_red)}, + {CPSW2_STATS8_INFO(ale_pol_match_yellow)}, + {CPSW2_STATS8_INFO(tx_mem_protect_err)}, + {CPSW2_STATS8_INFO(tx_pri0_drop)}, + {CPSW2_STATS8_INFO(tx_pri1_drop)}, + {CPSW2_STATS8_INFO(tx_pri2_drop)}, + {CPSW2_STATS8_INFO(tx_pri3_drop)}, + {CPSW2_STATS8_INFO(tx_pri4_drop)}, + {CPSW2_STATS8_INFO(tx_pri5_drop)}, + {CPSW2_STATS8_INFO(tx_pri6_drop)}, + {CPSW2_STATS8_INFO(tx_pri7_drop)}, + {CPSW2_STATS8_INFO(tx_pri0_drop_bcnt)}, + {CPSW2_STATS8_INFO(tx_pri1_drop_bcnt)}, + {CPSW2_STATS8_INFO(tx_pri2_drop_bcnt)}, + {CPSW2_STATS8_INFO(tx_pri3_drop_bcnt)}, + {CPSW2_STATS8_INFO(tx_pri4_drop_bcnt)}, + {CPSW2_STATS8_INFO(tx_pri5_drop_bcnt)}, + {CPSW2_STATS8_INFO(tx_pri6_drop_bcnt)}, + {CPSW2_STATS8_INFO(tx_pri7_drop_bcnt)}, }; #define ETHTOOL_PORT_STATS_NUM (ARRAY_SIZE(et_stats)/CPSW2_NUM_PORTS) -- cgit v1.2.3-54-g00ecf