16f8d3f33SWingman Kwok /* 290cff9e2SWingman Kwok * Keystone GBE and XGBE subsystem code 36f8d3f33SWingman Kwok * 46f8d3f33SWingman Kwok * Copyright (C) 2014 Texas Instruments Incorporated 56f8d3f33SWingman Kwok * Authors: Sandeep Nair <sandeep_n@ti.com> 66f8d3f33SWingman Kwok * Sandeep Paulraj <s-paulraj@ti.com> 76f8d3f33SWingman Kwok * Cyril Chemparathy <cyril@ti.com> 86f8d3f33SWingman Kwok * Santosh Shilimkar <santosh.shilimkar@ti.com> 96f8d3f33SWingman Kwok * Wingman Kwok <w-kwok2@ti.com> 106f8d3f33SWingman Kwok * 116f8d3f33SWingman Kwok * This program is free software; you can redistribute it and/or 126f8d3f33SWingman Kwok * modify it under the terms of the GNU General Public License as 136f8d3f33SWingman Kwok * published by the Free Software Foundation version 2. 146f8d3f33SWingman Kwok * 156f8d3f33SWingman Kwok * This program is distributed "as is" WITHOUT ANY WARRANTY of any 166f8d3f33SWingman Kwok * kind, whether express or implied; without even the implied warranty 176f8d3f33SWingman Kwok * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 186f8d3f33SWingman Kwok * GNU General Public License for more details. 196f8d3f33SWingman Kwok */ 206f8d3f33SWingman Kwok 216f8d3f33SWingman Kwok #include <linux/io.h> 2258c11b5fSKaricheri, Muralidharan #include <linux/module.h> 236f8d3f33SWingman Kwok #include <linux/of_mdio.h> 247b647b93SMurali Karicheri #include <linux/of_net.h> 256f8d3f33SWingman Kwok #include <linux/of_address.h> 266f8d3f33SWingman Kwok #include <linux/if_vlan.h> 276246168bSWingMan Kwok #include <linux/ptp_classify.h> 286246168bSWingMan Kwok #include <linux/net_tstamp.h> 296f8d3f33SWingman Kwok #include <linux/ethtool.h> 306f8d3f33SWingman Kwok 312733d7b8SGrygorii Strashko #include "cpsw.h" 326f8d3f33SWingman Kwok #include "cpsw_ale.h" 336f8d3f33SWingman Kwok #include "netcp.h" 346246168bSWingMan Kwok #include "cpts.h" 356f8d3f33SWingman Kwok 366f8d3f33SWingman Kwok #define NETCP_DRIVER_NAME "TI KeyStone Ethernet Driver" 376f8d3f33SWingman Kwok #define NETCP_DRIVER_VERSION "v1.0" 386f8d3f33SWingman Kwok 396f8d3f33SWingman Kwok #define GBE_IDENT(reg) ((reg >> 16) & 0xffff) 406f8d3f33SWingman Kwok #define GBE_MAJOR_VERSION(reg) (reg >> 8 & 0x7) 416f8d3f33SWingman Kwok #define GBE_MINOR_VERSION(reg) (reg & 0xff) 426f8d3f33SWingman Kwok #define GBE_RTL_VERSION(reg) ((reg >> 11) & 0x1f) 436f8d3f33SWingman Kwok 446f8d3f33SWingman Kwok /* 1G Ethernet SS defines */ 456f8d3f33SWingman Kwok #define GBE_MODULE_NAME "netcp-gbe" 462953586dSMurali Karicheri #define GBE_SS_VERSION_14 0x4ed2 476f8d3f33SWingman Kwok 4821e0e0ddSKaricheri, Muralidharan #define GBE_SS_REG_INDEX 0 4921e0e0ddSKaricheri, Muralidharan #define GBE_SGMII34_REG_INDEX 1 5021e0e0ddSKaricheri, Muralidharan #define GBE_SM_REG_INDEX 2 5121e0e0ddSKaricheri, Muralidharan /* offset relative to base of GBE_SS_REG_INDEX */ 526f8d3f33SWingman Kwok #define GBE13_SGMII_MODULE_OFFSET 0x100 5321e0e0ddSKaricheri, Muralidharan /* offset relative to base of GBE_SM_REG_INDEX */ 5421e0e0ddSKaricheri, Muralidharan #define GBE13_HOST_PORT_OFFSET 0x34 5521e0e0ddSKaricheri, Muralidharan #define GBE13_SLAVE_PORT_OFFSET 0x60 5621e0e0ddSKaricheri, Muralidharan #define GBE13_EMAC_OFFSET 0x100 5721e0e0ddSKaricheri, Muralidharan #define GBE13_SLAVE_PORT2_OFFSET 0x200 5821e0e0ddSKaricheri, Muralidharan #define GBE13_HW_STATS_OFFSET 0x300 596246168bSWingMan Kwok #define GBE13_CPTS_OFFSET 0x500 6021e0e0ddSKaricheri, Muralidharan #define GBE13_ALE_OFFSET 0x600 616f8d3f33SWingman Kwok #define GBE13_HOST_PORT_NUM 0 626f8d3f33SWingman Kwok #define GBE13_NUM_ALE_ENTRIES 1024 636f8d3f33SWingman Kwok 649a391c7bSWingMan Kwok /* 1G Ethernet NU SS defines */ 659a391c7bSWingMan Kwok #define GBENU_MODULE_NAME "netcp-gbenu" 669a391c7bSWingMan Kwok #define GBE_SS_ID_NU 0x4ee6 679a391c7bSWingMan Kwok #define GBE_SS_ID_2U 0x4ee8 689a391c7bSWingMan Kwok 699a391c7bSWingMan Kwok #define IS_SS_ID_MU(d) \ 709a391c7bSWingMan Kwok ((GBE_IDENT((d)->ss_version) == GBE_SS_ID_NU) || \ 719a391c7bSWingMan Kwok (GBE_IDENT((d)->ss_version) == GBE_SS_ID_2U)) 729a391c7bSWingMan Kwok 739a391c7bSWingMan Kwok #define IS_SS_ID_NU(d) \ 749a391c7bSWingMan Kwok (GBE_IDENT((d)->ss_version) == GBE_SS_ID_NU) 759a391c7bSWingMan Kwok 762953586dSMurali Karicheri #define IS_SS_ID_VER_14(d) \ 772953586dSMurali Karicheri (GBE_IDENT((d)->ss_version) == GBE_SS_VERSION_14) 78775f9535SMurali Karicheri #define IS_SS_ID_2U(d) \ 79775f9535SMurali Karicheri (GBE_IDENT((d)->ss_version) == GBE_SS_ID_2U) 802953586dSMurali Karicheri 819a391c7bSWingMan Kwok #define GBENU_SS_REG_INDEX 0 829a391c7bSWingMan Kwok #define GBENU_SM_REG_INDEX 1 839a391c7bSWingMan Kwok #define GBENU_SGMII_MODULE_OFFSET 0x100 849a391c7bSWingMan Kwok #define GBENU_HOST_PORT_OFFSET 0x1000 859a391c7bSWingMan Kwok #define GBENU_SLAVE_PORT_OFFSET 0x2000 869a391c7bSWingMan Kwok #define GBENU_EMAC_OFFSET 0x2330 879a391c7bSWingMan Kwok #define GBENU_HW_STATS_OFFSET 0x1a000 886246168bSWingMan Kwok #define GBENU_CPTS_OFFSET 0x1d000 899a391c7bSWingMan Kwok #define GBENU_ALE_OFFSET 0x1e000 909a391c7bSWingMan Kwok #define GBENU_HOST_PORT_NUM 0 918c85151dSWingMan Kwok #define GBENU_SGMII_MODULE_SIZE 0x100 929a391c7bSWingMan Kwok 9390cff9e2SWingman Kwok /* 10G Ethernet SS defines */ 9490cff9e2SWingman Kwok #define XGBE_MODULE_NAME "netcp-xgbe" 952953586dSMurali Karicheri #define XGBE_SS_VERSION_10 0x4ee4 9690cff9e2SWingman Kwok 9721e0e0ddSKaricheri, Muralidharan #define XGBE_SS_REG_INDEX 0 9821e0e0ddSKaricheri, Muralidharan #define XGBE_SM_REG_INDEX 1 9921e0e0ddSKaricheri, Muralidharan #define XGBE_SERDES_REG_INDEX 2 10021e0e0ddSKaricheri, Muralidharan 10121e0e0ddSKaricheri, Muralidharan /* offset relative to base of XGBE_SS_REG_INDEX */ 10290cff9e2SWingman Kwok #define XGBE10_SGMII_MODULE_OFFSET 0x100 1034c0ef231SWingMan Kwok #define IS_SS_ID_XGBE(d) ((d)->ss_version == XGBE_SS_VERSION_10) 10421e0e0ddSKaricheri, Muralidharan /* offset relative to base of XGBE_SM_REG_INDEX */ 10521e0e0ddSKaricheri, Muralidharan #define XGBE10_HOST_PORT_OFFSET 0x34 10621e0e0ddSKaricheri, Muralidharan #define XGBE10_SLAVE_PORT_OFFSET 0x64 10721e0e0ddSKaricheri, Muralidharan #define XGBE10_EMAC_OFFSET 0x400 1086246168bSWingMan Kwok #define XGBE10_CPTS_OFFSET 0x600 10921e0e0ddSKaricheri, Muralidharan #define XGBE10_ALE_OFFSET 0x700 11021e0e0ddSKaricheri, Muralidharan #define XGBE10_HW_STATS_OFFSET 0x800 11190cff9e2SWingman Kwok #define XGBE10_HOST_PORT_NUM 0 1127938a0d7SKaricheri, Muralidharan #define XGBE10_NUM_ALE_ENTRIES 2048 11390cff9e2SWingman Kwok 1146f8d3f33SWingman Kwok #define GBE_TIMER_INTERVAL (HZ / 2) 1156f8d3f33SWingman Kwok 1166f8d3f33SWingman Kwok /* Soft reset register values */ 1176f8d3f33SWingman Kwok #define SOFT_RESET_MASK BIT(0) 1186f8d3f33SWingman Kwok #define SOFT_RESET BIT(0) 1196f8d3f33SWingman Kwok #define DEVICE_EMACSL_RESET_POLL_COUNT 100 1206f8d3f33SWingman Kwok #define GMACSL_RET_WARN_RESET_INCOMPLETE -2 1216f8d3f33SWingman Kwok 1226f8d3f33SWingman Kwok #define MACSL_RX_ENABLE_CSF BIT(23) 1236f8d3f33SWingman Kwok #define MACSL_ENABLE_EXT_CTL BIT(18) 12490cff9e2SWingman Kwok #define MACSL_XGMII_ENABLE BIT(13) 12590cff9e2SWingman Kwok #define MACSL_XGIG_MODE BIT(8) 1266f8d3f33SWingman Kwok #define MACSL_GIG_MODE BIT(7) 1276f8d3f33SWingman Kwok #define MACSL_GMII_ENABLE BIT(5) 1286f8d3f33SWingman Kwok #define MACSL_FULLDUPLEX BIT(0) 1296f8d3f33SWingman Kwok 1306f8d3f33SWingman Kwok #define GBE_CTL_P0_ENABLE BIT(2) 1314cd85a61SKaricheri, Muralidharan #define ETH_SW_CTL_P0_TX_CRC_REMOVE BIT(13) 1329a391c7bSWingMan Kwok #define GBE13_REG_VAL_STAT_ENABLE_ALL 0xff 13390cff9e2SWingman Kwok #define XGBE_REG_VAL_STAT_ENABLE_ALL 0xf 1346f8d3f33SWingman Kwok #define GBE_STATS_CD_SEL BIT(28) 1356f8d3f33SWingman Kwok 1366f8d3f33SWingman Kwok #define GBE_PORT_MASK(x) (BIT(x) - 1) 1376f8d3f33SWingman Kwok #define GBE_MASK_NO_PORTS 0 1386f8d3f33SWingman Kwok 1396f8d3f33SWingman Kwok #define GBE_DEF_1G_MAC_CONTROL \ 1406f8d3f33SWingman Kwok (MACSL_GIG_MODE | MACSL_GMII_ENABLE | \ 1416f8d3f33SWingman Kwok MACSL_ENABLE_EXT_CTL | MACSL_RX_ENABLE_CSF) 1426f8d3f33SWingman Kwok 14390cff9e2SWingman Kwok #define GBE_DEF_10G_MAC_CONTROL \ 14490cff9e2SWingman Kwok (MACSL_XGIG_MODE | MACSL_XGMII_ENABLE | \ 14590cff9e2SWingman Kwok MACSL_ENABLE_EXT_CTL | MACSL_RX_ENABLE_CSF) 14690cff9e2SWingman Kwok 1476f8d3f33SWingman Kwok #define GBE_STATSA_MODULE 0 1486f8d3f33SWingman Kwok #define GBE_STATSB_MODULE 1 1496f8d3f33SWingman Kwok #define GBE_STATSC_MODULE 2 1506f8d3f33SWingman Kwok #define GBE_STATSD_MODULE 3 1516f8d3f33SWingman Kwok 1529a391c7bSWingMan Kwok #define GBENU_STATS0_MODULE 0 1539a391c7bSWingMan Kwok #define GBENU_STATS1_MODULE 1 1549a391c7bSWingMan Kwok #define GBENU_STATS2_MODULE 2 1559a391c7bSWingMan Kwok #define GBENU_STATS3_MODULE 3 1569a391c7bSWingMan Kwok #define GBENU_STATS4_MODULE 4 1579a391c7bSWingMan Kwok #define GBENU_STATS5_MODULE 5 1589a391c7bSWingMan Kwok #define GBENU_STATS6_MODULE 6 1599a391c7bSWingMan Kwok #define GBENU_STATS7_MODULE 7 1609a391c7bSWingMan Kwok #define GBENU_STATS8_MODULE 8 1619a391c7bSWingMan Kwok 16290cff9e2SWingman Kwok #define XGBE_STATS0_MODULE 0 16390cff9e2SWingman Kwok #define XGBE_STATS1_MODULE 1 16490cff9e2SWingman Kwok #define XGBE_STATS2_MODULE 2 16590cff9e2SWingman Kwok 1666f8d3f33SWingman Kwok /* s: 0-based slave_port */ 1678c85151dSWingMan Kwok #define SGMII_BASE(d, s) \ 1688c85151dSWingMan Kwok (((s) < 2) ? (d)->sgmii_port_regs : (d)->sgmii_port34_regs) 1696f8d3f33SWingman Kwok 1706f8d3f33SWingman Kwok #define GBE_TX_QUEUE 648 1716f8d3f33SWingman Kwok #define GBE_TXHOOK_ORDER 0 1726246168bSWingMan Kwok #define GBE_RXHOOK_ORDER 0 1736f8d3f33SWingman Kwok #define GBE_DEFAULT_ALE_AGEOUT 30 17490cff9e2SWingman Kwok #define SLAVE_LINK_IS_XGMII(s) ((s)->link_interface >= XGMII_LINK_MAC_PHY) 1757771f2b4SMurali Karicheri #define SLAVE_LINK_IS_RGMII(s) \ 1767771f2b4SMurali Karicheri (((s)->link_interface >= RGMII_LINK_MAC_PHY) && \ 1777771f2b4SMurali Karicheri ((s)->link_interface <= RGMII_LINK_MAC_PHY_NO_MDIO)) 1787771f2b4SMurali Karicheri #define SLAVE_LINK_IS_SGMII(s) \ 1797771f2b4SMurali Karicheri ((s)->link_interface <= SGMII_LINK_MAC_PHY_NO_MDIO) 1806f8d3f33SWingman Kwok #define NETCP_LINK_STATE_INVALID -1 1816f8d3f33SWingman Kwok 1826f8d3f33SWingman Kwok #define GBE_SET_REG_OFS(p, rb, rn) p->rb##_ofs.rn = \ 1836f8d3f33SWingman Kwok offsetof(struct gbe##_##rb, rn) 1849a391c7bSWingMan Kwok #define GBENU_SET_REG_OFS(p, rb, rn) p->rb##_ofs.rn = \ 1859a391c7bSWingMan Kwok offsetof(struct gbenu##_##rb, rn) 18690cff9e2SWingman Kwok #define XGBE_SET_REG_OFS(p, rb, rn) p->rb##_ofs.rn = \ 18790cff9e2SWingman Kwok offsetof(struct xgbe##_##rb, rn) 1886f8d3f33SWingman Kwok #define GBE_REG_ADDR(p, rb, rn) (p->rb + p->rb##_ofs.rn) 1896f8d3f33SWingman Kwok 1909a391c7bSWingMan Kwok #define HOST_TX_PRI_MAP_DEFAULT 0x00000000 1919a391c7bSWingMan Kwok 1926246168bSWingMan Kwok #if IS_ENABLED(CONFIG_TI_CPTS) 1936246168bSWingMan Kwok /* Px_TS_CTL register fields */ 1946246168bSWingMan Kwok #define TS_RX_ANX_F_EN BIT(0) 1956246168bSWingMan Kwok #define TS_RX_VLAN_LT1_EN BIT(1) 1966246168bSWingMan Kwok #define TS_RX_VLAN_LT2_EN BIT(2) 1976246168bSWingMan Kwok #define TS_RX_ANX_D_EN BIT(3) 1986246168bSWingMan Kwok #define TS_TX_ANX_F_EN BIT(4) 1996246168bSWingMan Kwok #define TS_TX_VLAN_LT1_EN BIT(5) 2006246168bSWingMan Kwok #define TS_TX_VLAN_LT2_EN BIT(6) 2016246168bSWingMan Kwok #define TS_TX_ANX_D_EN BIT(7) 2026246168bSWingMan Kwok #define TS_LT2_EN BIT(8) 2036246168bSWingMan Kwok #define TS_RX_ANX_E_EN BIT(9) 2046246168bSWingMan Kwok #define TS_TX_ANX_E_EN BIT(10) 2056246168bSWingMan Kwok #define TS_MSG_TYPE_EN_SHIFT 16 2066246168bSWingMan Kwok #define TS_MSG_TYPE_EN_MASK 0xffff 2076246168bSWingMan Kwok 2086246168bSWingMan Kwok /* Px_TS_SEQ_LTYPE register fields */ 2096246168bSWingMan Kwok #define TS_SEQ_ID_OFS_SHIFT 16 2106246168bSWingMan Kwok #define TS_SEQ_ID_OFS_MASK 0x3f 2116246168bSWingMan Kwok 2126246168bSWingMan Kwok /* Px_TS_CTL_LTYPE2 register fields */ 2136246168bSWingMan Kwok #define TS_107 BIT(16) 2146246168bSWingMan Kwok #define TS_129 BIT(17) 2156246168bSWingMan Kwok #define TS_130 BIT(18) 2166246168bSWingMan Kwok #define TS_131 BIT(19) 2176246168bSWingMan Kwok #define TS_132 BIT(20) 2186246168bSWingMan Kwok #define TS_319 BIT(21) 2196246168bSWingMan Kwok #define TS_320 BIT(22) 2206246168bSWingMan Kwok #define TS_TTL_NONZERO BIT(23) 2216246168bSWingMan Kwok #define TS_UNI_EN BIT(24) 2226246168bSWingMan Kwok #define TS_UNI_EN_SHIFT 24 2236246168bSWingMan Kwok 2246246168bSWingMan Kwok #define TS_TX_ANX_ALL_EN \ 2256246168bSWingMan Kwok (TS_TX_ANX_D_EN | TS_TX_ANX_E_EN | TS_TX_ANX_F_EN) 2266246168bSWingMan Kwok 2276246168bSWingMan Kwok #define TS_RX_ANX_ALL_EN \ 2286246168bSWingMan Kwok (TS_RX_ANX_D_EN | TS_RX_ANX_E_EN | TS_RX_ANX_F_EN) 2296246168bSWingMan Kwok 2306246168bSWingMan Kwok #define TS_CTL_DST_PORT TS_319 2316246168bSWingMan Kwok #define TS_CTL_DST_PORT_SHIFT 21 2326246168bSWingMan Kwok 2336246168bSWingMan Kwok #define TS_CTL_MADDR_ALL \ 2346246168bSWingMan Kwok (TS_107 | TS_129 | TS_130 | TS_131 | TS_132) 2356246168bSWingMan Kwok 2366246168bSWingMan Kwok #define TS_CTL_MADDR_SHIFT 16 2376246168bSWingMan Kwok 2386246168bSWingMan Kwok /* The PTP event messages - Sync, Delay_Req, Pdelay_Req, and Pdelay_Resp. */ 2396246168bSWingMan Kwok #define EVENT_MSG_BITS (BIT(0) | BIT(1) | BIT(2) | BIT(3)) 2406246168bSWingMan Kwok #endif /* CONFIG_TI_CPTS */ 2416246168bSWingMan Kwok 24290cff9e2SWingman Kwok struct xgbe_ss_regs { 24390cff9e2SWingman Kwok u32 id_ver; 24490cff9e2SWingman Kwok u32 synce_count; 24590cff9e2SWingman Kwok u32 synce_mux; 24690cff9e2SWingman Kwok u32 control; 24790cff9e2SWingman Kwok }; 24890cff9e2SWingman Kwok 24990cff9e2SWingman Kwok struct xgbe_switch_regs { 25090cff9e2SWingman Kwok u32 id_ver; 25190cff9e2SWingman Kwok u32 control; 25290cff9e2SWingman Kwok u32 emcontrol; 25390cff9e2SWingman Kwok u32 stat_port_en; 25490cff9e2SWingman Kwok u32 ptype; 25590cff9e2SWingman Kwok u32 soft_idle; 25690cff9e2SWingman Kwok u32 thru_rate; 25790cff9e2SWingman Kwok u32 gap_thresh; 25890cff9e2SWingman Kwok u32 tx_start_wds; 25990cff9e2SWingman Kwok u32 flow_control; 26090cff9e2SWingman Kwok u32 cppi_thresh; 26190cff9e2SWingman Kwok }; 26290cff9e2SWingman Kwok 26390cff9e2SWingman Kwok struct xgbe_port_regs { 26490cff9e2SWingman Kwok u32 blk_cnt; 26590cff9e2SWingman Kwok u32 port_vlan; 26690cff9e2SWingman Kwok u32 tx_pri_map; 26790cff9e2SWingman Kwok u32 sa_lo; 26890cff9e2SWingman Kwok u32 sa_hi; 26990cff9e2SWingman Kwok u32 ts_ctl; 27090cff9e2SWingman Kwok u32 ts_seq_ltype; 27190cff9e2SWingman Kwok u32 ts_vlan; 27290cff9e2SWingman Kwok u32 ts_ctl_ltype2; 27390cff9e2SWingman Kwok u32 ts_ctl2; 27490cff9e2SWingman Kwok u32 control; 27590cff9e2SWingman Kwok }; 27690cff9e2SWingman Kwok 27790cff9e2SWingman Kwok struct xgbe_host_port_regs { 27890cff9e2SWingman Kwok u32 blk_cnt; 27990cff9e2SWingman Kwok u32 port_vlan; 28090cff9e2SWingman Kwok u32 tx_pri_map; 28190cff9e2SWingman Kwok u32 src_id; 28290cff9e2SWingman Kwok u32 rx_pri_map; 28390cff9e2SWingman Kwok u32 rx_maxlen; 28490cff9e2SWingman Kwok }; 28590cff9e2SWingman Kwok 28690cff9e2SWingman Kwok struct xgbe_emac_regs { 28790cff9e2SWingman Kwok u32 id_ver; 28890cff9e2SWingman Kwok u32 mac_control; 28990cff9e2SWingman Kwok u32 mac_status; 29090cff9e2SWingman Kwok u32 soft_reset; 29190cff9e2SWingman Kwok u32 rx_maxlen; 29290cff9e2SWingman Kwok u32 __reserved_0; 29390cff9e2SWingman Kwok u32 rx_pause; 29490cff9e2SWingman Kwok u32 tx_pause; 29590cff9e2SWingman Kwok u32 em_control; 29690cff9e2SWingman Kwok u32 __reserved_1; 29790cff9e2SWingman Kwok u32 tx_gap; 29890cff9e2SWingman Kwok u32 rsvd[4]; 29990cff9e2SWingman Kwok }; 30090cff9e2SWingman Kwok 30190cff9e2SWingman Kwok struct xgbe_host_hw_stats { 30290cff9e2SWingman Kwok u32 rx_good_frames; 30390cff9e2SWingman Kwok u32 rx_broadcast_frames; 30490cff9e2SWingman Kwok u32 rx_multicast_frames; 30590cff9e2SWingman Kwok u32 __rsvd_0[3]; 30690cff9e2SWingman Kwok u32 rx_oversized_frames; 30790cff9e2SWingman Kwok u32 __rsvd_1; 30890cff9e2SWingman Kwok u32 rx_undersized_frames; 30990cff9e2SWingman Kwok u32 __rsvd_2; 31090cff9e2SWingman Kwok u32 overrun_type4; 31190cff9e2SWingman Kwok u32 overrun_type5; 31290cff9e2SWingman Kwok u32 rx_bytes; 31390cff9e2SWingman Kwok u32 tx_good_frames; 31490cff9e2SWingman Kwok u32 tx_broadcast_frames; 31590cff9e2SWingman Kwok u32 tx_multicast_frames; 31690cff9e2SWingman Kwok u32 __rsvd_3[9]; 31790cff9e2SWingman Kwok u32 tx_bytes; 31890cff9e2SWingman Kwok u32 tx_64byte_frames; 31990cff9e2SWingman Kwok u32 tx_65_to_127byte_frames; 32090cff9e2SWingman Kwok u32 tx_128_to_255byte_frames; 32190cff9e2SWingman Kwok u32 tx_256_to_511byte_frames; 32290cff9e2SWingman Kwok u32 tx_512_to_1023byte_frames; 32390cff9e2SWingman Kwok u32 tx_1024byte_frames; 32490cff9e2SWingman Kwok u32 net_bytes; 32590cff9e2SWingman Kwok u32 rx_sof_overruns; 32690cff9e2SWingman Kwok u32 rx_mof_overruns; 32790cff9e2SWingman Kwok u32 rx_dma_overruns; 32890cff9e2SWingman Kwok }; 32990cff9e2SWingman Kwok 33090cff9e2SWingman Kwok struct xgbe_hw_stats { 33190cff9e2SWingman Kwok u32 rx_good_frames; 33290cff9e2SWingman Kwok u32 rx_broadcast_frames; 33390cff9e2SWingman Kwok u32 rx_multicast_frames; 33490cff9e2SWingman Kwok u32 rx_pause_frames; 33590cff9e2SWingman Kwok u32 rx_crc_errors; 33690cff9e2SWingman Kwok u32 rx_align_code_errors; 33790cff9e2SWingman Kwok u32 rx_oversized_frames; 33890cff9e2SWingman Kwok u32 rx_jabber_frames; 33990cff9e2SWingman Kwok u32 rx_undersized_frames; 34090cff9e2SWingman Kwok u32 rx_fragments; 34190cff9e2SWingman Kwok u32 overrun_type4; 34290cff9e2SWingman Kwok u32 overrun_type5; 34390cff9e2SWingman Kwok u32 rx_bytes; 34490cff9e2SWingman Kwok u32 tx_good_frames; 34590cff9e2SWingman Kwok u32 tx_broadcast_frames; 34690cff9e2SWingman Kwok u32 tx_multicast_frames; 34790cff9e2SWingman Kwok u32 tx_pause_frames; 34890cff9e2SWingman Kwok u32 tx_deferred_frames; 34990cff9e2SWingman Kwok u32 tx_collision_frames; 35090cff9e2SWingman Kwok u32 tx_single_coll_frames; 35190cff9e2SWingman Kwok u32 tx_mult_coll_frames; 35290cff9e2SWingman Kwok u32 tx_excessive_collisions; 35390cff9e2SWingman Kwok u32 tx_late_collisions; 35490cff9e2SWingman Kwok u32 tx_underrun; 35590cff9e2SWingman Kwok u32 tx_carrier_sense_errors; 35690cff9e2SWingman Kwok u32 tx_bytes; 35790cff9e2SWingman Kwok u32 tx_64byte_frames; 35890cff9e2SWingman Kwok u32 tx_65_to_127byte_frames; 35990cff9e2SWingman Kwok u32 tx_128_to_255byte_frames; 36090cff9e2SWingman Kwok u32 tx_256_to_511byte_frames; 36190cff9e2SWingman Kwok u32 tx_512_to_1023byte_frames; 36290cff9e2SWingman Kwok u32 tx_1024byte_frames; 36390cff9e2SWingman Kwok u32 net_bytes; 36490cff9e2SWingman Kwok u32 rx_sof_overruns; 36590cff9e2SWingman Kwok u32 rx_mof_overruns; 36690cff9e2SWingman Kwok u32 rx_dma_overruns; 36790cff9e2SWingman Kwok }; 36890cff9e2SWingman Kwok 3699a391c7bSWingMan Kwok struct gbenu_ss_regs { 3709a391c7bSWingMan Kwok u32 id_ver; 3719a391c7bSWingMan Kwok u32 synce_count; /* NU */ 3729a391c7bSWingMan Kwok u32 synce_mux; /* NU */ 3739a391c7bSWingMan Kwok u32 control; /* 2U */ 3749a391c7bSWingMan Kwok u32 __rsvd_0[2]; /* 2U */ 3759a391c7bSWingMan Kwok u32 rgmii_status; /* 2U */ 3769a391c7bSWingMan Kwok u32 ss_status; /* 2U */ 3779a391c7bSWingMan Kwok }; 3789a391c7bSWingMan Kwok 3799a391c7bSWingMan Kwok struct gbenu_switch_regs { 3809a391c7bSWingMan Kwok u32 id_ver; 3819a391c7bSWingMan Kwok u32 control; 3829a391c7bSWingMan Kwok u32 __rsvd_0[2]; 3839a391c7bSWingMan Kwok u32 emcontrol; 3849a391c7bSWingMan Kwok u32 stat_port_en; 3859a391c7bSWingMan Kwok u32 ptype; /* NU */ 3869a391c7bSWingMan Kwok u32 soft_idle; 3879a391c7bSWingMan Kwok u32 thru_rate; /* NU */ 3889a391c7bSWingMan Kwok u32 gap_thresh; /* NU */ 3899a391c7bSWingMan Kwok u32 tx_start_wds; /* NU */ 3909a391c7bSWingMan Kwok u32 eee_prescale; /* 2U */ 3919a391c7bSWingMan Kwok u32 tx_g_oflow_thresh_set; /* NU */ 3929a391c7bSWingMan Kwok u32 tx_g_oflow_thresh_clr; /* NU */ 3939a391c7bSWingMan Kwok u32 tx_g_buf_thresh_set_l; /* NU */ 3949a391c7bSWingMan Kwok u32 tx_g_buf_thresh_set_h; /* NU */ 3959a391c7bSWingMan Kwok u32 tx_g_buf_thresh_clr_l; /* NU */ 3969a391c7bSWingMan Kwok u32 tx_g_buf_thresh_clr_h; /* NU */ 3979a391c7bSWingMan Kwok }; 3989a391c7bSWingMan Kwok 3999a391c7bSWingMan Kwok struct gbenu_port_regs { 4009a391c7bSWingMan Kwok u32 __rsvd_0; 4019a391c7bSWingMan Kwok u32 control; 4029a391c7bSWingMan Kwok u32 max_blks; /* 2U */ 4039a391c7bSWingMan Kwok u32 mem_align1; 4049a391c7bSWingMan Kwok u32 blk_cnt; 4059a391c7bSWingMan Kwok u32 port_vlan; 4069a391c7bSWingMan Kwok u32 tx_pri_map; /* NU */ 4079a391c7bSWingMan Kwok u32 pri_ctl; /* 2U */ 4089a391c7bSWingMan Kwok u32 rx_pri_map; 4099a391c7bSWingMan Kwok u32 rx_maxlen; 4109a391c7bSWingMan Kwok u32 tx_blks_pri; /* NU */ 4119a391c7bSWingMan Kwok u32 __rsvd_1; 4129a391c7bSWingMan Kwok u32 idle2lpi; /* 2U */ 4139a391c7bSWingMan Kwok u32 lpi2idle; /* 2U */ 4149a391c7bSWingMan Kwok u32 eee_status; /* 2U */ 4159a391c7bSWingMan Kwok u32 __rsvd_2; 4169a391c7bSWingMan Kwok u32 __rsvd_3[176]; /* NU: more to add */ 4179a391c7bSWingMan Kwok u32 __rsvd_4[2]; 4189a391c7bSWingMan Kwok u32 sa_lo; 4199a391c7bSWingMan Kwok u32 sa_hi; 4209a391c7bSWingMan Kwok u32 ts_ctl; 4219a391c7bSWingMan Kwok u32 ts_seq_ltype; 4229a391c7bSWingMan Kwok u32 ts_vlan; 4239a391c7bSWingMan Kwok u32 ts_ctl_ltype2; 4249a391c7bSWingMan Kwok u32 ts_ctl2; 4259a391c7bSWingMan Kwok }; 4269a391c7bSWingMan Kwok 4279a391c7bSWingMan Kwok struct gbenu_host_port_regs { 4289a391c7bSWingMan Kwok u32 __rsvd_0; 4299a391c7bSWingMan Kwok u32 control; 4309a391c7bSWingMan Kwok u32 flow_id_offset; /* 2U */ 4319a391c7bSWingMan Kwok u32 __rsvd_1; 4329a391c7bSWingMan Kwok u32 blk_cnt; 4339a391c7bSWingMan Kwok u32 port_vlan; 4349a391c7bSWingMan Kwok u32 tx_pri_map; /* NU */ 4359a391c7bSWingMan Kwok u32 pri_ctl; 4369a391c7bSWingMan Kwok u32 rx_pri_map; 4379a391c7bSWingMan Kwok u32 rx_maxlen; 4389a391c7bSWingMan Kwok u32 tx_blks_pri; /* NU */ 4399a391c7bSWingMan Kwok u32 __rsvd_2; 4409a391c7bSWingMan Kwok u32 idle2lpi; /* 2U */ 4419a391c7bSWingMan Kwok u32 lpi2wake; /* 2U */ 4429a391c7bSWingMan Kwok u32 eee_status; /* 2U */ 4439a391c7bSWingMan Kwok u32 __rsvd_3; 4449a391c7bSWingMan Kwok u32 __rsvd_4[184]; /* NU */ 4459a391c7bSWingMan Kwok u32 host_blks_pri; /* NU */ 4469a391c7bSWingMan Kwok }; 4479a391c7bSWingMan Kwok 4489a391c7bSWingMan Kwok struct gbenu_emac_regs { 4499a391c7bSWingMan Kwok u32 mac_control; 4509a391c7bSWingMan Kwok u32 mac_status; 4519a391c7bSWingMan Kwok u32 soft_reset; 4529a391c7bSWingMan Kwok u32 boff_test; 4539a391c7bSWingMan Kwok u32 rx_pause; 4549a391c7bSWingMan Kwok u32 __rsvd_0[11]; /* NU */ 4559a391c7bSWingMan Kwok u32 tx_pause; 4569a391c7bSWingMan Kwok u32 __rsvd_1[11]; /* NU */ 4579a391c7bSWingMan Kwok u32 em_control; 4589a391c7bSWingMan Kwok u32 tx_gap; 4599a391c7bSWingMan Kwok }; 4609a391c7bSWingMan Kwok 4619a391c7bSWingMan Kwok /* Some hw stat regs are applicable to slave port only. 4629a391c7bSWingMan Kwok * This is handled by gbenu_et_stats struct. Also some 4639a391c7bSWingMan Kwok * are for SS version NU and some are for 2U. 4649a391c7bSWingMan Kwok */ 4659a391c7bSWingMan Kwok struct gbenu_hw_stats { 4669a391c7bSWingMan Kwok u32 rx_good_frames; 4679a391c7bSWingMan Kwok u32 rx_broadcast_frames; 4689a391c7bSWingMan Kwok u32 rx_multicast_frames; 4699a391c7bSWingMan Kwok u32 rx_pause_frames; /* slave */ 4709a391c7bSWingMan Kwok u32 rx_crc_errors; 4719a391c7bSWingMan Kwok u32 rx_align_code_errors; /* slave */ 4729a391c7bSWingMan Kwok u32 rx_oversized_frames; 4739a391c7bSWingMan Kwok u32 rx_jabber_frames; /* slave */ 4749a391c7bSWingMan Kwok u32 rx_undersized_frames; 4759a391c7bSWingMan Kwok u32 rx_fragments; /* slave */ 4769a391c7bSWingMan Kwok u32 ale_drop; 4779a391c7bSWingMan Kwok u32 ale_overrun_drop; 4789a391c7bSWingMan Kwok u32 rx_bytes; 4799a391c7bSWingMan Kwok u32 tx_good_frames; 4809a391c7bSWingMan Kwok u32 tx_broadcast_frames; 4819a391c7bSWingMan Kwok u32 tx_multicast_frames; 4829a391c7bSWingMan Kwok u32 tx_pause_frames; /* slave */ 4839a391c7bSWingMan Kwok u32 tx_deferred_frames; /* slave */ 4849a391c7bSWingMan Kwok u32 tx_collision_frames; /* slave */ 4859a391c7bSWingMan Kwok u32 tx_single_coll_frames; /* slave */ 4869a391c7bSWingMan Kwok u32 tx_mult_coll_frames; /* slave */ 4879a391c7bSWingMan Kwok u32 tx_excessive_collisions; /* slave */ 4889a391c7bSWingMan Kwok u32 tx_late_collisions; /* slave */ 4899a391c7bSWingMan Kwok u32 rx_ipg_error; /* slave 10G only */ 4909a391c7bSWingMan Kwok u32 tx_carrier_sense_errors; /* slave */ 4919a391c7bSWingMan Kwok u32 tx_bytes; 4929a391c7bSWingMan Kwok u32 tx_64B_frames; 4939a391c7bSWingMan Kwok u32 tx_65_to_127B_frames; 4949a391c7bSWingMan Kwok u32 tx_128_to_255B_frames; 4959a391c7bSWingMan Kwok u32 tx_256_to_511B_frames; 4969a391c7bSWingMan Kwok u32 tx_512_to_1023B_frames; 4979a391c7bSWingMan Kwok u32 tx_1024B_frames; 4989a391c7bSWingMan Kwok u32 net_bytes; 4999a391c7bSWingMan Kwok u32 rx_bottom_fifo_drop; 5009a391c7bSWingMan Kwok u32 rx_port_mask_drop; 5019a391c7bSWingMan Kwok u32 rx_top_fifo_drop; 5029a391c7bSWingMan Kwok u32 ale_rate_limit_drop; 5039a391c7bSWingMan Kwok u32 ale_vid_ingress_drop; 5049a391c7bSWingMan Kwok u32 ale_da_eq_sa_drop; 5059a391c7bSWingMan Kwok u32 __rsvd_0[3]; 5069a391c7bSWingMan Kwok u32 ale_unknown_ucast; 5079a391c7bSWingMan Kwok u32 ale_unknown_ucast_bytes; 5089a391c7bSWingMan Kwok u32 ale_unknown_mcast; 5099a391c7bSWingMan Kwok u32 ale_unknown_mcast_bytes; 5109a391c7bSWingMan Kwok u32 ale_unknown_bcast; 5119a391c7bSWingMan Kwok u32 ale_unknown_bcast_bytes; 5129a391c7bSWingMan Kwok u32 ale_pol_match; 5139a391c7bSWingMan Kwok u32 ale_pol_match_red; /* NU */ 5149a391c7bSWingMan Kwok u32 ale_pol_match_yellow; /* NU */ 5159a391c7bSWingMan Kwok u32 __rsvd_1[44]; 5169a391c7bSWingMan Kwok u32 tx_mem_protect_err; 5179a391c7bSWingMan Kwok /* following NU only */ 5189a391c7bSWingMan Kwok u32 tx_pri0; 5199a391c7bSWingMan Kwok u32 tx_pri1; 5209a391c7bSWingMan Kwok u32 tx_pri2; 5219a391c7bSWingMan Kwok u32 tx_pri3; 5229a391c7bSWingMan Kwok u32 tx_pri4; 5239a391c7bSWingMan Kwok u32 tx_pri5; 5249a391c7bSWingMan Kwok u32 tx_pri6; 5259a391c7bSWingMan Kwok u32 tx_pri7; 5269a391c7bSWingMan Kwok u32 tx_pri0_bcnt; 5279a391c7bSWingMan Kwok u32 tx_pri1_bcnt; 5289a391c7bSWingMan Kwok u32 tx_pri2_bcnt; 5299a391c7bSWingMan Kwok u32 tx_pri3_bcnt; 5309a391c7bSWingMan Kwok u32 tx_pri4_bcnt; 5319a391c7bSWingMan Kwok u32 tx_pri5_bcnt; 5329a391c7bSWingMan Kwok u32 tx_pri6_bcnt; 5339a391c7bSWingMan Kwok u32 tx_pri7_bcnt; 5349a391c7bSWingMan Kwok u32 tx_pri0_drop; 5359a391c7bSWingMan Kwok u32 tx_pri1_drop; 5369a391c7bSWingMan Kwok u32 tx_pri2_drop; 5379a391c7bSWingMan Kwok u32 tx_pri3_drop; 5389a391c7bSWingMan Kwok u32 tx_pri4_drop; 5399a391c7bSWingMan Kwok u32 tx_pri5_drop; 5409a391c7bSWingMan Kwok u32 tx_pri6_drop; 5419a391c7bSWingMan Kwok u32 tx_pri7_drop; 5429a391c7bSWingMan Kwok u32 tx_pri0_drop_bcnt; 5439a391c7bSWingMan Kwok u32 tx_pri1_drop_bcnt; 5449a391c7bSWingMan Kwok u32 tx_pri2_drop_bcnt; 5459a391c7bSWingMan Kwok u32 tx_pri3_drop_bcnt; 5469a391c7bSWingMan Kwok u32 tx_pri4_drop_bcnt; 5479a391c7bSWingMan Kwok u32 tx_pri5_drop_bcnt; 5489a391c7bSWingMan Kwok u32 tx_pri6_drop_bcnt; 5499a391c7bSWingMan Kwok u32 tx_pri7_drop_bcnt; 5509a391c7bSWingMan Kwok }; 5519a391c7bSWingMan Kwok 5529a391c7bSWingMan Kwok #define GBENU_HW_STATS_REG_MAP_SZ 0x200 5539a391c7bSWingMan Kwok 5546f8d3f33SWingman Kwok struct gbe_ss_regs { 5556f8d3f33SWingman Kwok u32 id_ver; 5566f8d3f33SWingman Kwok u32 synce_count; 5576f8d3f33SWingman Kwok u32 synce_mux; 5586f8d3f33SWingman Kwok }; 5596f8d3f33SWingman Kwok 5606f8d3f33SWingman Kwok struct gbe_ss_regs_ofs { 5616f8d3f33SWingman Kwok u16 id_ver; 5626f8d3f33SWingman Kwok u16 control; 5637771f2b4SMurali Karicheri u16 rgmii_status; /* 2U */ 5646f8d3f33SWingman Kwok }; 5656f8d3f33SWingman Kwok 5666f8d3f33SWingman Kwok struct gbe_switch_regs { 5676f8d3f33SWingman Kwok u32 id_ver; 5686f8d3f33SWingman Kwok u32 control; 5696f8d3f33SWingman Kwok u32 soft_reset; 5706f8d3f33SWingman Kwok u32 stat_port_en; 5716f8d3f33SWingman Kwok u32 ptype; 5726f8d3f33SWingman Kwok u32 soft_idle; 5736f8d3f33SWingman Kwok u32 thru_rate; 5746f8d3f33SWingman Kwok u32 gap_thresh; 5756f8d3f33SWingman Kwok u32 tx_start_wds; 5766f8d3f33SWingman Kwok u32 flow_control; 5776f8d3f33SWingman Kwok }; 5786f8d3f33SWingman Kwok 5796f8d3f33SWingman Kwok struct gbe_switch_regs_ofs { 5806f8d3f33SWingman Kwok u16 id_ver; 5816f8d3f33SWingman Kwok u16 control; 5826f8d3f33SWingman Kwok u16 soft_reset; 5836f8d3f33SWingman Kwok u16 emcontrol; 5846f8d3f33SWingman Kwok u16 stat_port_en; 5856f8d3f33SWingman Kwok u16 ptype; 5866f8d3f33SWingman Kwok u16 flow_control; 5876f8d3f33SWingman Kwok }; 5886f8d3f33SWingman Kwok 5896f8d3f33SWingman Kwok struct gbe_port_regs { 5906f8d3f33SWingman Kwok u32 max_blks; 5916f8d3f33SWingman Kwok u32 blk_cnt; 5926f8d3f33SWingman Kwok u32 port_vlan; 5936f8d3f33SWingman Kwok u32 tx_pri_map; 5946f8d3f33SWingman Kwok u32 sa_lo; 5956f8d3f33SWingman Kwok u32 sa_hi; 5966f8d3f33SWingman Kwok u32 ts_ctl; 5976f8d3f33SWingman Kwok u32 ts_seq_ltype; 5986f8d3f33SWingman Kwok u32 ts_vlan; 5996f8d3f33SWingman Kwok u32 ts_ctl_ltype2; 6006f8d3f33SWingman Kwok u32 ts_ctl2; 6016f8d3f33SWingman Kwok }; 6026f8d3f33SWingman Kwok 6036f8d3f33SWingman Kwok struct gbe_port_regs_ofs { 6046f8d3f33SWingman Kwok u16 port_vlan; 6056f8d3f33SWingman Kwok u16 tx_pri_map; 60665c45064SMurali Karicheri u16 rx_pri_map; 6076f8d3f33SWingman Kwok u16 sa_lo; 6086f8d3f33SWingman Kwok u16 sa_hi; 6096f8d3f33SWingman Kwok u16 ts_ctl; 6106f8d3f33SWingman Kwok u16 ts_seq_ltype; 6116f8d3f33SWingman Kwok u16 ts_vlan; 6126f8d3f33SWingman Kwok u16 ts_ctl_ltype2; 6136f8d3f33SWingman Kwok u16 ts_ctl2; 6149a391c7bSWingMan Kwok u16 rx_maxlen; /* 2U, NU */ 6156f8d3f33SWingman Kwok }; 6166f8d3f33SWingman Kwok 6176f8d3f33SWingman Kwok struct gbe_host_port_regs { 6186f8d3f33SWingman Kwok u32 src_id; 6196f8d3f33SWingman Kwok u32 port_vlan; 6206f8d3f33SWingman Kwok u32 rx_pri_map; 6216f8d3f33SWingman Kwok u32 rx_maxlen; 6226f8d3f33SWingman Kwok }; 6236f8d3f33SWingman Kwok 6246f8d3f33SWingman Kwok struct gbe_host_port_regs_ofs { 6256f8d3f33SWingman Kwok u16 port_vlan; 6266f8d3f33SWingman Kwok u16 tx_pri_map; 6276f8d3f33SWingman Kwok u16 rx_maxlen; 6286f8d3f33SWingman Kwok }; 6296f8d3f33SWingman Kwok 6306f8d3f33SWingman Kwok struct gbe_emac_regs { 6316f8d3f33SWingman Kwok u32 id_ver; 6326f8d3f33SWingman Kwok u32 mac_control; 6336f8d3f33SWingman Kwok u32 mac_status; 6346f8d3f33SWingman Kwok u32 soft_reset; 6356f8d3f33SWingman Kwok u32 rx_maxlen; 6366f8d3f33SWingman Kwok u32 __reserved_0; 6376f8d3f33SWingman Kwok u32 rx_pause; 6386f8d3f33SWingman Kwok u32 tx_pause; 6396f8d3f33SWingman Kwok u32 __reserved_1; 6406f8d3f33SWingman Kwok u32 rx_pri_map; 6416f8d3f33SWingman Kwok u32 rsvd[6]; 6426f8d3f33SWingman Kwok }; 6436f8d3f33SWingman Kwok 6446f8d3f33SWingman Kwok struct gbe_emac_regs_ofs { 6456f8d3f33SWingman Kwok u16 mac_control; 6466f8d3f33SWingman Kwok u16 soft_reset; 6476f8d3f33SWingman Kwok u16 rx_maxlen; 6486f8d3f33SWingman Kwok }; 6496f8d3f33SWingman Kwok 6506f8d3f33SWingman Kwok struct gbe_hw_stats { 6516f8d3f33SWingman Kwok u32 rx_good_frames; 6526f8d3f33SWingman Kwok u32 rx_broadcast_frames; 6536f8d3f33SWingman Kwok u32 rx_multicast_frames; 6546f8d3f33SWingman Kwok u32 rx_pause_frames; 6556f8d3f33SWingman Kwok u32 rx_crc_errors; 6566f8d3f33SWingman Kwok u32 rx_align_code_errors; 6576f8d3f33SWingman Kwok u32 rx_oversized_frames; 6586f8d3f33SWingman Kwok u32 rx_jabber_frames; 6596f8d3f33SWingman Kwok u32 rx_undersized_frames; 6606f8d3f33SWingman Kwok u32 rx_fragments; 6616f8d3f33SWingman Kwok u32 __pad_0[2]; 6626f8d3f33SWingman Kwok u32 rx_bytes; 6636f8d3f33SWingman Kwok u32 tx_good_frames; 6646f8d3f33SWingman Kwok u32 tx_broadcast_frames; 6656f8d3f33SWingman Kwok u32 tx_multicast_frames; 6666f8d3f33SWingman Kwok u32 tx_pause_frames; 6676f8d3f33SWingman Kwok u32 tx_deferred_frames; 6686f8d3f33SWingman Kwok u32 tx_collision_frames; 6696f8d3f33SWingman Kwok u32 tx_single_coll_frames; 6706f8d3f33SWingman Kwok u32 tx_mult_coll_frames; 6716f8d3f33SWingman Kwok u32 tx_excessive_collisions; 6726f8d3f33SWingman Kwok u32 tx_late_collisions; 6736f8d3f33SWingman Kwok u32 tx_underrun; 6746f8d3f33SWingman Kwok u32 tx_carrier_sense_errors; 6756f8d3f33SWingman Kwok u32 tx_bytes; 6766f8d3f33SWingman Kwok u32 tx_64byte_frames; 6776f8d3f33SWingman Kwok u32 tx_65_to_127byte_frames; 6786f8d3f33SWingman Kwok u32 tx_128_to_255byte_frames; 6796f8d3f33SWingman Kwok u32 tx_256_to_511byte_frames; 6806f8d3f33SWingman Kwok u32 tx_512_to_1023byte_frames; 6816f8d3f33SWingman Kwok u32 tx_1024byte_frames; 6826f8d3f33SWingman Kwok u32 net_bytes; 6836f8d3f33SWingman Kwok u32 rx_sof_overruns; 6846f8d3f33SWingman Kwok u32 rx_mof_overruns; 6856f8d3f33SWingman Kwok u32 rx_dma_overruns; 6866f8d3f33SWingman Kwok }; 6876f8d3f33SWingman Kwok 6889a391c7bSWingMan Kwok #define GBE_MAX_HW_STAT_MODS 9 6896f8d3f33SWingman Kwok #define GBE_HW_STATS_REG_MAP_SZ 0x100 6906f8d3f33SWingman Kwok 6916246168bSWingMan Kwok struct ts_ctl { 6926246168bSWingMan Kwok int uni; 6936246168bSWingMan Kwok u8 dst_port_map; 6946246168bSWingMan Kwok u8 maddr_map; 6956246168bSWingMan Kwok u8 ts_mcast_type; 6966246168bSWingMan Kwok }; 6976246168bSWingMan Kwok 6986f8d3f33SWingman Kwok struct gbe_slave { 6996f8d3f33SWingman Kwok void __iomem *port_regs; 7006f8d3f33SWingman Kwok void __iomem *emac_regs; 7016f8d3f33SWingman Kwok struct gbe_port_regs_ofs port_regs_ofs; 7026f8d3f33SWingman Kwok struct gbe_emac_regs_ofs emac_regs_ofs; 7036f8d3f33SWingman Kwok int slave_num; /* 0 based logical number */ 7046f8d3f33SWingman Kwok int port_num; /* actual port number */ 7056f8d3f33SWingman Kwok atomic_t link_state; 7066f8d3f33SWingman Kwok bool open; 7076f8d3f33SWingman Kwok struct phy_device *phy; 7086f8d3f33SWingman Kwok u32 link_interface; 7096f8d3f33SWingman Kwok u32 mac_control; 7106f8d3f33SWingman Kwok u8 phy_port_t; 7117b647b93SMurali Karicheri struct device_node *node; 7126f8d3f33SWingman Kwok struct device_node *phy_node; 7136246168bSWingMan Kwok struct ts_ctl ts_ctl; 7146f8d3f33SWingman Kwok struct list_head slave_list; 7156f8d3f33SWingman Kwok }; 7166f8d3f33SWingman Kwok 7176f8d3f33SWingman Kwok struct gbe_priv { 7186f8d3f33SWingman Kwok struct device *dev; 7196f8d3f33SWingman Kwok struct netcp_device *netcp_device; 7206f8d3f33SWingman Kwok struct timer_list timer; 7216f8d3f33SWingman Kwok u32 num_slaves; 7226f8d3f33SWingman Kwok u32 ale_entries; 7236f8d3f33SWingman Kwok u32 ale_ports; 7246f8d3f33SWingman Kwok bool enable_ale; 7259a391c7bSWingMan Kwok u8 max_num_slaves; 7269a391c7bSWingMan Kwok u8 max_num_ports; /* max_num_slaves + 1 */ 727489e8a2fSWingMan Kwok u8 num_stats_mods; 7286f8d3f33SWingman Kwok struct netcp_tx_pipe tx_pipe; 7296f8d3f33SWingman Kwok 7306f8d3f33SWingman Kwok int host_port; 7316f8d3f33SWingman Kwok u32 rx_packet_max; 7326f8d3f33SWingman Kwok u32 ss_version; 7339a391c7bSWingMan Kwok u32 stats_en_mask; 7346f8d3f33SWingman Kwok 7356f8d3f33SWingman Kwok void __iomem *ss_regs; 7366f8d3f33SWingman Kwok void __iomem *switch_regs; 7376f8d3f33SWingman Kwok void __iomem *host_port_regs; 7386f8d3f33SWingman Kwok void __iomem *ale_reg; 7396246168bSWingMan Kwok void __iomem *cpts_reg; 7406f8d3f33SWingman Kwok void __iomem *sgmii_port_regs; 7416f8d3f33SWingman Kwok void __iomem *sgmii_port34_regs; 7426f8d3f33SWingman Kwok void __iomem *xgbe_serdes_regs; 7436f8d3f33SWingman Kwok void __iomem *hw_stats_regs[GBE_MAX_HW_STAT_MODS]; 7446f8d3f33SWingman Kwok 7456f8d3f33SWingman Kwok struct gbe_ss_regs_ofs ss_regs_ofs; 7466f8d3f33SWingman Kwok struct gbe_switch_regs_ofs switch_regs_ofs; 7476f8d3f33SWingman Kwok struct gbe_host_port_regs_ofs host_port_regs_ofs; 7486f8d3f33SWingman Kwok 7496f8d3f33SWingman Kwok struct cpsw_ale *ale; 7506f8d3f33SWingman Kwok unsigned int tx_queue_id; 7516f8d3f33SWingman Kwok const char *dma_chan_name; 7526f8d3f33SWingman Kwok 7536f8d3f33SWingman Kwok struct list_head gbe_intf_head; 7546f8d3f33SWingman Kwok struct list_head secondary_slaves; 7556f8d3f33SWingman Kwok struct net_device *dummy_ndev; 7566f8d3f33SWingman Kwok 7576f8d3f33SWingman Kwok u64 *hw_stats; 758489e8a2fSWingMan Kwok u32 *hw_stats_prev; 7596f8d3f33SWingman Kwok const struct netcp_ethtool_stat *et_stats; 7606f8d3f33SWingman Kwok int num_et_stats; 7616f8d3f33SWingman Kwok /* Lock for updating the hwstats */ 7626f8d3f33SWingman Kwok spinlock_t hw_stats_lock; 7636246168bSWingMan Kwok 7646246168bSWingMan Kwok int cpts_registered; 7656246168bSWingMan Kwok struct cpts *cpts; 766a9423120SIvan Khoronzhuk int rx_ts_enabled; 767a9423120SIvan Khoronzhuk int tx_ts_enabled; 7686f8d3f33SWingman Kwok }; 7696f8d3f33SWingman Kwok 7706f8d3f33SWingman Kwok struct gbe_intf { 7716f8d3f33SWingman Kwok struct net_device *ndev; 7726f8d3f33SWingman Kwok struct device *dev; 7736f8d3f33SWingman Kwok struct gbe_priv *gbe_dev; 7746f8d3f33SWingman Kwok struct netcp_tx_pipe tx_pipe; 7756f8d3f33SWingman Kwok struct gbe_slave *slave; 7766f8d3f33SWingman Kwok struct list_head gbe_intf_list; 7776f8d3f33SWingman Kwok unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; 7786f8d3f33SWingman Kwok }; 7796f8d3f33SWingman Kwok 7806f8d3f33SWingman Kwok static struct netcp_module gbe_module; 78190cff9e2SWingman Kwok static struct netcp_module xgbe_module; 7826f8d3f33SWingman Kwok 7836f8d3f33SWingman Kwok /* Statistic management */ 7846f8d3f33SWingman Kwok struct netcp_ethtool_stat { 7856f8d3f33SWingman Kwok char desc[ETH_GSTRING_LEN]; 7866f8d3f33SWingman Kwok int type; 7876f8d3f33SWingman Kwok u32 size; 7886f8d3f33SWingman Kwok int offset; 7896f8d3f33SWingman Kwok }; 7906f8d3f33SWingman Kwok 791da866ba0SKaricheri, Muralidharan #define GBE_STATSA_INFO(field) \ 792da866ba0SKaricheri, Muralidharan { \ 793da866ba0SKaricheri, Muralidharan "GBE_A:"#field, GBE_STATSA_MODULE, \ 7946f8d3f33SWingman Kwok FIELD_SIZEOF(struct gbe_hw_stats, field), \ 795da866ba0SKaricheri, Muralidharan offsetof(struct gbe_hw_stats, field) \ 796da866ba0SKaricheri, Muralidharan } 7976f8d3f33SWingman Kwok 798da866ba0SKaricheri, Muralidharan #define GBE_STATSB_INFO(field) \ 799da866ba0SKaricheri, Muralidharan { \ 800da866ba0SKaricheri, Muralidharan "GBE_B:"#field, GBE_STATSB_MODULE, \ 8016f8d3f33SWingman Kwok FIELD_SIZEOF(struct gbe_hw_stats, field), \ 802da866ba0SKaricheri, Muralidharan offsetof(struct gbe_hw_stats, field) \ 803da866ba0SKaricheri, Muralidharan } 8046f8d3f33SWingman Kwok 805da866ba0SKaricheri, Muralidharan #define GBE_STATSC_INFO(field) \ 806da866ba0SKaricheri, Muralidharan { \ 807da866ba0SKaricheri, Muralidharan "GBE_C:"#field, GBE_STATSC_MODULE, \ 8086f8d3f33SWingman Kwok FIELD_SIZEOF(struct gbe_hw_stats, field), \ 809da866ba0SKaricheri, Muralidharan offsetof(struct gbe_hw_stats, field) \ 810da866ba0SKaricheri, Muralidharan } 8116f8d3f33SWingman Kwok 812da866ba0SKaricheri, Muralidharan #define GBE_STATSD_INFO(field) \ 813da866ba0SKaricheri, Muralidharan { \ 814da866ba0SKaricheri, Muralidharan "GBE_D:"#field, GBE_STATSD_MODULE, \ 8156f8d3f33SWingman Kwok FIELD_SIZEOF(struct gbe_hw_stats, field), \ 816da866ba0SKaricheri, Muralidharan offsetof(struct gbe_hw_stats, field) \ 817da866ba0SKaricheri, Muralidharan } 8186f8d3f33SWingman Kwok 8196f8d3f33SWingman Kwok static const struct netcp_ethtool_stat gbe13_et_stats[] = { 8206f8d3f33SWingman Kwok /* GBE module A */ 821da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_good_frames), 822da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_broadcast_frames), 823da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_multicast_frames), 824da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_pause_frames), 825da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_crc_errors), 826da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_align_code_errors), 827da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_oversized_frames), 828da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_jabber_frames), 829da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_undersized_frames), 830da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_fragments), 831da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_bytes), 832da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_good_frames), 833da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_broadcast_frames), 834da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_multicast_frames), 835da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_pause_frames), 836da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_deferred_frames), 837da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_collision_frames), 838da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_single_coll_frames), 839da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_mult_coll_frames), 840da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_excessive_collisions), 841da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_late_collisions), 842da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_underrun), 843da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_carrier_sense_errors), 844da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_bytes), 845da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_64byte_frames), 846da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_65_to_127byte_frames), 847da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_128_to_255byte_frames), 848da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_256_to_511byte_frames), 849da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_512_to_1023byte_frames), 850da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_1024byte_frames), 851da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(net_bytes), 852da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_sof_overruns), 853da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_mof_overruns), 854da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_dma_overruns), 8556f8d3f33SWingman Kwok /* GBE module B */ 856da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_good_frames), 857da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_broadcast_frames), 858da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_multicast_frames), 859da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_pause_frames), 860da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_crc_errors), 861da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_align_code_errors), 862da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_oversized_frames), 863da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_jabber_frames), 864da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_undersized_frames), 865da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_fragments), 866da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_bytes), 867da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_good_frames), 868da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_broadcast_frames), 869da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_multicast_frames), 870da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_pause_frames), 871da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_deferred_frames), 872da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_collision_frames), 873da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_single_coll_frames), 874da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_mult_coll_frames), 875da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_excessive_collisions), 876da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_late_collisions), 877da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_underrun), 878da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_carrier_sense_errors), 879da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_bytes), 880da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_64byte_frames), 881da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_65_to_127byte_frames), 882da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_128_to_255byte_frames), 883da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_256_to_511byte_frames), 884da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_512_to_1023byte_frames), 885da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_1024byte_frames), 886da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(net_bytes), 887da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_sof_overruns), 888da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_mof_overruns), 889da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_dma_overruns), 8906f8d3f33SWingman Kwok /* GBE module C */ 891da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_good_frames), 892da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_broadcast_frames), 893da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_multicast_frames), 894da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_pause_frames), 895da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_crc_errors), 896da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_align_code_errors), 897da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_oversized_frames), 898da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_jabber_frames), 899da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_undersized_frames), 900da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_fragments), 901da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_bytes), 902da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_good_frames), 903da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_broadcast_frames), 904da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_multicast_frames), 905da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_pause_frames), 906da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_deferred_frames), 907da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_collision_frames), 908da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_single_coll_frames), 909da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_mult_coll_frames), 910da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_excessive_collisions), 911da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_late_collisions), 912da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_underrun), 913da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_carrier_sense_errors), 914da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_bytes), 915da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_64byte_frames), 916da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_65_to_127byte_frames), 917da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_128_to_255byte_frames), 918da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_256_to_511byte_frames), 919da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_512_to_1023byte_frames), 920da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_1024byte_frames), 921da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(net_bytes), 922da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_sof_overruns), 923da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_mof_overruns), 924da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_dma_overruns), 9256f8d3f33SWingman Kwok /* GBE module D */ 926da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_good_frames), 927da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_broadcast_frames), 928da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_multicast_frames), 929da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_pause_frames), 930da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_crc_errors), 931da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_align_code_errors), 932da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_oversized_frames), 933da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_jabber_frames), 934da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_undersized_frames), 935da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_fragments), 936da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_bytes), 937da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_good_frames), 938da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_broadcast_frames), 939da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_multicast_frames), 940da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_pause_frames), 941da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_deferred_frames), 942da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_collision_frames), 943da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_single_coll_frames), 944da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_mult_coll_frames), 945da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_excessive_collisions), 946da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_late_collisions), 947da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_underrun), 948da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_carrier_sense_errors), 949da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_bytes), 950da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_64byte_frames), 951da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_65_to_127byte_frames), 952da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_128_to_255byte_frames), 953da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_256_to_511byte_frames), 954da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_512_to_1023byte_frames), 955da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_1024byte_frames), 956da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(net_bytes), 957da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_sof_overruns), 958da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_mof_overruns), 959da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_dma_overruns), 9606f8d3f33SWingman Kwok }; 9616f8d3f33SWingman Kwok 9629a391c7bSWingMan Kwok /* This is the size of entries in GBENU_STATS_HOST */ 9635be4001eSWingMan Kwok #define GBENU_ET_STATS_HOST_SIZE 52 9649a391c7bSWingMan Kwok 9659a391c7bSWingMan Kwok #define GBENU_STATS_HOST(field) \ 9669a391c7bSWingMan Kwok { \ 9679a391c7bSWingMan Kwok "GBE_HOST:"#field, GBENU_STATS0_MODULE, \ 9689a391c7bSWingMan Kwok FIELD_SIZEOF(struct gbenu_hw_stats, field), \ 9699a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \ 9709a391c7bSWingMan Kwok } 9719a391c7bSWingMan Kwok 9725be4001eSWingMan Kwok /* This is the size of entries in GBENU_STATS_PORT */ 9735be4001eSWingMan Kwok #define GBENU_ET_STATS_PORT_SIZE 65 9749a391c7bSWingMan Kwok 9759a391c7bSWingMan Kwok #define GBENU_STATS_P1(field) \ 9769a391c7bSWingMan Kwok { \ 9779a391c7bSWingMan Kwok "GBE_P1:"#field, GBENU_STATS1_MODULE, \ 9789a391c7bSWingMan Kwok FIELD_SIZEOF(struct gbenu_hw_stats, field), \ 9799a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \ 9809a391c7bSWingMan Kwok } 9819a391c7bSWingMan Kwok 9829a391c7bSWingMan Kwok #define GBENU_STATS_P2(field) \ 9839a391c7bSWingMan Kwok { \ 9849a391c7bSWingMan Kwok "GBE_P2:"#field, GBENU_STATS2_MODULE, \ 9859a391c7bSWingMan Kwok FIELD_SIZEOF(struct gbenu_hw_stats, field), \ 9869a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \ 9879a391c7bSWingMan Kwok } 9889a391c7bSWingMan Kwok 9899a391c7bSWingMan Kwok #define GBENU_STATS_P3(field) \ 9909a391c7bSWingMan Kwok { \ 9919a391c7bSWingMan Kwok "GBE_P3:"#field, GBENU_STATS3_MODULE, \ 9929a391c7bSWingMan Kwok FIELD_SIZEOF(struct gbenu_hw_stats, field), \ 9939a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \ 9949a391c7bSWingMan Kwok } 9959a391c7bSWingMan Kwok 9969a391c7bSWingMan Kwok #define GBENU_STATS_P4(field) \ 9979a391c7bSWingMan Kwok { \ 9989a391c7bSWingMan Kwok "GBE_P4:"#field, GBENU_STATS4_MODULE, \ 9999a391c7bSWingMan Kwok FIELD_SIZEOF(struct gbenu_hw_stats, field), \ 10009a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \ 10019a391c7bSWingMan Kwok } 10029a391c7bSWingMan Kwok 10039a391c7bSWingMan Kwok #define GBENU_STATS_P5(field) \ 10049a391c7bSWingMan Kwok { \ 10059a391c7bSWingMan Kwok "GBE_P5:"#field, GBENU_STATS5_MODULE, \ 10069a391c7bSWingMan Kwok FIELD_SIZEOF(struct gbenu_hw_stats, field), \ 10079a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \ 10089a391c7bSWingMan Kwok } 10099a391c7bSWingMan Kwok 10109a391c7bSWingMan Kwok #define GBENU_STATS_P6(field) \ 10119a391c7bSWingMan Kwok { \ 10129a391c7bSWingMan Kwok "GBE_P6:"#field, GBENU_STATS6_MODULE, \ 10139a391c7bSWingMan Kwok FIELD_SIZEOF(struct gbenu_hw_stats, field), \ 10149a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \ 10159a391c7bSWingMan Kwok } 10169a391c7bSWingMan Kwok 10179a391c7bSWingMan Kwok #define GBENU_STATS_P7(field) \ 10189a391c7bSWingMan Kwok { \ 10199a391c7bSWingMan Kwok "GBE_P7:"#field, GBENU_STATS7_MODULE, \ 10209a391c7bSWingMan Kwok FIELD_SIZEOF(struct gbenu_hw_stats, field), \ 10219a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \ 10229a391c7bSWingMan Kwok } 10239a391c7bSWingMan Kwok 10249a391c7bSWingMan Kwok #define GBENU_STATS_P8(field) \ 10259a391c7bSWingMan Kwok { \ 10269a391c7bSWingMan Kwok "GBE_P8:"#field, GBENU_STATS8_MODULE, \ 10279a391c7bSWingMan Kwok FIELD_SIZEOF(struct gbenu_hw_stats, field), \ 10289a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \ 10299a391c7bSWingMan Kwok } 10309a391c7bSWingMan Kwok 10319a391c7bSWingMan Kwok static const struct netcp_ethtool_stat gbenu_et_stats[] = { 10329a391c7bSWingMan Kwok /* GBENU Host Module */ 10339a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_good_frames), 10349a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_broadcast_frames), 10359a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_multicast_frames), 10369a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_crc_errors), 10379a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_oversized_frames), 10389a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_undersized_frames), 10399a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_drop), 10409a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_overrun_drop), 10419a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_bytes), 10429a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_good_frames), 10439a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_broadcast_frames), 10449a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_multicast_frames), 10459a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_bytes), 10469a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_64B_frames), 10479a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_65_to_127B_frames), 10489a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_128_to_255B_frames), 10499a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_256_to_511B_frames), 10509a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_512_to_1023B_frames), 10519a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_1024B_frames), 10529a391c7bSWingMan Kwok GBENU_STATS_HOST(net_bytes), 10539a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_bottom_fifo_drop), 10549a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_port_mask_drop), 10559a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_top_fifo_drop), 10569a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_rate_limit_drop), 10579a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_vid_ingress_drop), 10589a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_da_eq_sa_drop), 10599a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_unknown_ucast), 10609a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_unknown_ucast_bytes), 10619a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_unknown_mcast), 10629a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_unknown_mcast_bytes), 10639a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_unknown_bcast), 10649a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_unknown_bcast_bytes), 10655be4001eSWingMan Kwok GBENU_STATS_HOST(ale_pol_match), 10665be4001eSWingMan Kwok GBENU_STATS_HOST(ale_pol_match_red), 10675be4001eSWingMan Kwok GBENU_STATS_HOST(ale_pol_match_yellow), 10689a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_mem_protect_err), 10695be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri0_drop), 10705be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri1_drop), 10715be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri2_drop), 10725be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri3_drop), 10735be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri4_drop), 10745be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri5_drop), 10755be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri6_drop), 10765be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri7_drop), 10775be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri0_drop_bcnt), 10785be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri1_drop_bcnt), 10795be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri2_drop_bcnt), 10805be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri3_drop_bcnt), 10815be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri4_drop_bcnt), 10825be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri5_drop_bcnt), 10835be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri6_drop_bcnt), 10845be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri7_drop_bcnt), 10859a391c7bSWingMan Kwok /* GBENU Module 1 */ 10869a391c7bSWingMan Kwok GBENU_STATS_P1(rx_good_frames), 10879a391c7bSWingMan Kwok GBENU_STATS_P1(rx_broadcast_frames), 10889a391c7bSWingMan Kwok GBENU_STATS_P1(rx_multicast_frames), 10899a391c7bSWingMan Kwok GBENU_STATS_P1(rx_pause_frames), 10909a391c7bSWingMan Kwok GBENU_STATS_P1(rx_crc_errors), 10919a391c7bSWingMan Kwok GBENU_STATS_P1(rx_align_code_errors), 10929a391c7bSWingMan Kwok GBENU_STATS_P1(rx_oversized_frames), 10939a391c7bSWingMan Kwok GBENU_STATS_P1(rx_jabber_frames), 10949a391c7bSWingMan Kwok GBENU_STATS_P1(rx_undersized_frames), 10959a391c7bSWingMan Kwok GBENU_STATS_P1(rx_fragments), 10969a391c7bSWingMan Kwok GBENU_STATS_P1(ale_drop), 10979a391c7bSWingMan Kwok GBENU_STATS_P1(ale_overrun_drop), 10989a391c7bSWingMan Kwok GBENU_STATS_P1(rx_bytes), 10999a391c7bSWingMan Kwok GBENU_STATS_P1(tx_good_frames), 11009a391c7bSWingMan Kwok GBENU_STATS_P1(tx_broadcast_frames), 11019a391c7bSWingMan Kwok GBENU_STATS_P1(tx_multicast_frames), 11029a391c7bSWingMan Kwok GBENU_STATS_P1(tx_pause_frames), 11039a391c7bSWingMan Kwok GBENU_STATS_P1(tx_deferred_frames), 11049a391c7bSWingMan Kwok GBENU_STATS_P1(tx_collision_frames), 11059a391c7bSWingMan Kwok GBENU_STATS_P1(tx_single_coll_frames), 11069a391c7bSWingMan Kwok GBENU_STATS_P1(tx_mult_coll_frames), 11079a391c7bSWingMan Kwok GBENU_STATS_P1(tx_excessive_collisions), 11089a391c7bSWingMan Kwok GBENU_STATS_P1(tx_late_collisions), 11099a391c7bSWingMan Kwok GBENU_STATS_P1(rx_ipg_error), 11109a391c7bSWingMan Kwok GBENU_STATS_P1(tx_carrier_sense_errors), 11119a391c7bSWingMan Kwok GBENU_STATS_P1(tx_bytes), 11129a391c7bSWingMan Kwok GBENU_STATS_P1(tx_64B_frames), 11139a391c7bSWingMan Kwok GBENU_STATS_P1(tx_65_to_127B_frames), 11149a391c7bSWingMan Kwok GBENU_STATS_P1(tx_128_to_255B_frames), 11159a391c7bSWingMan Kwok GBENU_STATS_P1(tx_256_to_511B_frames), 11169a391c7bSWingMan Kwok GBENU_STATS_P1(tx_512_to_1023B_frames), 11179a391c7bSWingMan Kwok GBENU_STATS_P1(tx_1024B_frames), 11189a391c7bSWingMan Kwok GBENU_STATS_P1(net_bytes), 11199a391c7bSWingMan Kwok GBENU_STATS_P1(rx_bottom_fifo_drop), 11209a391c7bSWingMan Kwok GBENU_STATS_P1(rx_port_mask_drop), 11219a391c7bSWingMan Kwok GBENU_STATS_P1(rx_top_fifo_drop), 11229a391c7bSWingMan Kwok GBENU_STATS_P1(ale_rate_limit_drop), 11239a391c7bSWingMan Kwok GBENU_STATS_P1(ale_vid_ingress_drop), 11249a391c7bSWingMan Kwok GBENU_STATS_P1(ale_da_eq_sa_drop), 11259a391c7bSWingMan Kwok GBENU_STATS_P1(ale_unknown_ucast), 11269a391c7bSWingMan Kwok GBENU_STATS_P1(ale_unknown_ucast_bytes), 11279a391c7bSWingMan Kwok GBENU_STATS_P1(ale_unknown_mcast), 11289a391c7bSWingMan Kwok GBENU_STATS_P1(ale_unknown_mcast_bytes), 11299a391c7bSWingMan Kwok GBENU_STATS_P1(ale_unknown_bcast), 11309a391c7bSWingMan Kwok GBENU_STATS_P1(ale_unknown_bcast_bytes), 11315be4001eSWingMan Kwok GBENU_STATS_P1(ale_pol_match), 11325be4001eSWingMan Kwok GBENU_STATS_P1(ale_pol_match_red), 11335be4001eSWingMan Kwok GBENU_STATS_P1(ale_pol_match_yellow), 11349a391c7bSWingMan Kwok GBENU_STATS_P1(tx_mem_protect_err), 11355be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri0_drop), 11365be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri1_drop), 11375be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri2_drop), 11385be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri3_drop), 11395be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri4_drop), 11405be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri5_drop), 11415be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri6_drop), 11425be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri7_drop), 11435be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri0_drop_bcnt), 11445be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri1_drop_bcnt), 11455be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri2_drop_bcnt), 11465be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri3_drop_bcnt), 11475be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri4_drop_bcnt), 11485be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri5_drop_bcnt), 11495be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri6_drop_bcnt), 11505be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri7_drop_bcnt), 11519a391c7bSWingMan Kwok /* GBENU Module 2 */ 11529a391c7bSWingMan Kwok GBENU_STATS_P2(rx_good_frames), 11539a391c7bSWingMan Kwok GBENU_STATS_P2(rx_broadcast_frames), 11549a391c7bSWingMan Kwok GBENU_STATS_P2(rx_multicast_frames), 11559a391c7bSWingMan Kwok GBENU_STATS_P2(rx_pause_frames), 11569a391c7bSWingMan Kwok GBENU_STATS_P2(rx_crc_errors), 11579a391c7bSWingMan Kwok GBENU_STATS_P2(rx_align_code_errors), 11589a391c7bSWingMan Kwok GBENU_STATS_P2(rx_oversized_frames), 11599a391c7bSWingMan Kwok GBENU_STATS_P2(rx_jabber_frames), 11609a391c7bSWingMan Kwok GBENU_STATS_P2(rx_undersized_frames), 11619a391c7bSWingMan Kwok GBENU_STATS_P2(rx_fragments), 11629a391c7bSWingMan Kwok GBENU_STATS_P2(ale_drop), 11639a391c7bSWingMan Kwok GBENU_STATS_P2(ale_overrun_drop), 11649a391c7bSWingMan Kwok GBENU_STATS_P2(rx_bytes), 11659a391c7bSWingMan Kwok GBENU_STATS_P2(tx_good_frames), 11669a391c7bSWingMan Kwok GBENU_STATS_P2(tx_broadcast_frames), 11679a391c7bSWingMan Kwok GBENU_STATS_P2(tx_multicast_frames), 11689a391c7bSWingMan Kwok GBENU_STATS_P2(tx_pause_frames), 11699a391c7bSWingMan Kwok GBENU_STATS_P2(tx_deferred_frames), 11709a391c7bSWingMan Kwok GBENU_STATS_P2(tx_collision_frames), 11719a391c7bSWingMan Kwok GBENU_STATS_P2(tx_single_coll_frames), 11729a391c7bSWingMan Kwok GBENU_STATS_P2(tx_mult_coll_frames), 11739a391c7bSWingMan Kwok GBENU_STATS_P2(tx_excessive_collisions), 11749a391c7bSWingMan Kwok GBENU_STATS_P2(tx_late_collisions), 11759a391c7bSWingMan Kwok GBENU_STATS_P2(rx_ipg_error), 11769a391c7bSWingMan Kwok GBENU_STATS_P2(tx_carrier_sense_errors), 11779a391c7bSWingMan Kwok GBENU_STATS_P2(tx_bytes), 11789a391c7bSWingMan Kwok GBENU_STATS_P2(tx_64B_frames), 11799a391c7bSWingMan Kwok GBENU_STATS_P2(tx_65_to_127B_frames), 11809a391c7bSWingMan Kwok GBENU_STATS_P2(tx_128_to_255B_frames), 11819a391c7bSWingMan Kwok GBENU_STATS_P2(tx_256_to_511B_frames), 11829a391c7bSWingMan Kwok GBENU_STATS_P2(tx_512_to_1023B_frames), 11839a391c7bSWingMan Kwok GBENU_STATS_P2(tx_1024B_frames), 11849a391c7bSWingMan Kwok GBENU_STATS_P2(net_bytes), 11859a391c7bSWingMan Kwok GBENU_STATS_P2(rx_bottom_fifo_drop), 11869a391c7bSWingMan Kwok GBENU_STATS_P2(rx_port_mask_drop), 11879a391c7bSWingMan Kwok GBENU_STATS_P2(rx_top_fifo_drop), 11889a391c7bSWingMan Kwok GBENU_STATS_P2(ale_rate_limit_drop), 11899a391c7bSWingMan Kwok GBENU_STATS_P2(ale_vid_ingress_drop), 11909a391c7bSWingMan Kwok GBENU_STATS_P2(ale_da_eq_sa_drop), 11919a391c7bSWingMan Kwok GBENU_STATS_P2(ale_unknown_ucast), 11929a391c7bSWingMan Kwok GBENU_STATS_P2(ale_unknown_ucast_bytes), 11939a391c7bSWingMan Kwok GBENU_STATS_P2(ale_unknown_mcast), 11949a391c7bSWingMan Kwok GBENU_STATS_P2(ale_unknown_mcast_bytes), 11959a391c7bSWingMan Kwok GBENU_STATS_P2(ale_unknown_bcast), 11969a391c7bSWingMan Kwok GBENU_STATS_P2(ale_unknown_bcast_bytes), 11975be4001eSWingMan Kwok GBENU_STATS_P2(ale_pol_match), 11985be4001eSWingMan Kwok GBENU_STATS_P2(ale_pol_match_red), 11995be4001eSWingMan Kwok GBENU_STATS_P2(ale_pol_match_yellow), 12009a391c7bSWingMan Kwok GBENU_STATS_P2(tx_mem_protect_err), 12015be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri0_drop), 12025be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri1_drop), 12035be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri2_drop), 12045be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri3_drop), 12055be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri4_drop), 12065be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri5_drop), 12075be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri6_drop), 12085be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri7_drop), 12095be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri0_drop_bcnt), 12105be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri1_drop_bcnt), 12115be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri2_drop_bcnt), 12125be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri3_drop_bcnt), 12135be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri4_drop_bcnt), 12145be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri5_drop_bcnt), 12155be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri6_drop_bcnt), 12165be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri7_drop_bcnt), 12179a391c7bSWingMan Kwok /* GBENU Module 3 */ 12189a391c7bSWingMan Kwok GBENU_STATS_P3(rx_good_frames), 12199a391c7bSWingMan Kwok GBENU_STATS_P3(rx_broadcast_frames), 12209a391c7bSWingMan Kwok GBENU_STATS_P3(rx_multicast_frames), 12219a391c7bSWingMan Kwok GBENU_STATS_P3(rx_pause_frames), 12229a391c7bSWingMan Kwok GBENU_STATS_P3(rx_crc_errors), 12239a391c7bSWingMan Kwok GBENU_STATS_P3(rx_align_code_errors), 12249a391c7bSWingMan Kwok GBENU_STATS_P3(rx_oversized_frames), 12259a391c7bSWingMan Kwok GBENU_STATS_P3(rx_jabber_frames), 12269a391c7bSWingMan Kwok GBENU_STATS_P3(rx_undersized_frames), 12279a391c7bSWingMan Kwok GBENU_STATS_P3(rx_fragments), 12289a391c7bSWingMan Kwok GBENU_STATS_P3(ale_drop), 12299a391c7bSWingMan Kwok GBENU_STATS_P3(ale_overrun_drop), 12309a391c7bSWingMan Kwok GBENU_STATS_P3(rx_bytes), 12319a391c7bSWingMan Kwok GBENU_STATS_P3(tx_good_frames), 12329a391c7bSWingMan Kwok GBENU_STATS_P3(tx_broadcast_frames), 12339a391c7bSWingMan Kwok GBENU_STATS_P3(tx_multicast_frames), 12349a391c7bSWingMan Kwok GBENU_STATS_P3(tx_pause_frames), 12359a391c7bSWingMan Kwok GBENU_STATS_P3(tx_deferred_frames), 12369a391c7bSWingMan Kwok GBENU_STATS_P3(tx_collision_frames), 12379a391c7bSWingMan Kwok GBENU_STATS_P3(tx_single_coll_frames), 12389a391c7bSWingMan Kwok GBENU_STATS_P3(tx_mult_coll_frames), 12399a391c7bSWingMan Kwok GBENU_STATS_P3(tx_excessive_collisions), 12409a391c7bSWingMan Kwok GBENU_STATS_P3(tx_late_collisions), 12419a391c7bSWingMan Kwok GBENU_STATS_P3(rx_ipg_error), 12429a391c7bSWingMan Kwok GBENU_STATS_P3(tx_carrier_sense_errors), 12439a391c7bSWingMan Kwok GBENU_STATS_P3(tx_bytes), 12449a391c7bSWingMan Kwok GBENU_STATS_P3(tx_64B_frames), 12459a391c7bSWingMan Kwok GBENU_STATS_P3(tx_65_to_127B_frames), 12469a391c7bSWingMan Kwok GBENU_STATS_P3(tx_128_to_255B_frames), 12479a391c7bSWingMan Kwok GBENU_STATS_P3(tx_256_to_511B_frames), 12489a391c7bSWingMan Kwok GBENU_STATS_P3(tx_512_to_1023B_frames), 12499a391c7bSWingMan Kwok GBENU_STATS_P3(tx_1024B_frames), 12509a391c7bSWingMan Kwok GBENU_STATS_P3(net_bytes), 12519a391c7bSWingMan Kwok GBENU_STATS_P3(rx_bottom_fifo_drop), 12529a391c7bSWingMan Kwok GBENU_STATS_P3(rx_port_mask_drop), 12539a391c7bSWingMan Kwok GBENU_STATS_P3(rx_top_fifo_drop), 12549a391c7bSWingMan Kwok GBENU_STATS_P3(ale_rate_limit_drop), 12559a391c7bSWingMan Kwok GBENU_STATS_P3(ale_vid_ingress_drop), 12569a391c7bSWingMan Kwok GBENU_STATS_P3(ale_da_eq_sa_drop), 12579a391c7bSWingMan Kwok GBENU_STATS_P3(ale_unknown_ucast), 12589a391c7bSWingMan Kwok GBENU_STATS_P3(ale_unknown_ucast_bytes), 12599a391c7bSWingMan Kwok GBENU_STATS_P3(ale_unknown_mcast), 12609a391c7bSWingMan Kwok GBENU_STATS_P3(ale_unknown_mcast_bytes), 12619a391c7bSWingMan Kwok GBENU_STATS_P3(ale_unknown_bcast), 12629a391c7bSWingMan Kwok GBENU_STATS_P3(ale_unknown_bcast_bytes), 12635be4001eSWingMan Kwok GBENU_STATS_P3(ale_pol_match), 12645be4001eSWingMan Kwok GBENU_STATS_P3(ale_pol_match_red), 12655be4001eSWingMan Kwok GBENU_STATS_P3(ale_pol_match_yellow), 12669a391c7bSWingMan Kwok GBENU_STATS_P3(tx_mem_protect_err), 12675be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri0_drop), 12685be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri1_drop), 12695be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri2_drop), 12705be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri3_drop), 12715be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri4_drop), 12725be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri5_drop), 12735be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri6_drop), 12745be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri7_drop), 12755be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri0_drop_bcnt), 12765be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri1_drop_bcnt), 12775be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri2_drop_bcnt), 12785be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri3_drop_bcnt), 12795be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri4_drop_bcnt), 12805be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri5_drop_bcnt), 12815be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri6_drop_bcnt), 12825be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri7_drop_bcnt), 12839a391c7bSWingMan Kwok /* GBENU Module 4 */ 12849a391c7bSWingMan Kwok GBENU_STATS_P4(rx_good_frames), 12859a391c7bSWingMan Kwok GBENU_STATS_P4(rx_broadcast_frames), 12869a391c7bSWingMan Kwok GBENU_STATS_P4(rx_multicast_frames), 12879a391c7bSWingMan Kwok GBENU_STATS_P4(rx_pause_frames), 12889a391c7bSWingMan Kwok GBENU_STATS_P4(rx_crc_errors), 12899a391c7bSWingMan Kwok GBENU_STATS_P4(rx_align_code_errors), 12909a391c7bSWingMan Kwok GBENU_STATS_P4(rx_oversized_frames), 12919a391c7bSWingMan Kwok GBENU_STATS_P4(rx_jabber_frames), 12929a391c7bSWingMan Kwok GBENU_STATS_P4(rx_undersized_frames), 12939a391c7bSWingMan Kwok GBENU_STATS_P4(rx_fragments), 12949a391c7bSWingMan Kwok GBENU_STATS_P4(ale_drop), 12959a391c7bSWingMan Kwok GBENU_STATS_P4(ale_overrun_drop), 12969a391c7bSWingMan Kwok GBENU_STATS_P4(rx_bytes), 12979a391c7bSWingMan Kwok GBENU_STATS_P4(tx_good_frames), 12989a391c7bSWingMan Kwok GBENU_STATS_P4(tx_broadcast_frames), 12999a391c7bSWingMan Kwok GBENU_STATS_P4(tx_multicast_frames), 13009a391c7bSWingMan Kwok GBENU_STATS_P4(tx_pause_frames), 13019a391c7bSWingMan Kwok GBENU_STATS_P4(tx_deferred_frames), 13029a391c7bSWingMan Kwok GBENU_STATS_P4(tx_collision_frames), 13039a391c7bSWingMan Kwok GBENU_STATS_P4(tx_single_coll_frames), 13049a391c7bSWingMan Kwok GBENU_STATS_P4(tx_mult_coll_frames), 13059a391c7bSWingMan Kwok GBENU_STATS_P4(tx_excessive_collisions), 13069a391c7bSWingMan Kwok GBENU_STATS_P4(tx_late_collisions), 13079a391c7bSWingMan Kwok GBENU_STATS_P4(rx_ipg_error), 13089a391c7bSWingMan Kwok GBENU_STATS_P4(tx_carrier_sense_errors), 13099a391c7bSWingMan Kwok GBENU_STATS_P4(tx_bytes), 13109a391c7bSWingMan Kwok GBENU_STATS_P4(tx_64B_frames), 13119a391c7bSWingMan Kwok GBENU_STATS_P4(tx_65_to_127B_frames), 13129a391c7bSWingMan Kwok GBENU_STATS_P4(tx_128_to_255B_frames), 13139a391c7bSWingMan Kwok GBENU_STATS_P4(tx_256_to_511B_frames), 13149a391c7bSWingMan Kwok GBENU_STATS_P4(tx_512_to_1023B_frames), 13159a391c7bSWingMan Kwok GBENU_STATS_P4(tx_1024B_frames), 13169a391c7bSWingMan Kwok GBENU_STATS_P4(net_bytes), 13179a391c7bSWingMan Kwok GBENU_STATS_P4(rx_bottom_fifo_drop), 13189a391c7bSWingMan Kwok GBENU_STATS_P4(rx_port_mask_drop), 13199a391c7bSWingMan Kwok GBENU_STATS_P4(rx_top_fifo_drop), 13209a391c7bSWingMan Kwok GBENU_STATS_P4(ale_rate_limit_drop), 13219a391c7bSWingMan Kwok GBENU_STATS_P4(ale_vid_ingress_drop), 13229a391c7bSWingMan Kwok GBENU_STATS_P4(ale_da_eq_sa_drop), 13239a391c7bSWingMan Kwok GBENU_STATS_P4(ale_unknown_ucast), 13249a391c7bSWingMan Kwok GBENU_STATS_P4(ale_unknown_ucast_bytes), 13259a391c7bSWingMan Kwok GBENU_STATS_P4(ale_unknown_mcast), 13269a391c7bSWingMan Kwok GBENU_STATS_P4(ale_unknown_mcast_bytes), 13279a391c7bSWingMan Kwok GBENU_STATS_P4(ale_unknown_bcast), 13289a391c7bSWingMan Kwok GBENU_STATS_P4(ale_unknown_bcast_bytes), 13295be4001eSWingMan Kwok GBENU_STATS_P4(ale_pol_match), 13305be4001eSWingMan Kwok GBENU_STATS_P4(ale_pol_match_red), 13315be4001eSWingMan Kwok GBENU_STATS_P4(ale_pol_match_yellow), 13329a391c7bSWingMan Kwok GBENU_STATS_P4(tx_mem_protect_err), 13335be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri0_drop), 13345be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri1_drop), 13355be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri2_drop), 13365be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri3_drop), 13375be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri4_drop), 13385be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri5_drop), 13395be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri6_drop), 13405be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri7_drop), 13415be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri0_drop_bcnt), 13425be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri1_drop_bcnt), 13435be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri2_drop_bcnt), 13445be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri3_drop_bcnt), 13455be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri4_drop_bcnt), 13465be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri5_drop_bcnt), 13475be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri6_drop_bcnt), 13485be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri7_drop_bcnt), 13499a391c7bSWingMan Kwok /* GBENU Module 5 */ 13509a391c7bSWingMan Kwok GBENU_STATS_P5(rx_good_frames), 13519a391c7bSWingMan Kwok GBENU_STATS_P5(rx_broadcast_frames), 13529a391c7bSWingMan Kwok GBENU_STATS_P5(rx_multicast_frames), 13539a391c7bSWingMan Kwok GBENU_STATS_P5(rx_pause_frames), 13549a391c7bSWingMan Kwok GBENU_STATS_P5(rx_crc_errors), 13559a391c7bSWingMan Kwok GBENU_STATS_P5(rx_align_code_errors), 13569a391c7bSWingMan Kwok GBENU_STATS_P5(rx_oversized_frames), 13579a391c7bSWingMan Kwok GBENU_STATS_P5(rx_jabber_frames), 13589a391c7bSWingMan Kwok GBENU_STATS_P5(rx_undersized_frames), 13599a391c7bSWingMan Kwok GBENU_STATS_P5(rx_fragments), 13609a391c7bSWingMan Kwok GBENU_STATS_P5(ale_drop), 13619a391c7bSWingMan Kwok GBENU_STATS_P5(ale_overrun_drop), 13629a391c7bSWingMan Kwok GBENU_STATS_P5(rx_bytes), 13639a391c7bSWingMan Kwok GBENU_STATS_P5(tx_good_frames), 13649a391c7bSWingMan Kwok GBENU_STATS_P5(tx_broadcast_frames), 13659a391c7bSWingMan Kwok GBENU_STATS_P5(tx_multicast_frames), 13669a391c7bSWingMan Kwok GBENU_STATS_P5(tx_pause_frames), 13679a391c7bSWingMan Kwok GBENU_STATS_P5(tx_deferred_frames), 13689a391c7bSWingMan Kwok GBENU_STATS_P5(tx_collision_frames), 13699a391c7bSWingMan Kwok GBENU_STATS_P5(tx_single_coll_frames), 13709a391c7bSWingMan Kwok GBENU_STATS_P5(tx_mult_coll_frames), 13719a391c7bSWingMan Kwok GBENU_STATS_P5(tx_excessive_collisions), 13729a391c7bSWingMan Kwok GBENU_STATS_P5(tx_late_collisions), 13739a391c7bSWingMan Kwok GBENU_STATS_P5(rx_ipg_error), 13749a391c7bSWingMan Kwok GBENU_STATS_P5(tx_carrier_sense_errors), 13759a391c7bSWingMan Kwok GBENU_STATS_P5(tx_bytes), 13769a391c7bSWingMan Kwok GBENU_STATS_P5(tx_64B_frames), 13779a391c7bSWingMan Kwok GBENU_STATS_P5(tx_65_to_127B_frames), 13789a391c7bSWingMan Kwok GBENU_STATS_P5(tx_128_to_255B_frames), 13799a391c7bSWingMan Kwok GBENU_STATS_P5(tx_256_to_511B_frames), 13809a391c7bSWingMan Kwok GBENU_STATS_P5(tx_512_to_1023B_frames), 13819a391c7bSWingMan Kwok GBENU_STATS_P5(tx_1024B_frames), 13829a391c7bSWingMan Kwok GBENU_STATS_P5(net_bytes), 13839a391c7bSWingMan Kwok GBENU_STATS_P5(rx_bottom_fifo_drop), 13849a391c7bSWingMan Kwok GBENU_STATS_P5(rx_port_mask_drop), 13859a391c7bSWingMan Kwok GBENU_STATS_P5(rx_top_fifo_drop), 13869a391c7bSWingMan Kwok GBENU_STATS_P5(ale_rate_limit_drop), 13879a391c7bSWingMan Kwok GBENU_STATS_P5(ale_vid_ingress_drop), 13889a391c7bSWingMan Kwok GBENU_STATS_P5(ale_da_eq_sa_drop), 13899a391c7bSWingMan Kwok GBENU_STATS_P5(ale_unknown_ucast), 13909a391c7bSWingMan Kwok GBENU_STATS_P5(ale_unknown_ucast_bytes), 13919a391c7bSWingMan Kwok GBENU_STATS_P5(ale_unknown_mcast), 13929a391c7bSWingMan Kwok GBENU_STATS_P5(ale_unknown_mcast_bytes), 13939a391c7bSWingMan Kwok GBENU_STATS_P5(ale_unknown_bcast), 13949a391c7bSWingMan Kwok GBENU_STATS_P5(ale_unknown_bcast_bytes), 13955be4001eSWingMan Kwok GBENU_STATS_P5(ale_pol_match), 13965be4001eSWingMan Kwok GBENU_STATS_P5(ale_pol_match_red), 13975be4001eSWingMan Kwok GBENU_STATS_P5(ale_pol_match_yellow), 13989a391c7bSWingMan Kwok GBENU_STATS_P5(tx_mem_protect_err), 13995be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri0_drop), 14005be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri1_drop), 14015be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri2_drop), 14025be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri3_drop), 14035be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri4_drop), 14045be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri5_drop), 14055be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri6_drop), 14065be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri7_drop), 14075be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri0_drop_bcnt), 14085be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri1_drop_bcnt), 14095be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri2_drop_bcnt), 14105be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri3_drop_bcnt), 14115be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri4_drop_bcnt), 14125be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri5_drop_bcnt), 14135be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri6_drop_bcnt), 14145be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri7_drop_bcnt), 14159a391c7bSWingMan Kwok /* GBENU Module 6 */ 14169a391c7bSWingMan Kwok GBENU_STATS_P6(rx_good_frames), 14179a391c7bSWingMan Kwok GBENU_STATS_P6(rx_broadcast_frames), 14189a391c7bSWingMan Kwok GBENU_STATS_P6(rx_multicast_frames), 14199a391c7bSWingMan Kwok GBENU_STATS_P6(rx_pause_frames), 14209a391c7bSWingMan Kwok GBENU_STATS_P6(rx_crc_errors), 14219a391c7bSWingMan Kwok GBENU_STATS_P6(rx_align_code_errors), 14229a391c7bSWingMan Kwok GBENU_STATS_P6(rx_oversized_frames), 14239a391c7bSWingMan Kwok GBENU_STATS_P6(rx_jabber_frames), 14249a391c7bSWingMan Kwok GBENU_STATS_P6(rx_undersized_frames), 14259a391c7bSWingMan Kwok GBENU_STATS_P6(rx_fragments), 14269a391c7bSWingMan Kwok GBENU_STATS_P6(ale_drop), 14279a391c7bSWingMan Kwok GBENU_STATS_P6(ale_overrun_drop), 14289a391c7bSWingMan Kwok GBENU_STATS_P6(rx_bytes), 14299a391c7bSWingMan Kwok GBENU_STATS_P6(tx_good_frames), 14309a391c7bSWingMan Kwok GBENU_STATS_P6(tx_broadcast_frames), 14319a391c7bSWingMan Kwok GBENU_STATS_P6(tx_multicast_frames), 14329a391c7bSWingMan Kwok GBENU_STATS_P6(tx_pause_frames), 14339a391c7bSWingMan Kwok GBENU_STATS_P6(tx_deferred_frames), 14349a391c7bSWingMan Kwok GBENU_STATS_P6(tx_collision_frames), 14359a391c7bSWingMan Kwok GBENU_STATS_P6(tx_single_coll_frames), 14369a391c7bSWingMan Kwok GBENU_STATS_P6(tx_mult_coll_frames), 14379a391c7bSWingMan Kwok GBENU_STATS_P6(tx_excessive_collisions), 14389a391c7bSWingMan Kwok GBENU_STATS_P6(tx_late_collisions), 14399a391c7bSWingMan Kwok GBENU_STATS_P6(rx_ipg_error), 14409a391c7bSWingMan Kwok GBENU_STATS_P6(tx_carrier_sense_errors), 14419a391c7bSWingMan Kwok GBENU_STATS_P6(tx_bytes), 14429a391c7bSWingMan Kwok GBENU_STATS_P6(tx_64B_frames), 14439a391c7bSWingMan Kwok GBENU_STATS_P6(tx_65_to_127B_frames), 14449a391c7bSWingMan Kwok GBENU_STATS_P6(tx_128_to_255B_frames), 14459a391c7bSWingMan Kwok GBENU_STATS_P6(tx_256_to_511B_frames), 14469a391c7bSWingMan Kwok GBENU_STATS_P6(tx_512_to_1023B_frames), 14479a391c7bSWingMan Kwok GBENU_STATS_P6(tx_1024B_frames), 14489a391c7bSWingMan Kwok GBENU_STATS_P6(net_bytes), 14499a391c7bSWingMan Kwok GBENU_STATS_P6(rx_bottom_fifo_drop), 14509a391c7bSWingMan Kwok GBENU_STATS_P6(rx_port_mask_drop), 14519a391c7bSWingMan Kwok GBENU_STATS_P6(rx_top_fifo_drop), 14529a391c7bSWingMan Kwok GBENU_STATS_P6(ale_rate_limit_drop), 14539a391c7bSWingMan Kwok GBENU_STATS_P6(ale_vid_ingress_drop), 14549a391c7bSWingMan Kwok GBENU_STATS_P6(ale_da_eq_sa_drop), 14559a391c7bSWingMan Kwok GBENU_STATS_P6(ale_unknown_ucast), 14569a391c7bSWingMan Kwok GBENU_STATS_P6(ale_unknown_ucast_bytes), 14579a391c7bSWingMan Kwok GBENU_STATS_P6(ale_unknown_mcast), 14589a391c7bSWingMan Kwok GBENU_STATS_P6(ale_unknown_mcast_bytes), 14599a391c7bSWingMan Kwok GBENU_STATS_P6(ale_unknown_bcast), 14609a391c7bSWingMan Kwok GBENU_STATS_P6(ale_unknown_bcast_bytes), 14615be4001eSWingMan Kwok GBENU_STATS_P6(ale_pol_match), 14625be4001eSWingMan Kwok GBENU_STATS_P6(ale_pol_match_red), 14635be4001eSWingMan Kwok GBENU_STATS_P6(ale_pol_match_yellow), 14649a391c7bSWingMan Kwok GBENU_STATS_P6(tx_mem_protect_err), 14655be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri0_drop), 14665be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri1_drop), 14675be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri2_drop), 14685be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri3_drop), 14695be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri4_drop), 14705be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri5_drop), 14715be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri6_drop), 14725be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri7_drop), 14735be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri0_drop_bcnt), 14745be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri1_drop_bcnt), 14755be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri2_drop_bcnt), 14765be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri3_drop_bcnt), 14775be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri4_drop_bcnt), 14785be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri5_drop_bcnt), 14795be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri6_drop_bcnt), 14805be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri7_drop_bcnt), 14819a391c7bSWingMan Kwok /* GBENU Module 7 */ 14829a391c7bSWingMan Kwok GBENU_STATS_P7(rx_good_frames), 14839a391c7bSWingMan Kwok GBENU_STATS_P7(rx_broadcast_frames), 14849a391c7bSWingMan Kwok GBENU_STATS_P7(rx_multicast_frames), 14859a391c7bSWingMan Kwok GBENU_STATS_P7(rx_pause_frames), 14869a391c7bSWingMan Kwok GBENU_STATS_P7(rx_crc_errors), 14879a391c7bSWingMan Kwok GBENU_STATS_P7(rx_align_code_errors), 14889a391c7bSWingMan Kwok GBENU_STATS_P7(rx_oversized_frames), 14899a391c7bSWingMan Kwok GBENU_STATS_P7(rx_jabber_frames), 14909a391c7bSWingMan Kwok GBENU_STATS_P7(rx_undersized_frames), 14919a391c7bSWingMan Kwok GBENU_STATS_P7(rx_fragments), 14929a391c7bSWingMan Kwok GBENU_STATS_P7(ale_drop), 14939a391c7bSWingMan Kwok GBENU_STATS_P7(ale_overrun_drop), 14949a391c7bSWingMan Kwok GBENU_STATS_P7(rx_bytes), 14959a391c7bSWingMan Kwok GBENU_STATS_P7(tx_good_frames), 14969a391c7bSWingMan Kwok GBENU_STATS_P7(tx_broadcast_frames), 14979a391c7bSWingMan Kwok GBENU_STATS_P7(tx_multicast_frames), 14989a391c7bSWingMan Kwok GBENU_STATS_P7(tx_pause_frames), 14999a391c7bSWingMan Kwok GBENU_STATS_P7(tx_deferred_frames), 15009a391c7bSWingMan Kwok GBENU_STATS_P7(tx_collision_frames), 15019a391c7bSWingMan Kwok GBENU_STATS_P7(tx_single_coll_frames), 15029a391c7bSWingMan Kwok GBENU_STATS_P7(tx_mult_coll_frames), 15039a391c7bSWingMan Kwok GBENU_STATS_P7(tx_excessive_collisions), 15049a391c7bSWingMan Kwok GBENU_STATS_P7(tx_late_collisions), 15059a391c7bSWingMan Kwok GBENU_STATS_P7(rx_ipg_error), 15069a391c7bSWingMan Kwok GBENU_STATS_P7(tx_carrier_sense_errors), 15079a391c7bSWingMan Kwok GBENU_STATS_P7(tx_bytes), 15089a391c7bSWingMan Kwok GBENU_STATS_P7(tx_64B_frames), 15099a391c7bSWingMan Kwok GBENU_STATS_P7(tx_65_to_127B_frames), 15109a391c7bSWingMan Kwok GBENU_STATS_P7(tx_128_to_255B_frames), 15119a391c7bSWingMan Kwok GBENU_STATS_P7(tx_256_to_511B_frames), 15129a391c7bSWingMan Kwok GBENU_STATS_P7(tx_512_to_1023B_frames), 15139a391c7bSWingMan Kwok GBENU_STATS_P7(tx_1024B_frames), 15149a391c7bSWingMan Kwok GBENU_STATS_P7(net_bytes), 15159a391c7bSWingMan Kwok GBENU_STATS_P7(rx_bottom_fifo_drop), 15169a391c7bSWingMan Kwok GBENU_STATS_P7(rx_port_mask_drop), 15179a391c7bSWingMan Kwok GBENU_STATS_P7(rx_top_fifo_drop), 15189a391c7bSWingMan Kwok GBENU_STATS_P7(ale_rate_limit_drop), 15199a391c7bSWingMan Kwok GBENU_STATS_P7(ale_vid_ingress_drop), 15209a391c7bSWingMan Kwok GBENU_STATS_P7(ale_da_eq_sa_drop), 15219a391c7bSWingMan Kwok GBENU_STATS_P7(ale_unknown_ucast), 15229a391c7bSWingMan Kwok GBENU_STATS_P7(ale_unknown_ucast_bytes), 15239a391c7bSWingMan Kwok GBENU_STATS_P7(ale_unknown_mcast), 15249a391c7bSWingMan Kwok GBENU_STATS_P7(ale_unknown_mcast_bytes), 15259a391c7bSWingMan Kwok GBENU_STATS_P7(ale_unknown_bcast), 15269a391c7bSWingMan Kwok GBENU_STATS_P7(ale_unknown_bcast_bytes), 15275be4001eSWingMan Kwok GBENU_STATS_P7(ale_pol_match), 15285be4001eSWingMan Kwok GBENU_STATS_P7(ale_pol_match_red), 15295be4001eSWingMan Kwok GBENU_STATS_P7(ale_pol_match_yellow), 15309a391c7bSWingMan Kwok GBENU_STATS_P7(tx_mem_protect_err), 15315be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri0_drop), 15325be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri1_drop), 15335be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri2_drop), 15345be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri3_drop), 15355be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri4_drop), 15365be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri5_drop), 15375be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri6_drop), 15385be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri7_drop), 15395be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri0_drop_bcnt), 15405be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri1_drop_bcnt), 15415be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri2_drop_bcnt), 15425be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri3_drop_bcnt), 15435be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri4_drop_bcnt), 15445be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri5_drop_bcnt), 15455be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri6_drop_bcnt), 15465be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri7_drop_bcnt), 15479a391c7bSWingMan Kwok /* GBENU Module 8 */ 15489a391c7bSWingMan Kwok GBENU_STATS_P8(rx_good_frames), 15499a391c7bSWingMan Kwok GBENU_STATS_P8(rx_broadcast_frames), 15509a391c7bSWingMan Kwok GBENU_STATS_P8(rx_multicast_frames), 15519a391c7bSWingMan Kwok GBENU_STATS_P8(rx_pause_frames), 15529a391c7bSWingMan Kwok GBENU_STATS_P8(rx_crc_errors), 15539a391c7bSWingMan Kwok GBENU_STATS_P8(rx_align_code_errors), 15549a391c7bSWingMan Kwok GBENU_STATS_P8(rx_oversized_frames), 15559a391c7bSWingMan Kwok GBENU_STATS_P8(rx_jabber_frames), 15569a391c7bSWingMan Kwok GBENU_STATS_P8(rx_undersized_frames), 15579a391c7bSWingMan Kwok GBENU_STATS_P8(rx_fragments), 15589a391c7bSWingMan Kwok GBENU_STATS_P8(ale_drop), 15599a391c7bSWingMan Kwok GBENU_STATS_P8(ale_overrun_drop), 15609a391c7bSWingMan Kwok GBENU_STATS_P8(rx_bytes), 15619a391c7bSWingMan Kwok GBENU_STATS_P8(tx_good_frames), 15629a391c7bSWingMan Kwok GBENU_STATS_P8(tx_broadcast_frames), 15639a391c7bSWingMan Kwok GBENU_STATS_P8(tx_multicast_frames), 15649a391c7bSWingMan Kwok GBENU_STATS_P8(tx_pause_frames), 15659a391c7bSWingMan Kwok GBENU_STATS_P8(tx_deferred_frames), 15669a391c7bSWingMan Kwok GBENU_STATS_P8(tx_collision_frames), 15679a391c7bSWingMan Kwok GBENU_STATS_P8(tx_single_coll_frames), 15689a391c7bSWingMan Kwok GBENU_STATS_P8(tx_mult_coll_frames), 15699a391c7bSWingMan Kwok GBENU_STATS_P8(tx_excessive_collisions), 15709a391c7bSWingMan Kwok GBENU_STATS_P8(tx_late_collisions), 15719a391c7bSWingMan Kwok GBENU_STATS_P8(rx_ipg_error), 15729a391c7bSWingMan Kwok GBENU_STATS_P8(tx_carrier_sense_errors), 15739a391c7bSWingMan Kwok GBENU_STATS_P8(tx_bytes), 15749a391c7bSWingMan Kwok GBENU_STATS_P8(tx_64B_frames), 15759a391c7bSWingMan Kwok GBENU_STATS_P8(tx_65_to_127B_frames), 15769a391c7bSWingMan Kwok GBENU_STATS_P8(tx_128_to_255B_frames), 15779a391c7bSWingMan Kwok GBENU_STATS_P8(tx_256_to_511B_frames), 15789a391c7bSWingMan Kwok GBENU_STATS_P8(tx_512_to_1023B_frames), 15799a391c7bSWingMan Kwok GBENU_STATS_P8(tx_1024B_frames), 15809a391c7bSWingMan Kwok GBENU_STATS_P8(net_bytes), 15819a391c7bSWingMan Kwok GBENU_STATS_P8(rx_bottom_fifo_drop), 15829a391c7bSWingMan Kwok GBENU_STATS_P8(rx_port_mask_drop), 15839a391c7bSWingMan Kwok GBENU_STATS_P8(rx_top_fifo_drop), 15849a391c7bSWingMan Kwok GBENU_STATS_P8(ale_rate_limit_drop), 15859a391c7bSWingMan Kwok GBENU_STATS_P8(ale_vid_ingress_drop), 15869a391c7bSWingMan Kwok GBENU_STATS_P8(ale_da_eq_sa_drop), 15879a391c7bSWingMan Kwok GBENU_STATS_P8(ale_unknown_ucast), 15889a391c7bSWingMan Kwok GBENU_STATS_P8(ale_unknown_ucast_bytes), 15899a391c7bSWingMan Kwok GBENU_STATS_P8(ale_unknown_mcast), 15909a391c7bSWingMan Kwok GBENU_STATS_P8(ale_unknown_mcast_bytes), 15919a391c7bSWingMan Kwok GBENU_STATS_P8(ale_unknown_bcast), 15929a391c7bSWingMan Kwok GBENU_STATS_P8(ale_unknown_bcast_bytes), 15935be4001eSWingMan Kwok GBENU_STATS_P8(ale_pol_match), 15945be4001eSWingMan Kwok GBENU_STATS_P8(ale_pol_match_red), 15955be4001eSWingMan Kwok GBENU_STATS_P8(ale_pol_match_yellow), 15969a391c7bSWingMan Kwok GBENU_STATS_P8(tx_mem_protect_err), 15975be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri0_drop), 15985be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri1_drop), 15995be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri2_drop), 16005be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri3_drop), 16015be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri4_drop), 16025be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri5_drop), 16035be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri6_drop), 16045be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri7_drop), 16055be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri0_drop_bcnt), 16065be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri1_drop_bcnt), 16075be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri2_drop_bcnt), 16085be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri3_drop_bcnt), 16095be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri4_drop_bcnt), 16105be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri5_drop_bcnt), 16115be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri6_drop_bcnt), 16125be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri7_drop_bcnt), 16139a391c7bSWingMan Kwok }; 16149a391c7bSWingMan Kwok 1615da866ba0SKaricheri, Muralidharan #define XGBE_STATS0_INFO(field) \ 1616da866ba0SKaricheri, Muralidharan { \ 1617da866ba0SKaricheri, Muralidharan "GBE_0:"#field, XGBE_STATS0_MODULE, \ 161890cff9e2SWingman Kwok FIELD_SIZEOF(struct xgbe_hw_stats, field), \ 1619da866ba0SKaricheri, Muralidharan offsetof(struct xgbe_hw_stats, field) \ 1620da866ba0SKaricheri, Muralidharan } 162190cff9e2SWingman Kwok 1622da866ba0SKaricheri, Muralidharan #define XGBE_STATS1_INFO(field) \ 1623da866ba0SKaricheri, Muralidharan { \ 1624da866ba0SKaricheri, Muralidharan "GBE_1:"#field, XGBE_STATS1_MODULE, \ 162590cff9e2SWingman Kwok FIELD_SIZEOF(struct xgbe_hw_stats, field), \ 1626da866ba0SKaricheri, Muralidharan offsetof(struct xgbe_hw_stats, field) \ 1627da866ba0SKaricheri, Muralidharan } 162890cff9e2SWingman Kwok 1629da866ba0SKaricheri, Muralidharan #define XGBE_STATS2_INFO(field) \ 1630da866ba0SKaricheri, Muralidharan { \ 1631da866ba0SKaricheri, Muralidharan "GBE_2:"#field, XGBE_STATS2_MODULE, \ 163290cff9e2SWingman Kwok FIELD_SIZEOF(struct xgbe_hw_stats, field), \ 1633da866ba0SKaricheri, Muralidharan offsetof(struct xgbe_hw_stats, field) \ 1634da866ba0SKaricheri, Muralidharan } 163590cff9e2SWingman Kwok 163690cff9e2SWingman Kwok static const struct netcp_ethtool_stat xgbe10_et_stats[] = { 163790cff9e2SWingman Kwok /* GBE module 0 */ 1638da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_good_frames), 1639da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_broadcast_frames), 1640da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_multicast_frames), 1641da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_oversized_frames), 1642da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_undersized_frames), 1643da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(overrun_type4), 1644da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(overrun_type5), 1645da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_bytes), 1646da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_good_frames), 1647da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_broadcast_frames), 1648da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_multicast_frames), 1649da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_bytes), 1650da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_64byte_frames), 1651da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_65_to_127byte_frames), 1652da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_128_to_255byte_frames), 1653da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_256_to_511byte_frames), 1654da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_512_to_1023byte_frames), 1655da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_1024byte_frames), 1656da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(net_bytes), 1657da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_sof_overruns), 1658da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_mof_overruns), 1659da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_dma_overruns), 166090cff9e2SWingman Kwok /* XGBE module 1 */ 1661da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_good_frames), 1662da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_broadcast_frames), 1663da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_multicast_frames), 1664da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_pause_frames), 1665da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_crc_errors), 1666da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_align_code_errors), 1667da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_oversized_frames), 1668da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_jabber_frames), 1669da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_undersized_frames), 1670da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_fragments), 1671da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(overrun_type4), 1672da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(overrun_type5), 1673da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_bytes), 1674da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_good_frames), 1675da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_broadcast_frames), 1676da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_multicast_frames), 1677da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_pause_frames), 1678da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_deferred_frames), 1679da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_collision_frames), 1680da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_single_coll_frames), 1681da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_mult_coll_frames), 1682da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_excessive_collisions), 1683da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_late_collisions), 1684da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_underrun), 1685da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_carrier_sense_errors), 1686da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_bytes), 1687da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_64byte_frames), 1688da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_65_to_127byte_frames), 1689da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_128_to_255byte_frames), 1690da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_256_to_511byte_frames), 1691da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_512_to_1023byte_frames), 1692da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_1024byte_frames), 1693da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(net_bytes), 1694da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_sof_overruns), 1695da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_mof_overruns), 1696da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_dma_overruns), 169790cff9e2SWingman Kwok /* XGBE module 2 */ 1698da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_good_frames), 1699da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_broadcast_frames), 1700da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_multicast_frames), 1701da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_pause_frames), 1702da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_crc_errors), 1703da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_align_code_errors), 1704da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_oversized_frames), 1705da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_jabber_frames), 1706da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_undersized_frames), 1707da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_fragments), 1708da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(overrun_type4), 1709da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(overrun_type5), 1710da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_bytes), 1711da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_good_frames), 1712da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_broadcast_frames), 1713da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_multicast_frames), 1714da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_pause_frames), 1715da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_deferred_frames), 1716da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_collision_frames), 1717da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_single_coll_frames), 1718da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_mult_coll_frames), 1719da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_excessive_collisions), 1720da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_late_collisions), 1721da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_underrun), 1722da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_carrier_sense_errors), 1723da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_bytes), 1724da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_64byte_frames), 1725da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_65_to_127byte_frames), 1726da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_128_to_255byte_frames), 1727da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_256_to_511byte_frames), 1728da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_512_to_1023byte_frames), 1729da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_1024byte_frames), 1730da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(net_bytes), 1731da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_sof_overruns), 1732da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_mof_overruns), 1733da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_dma_overruns), 173490cff9e2SWingman Kwok }; 173590cff9e2SWingman Kwok 17366f8d3f33SWingman Kwok #define for_each_intf(i, priv) \ 17376f8d3f33SWingman Kwok list_for_each_entry((i), &(priv)->gbe_intf_head, gbe_intf_list) 17386f8d3f33SWingman Kwok 17396f8d3f33SWingman Kwok #define for_each_sec_slave(slave, priv) \ 17406f8d3f33SWingman Kwok list_for_each_entry((slave), &(priv)->secondary_slaves, slave_list) 17416f8d3f33SWingman Kwok 17426f8d3f33SWingman Kwok #define first_sec_slave(priv) \ 17436f8d3f33SWingman Kwok list_first_entry(&priv->secondary_slaves, \ 17446f8d3f33SWingman Kwok struct gbe_slave, slave_list) 17456f8d3f33SWingman Kwok 17466f8d3f33SWingman Kwok static void keystone_get_drvinfo(struct net_device *ndev, 17476f8d3f33SWingman Kwok struct ethtool_drvinfo *info) 17486f8d3f33SWingman Kwok { 17496f8d3f33SWingman Kwok strncpy(info->driver, NETCP_DRIVER_NAME, sizeof(info->driver)); 17506f8d3f33SWingman Kwok strncpy(info->version, NETCP_DRIVER_VERSION, sizeof(info->version)); 17516f8d3f33SWingman Kwok } 17526f8d3f33SWingman Kwok 17536f8d3f33SWingman Kwok static u32 keystone_get_msglevel(struct net_device *ndev) 17546f8d3f33SWingman Kwok { 17556f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 17566f8d3f33SWingman Kwok 17576f8d3f33SWingman Kwok return netcp->msg_enable; 17586f8d3f33SWingman Kwok } 17596f8d3f33SWingman Kwok 17606f8d3f33SWingman Kwok static void keystone_set_msglevel(struct net_device *ndev, u32 value) 17616f8d3f33SWingman Kwok { 17626f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 17636f8d3f33SWingman Kwok 17646f8d3f33SWingman Kwok netcp->msg_enable = value; 17656f8d3f33SWingman Kwok } 17666f8d3f33SWingman Kwok 1767e9838ef2SWingMan Kwok static struct gbe_intf *keystone_get_intf_data(struct netcp_intf *netcp) 1768e9838ef2SWingMan Kwok { 1769e9838ef2SWingMan Kwok struct gbe_intf *gbe_intf; 1770e9838ef2SWingMan Kwok 1771e9838ef2SWingMan Kwok gbe_intf = netcp_module_get_intf_data(&gbe_module, netcp); 1772e9838ef2SWingMan Kwok if (!gbe_intf) 1773e9838ef2SWingMan Kwok gbe_intf = netcp_module_get_intf_data(&xgbe_module, netcp); 1774e9838ef2SWingMan Kwok 1775e9838ef2SWingMan Kwok return gbe_intf; 1776e9838ef2SWingMan Kwok } 1777e9838ef2SWingMan Kwok 17786f8d3f33SWingman Kwok static void keystone_get_stat_strings(struct net_device *ndev, 17796f8d3f33SWingman Kwok uint32_t stringset, uint8_t *data) 17806f8d3f33SWingman Kwok { 17816f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 17826f8d3f33SWingman Kwok struct gbe_intf *gbe_intf; 17836f8d3f33SWingman Kwok struct gbe_priv *gbe_dev; 17846f8d3f33SWingman Kwok int i; 17856f8d3f33SWingman Kwok 1786e9838ef2SWingMan Kwok gbe_intf = keystone_get_intf_data(netcp); 17876f8d3f33SWingman Kwok if (!gbe_intf) 17886f8d3f33SWingman Kwok return; 17896f8d3f33SWingman Kwok gbe_dev = gbe_intf->gbe_dev; 17906f8d3f33SWingman Kwok 17916f8d3f33SWingman Kwok switch (stringset) { 17926f8d3f33SWingman Kwok case ETH_SS_STATS: 17936f8d3f33SWingman Kwok for (i = 0; i < gbe_dev->num_et_stats; i++) { 17946f8d3f33SWingman Kwok memcpy(data, gbe_dev->et_stats[i].desc, 17956f8d3f33SWingman Kwok ETH_GSTRING_LEN); 17966f8d3f33SWingman Kwok data += ETH_GSTRING_LEN; 17976f8d3f33SWingman Kwok } 17986f8d3f33SWingman Kwok break; 17996f8d3f33SWingman Kwok case ETH_SS_TEST: 18006f8d3f33SWingman Kwok break; 18016f8d3f33SWingman Kwok } 18026f8d3f33SWingman Kwok } 18036f8d3f33SWingman Kwok 18046f8d3f33SWingman Kwok static int keystone_get_sset_count(struct net_device *ndev, int stringset) 18056f8d3f33SWingman Kwok { 18066f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 18076f8d3f33SWingman Kwok struct gbe_intf *gbe_intf; 18086f8d3f33SWingman Kwok struct gbe_priv *gbe_dev; 18096f8d3f33SWingman Kwok 1810e9838ef2SWingMan Kwok gbe_intf = keystone_get_intf_data(netcp); 18116f8d3f33SWingman Kwok if (!gbe_intf) 18126f8d3f33SWingman Kwok return -EINVAL; 18136f8d3f33SWingman Kwok gbe_dev = gbe_intf->gbe_dev; 18146f8d3f33SWingman Kwok 18156f8d3f33SWingman Kwok switch (stringset) { 18166f8d3f33SWingman Kwok case ETH_SS_TEST: 18176f8d3f33SWingman Kwok return 0; 18186f8d3f33SWingman Kwok case ETH_SS_STATS: 18196f8d3f33SWingman Kwok return gbe_dev->num_et_stats; 18206f8d3f33SWingman Kwok default: 18216f8d3f33SWingman Kwok return -EINVAL; 18226f8d3f33SWingman Kwok } 18236f8d3f33SWingman Kwok } 18246f8d3f33SWingman Kwok 1825489e8a2fSWingMan Kwok static void gbe_reset_mod_stats(struct gbe_priv *gbe_dev, int stats_mod) 1826489e8a2fSWingMan Kwok { 1827489e8a2fSWingMan Kwok void __iomem *base = gbe_dev->hw_stats_regs[stats_mod]; 1828489e8a2fSWingMan Kwok u32 __iomem *p_stats_entry; 1829489e8a2fSWingMan Kwok int i; 1830489e8a2fSWingMan Kwok 1831489e8a2fSWingMan Kwok for (i = 0; i < gbe_dev->num_et_stats; i++) { 1832489e8a2fSWingMan Kwok if (gbe_dev->et_stats[i].type == stats_mod) { 1833489e8a2fSWingMan Kwok p_stats_entry = base + gbe_dev->et_stats[i].offset; 1834489e8a2fSWingMan Kwok gbe_dev->hw_stats[i] = 0; 1835489e8a2fSWingMan Kwok gbe_dev->hw_stats_prev[i] = readl(p_stats_entry); 1836489e8a2fSWingMan Kwok } 1837489e8a2fSWingMan Kwok } 1838489e8a2fSWingMan Kwok } 1839489e8a2fSWingMan Kwok 1840fbf64c19SWingMan Kwok static inline void gbe_update_hw_stats_entry(struct gbe_priv *gbe_dev, 1841fbf64c19SWingMan Kwok int et_stats_entry) 18426f8d3f33SWingman Kwok { 18436f8d3f33SWingman Kwok void __iomem *base = NULL; 1844489e8a2fSWingMan Kwok u32 __iomem *p_stats_entry; 1845489e8a2fSWingMan Kwok u32 curr, delta; 18466f8d3f33SWingman Kwok 1847fbf64c19SWingMan Kwok /* The hw_stats_regs pointers are already 1848fbf64c19SWingMan Kwok * properly set to point to the right base: 1849fbf64c19SWingMan Kwok */ 1850fbf64c19SWingMan Kwok base = gbe_dev->hw_stats_regs[gbe_dev->et_stats[et_stats_entry].type]; 1851489e8a2fSWingMan Kwok p_stats_entry = base + gbe_dev->et_stats[et_stats_entry].offset; 1852489e8a2fSWingMan Kwok curr = readl(p_stats_entry); 1853489e8a2fSWingMan Kwok delta = curr - gbe_dev->hw_stats_prev[et_stats_entry]; 1854489e8a2fSWingMan Kwok gbe_dev->hw_stats_prev[et_stats_entry] = curr; 1855489e8a2fSWingMan Kwok gbe_dev->hw_stats[et_stats_entry] += delta; 18566f8d3f33SWingman Kwok } 1857fbf64c19SWingMan Kwok 1858fbf64c19SWingMan Kwok static void gbe_update_stats(struct gbe_priv *gbe_dev, uint64_t *data) 1859fbf64c19SWingMan Kwok { 1860fbf64c19SWingMan Kwok int i; 1861fbf64c19SWingMan Kwok 1862fbf64c19SWingMan Kwok for (i = 0; i < gbe_dev->num_et_stats; i++) { 1863fbf64c19SWingMan Kwok gbe_update_hw_stats_entry(gbe_dev, i); 1864fbf64c19SWingMan Kwok 1865fbf64c19SWingMan Kwok if (data) 1866fbf64c19SWingMan Kwok data[i] = gbe_dev->hw_stats[i]; 1867fbf64c19SWingMan Kwok } 1868fbf64c19SWingMan Kwok } 1869fbf64c19SWingMan Kwok 1870fbf64c19SWingMan Kwok static inline void gbe_stats_mod_visible_ver14(struct gbe_priv *gbe_dev, 1871fbf64c19SWingMan Kwok int stats_mod) 1872fbf64c19SWingMan Kwok { 1873fbf64c19SWingMan Kwok u32 val; 1874fbf64c19SWingMan Kwok 1875fbf64c19SWingMan Kwok val = readl(GBE_REG_ADDR(gbe_dev, switch_regs, stat_port_en)); 1876fbf64c19SWingMan Kwok 1877fbf64c19SWingMan Kwok switch (stats_mod) { 1878fbf64c19SWingMan Kwok case GBE_STATSA_MODULE: 1879fbf64c19SWingMan Kwok case GBE_STATSB_MODULE: 1880fbf64c19SWingMan Kwok val &= ~GBE_STATS_CD_SEL; 1881fbf64c19SWingMan Kwok break; 1882fbf64c19SWingMan Kwok case GBE_STATSC_MODULE: 1883fbf64c19SWingMan Kwok case GBE_STATSD_MODULE: 1884fbf64c19SWingMan Kwok val |= GBE_STATS_CD_SEL; 1885fbf64c19SWingMan Kwok break; 1886fbf64c19SWingMan Kwok default: 1887fbf64c19SWingMan Kwok return; 1888fbf64c19SWingMan Kwok } 1889fbf64c19SWingMan Kwok 1890fbf64c19SWingMan Kwok /* make the stat module visible */ 1891fbf64c19SWingMan Kwok writel(val, GBE_REG_ADDR(gbe_dev, switch_regs, stat_port_en)); 18926f8d3f33SWingman Kwok } 18936f8d3f33SWingman Kwok 1894489e8a2fSWingMan Kwok static void gbe_reset_mod_stats_ver14(struct gbe_priv *gbe_dev, int stats_mod) 1895489e8a2fSWingMan Kwok { 1896489e8a2fSWingMan Kwok gbe_stats_mod_visible_ver14(gbe_dev, stats_mod); 1897489e8a2fSWingMan Kwok gbe_reset_mod_stats(gbe_dev, stats_mod); 1898489e8a2fSWingMan Kwok } 1899489e8a2fSWingMan Kwok 19006f8d3f33SWingman Kwok static void gbe_update_stats_ver14(struct gbe_priv *gbe_dev, uint64_t *data) 19016f8d3f33SWingman Kwok { 1902fbf64c19SWingMan Kwok u32 half_num_et_stats = (gbe_dev->num_et_stats / 2); 1903fbf64c19SWingMan Kwok int et_entry, j, pair; 19046f8d3f33SWingman Kwok 19056f8d3f33SWingman Kwok for (pair = 0; pair < 2; pair++) { 1906fbf64c19SWingMan Kwok gbe_stats_mod_visible_ver14(gbe_dev, (pair ? 1907fbf64c19SWingMan Kwok GBE_STATSC_MODULE : 1908fbf64c19SWingMan Kwok GBE_STATSA_MODULE)); 19096f8d3f33SWingman Kwok 1910fbf64c19SWingMan Kwok for (j = 0; j < half_num_et_stats; j++) { 1911fbf64c19SWingMan Kwok et_entry = pair * half_num_et_stats + j; 1912fbf64c19SWingMan Kwok gbe_update_hw_stats_entry(gbe_dev, et_entry); 19136f8d3f33SWingman Kwok 19146f8d3f33SWingman Kwok if (data) 1915fbf64c19SWingMan Kwok data[et_entry] = gbe_dev->hw_stats[et_entry]; 19166f8d3f33SWingman Kwok } 19176f8d3f33SWingman Kwok } 19186f8d3f33SWingman Kwok } 19196f8d3f33SWingman Kwok 19206f8d3f33SWingman Kwok static void keystone_get_ethtool_stats(struct net_device *ndev, 19216f8d3f33SWingman Kwok struct ethtool_stats *stats, 19226f8d3f33SWingman Kwok uint64_t *data) 19236f8d3f33SWingman Kwok { 19246f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 19256f8d3f33SWingman Kwok struct gbe_intf *gbe_intf; 19266f8d3f33SWingman Kwok struct gbe_priv *gbe_dev; 19276f8d3f33SWingman Kwok 1928e9838ef2SWingMan Kwok gbe_intf = keystone_get_intf_data(netcp); 19296f8d3f33SWingman Kwok if (!gbe_intf) 19306f8d3f33SWingman Kwok return; 19316f8d3f33SWingman Kwok 19326f8d3f33SWingman Kwok gbe_dev = gbe_intf->gbe_dev; 19336f8d3f33SWingman Kwok spin_lock_bh(&gbe_dev->hw_stats_lock); 19342953586dSMurali Karicheri if (IS_SS_ID_VER_14(gbe_dev)) 19356f8d3f33SWingman Kwok gbe_update_stats_ver14(gbe_dev, data); 193690cff9e2SWingman Kwok else 193790cff9e2SWingman Kwok gbe_update_stats(gbe_dev, data); 19386f8d3f33SWingman Kwok spin_unlock_bh(&gbe_dev->hw_stats_lock); 19396f8d3f33SWingman Kwok } 19406f8d3f33SWingman Kwok 194186e3a040SPhilippe Reynes static int keystone_get_link_ksettings(struct net_device *ndev, 194286e3a040SPhilippe Reynes struct ethtool_link_ksettings *cmd) 19436f8d3f33SWingman Kwok { 19446f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 19456f8d3f33SWingman Kwok struct phy_device *phy = ndev->phydev; 19466f8d3f33SWingman Kwok struct gbe_intf *gbe_intf; 19476f8d3f33SWingman Kwok 19486f8d3f33SWingman Kwok if (!phy) 19496f8d3f33SWingman Kwok return -EINVAL; 19506f8d3f33SWingman Kwok 1951e9838ef2SWingMan Kwok gbe_intf = keystone_get_intf_data(netcp); 19526f8d3f33SWingman Kwok if (!gbe_intf) 19536f8d3f33SWingman Kwok return -EINVAL; 19546f8d3f33SWingman Kwok 19556f8d3f33SWingman Kwok if (!gbe_intf->slave) 19566f8d3f33SWingman Kwok return -EINVAL; 19576f8d3f33SWingman Kwok 19585514174fSyuval.shaia@oracle.com phy_ethtool_ksettings_get(phy, cmd); 195986e3a040SPhilippe Reynes cmd->base.port = gbe_intf->slave->phy_port_t; 19606f8d3f33SWingman Kwok 19615514174fSyuval.shaia@oracle.com return 0; 19626f8d3f33SWingman Kwok } 19636f8d3f33SWingman Kwok 196486e3a040SPhilippe Reynes static int keystone_set_link_ksettings(struct net_device *ndev, 196586e3a040SPhilippe Reynes const struct ethtool_link_ksettings *cmd) 19666f8d3f33SWingman Kwok { 19676f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 19686f8d3f33SWingman Kwok struct phy_device *phy = ndev->phydev; 19696f8d3f33SWingman Kwok struct gbe_intf *gbe_intf; 197086e3a040SPhilippe Reynes u8 port = cmd->base.port; 197186e3a040SPhilippe Reynes u32 advertising, supported; 197286e3a040SPhilippe Reynes u32 features; 197386e3a040SPhilippe Reynes 197486e3a040SPhilippe Reynes ethtool_convert_link_mode_to_legacy_u32(&advertising, 197586e3a040SPhilippe Reynes cmd->link_modes.advertising); 197686e3a040SPhilippe Reynes ethtool_convert_link_mode_to_legacy_u32(&supported, 197786e3a040SPhilippe Reynes cmd->link_modes.supported); 197886e3a040SPhilippe Reynes features = advertising & supported; 19796f8d3f33SWingman Kwok 19806f8d3f33SWingman Kwok if (!phy) 19816f8d3f33SWingman Kwok return -EINVAL; 19826f8d3f33SWingman Kwok 1983e9838ef2SWingMan Kwok gbe_intf = keystone_get_intf_data(netcp); 19846f8d3f33SWingman Kwok if (!gbe_intf) 19856f8d3f33SWingman Kwok return -EINVAL; 19866f8d3f33SWingman Kwok 19876f8d3f33SWingman Kwok if (!gbe_intf->slave) 19886f8d3f33SWingman Kwok return -EINVAL; 19896f8d3f33SWingman Kwok 199086e3a040SPhilippe Reynes if (port != gbe_intf->slave->phy_port_t) { 199186e3a040SPhilippe Reynes if ((port == PORT_TP) && !(features & ADVERTISED_TP)) 19926f8d3f33SWingman Kwok return -EINVAL; 19936f8d3f33SWingman Kwok 199486e3a040SPhilippe Reynes if ((port == PORT_AUI) && !(features & ADVERTISED_AUI)) 19956f8d3f33SWingman Kwok return -EINVAL; 19966f8d3f33SWingman Kwok 199786e3a040SPhilippe Reynes if ((port == PORT_BNC) && !(features & ADVERTISED_BNC)) 19986f8d3f33SWingman Kwok return -EINVAL; 19996f8d3f33SWingman Kwok 200086e3a040SPhilippe Reynes if ((port == PORT_MII) && !(features & ADVERTISED_MII)) 20016f8d3f33SWingman Kwok return -EINVAL; 20026f8d3f33SWingman Kwok 200386e3a040SPhilippe Reynes if ((port == PORT_FIBRE) && !(features & ADVERTISED_FIBRE)) 20046f8d3f33SWingman Kwok return -EINVAL; 20056f8d3f33SWingman Kwok } 20066f8d3f33SWingman Kwok 200786e3a040SPhilippe Reynes gbe_intf->slave->phy_port_t = port; 200886e3a040SPhilippe Reynes return phy_ethtool_ksettings_set(phy, cmd); 20096f8d3f33SWingman Kwok } 20106f8d3f33SWingman Kwok 20116246168bSWingMan Kwok #if IS_ENABLED(CONFIG_TI_CPTS) 20126246168bSWingMan Kwok static int keystone_get_ts_info(struct net_device *ndev, 20136246168bSWingMan Kwok struct ethtool_ts_info *info) 20146246168bSWingMan Kwok { 20156246168bSWingMan Kwok struct netcp_intf *netcp = netdev_priv(ndev); 20166246168bSWingMan Kwok struct gbe_intf *gbe_intf; 20176246168bSWingMan Kwok 20186246168bSWingMan Kwok gbe_intf = netcp_module_get_intf_data(&gbe_module, netcp); 20196246168bSWingMan Kwok if (!gbe_intf || !gbe_intf->gbe_dev->cpts) 20206246168bSWingMan Kwok return -EINVAL; 20216246168bSWingMan Kwok 20226246168bSWingMan Kwok info->so_timestamping = 20236246168bSWingMan Kwok SOF_TIMESTAMPING_TX_HARDWARE | 20246246168bSWingMan Kwok SOF_TIMESTAMPING_TX_SOFTWARE | 20256246168bSWingMan Kwok SOF_TIMESTAMPING_RX_HARDWARE | 20266246168bSWingMan Kwok SOF_TIMESTAMPING_RX_SOFTWARE | 20276246168bSWingMan Kwok SOF_TIMESTAMPING_SOFTWARE | 20286246168bSWingMan Kwok SOF_TIMESTAMPING_RAW_HARDWARE; 20296246168bSWingMan Kwok info->phc_index = gbe_intf->gbe_dev->cpts->phc_index; 20306246168bSWingMan Kwok info->tx_types = 20316246168bSWingMan Kwok (1 << HWTSTAMP_TX_OFF) | 20326246168bSWingMan Kwok (1 << HWTSTAMP_TX_ON); 20336246168bSWingMan Kwok info->rx_filters = 20346246168bSWingMan Kwok (1 << HWTSTAMP_FILTER_NONE) | 20356246168bSWingMan Kwok (1 << HWTSTAMP_FILTER_PTP_V1_L4_EVENT) | 20366246168bSWingMan Kwok (1 << HWTSTAMP_FILTER_PTP_V2_EVENT); 20376246168bSWingMan Kwok return 0; 20386246168bSWingMan Kwok } 20396246168bSWingMan Kwok #else 20406246168bSWingMan Kwok static int keystone_get_ts_info(struct net_device *ndev, 20416246168bSWingMan Kwok struct ethtool_ts_info *info) 20426246168bSWingMan Kwok { 20436246168bSWingMan Kwok info->so_timestamping = 20446246168bSWingMan Kwok SOF_TIMESTAMPING_TX_SOFTWARE | 20456246168bSWingMan Kwok SOF_TIMESTAMPING_RX_SOFTWARE | 20466246168bSWingMan Kwok SOF_TIMESTAMPING_SOFTWARE; 20476246168bSWingMan Kwok info->phc_index = -1; 20486246168bSWingMan Kwok info->tx_types = 0; 20496246168bSWingMan Kwok info->rx_filters = 0; 20506246168bSWingMan Kwok return 0; 20516246168bSWingMan Kwok } 20526246168bSWingMan Kwok #endif /* CONFIG_TI_CPTS */ 20536246168bSWingMan Kwok 20546f8d3f33SWingman Kwok static const struct ethtool_ops keystone_ethtool_ops = { 20556f8d3f33SWingman Kwok .get_drvinfo = keystone_get_drvinfo, 20566f8d3f33SWingman Kwok .get_link = ethtool_op_get_link, 20576f8d3f33SWingman Kwok .get_msglevel = keystone_get_msglevel, 20586f8d3f33SWingman Kwok .set_msglevel = keystone_set_msglevel, 20596f8d3f33SWingman Kwok .get_strings = keystone_get_stat_strings, 20606f8d3f33SWingman Kwok .get_sset_count = keystone_get_sset_count, 20616f8d3f33SWingman Kwok .get_ethtool_stats = keystone_get_ethtool_stats, 206286e3a040SPhilippe Reynes .get_link_ksettings = keystone_get_link_ksettings, 206386e3a040SPhilippe Reynes .set_link_ksettings = keystone_set_link_ksettings, 20646246168bSWingMan Kwok .get_ts_info = keystone_get_ts_info, 20656f8d3f33SWingman Kwok }; 20666f8d3f33SWingman Kwok 20676f8d3f33SWingman Kwok static void gbe_set_slave_mac(struct gbe_slave *slave, 20686f8d3f33SWingman Kwok struct gbe_intf *gbe_intf) 20696f8d3f33SWingman Kwok { 20706f8d3f33SWingman Kwok struct net_device *ndev = gbe_intf->ndev; 20716f8d3f33SWingman Kwok 20726f8d3f33SWingman Kwok writel(mac_hi(ndev->dev_addr), GBE_REG_ADDR(slave, port_regs, sa_hi)); 20736f8d3f33SWingman Kwok writel(mac_lo(ndev->dev_addr), GBE_REG_ADDR(slave, port_regs, sa_lo)); 20746f8d3f33SWingman Kwok } 20756f8d3f33SWingman Kwok 20766f8d3f33SWingman Kwok static int gbe_get_slave_port(struct gbe_priv *priv, u32 slave_num) 20776f8d3f33SWingman Kwok { 20786f8d3f33SWingman Kwok if (priv->host_port == 0) 20796f8d3f33SWingman Kwok return slave_num + 1; 20806f8d3f33SWingman Kwok 20816f8d3f33SWingman Kwok return slave_num; 20826f8d3f33SWingman Kwok } 20836f8d3f33SWingman Kwok 20846f8d3f33SWingman Kwok static void netcp_ethss_link_state_action(struct gbe_priv *gbe_dev, 20856f8d3f33SWingman Kwok struct net_device *ndev, 20866f8d3f33SWingman Kwok struct gbe_slave *slave, 20876f8d3f33SWingman Kwok int up) 20886f8d3f33SWingman Kwok { 20896f8d3f33SWingman Kwok struct phy_device *phy = slave->phy; 20906f8d3f33SWingman Kwok u32 mac_control = 0; 20916f8d3f33SWingman Kwok 20926f8d3f33SWingman Kwok if (up) { 20936f8d3f33SWingman Kwok mac_control = slave->mac_control; 209490cff9e2SWingman Kwok if (phy && (phy->speed == SPEED_1000)) { 20956f8d3f33SWingman Kwok mac_control |= MACSL_GIG_MODE; 209690cff9e2SWingman Kwok mac_control &= ~MACSL_XGIG_MODE; 209790cff9e2SWingman Kwok } else if (phy && (phy->speed == SPEED_10000)) { 209890cff9e2SWingman Kwok mac_control |= MACSL_XGIG_MODE; 209990cff9e2SWingman Kwok mac_control &= ~MACSL_GIG_MODE; 210090cff9e2SWingman Kwok } 21016f8d3f33SWingman Kwok 21026f8d3f33SWingman Kwok writel(mac_control, GBE_REG_ADDR(slave, emac_regs, 21036f8d3f33SWingman Kwok mac_control)); 21046f8d3f33SWingman Kwok 21056f8d3f33SWingman Kwok cpsw_ale_control_set(gbe_dev->ale, slave->port_num, 21066f8d3f33SWingman Kwok ALE_PORT_STATE, 21076f8d3f33SWingman Kwok ALE_PORT_STATE_FORWARD); 21086f8d3f33SWingman Kwok 21098e046d68SKaricheri, Muralidharan if (ndev && slave->open && 2110478e9a5fSMurali Karicheri ((slave->link_interface != SGMII_LINK_MAC_PHY) && 2111478e9a5fSMurali Karicheri (slave->link_interface != RGMII_LINK_MAC_PHY) && 2112478e9a5fSMurali Karicheri (slave->link_interface != XGMII_LINK_MAC_PHY))) 21136f8d3f33SWingman Kwok netif_carrier_on(ndev); 21146f8d3f33SWingman Kwok } else { 21156f8d3f33SWingman Kwok writel(mac_control, GBE_REG_ADDR(slave, emac_regs, 21166f8d3f33SWingman Kwok mac_control)); 21176f8d3f33SWingman Kwok cpsw_ale_control_set(gbe_dev->ale, slave->port_num, 21186f8d3f33SWingman Kwok ALE_PORT_STATE, 21196f8d3f33SWingman Kwok ALE_PORT_STATE_DISABLE); 21208e046d68SKaricheri, Muralidharan if (ndev && 2121478e9a5fSMurali Karicheri ((slave->link_interface != SGMII_LINK_MAC_PHY) && 2122478e9a5fSMurali Karicheri (slave->link_interface != RGMII_LINK_MAC_PHY) && 2123478e9a5fSMurali Karicheri (slave->link_interface != XGMII_LINK_MAC_PHY))) 21246f8d3f33SWingman Kwok netif_carrier_off(ndev); 21256f8d3f33SWingman Kwok } 21266f8d3f33SWingman Kwok 21276f8d3f33SWingman Kwok if (phy) 21286f8d3f33SWingman Kwok phy_print_status(phy); 21296f8d3f33SWingman Kwok } 21306f8d3f33SWingman Kwok 21316f8d3f33SWingman Kwok static bool gbe_phy_link_status(struct gbe_slave *slave) 21326f8d3f33SWingman Kwok { 21336f8d3f33SWingman Kwok return !slave->phy || slave->phy->link; 21346f8d3f33SWingman Kwok } 21356f8d3f33SWingman Kwok 21367771f2b4SMurali Karicheri #define RGMII_REG_STATUS_LINK BIT(0) 21377771f2b4SMurali Karicheri 21387771f2b4SMurali Karicheri static void netcp_2u_rgmii_get_port_link(struct gbe_priv *gbe_dev, bool *status) 21397771f2b4SMurali Karicheri { 21407771f2b4SMurali Karicheri u32 val = 0; 21417771f2b4SMurali Karicheri 21427771f2b4SMurali Karicheri val = readl(GBE_REG_ADDR(gbe_dev, ss_regs, rgmii_status)); 21437771f2b4SMurali Karicheri *status = !!(val & RGMII_REG_STATUS_LINK); 21447771f2b4SMurali Karicheri } 21457771f2b4SMurali Karicheri 21466f8d3f33SWingman Kwok static void netcp_ethss_update_link_state(struct gbe_priv *gbe_dev, 21476f8d3f33SWingman Kwok struct gbe_slave *slave, 21486f8d3f33SWingman Kwok struct net_device *ndev) 21496f8d3f33SWingman Kwok { 21507771f2b4SMurali Karicheri bool sw_link_state = true, phy_link_state; 21517771f2b4SMurali Karicheri int sp = slave->slave_num, link_state; 21526f8d3f33SWingman Kwok 21536f8d3f33SWingman Kwok if (!slave->open) 21546f8d3f33SWingman Kwok return; 21556f8d3f33SWingman Kwok 21567771f2b4SMurali Karicheri if (SLAVE_LINK_IS_RGMII(slave)) 21577771f2b4SMurali Karicheri netcp_2u_rgmii_get_port_link(gbe_dev, 21587771f2b4SMurali Karicheri &sw_link_state); 21597771f2b4SMurali Karicheri if (SLAVE_LINK_IS_SGMII(slave)) 21607771f2b4SMurali Karicheri sw_link_state = 21618c85151dSWingMan Kwok netcp_sgmii_get_port_link(SGMII_BASE(gbe_dev, sp), sp); 21629a391c7bSWingMan Kwok 21636f8d3f33SWingman Kwok phy_link_state = gbe_phy_link_status(slave); 21647771f2b4SMurali Karicheri link_state = phy_link_state & sw_link_state; 21656f8d3f33SWingman Kwok 21666f8d3f33SWingman Kwok if (atomic_xchg(&slave->link_state, link_state) != link_state) 21676f8d3f33SWingman Kwok netcp_ethss_link_state_action(gbe_dev, ndev, slave, 21686f8d3f33SWingman Kwok link_state); 21696f8d3f33SWingman Kwok } 21706f8d3f33SWingman Kwok 217190cff9e2SWingman Kwok static void xgbe_adjust_link(struct net_device *ndev) 217290cff9e2SWingman Kwok { 217390cff9e2SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 217490cff9e2SWingman Kwok struct gbe_intf *gbe_intf; 217590cff9e2SWingman Kwok 217690cff9e2SWingman Kwok gbe_intf = netcp_module_get_intf_data(&xgbe_module, netcp); 217790cff9e2SWingman Kwok if (!gbe_intf) 217890cff9e2SWingman Kwok return; 217990cff9e2SWingman Kwok 218090cff9e2SWingman Kwok netcp_ethss_update_link_state(gbe_intf->gbe_dev, gbe_intf->slave, 218190cff9e2SWingman Kwok ndev); 218290cff9e2SWingman Kwok } 218390cff9e2SWingman Kwok 21846f8d3f33SWingman Kwok static void gbe_adjust_link(struct net_device *ndev) 21856f8d3f33SWingman Kwok { 21866f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 21876f8d3f33SWingman Kwok struct gbe_intf *gbe_intf; 21886f8d3f33SWingman Kwok 21896f8d3f33SWingman Kwok gbe_intf = netcp_module_get_intf_data(&gbe_module, netcp); 21906f8d3f33SWingman Kwok if (!gbe_intf) 21916f8d3f33SWingman Kwok return; 21926f8d3f33SWingman Kwok 21936f8d3f33SWingman Kwok netcp_ethss_update_link_state(gbe_intf->gbe_dev, gbe_intf->slave, 21946f8d3f33SWingman Kwok ndev); 21956f8d3f33SWingman Kwok } 21966f8d3f33SWingman Kwok 21976f8d3f33SWingman Kwok static void gbe_adjust_link_sec_slaves(struct net_device *ndev) 21986f8d3f33SWingman Kwok { 21996f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = netdev_priv(ndev); 22006f8d3f33SWingman Kwok struct gbe_slave *slave; 22016f8d3f33SWingman Kwok 22026f8d3f33SWingman Kwok for_each_sec_slave(slave, gbe_dev) 22036f8d3f33SWingman Kwok netcp_ethss_update_link_state(gbe_dev, slave, NULL); 22046f8d3f33SWingman Kwok } 22056f8d3f33SWingman Kwok 22066f8d3f33SWingman Kwok /* Reset EMAC 22076f8d3f33SWingman Kwok * Soft reset is set and polled until clear, or until a timeout occurs 22086f8d3f33SWingman Kwok */ 22096f8d3f33SWingman Kwok static int gbe_port_reset(struct gbe_slave *slave) 22106f8d3f33SWingman Kwok { 22116f8d3f33SWingman Kwok u32 i, v; 22126f8d3f33SWingman Kwok 22136f8d3f33SWingman Kwok /* Set the soft reset bit */ 22146f8d3f33SWingman Kwok writel(SOFT_RESET, GBE_REG_ADDR(slave, emac_regs, soft_reset)); 22156f8d3f33SWingman Kwok 22166f8d3f33SWingman Kwok /* Wait for the bit to clear */ 22176f8d3f33SWingman Kwok for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) { 22186f8d3f33SWingman Kwok v = readl(GBE_REG_ADDR(slave, emac_regs, soft_reset)); 22196f8d3f33SWingman Kwok if ((v & SOFT_RESET_MASK) != SOFT_RESET) 22206f8d3f33SWingman Kwok return 0; 22216f8d3f33SWingman Kwok } 22226f8d3f33SWingman Kwok 22236f8d3f33SWingman Kwok /* Timeout on the reset */ 22246f8d3f33SWingman Kwok return GMACSL_RET_WARN_RESET_INCOMPLETE; 22256f8d3f33SWingman Kwok } 22266f8d3f33SWingman Kwok 22276f8d3f33SWingman Kwok /* Configure EMAC */ 22286f8d3f33SWingman Kwok static void gbe_port_config(struct gbe_priv *gbe_dev, struct gbe_slave *slave, 22296f8d3f33SWingman Kwok int max_rx_len) 22306f8d3f33SWingman Kwok { 22319a391c7bSWingMan Kwok void __iomem *rx_maxlen_reg; 223290cff9e2SWingman Kwok u32 xgmii_mode; 223390cff9e2SWingman Kwok 22346f8d3f33SWingman Kwok if (max_rx_len > NETCP_MAX_FRAME_SIZE) 22356f8d3f33SWingman Kwok max_rx_len = NETCP_MAX_FRAME_SIZE; 22366f8d3f33SWingman Kwok 223790cff9e2SWingman Kwok /* Enable correct MII mode at SS level */ 22382953586dSMurali Karicheri if (IS_SS_ID_XGBE(gbe_dev) && 223990cff9e2SWingman Kwok (slave->link_interface >= XGMII_LINK_MAC_PHY)) { 224090cff9e2SWingman Kwok xgmii_mode = readl(GBE_REG_ADDR(gbe_dev, ss_regs, control)); 224190cff9e2SWingman Kwok xgmii_mode |= (1 << slave->slave_num); 224290cff9e2SWingman Kwok writel(xgmii_mode, GBE_REG_ADDR(gbe_dev, ss_regs, control)); 224390cff9e2SWingman Kwok } 224490cff9e2SWingman Kwok 22459a391c7bSWingMan Kwok if (IS_SS_ID_MU(gbe_dev)) 22469a391c7bSWingMan Kwok rx_maxlen_reg = GBE_REG_ADDR(slave, port_regs, rx_maxlen); 22479a391c7bSWingMan Kwok else 22489a391c7bSWingMan Kwok rx_maxlen_reg = GBE_REG_ADDR(slave, emac_regs, rx_maxlen); 22499a391c7bSWingMan Kwok 22509a391c7bSWingMan Kwok writel(max_rx_len, rx_maxlen_reg); 22516f8d3f33SWingman Kwok writel(slave->mac_control, GBE_REG_ADDR(slave, emac_regs, mac_control)); 22526f8d3f33SWingman Kwok } 22536f8d3f33SWingman Kwok 22547025e88aSWingMan Kwok static void gbe_sgmii_rtreset(struct gbe_priv *priv, 22557025e88aSWingMan Kwok struct gbe_slave *slave, bool set) 22567025e88aSWingMan Kwok { 22577025e88aSWingMan Kwok if (SLAVE_LINK_IS_XGMII(slave)) 22587025e88aSWingMan Kwok return; 22597025e88aSWingMan Kwok 22608c85151dSWingMan Kwok netcp_sgmii_rtreset(SGMII_BASE(priv, slave->slave_num), 22618c85151dSWingMan Kwok slave->slave_num, set); 22627025e88aSWingMan Kwok } 22637025e88aSWingMan Kwok 22646f8d3f33SWingman Kwok static void gbe_slave_stop(struct gbe_intf *intf) 22656f8d3f33SWingman Kwok { 22666f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = intf->gbe_dev; 22676f8d3f33SWingman Kwok struct gbe_slave *slave = intf->slave; 22686f8d3f33SWingman Kwok 2269775f9535SMurali Karicheri if (!IS_SS_ID_2U(gbe_dev)) 22707025e88aSWingMan Kwok gbe_sgmii_rtreset(gbe_dev, slave, true); 22716f8d3f33SWingman Kwok gbe_port_reset(slave); 22726f8d3f33SWingman Kwok /* Disable forwarding */ 22736f8d3f33SWingman Kwok cpsw_ale_control_set(gbe_dev->ale, slave->port_num, 22746f8d3f33SWingman Kwok ALE_PORT_STATE, ALE_PORT_STATE_DISABLE); 22756f8d3f33SWingman Kwok cpsw_ale_del_mcast(gbe_dev->ale, intf->ndev->broadcast, 22766f8d3f33SWingman Kwok 1 << slave->port_num, 0, 0); 22776f8d3f33SWingman Kwok 22786f8d3f33SWingman Kwok if (!slave->phy) 22796f8d3f33SWingman Kwok return; 22806f8d3f33SWingman Kwok 22816f8d3f33SWingman Kwok phy_stop(slave->phy); 22826f8d3f33SWingman Kwok phy_disconnect(slave->phy); 22836f8d3f33SWingman Kwok slave->phy = NULL; 22846f8d3f33SWingman Kwok } 22856f8d3f33SWingman Kwok 22866f8d3f33SWingman Kwok static void gbe_sgmii_config(struct gbe_priv *priv, struct gbe_slave *slave) 22876f8d3f33SWingman Kwok { 22888c85151dSWingMan Kwok if (SLAVE_LINK_IS_XGMII(slave)) 22898c85151dSWingMan Kwok return; 22906f8d3f33SWingman Kwok 22918c85151dSWingMan Kwok netcp_sgmii_reset(SGMII_BASE(priv, slave->slave_num), slave->slave_num); 22928c85151dSWingMan Kwok netcp_sgmii_config(SGMII_BASE(priv, slave->slave_num), slave->slave_num, 22936f8d3f33SWingman Kwok slave->link_interface); 22946f8d3f33SWingman Kwok } 22956f8d3f33SWingman Kwok 22966f8d3f33SWingman Kwok static int gbe_slave_open(struct gbe_intf *gbe_intf) 22976f8d3f33SWingman Kwok { 22986f8d3f33SWingman Kwok struct gbe_priv *priv = gbe_intf->gbe_dev; 22996f8d3f33SWingman Kwok struct gbe_slave *slave = gbe_intf->slave; 23006f8d3f33SWingman Kwok phy_interface_t phy_mode; 23016f8d3f33SWingman Kwok bool has_phy = false; 23026f8d3f33SWingman Kwok 23036f8d3f33SWingman Kwok void (*hndlr)(struct net_device *) = gbe_adjust_link; 23046f8d3f33SWingman Kwok 2305775f9535SMurali Karicheri if (!IS_SS_ID_2U(priv)) 23066f8d3f33SWingman Kwok gbe_sgmii_config(priv, slave); 23076f8d3f33SWingman Kwok gbe_port_reset(slave); 2308775f9535SMurali Karicheri if (!IS_SS_ID_2U(priv)) 23097025e88aSWingMan Kwok gbe_sgmii_rtreset(priv, slave, false); 23106f8d3f33SWingman Kwok gbe_port_config(priv, slave, priv->rx_packet_max); 23116f8d3f33SWingman Kwok gbe_set_slave_mac(slave, gbe_intf); 231265c45064SMurali Karicheri /* For NU & 2U switch, map the vlan priorities to zero 231365c45064SMurali Karicheri * as we only configure to use priority 0 231465c45064SMurali Karicheri */ 231565c45064SMurali Karicheri if (IS_SS_ID_MU(priv)) 231665c45064SMurali Karicheri writel(HOST_TX_PRI_MAP_DEFAULT, 231765c45064SMurali Karicheri GBE_REG_ADDR(slave, port_regs, rx_pri_map)); 231865c45064SMurali Karicheri 23196f8d3f33SWingman Kwok /* enable forwarding */ 23206f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, slave->port_num, 23216f8d3f33SWingman Kwok ALE_PORT_STATE, ALE_PORT_STATE_FORWARD); 23226f8d3f33SWingman Kwok cpsw_ale_add_mcast(priv->ale, gbe_intf->ndev->broadcast, 23236f8d3f33SWingman Kwok 1 << slave->port_num, 0, 0, ALE_MCAST_FWD_2); 23246f8d3f33SWingman Kwok 23256f8d3f33SWingman Kwok if (slave->link_interface == SGMII_LINK_MAC_PHY) { 23266f8d3f33SWingman Kwok has_phy = true; 23276f8d3f33SWingman Kwok phy_mode = PHY_INTERFACE_MODE_SGMII; 23286f8d3f33SWingman Kwok slave->phy_port_t = PORT_MII; 23297b647b93SMurali Karicheri } else if (slave->link_interface == RGMII_LINK_MAC_PHY) { 23307b647b93SMurali Karicheri has_phy = true; 23317b647b93SMurali Karicheri phy_mode = of_get_phy_mode(slave->node); 23327b647b93SMurali Karicheri /* if phy-mode is not present, default to 23337b647b93SMurali Karicheri * PHY_INTERFACE_MODE_RGMII 23347b647b93SMurali Karicheri */ 23357b647b93SMurali Karicheri if (phy_mode < 0) 23367b647b93SMurali Karicheri phy_mode = PHY_INTERFACE_MODE_RGMII; 23377b647b93SMurali Karicheri 23387b647b93SMurali Karicheri if (!phy_interface_mode_is_rgmii(phy_mode)) { 23397b647b93SMurali Karicheri dev_err(priv->dev, 23407b647b93SMurali Karicheri "Unsupported phy mode %d\n", phy_mode); 23417b647b93SMurali Karicheri return -EINVAL; 23427b647b93SMurali Karicheri } 23437b647b93SMurali Karicheri slave->phy_port_t = PORT_MII; 23446f8d3f33SWingman Kwok } else if (slave->link_interface == XGMII_LINK_MAC_PHY) { 23456f8d3f33SWingman Kwok has_phy = true; 23466f8d3f33SWingman Kwok phy_mode = PHY_INTERFACE_MODE_NA; 23476f8d3f33SWingman Kwok slave->phy_port_t = PORT_FIBRE; 23486f8d3f33SWingman Kwok } 23496f8d3f33SWingman Kwok 23506f8d3f33SWingman Kwok if (has_phy) { 23512953586dSMurali Karicheri if (IS_SS_ID_XGBE(priv)) 235290cff9e2SWingman Kwok hndlr = xgbe_adjust_link; 235390cff9e2SWingman Kwok 23546f8d3f33SWingman Kwok slave->phy = of_phy_connect(gbe_intf->ndev, 23556f8d3f33SWingman Kwok slave->phy_node, 23566f8d3f33SWingman Kwok hndlr, 0, 23576f8d3f33SWingman Kwok phy_mode); 23586f8d3f33SWingman Kwok if (!slave->phy) { 23596f8d3f33SWingman Kwok dev_err(priv->dev, "phy not found on slave %d\n", 23606f8d3f33SWingman Kwok slave->slave_num); 23616f8d3f33SWingman Kwok return -ENODEV; 23626f8d3f33SWingman Kwok } 23636f8d3f33SWingman Kwok dev_dbg(priv->dev, "phy found: id is: 0x%s\n", 236484eff6d1SAndrew Lunn phydev_name(slave->phy)); 23656f8d3f33SWingman Kwok phy_start(slave->phy); 23666f8d3f33SWingman Kwok } 23676f8d3f33SWingman Kwok return 0; 23686f8d3f33SWingman Kwok } 23696f8d3f33SWingman Kwok 23706f8d3f33SWingman Kwok static void gbe_init_host_port(struct gbe_priv *priv) 23716f8d3f33SWingman Kwok { 23726f8d3f33SWingman Kwok int bypass_en = 1; 23739a391c7bSWingMan Kwok 23749a391c7bSWingMan Kwok /* Host Tx Pri */ 23754c0ef231SWingMan Kwok if (IS_SS_ID_NU(priv) || IS_SS_ID_XGBE(priv)) 23769a391c7bSWingMan Kwok writel(HOST_TX_PRI_MAP_DEFAULT, 23779a391c7bSWingMan Kwok GBE_REG_ADDR(priv, host_port_regs, tx_pri_map)); 23789a391c7bSWingMan Kwok 23796f8d3f33SWingman Kwok /* Max length register */ 23806f8d3f33SWingman Kwok writel(NETCP_MAX_FRAME_SIZE, GBE_REG_ADDR(priv, host_port_regs, 23816f8d3f33SWingman Kwok rx_maxlen)); 23826f8d3f33SWingman Kwok 23836f8d3f33SWingman Kwok cpsw_ale_start(priv->ale); 23846f8d3f33SWingman Kwok 23856f8d3f33SWingman Kwok if (priv->enable_ale) 23866f8d3f33SWingman Kwok bypass_en = 0; 23876f8d3f33SWingman Kwok 23886f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, 0, ALE_BYPASS, bypass_en); 23896f8d3f33SWingman Kwok 23906f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, 0, ALE_NO_PORT_VLAN, 1); 23916f8d3f33SWingman Kwok 23926f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, priv->host_port, 23936f8d3f33SWingman Kwok ALE_PORT_STATE, ALE_PORT_STATE_FORWARD); 23946f8d3f33SWingman Kwok 23956f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, 0, 23966f8d3f33SWingman Kwok ALE_PORT_UNKNOWN_VLAN_MEMBER, 23976f8d3f33SWingman Kwok GBE_PORT_MASK(priv->ale_ports)); 23986f8d3f33SWingman Kwok 23996f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, 0, 24006f8d3f33SWingman Kwok ALE_PORT_UNKNOWN_MCAST_FLOOD, 24016f8d3f33SWingman Kwok GBE_PORT_MASK(priv->ale_ports - 1)); 24026f8d3f33SWingman Kwok 24036f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, 0, 24046f8d3f33SWingman Kwok ALE_PORT_UNKNOWN_REG_MCAST_FLOOD, 24056f8d3f33SWingman Kwok GBE_PORT_MASK(priv->ale_ports)); 24066f8d3f33SWingman Kwok 24076f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, 0, 24086f8d3f33SWingman Kwok ALE_PORT_UNTAGGED_EGRESS, 24096f8d3f33SWingman Kwok GBE_PORT_MASK(priv->ale_ports)); 24106f8d3f33SWingman Kwok } 24116f8d3f33SWingman Kwok 24126f8d3f33SWingman Kwok static void gbe_add_mcast_addr(struct gbe_intf *gbe_intf, u8 *addr) 24136f8d3f33SWingman Kwok { 24146f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 24156f8d3f33SWingman Kwok u16 vlan_id; 24166f8d3f33SWingman Kwok 24176f8d3f33SWingman Kwok cpsw_ale_add_mcast(gbe_dev->ale, addr, 24186f8d3f33SWingman Kwok GBE_PORT_MASK(gbe_dev->ale_ports), 0, 0, 24196f8d3f33SWingman Kwok ALE_MCAST_FWD_2); 24206f8d3f33SWingman Kwok for_each_set_bit(vlan_id, gbe_intf->active_vlans, VLAN_N_VID) { 24216f8d3f33SWingman Kwok cpsw_ale_add_mcast(gbe_dev->ale, addr, 24226f8d3f33SWingman Kwok GBE_PORT_MASK(gbe_dev->ale_ports), 24236f8d3f33SWingman Kwok ALE_VLAN, vlan_id, ALE_MCAST_FWD_2); 24246f8d3f33SWingman Kwok } 24256f8d3f33SWingman Kwok } 24266f8d3f33SWingman Kwok 24276f8d3f33SWingman Kwok static void gbe_add_ucast_addr(struct gbe_intf *gbe_intf, u8 *addr) 24286f8d3f33SWingman Kwok { 24296f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 24306f8d3f33SWingman Kwok u16 vlan_id; 24316f8d3f33SWingman Kwok 24326f8d3f33SWingman Kwok cpsw_ale_add_ucast(gbe_dev->ale, addr, gbe_dev->host_port, 0, 0); 24336f8d3f33SWingman Kwok 24346f8d3f33SWingman Kwok for_each_set_bit(vlan_id, gbe_intf->active_vlans, VLAN_N_VID) 24356f8d3f33SWingman Kwok cpsw_ale_add_ucast(gbe_dev->ale, addr, gbe_dev->host_port, 24366f8d3f33SWingman Kwok ALE_VLAN, vlan_id); 24376f8d3f33SWingman Kwok } 24386f8d3f33SWingman Kwok 24396f8d3f33SWingman Kwok static void gbe_del_mcast_addr(struct gbe_intf *gbe_intf, u8 *addr) 24406f8d3f33SWingman Kwok { 24416f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 24426f8d3f33SWingman Kwok u16 vlan_id; 24436f8d3f33SWingman Kwok 24446f8d3f33SWingman Kwok cpsw_ale_del_mcast(gbe_dev->ale, addr, 0, 0, 0); 24456f8d3f33SWingman Kwok 24466f8d3f33SWingman Kwok for_each_set_bit(vlan_id, gbe_intf->active_vlans, VLAN_N_VID) { 24476f8d3f33SWingman Kwok cpsw_ale_del_mcast(gbe_dev->ale, addr, 0, ALE_VLAN, vlan_id); 24486f8d3f33SWingman Kwok } 24496f8d3f33SWingman Kwok } 24506f8d3f33SWingman Kwok 24516f8d3f33SWingman Kwok static void gbe_del_ucast_addr(struct gbe_intf *gbe_intf, u8 *addr) 24526f8d3f33SWingman Kwok { 24536f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 24546f8d3f33SWingman Kwok u16 vlan_id; 24556f8d3f33SWingman Kwok 24566f8d3f33SWingman Kwok cpsw_ale_del_ucast(gbe_dev->ale, addr, gbe_dev->host_port, 0, 0); 24576f8d3f33SWingman Kwok 24586f8d3f33SWingman Kwok for_each_set_bit(vlan_id, gbe_intf->active_vlans, VLAN_N_VID) { 24596f8d3f33SWingman Kwok cpsw_ale_del_ucast(gbe_dev->ale, addr, gbe_dev->host_port, 24606f8d3f33SWingman Kwok ALE_VLAN, vlan_id); 24616f8d3f33SWingman Kwok } 24626f8d3f33SWingman Kwok } 24636f8d3f33SWingman Kwok 24646f8d3f33SWingman Kwok static int gbe_add_addr(void *intf_priv, struct netcp_addr *naddr) 24656f8d3f33SWingman Kwok { 24666f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv; 24676f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 24686f8d3f33SWingman Kwok 24696f8d3f33SWingman Kwok dev_dbg(gbe_dev->dev, "ethss adding address %pM, type %d\n", 24706f8d3f33SWingman Kwok naddr->addr, naddr->type); 24716f8d3f33SWingman Kwok 24726f8d3f33SWingman Kwok switch (naddr->type) { 24736f8d3f33SWingman Kwok case ADDR_MCAST: 24746f8d3f33SWingman Kwok case ADDR_BCAST: 24756f8d3f33SWingman Kwok gbe_add_mcast_addr(gbe_intf, naddr->addr); 24766f8d3f33SWingman Kwok break; 24776f8d3f33SWingman Kwok case ADDR_UCAST: 24786f8d3f33SWingman Kwok case ADDR_DEV: 24796f8d3f33SWingman Kwok gbe_add_ucast_addr(gbe_intf, naddr->addr); 24806f8d3f33SWingman Kwok break; 24816f8d3f33SWingman Kwok case ADDR_ANY: 24826f8d3f33SWingman Kwok /* nothing to do for promiscuous */ 24836f8d3f33SWingman Kwok default: 24846f8d3f33SWingman Kwok break; 24856f8d3f33SWingman Kwok } 24866f8d3f33SWingman Kwok 24876f8d3f33SWingman Kwok return 0; 24886f8d3f33SWingman Kwok } 24896f8d3f33SWingman Kwok 24906f8d3f33SWingman Kwok static int gbe_del_addr(void *intf_priv, struct netcp_addr *naddr) 24916f8d3f33SWingman Kwok { 24926f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv; 24936f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 24946f8d3f33SWingman Kwok 24956f8d3f33SWingman Kwok dev_dbg(gbe_dev->dev, "ethss deleting address %pM, type %d\n", 24966f8d3f33SWingman Kwok naddr->addr, naddr->type); 24976f8d3f33SWingman Kwok 24986f8d3f33SWingman Kwok switch (naddr->type) { 24996f8d3f33SWingman Kwok case ADDR_MCAST: 25006f8d3f33SWingman Kwok case ADDR_BCAST: 25016f8d3f33SWingman Kwok gbe_del_mcast_addr(gbe_intf, naddr->addr); 25026f8d3f33SWingman Kwok break; 25036f8d3f33SWingman Kwok case ADDR_UCAST: 25046f8d3f33SWingman Kwok case ADDR_DEV: 25056f8d3f33SWingman Kwok gbe_del_ucast_addr(gbe_intf, naddr->addr); 25066f8d3f33SWingman Kwok break; 25076f8d3f33SWingman Kwok case ADDR_ANY: 25086f8d3f33SWingman Kwok /* nothing to do for promiscuous */ 25096f8d3f33SWingman Kwok default: 25106f8d3f33SWingman Kwok break; 25116f8d3f33SWingman Kwok } 25126f8d3f33SWingman Kwok 25136f8d3f33SWingman Kwok return 0; 25146f8d3f33SWingman Kwok } 25156f8d3f33SWingman Kwok 25166f8d3f33SWingman Kwok static int gbe_add_vid(void *intf_priv, int vid) 25176f8d3f33SWingman Kwok { 25186f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv; 25196f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 25206f8d3f33SWingman Kwok 25216f8d3f33SWingman Kwok set_bit(vid, gbe_intf->active_vlans); 25226f8d3f33SWingman Kwok 25236f8d3f33SWingman Kwok cpsw_ale_add_vlan(gbe_dev->ale, vid, 25246f8d3f33SWingman Kwok GBE_PORT_MASK(gbe_dev->ale_ports), 25256f8d3f33SWingman Kwok GBE_MASK_NO_PORTS, 25266f8d3f33SWingman Kwok GBE_PORT_MASK(gbe_dev->ale_ports), 25276f8d3f33SWingman Kwok GBE_PORT_MASK(gbe_dev->ale_ports - 1)); 25286f8d3f33SWingman Kwok 25296f8d3f33SWingman Kwok return 0; 25306f8d3f33SWingman Kwok } 25316f8d3f33SWingman Kwok 25326f8d3f33SWingman Kwok static int gbe_del_vid(void *intf_priv, int vid) 25336f8d3f33SWingman Kwok { 25346f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv; 25356f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 25366f8d3f33SWingman Kwok 25376f8d3f33SWingman Kwok cpsw_ale_del_vlan(gbe_dev->ale, vid, 0); 25386f8d3f33SWingman Kwok clear_bit(vid, gbe_intf->active_vlans); 25396f8d3f33SWingman Kwok return 0; 25406f8d3f33SWingman Kwok } 25416f8d3f33SWingman Kwok 25426246168bSWingMan Kwok #if IS_ENABLED(CONFIG_TI_CPTS) 25436246168bSWingMan Kwok #define HAS_PHY_TXTSTAMP(p) ((p)->drv && (p)->drv->txtstamp) 25446246168bSWingMan Kwok #define HAS_PHY_RXTSTAMP(p) ((p)->drv && (p)->drv->rxtstamp) 25456246168bSWingMan Kwok 25466246168bSWingMan Kwok static void gbe_txtstamp(void *context, struct sk_buff *skb) 25476246168bSWingMan Kwok { 25486246168bSWingMan Kwok struct gbe_intf *gbe_intf = context; 25496246168bSWingMan Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 25506246168bSWingMan Kwok 25516246168bSWingMan Kwok cpts_tx_timestamp(gbe_dev->cpts, skb); 25526246168bSWingMan Kwok } 25536246168bSWingMan Kwok 25546246168bSWingMan Kwok static bool gbe_need_txtstamp(struct gbe_intf *gbe_intf, 25556246168bSWingMan Kwok const struct netcp_packet *p_info) 25566246168bSWingMan Kwok { 25576246168bSWingMan Kwok struct sk_buff *skb = p_info->skb; 25586246168bSWingMan Kwok 25590ccf59baSIvan Khoronzhuk return cpts_can_timestamp(gbe_intf->gbe_dev->cpts, skb); 25606246168bSWingMan Kwok } 25616246168bSWingMan Kwok 25626246168bSWingMan Kwok static int gbe_txtstamp_mark_pkt(struct gbe_intf *gbe_intf, 25636246168bSWingMan Kwok struct netcp_packet *p_info) 25646246168bSWingMan Kwok { 25656246168bSWingMan Kwok struct phy_device *phydev = p_info->skb->dev->phydev; 25666246168bSWingMan Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 25676246168bSWingMan Kwok 25686246168bSWingMan Kwok if (!(skb_shinfo(p_info->skb)->tx_flags & SKBTX_HW_TSTAMP) || 2569a9423120SIvan Khoronzhuk !gbe_dev->tx_ts_enabled) 25706246168bSWingMan Kwok return 0; 25716246168bSWingMan Kwok 25726246168bSWingMan Kwok /* If phy has the txtstamp api, assume it will do it. 25736246168bSWingMan Kwok * We mark it here because skb_tx_timestamp() is called 25746246168bSWingMan Kwok * after all the txhooks are called. 25756246168bSWingMan Kwok */ 25766246168bSWingMan Kwok if (phydev && HAS_PHY_TXTSTAMP(phydev)) { 25776246168bSWingMan Kwok skb_shinfo(p_info->skb)->tx_flags |= SKBTX_IN_PROGRESS; 25786246168bSWingMan Kwok return 0; 25796246168bSWingMan Kwok } 25806246168bSWingMan Kwok 25816246168bSWingMan Kwok if (gbe_need_txtstamp(gbe_intf, p_info)) { 25826246168bSWingMan Kwok p_info->txtstamp = gbe_txtstamp; 25836246168bSWingMan Kwok p_info->ts_context = (void *)gbe_intf; 25846246168bSWingMan Kwok skb_shinfo(p_info->skb)->tx_flags |= SKBTX_IN_PROGRESS; 25856246168bSWingMan Kwok } 25866246168bSWingMan Kwok 25876246168bSWingMan Kwok return 0; 25886246168bSWingMan Kwok } 25896246168bSWingMan Kwok 25906246168bSWingMan Kwok static int gbe_rxtstamp(struct gbe_intf *gbe_intf, struct netcp_packet *p_info) 25916246168bSWingMan Kwok { 25926246168bSWingMan Kwok struct phy_device *phydev = p_info->skb->dev->phydev; 25936246168bSWingMan Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 25946246168bSWingMan Kwok 25956246168bSWingMan Kwok if (p_info->rxtstamp_complete) 25966246168bSWingMan Kwok return 0; 25976246168bSWingMan Kwok 25986246168bSWingMan Kwok if (phydev && HAS_PHY_RXTSTAMP(phydev)) { 25996246168bSWingMan Kwok p_info->rxtstamp_complete = true; 26006246168bSWingMan Kwok return 0; 26016246168bSWingMan Kwok } 26026246168bSWingMan Kwok 2603a9423120SIvan Khoronzhuk if (gbe_dev->rx_ts_enabled) 26046246168bSWingMan Kwok cpts_rx_timestamp(gbe_dev->cpts, p_info->skb); 2605a9423120SIvan Khoronzhuk 26066246168bSWingMan Kwok p_info->rxtstamp_complete = true; 26076246168bSWingMan Kwok 26086246168bSWingMan Kwok return 0; 26096246168bSWingMan Kwok } 26106246168bSWingMan Kwok 26116246168bSWingMan Kwok static int gbe_hwtstamp_get(struct gbe_intf *gbe_intf, struct ifreq *ifr) 26126246168bSWingMan Kwok { 26136246168bSWingMan Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 26146246168bSWingMan Kwok struct cpts *cpts = gbe_dev->cpts; 26156246168bSWingMan Kwok struct hwtstamp_config cfg; 26166246168bSWingMan Kwok 26176246168bSWingMan Kwok if (!cpts) 26186246168bSWingMan Kwok return -EOPNOTSUPP; 26196246168bSWingMan Kwok 26206246168bSWingMan Kwok cfg.flags = 0; 2621a9423120SIvan Khoronzhuk cfg.tx_type = gbe_dev->tx_ts_enabled ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF; 2622a9423120SIvan Khoronzhuk cfg.rx_filter = gbe_dev->rx_ts_enabled; 26236246168bSWingMan Kwok 26246246168bSWingMan Kwok return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0; 26256246168bSWingMan Kwok } 26266246168bSWingMan Kwok 26276246168bSWingMan Kwok static void gbe_hwtstamp(struct gbe_intf *gbe_intf) 26286246168bSWingMan Kwok { 26296246168bSWingMan Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 26306246168bSWingMan Kwok struct gbe_slave *slave = gbe_intf->slave; 26316246168bSWingMan Kwok u32 ts_en, seq_id, ctl; 26326246168bSWingMan Kwok 2633a9423120SIvan Khoronzhuk if (!gbe_dev->rx_ts_enabled && 2634a9423120SIvan Khoronzhuk !gbe_dev->tx_ts_enabled) { 26356246168bSWingMan Kwok writel(0, GBE_REG_ADDR(slave, port_regs, ts_ctl)); 26366246168bSWingMan Kwok return; 26376246168bSWingMan Kwok } 26386246168bSWingMan Kwok 26396246168bSWingMan Kwok seq_id = (30 << TS_SEQ_ID_OFS_SHIFT) | ETH_P_1588; 26406246168bSWingMan Kwok ts_en = EVENT_MSG_BITS << TS_MSG_TYPE_EN_SHIFT; 26416246168bSWingMan Kwok ctl = ETH_P_1588 | TS_TTL_NONZERO | 26426246168bSWingMan Kwok (slave->ts_ctl.dst_port_map << TS_CTL_DST_PORT_SHIFT) | 26436246168bSWingMan Kwok (slave->ts_ctl.uni ? TS_UNI_EN : 26446246168bSWingMan Kwok slave->ts_ctl.maddr_map << TS_CTL_MADDR_SHIFT); 26456246168bSWingMan Kwok 2646a9423120SIvan Khoronzhuk if (gbe_dev->tx_ts_enabled) 26476246168bSWingMan Kwok ts_en |= (TS_TX_ANX_ALL_EN | TS_TX_VLAN_LT1_EN); 26486246168bSWingMan Kwok 2649a9423120SIvan Khoronzhuk if (gbe_dev->rx_ts_enabled) 26506246168bSWingMan Kwok ts_en |= (TS_RX_ANX_ALL_EN | TS_RX_VLAN_LT1_EN); 26516246168bSWingMan Kwok 26526246168bSWingMan Kwok writel(ts_en, GBE_REG_ADDR(slave, port_regs, ts_ctl)); 26536246168bSWingMan Kwok writel(seq_id, GBE_REG_ADDR(slave, port_regs, ts_seq_ltype)); 26546246168bSWingMan Kwok writel(ctl, GBE_REG_ADDR(slave, port_regs, ts_ctl_ltype2)); 26556246168bSWingMan Kwok } 26566246168bSWingMan Kwok 26576246168bSWingMan Kwok static int gbe_hwtstamp_set(struct gbe_intf *gbe_intf, struct ifreq *ifr) 26586246168bSWingMan Kwok { 26596246168bSWingMan Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 26606246168bSWingMan Kwok struct cpts *cpts = gbe_dev->cpts; 26616246168bSWingMan Kwok struct hwtstamp_config cfg; 26626246168bSWingMan Kwok 26636246168bSWingMan Kwok if (!cpts) 26646246168bSWingMan Kwok return -EOPNOTSUPP; 26656246168bSWingMan Kwok 26666246168bSWingMan Kwok if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg))) 26676246168bSWingMan Kwok return -EFAULT; 26686246168bSWingMan Kwok 26696246168bSWingMan Kwok /* reserved for future extensions */ 26706246168bSWingMan Kwok if (cfg.flags) 26716246168bSWingMan Kwok return -EINVAL; 26726246168bSWingMan Kwok 26736246168bSWingMan Kwok switch (cfg.tx_type) { 26746246168bSWingMan Kwok case HWTSTAMP_TX_OFF: 2675a9423120SIvan Khoronzhuk gbe_dev->tx_ts_enabled = 0; 26766246168bSWingMan Kwok break; 26776246168bSWingMan Kwok case HWTSTAMP_TX_ON: 2678a9423120SIvan Khoronzhuk gbe_dev->tx_ts_enabled = 1; 26796246168bSWingMan Kwok break; 26806246168bSWingMan Kwok default: 26816246168bSWingMan Kwok return -ERANGE; 26826246168bSWingMan Kwok } 26836246168bSWingMan Kwok 26846246168bSWingMan Kwok switch (cfg.rx_filter) { 26856246168bSWingMan Kwok case HWTSTAMP_FILTER_NONE: 2686a9423120SIvan Khoronzhuk gbe_dev->rx_ts_enabled = HWTSTAMP_FILTER_NONE; 26876246168bSWingMan Kwok break; 26886246168bSWingMan Kwok case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: 26896246168bSWingMan Kwok case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: 26906246168bSWingMan Kwok case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: 2691a9423120SIvan Khoronzhuk gbe_dev->rx_ts_enabled = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; 26926246168bSWingMan Kwok cfg.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; 26936246168bSWingMan Kwok break; 26946246168bSWingMan Kwok case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: 26956246168bSWingMan Kwok case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: 26966246168bSWingMan Kwok case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: 26976246168bSWingMan Kwok case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: 26986246168bSWingMan Kwok case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: 26996246168bSWingMan Kwok case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: 27006246168bSWingMan Kwok case HWTSTAMP_FILTER_PTP_V2_EVENT: 27016246168bSWingMan Kwok case HWTSTAMP_FILTER_PTP_V2_SYNC: 27026246168bSWingMan Kwok case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: 2703a9423120SIvan Khoronzhuk gbe_dev->rx_ts_enabled = HWTSTAMP_FILTER_PTP_V2_EVENT; 27046246168bSWingMan Kwok cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; 27056246168bSWingMan Kwok break; 27066246168bSWingMan Kwok default: 27076246168bSWingMan Kwok return -ERANGE; 27086246168bSWingMan Kwok } 27096246168bSWingMan Kwok 27106246168bSWingMan Kwok gbe_hwtstamp(gbe_intf); 27116246168bSWingMan Kwok 27126246168bSWingMan Kwok return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0; 27136246168bSWingMan Kwok } 27146246168bSWingMan Kwok 27156246168bSWingMan Kwok static void gbe_register_cpts(struct gbe_priv *gbe_dev) 27166246168bSWingMan Kwok { 27176246168bSWingMan Kwok if (!gbe_dev->cpts) 27186246168bSWingMan Kwok return; 27196246168bSWingMan Kwok 27206246168bSWingMan Kwok if (gbe_dev->cpts_registered > 0) 27216246168bSWingMan Kwok goto done; 27226246168bSWingMan Kwok 27236246168bSWingMan Kwok if (cpts_register(gbe_dev->cpts)) { 27246246168bSWingMan Kwok dev_err(gbe_dev->dev, "error registering cpts device\n"); 27256246168bSWingMan Kwok return; 27266246168bSWingMan Kwok } 27276246168bSWingMan Kwok 27286246168bSWingMan Kwok done: 27296246168bSWingMan Kwok ++gbe_dev->cpts_registered; 27306246168bSWingMan Kwok } 27316246168bSWingMan Kwok 27326246168bSWingMan Kwok static void gbe_unregister_cpts(struct gbe_priv *gbe_dev) 27336246168bSWingMan Kwok { 27346246168bSWingMan Kwok if (!gbe_dev->cpts || (gbe_dev->cpts_registered <= 0)) 27356246168bSWingMan Kwok return; 27366246168bSWingMan Kwok 27376246168bSWingMan Kwok if (--gbe_dev->cpts_registered) 27386246168bSWingMan Kwok return; 27396246168bSWingMan Kwok 27406246168bSWingMan Kwok cpts_unregister(gbe_dev->cpts); 27416246168bSWingMan Kwok } 27426246168bSWingMan Kwok #else 27436246168bSWingMan Kwok static inline int gbe_txtstamp_mark_pkt(struct gbe_intf *gbe_intf, 27446246168bSWingMan Kwok struct netcp_packet *p_info) 27456246168bSWingMan Kwok { 27466246168bSWingMan Kwok return 0; 27476246168bSWingMan Kwok } 27486246168bSWingMan Kwok 27496246168bSWingMan Kwok static inline int gbe_rxtstamp(struct gbe_intf *gbe_intf, 27506246168bSWingMan Kwok struct netcp_packet *p_info) 27516246168bSWingMan Kwok { 27526246168bSWingMan Kwok return 0; 27536246168bSWingMan Kwok } 27546246168bSWingMan Kwok 27556246168bSWingMan Kwok static inline int gbe_hwtstamp(struct gbe_intf *gbe_intf, 27566246168bSWingMan Kwok struct ifreq *ifr, int cmd) 27576246168bSWingMan Kwok { 27586246168bSWingMan Kwok return -EOPNOTSUPP; 27596246168bSWingMan Kwok } 27606246168bSWingMan Kwok 27616246168bSWingMan Kwok static inline void gbe_register_cpts(struct gbe_priv *gbe_dev) 27626246168bSWingMan Kwok { 27636246168bSWingMan Kwok } 27646246168bSWingMan Kwok 27656246168bSWingMan Kwok static inline void gbe_unregister_cpts(struct gbe_priv *gbe_dev) 27666246168bSWingMan Kwok { 27676246168bSWingMan Kwok } 27686246168bSWingMan Kwok 27696246168bSWingMan Kwok static inline int gbe_hwtstamp_get(struct gbe_intf *gbe_intf, struct ifreq *req) 27706246168bSWingMan Kwok { 27716246168bSWingMan Kwok return -EOPNOTSUPP; 27726246168bSWingMan Kwok } 27736246168bSWingMan Kwok 27746246168bSWingMan Kwok static inline int gbe_hwtstamp_set(struct gbe_intf *gbe_intf, struct ifreq *req) 27756246168bSWingMan Kwok { 27766246168bSWingMan Kwok return -EOPNOTSUPP; 27776246168bSWingMan Kwok } 27786246168bSWingMan Kwok #endif /* CONFIG_TI_CPTS */ 27796246168bSWingMan Kwok 27808585661bSWingMan Kwok static int gbe_set_rx_mode(void *intf_priv, bool promisc) 27818585661bSWingMan Kwok { 27828585661bSWingMan Kwok struct gbe_intf *gbe_intf = intf_priv; 27838585661bSWingMan Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 27848585661bSWingMan Kwok struct cpsw_ale *ale = gbe_dev->ale; 27858585661bSWingMan Kwok unsigned long timeout; 27868585661bSWingMan Kwok int i, ret = -ETIMEDOUT; 27878585661bSWingMan Kwok 27888585661bSWingMan Kwok /* Disable(1)/Enable(0) Learn for all ports (host is port 0 and 27898585661bSWingMan Kwok * slaves are port 1 and up 27908585661bSWingMan Kwok */ 27918585661bSWingMan Kwok for (i = 0; i <= gbe_dev->num_slaves; i++) { 27928585661bSWingMan Kwok cpsw_ale_control_set(ale, i, 27938585661bSWingMan Kwok ALE_PORT_NOLEARN, !!promisc); 27948585661bSWingMan Kwok cpsw_ale_control_set(ale, i, 27958585661bSWingMan Kwok ALE_PORT_NO_SA_UPDATE, !!promisc); 27968585661bSWingMan Kwok } 27978585661bSWingMan Kwok 27988585661bSWingMan Kwok if (!promisc) { 27998585661bSWingMan Kwok /* Don't Flood All Unicast Packets to Host port */ 28008585661bSWingMan Kwok cpsw_ale_control_set(ale, 0, ALE_P0_UNI_FLOOD, 0); 28018585661bSWingMan Kwok dev_vdbg(gbe_dev->dev, "promiscuous mode disabled\n"); 28028585661bSWingMan Kwok return 0; 28038585661bSWingMan Kwok } 28048585661bSWingMan Kwok 28058585661bSWingMan Kwok timeout = jiffies + HZ; 28068585661bSWingMan Kwok 28078585661bSWingMan Kwok /* Clear All Untouched entries */ 28088585661bSWingMan Kwok cpsw_ale_control_set(ale, 0, ALE_AGEOUT, 1); 28098585661bSWingMan Kwok do { 28108585661bSWingMan Kwok cpu_relax(); 28118585661bSWingMan Kwok if (cpsw_ale_control_get(ale, 0, ALE_AGEOUT)) { 28128585661bSWingMan Kwok ret = 0; 28138585661bSWingMan Kwok break; 28148585661bSWingMan Kwok } 28158585661bSWingMan Kwok 28168585661bSWingMan Kwok } while (time_after(timeout, jiffies)); 28178585661bSWingMan Kwok 28188585661bSWingMan Kwok /* Make sure it is not a false timeout */ 28198585661bSWingMan Kwok if (ret && !cpsw_ale_control_get(ale, 0, ALE_AGEOUT)) 28208585661bSWingMan Kwok return ret; 28218585661bSWingMan Kwok 28228585661bSWingMan Kwok cpsw_ale_control_set(ale, 0, ALE_AGEOUT, 1); 28238585661bSWingMan Kwok 28248585661bSWingMan Kwok /* Clear all mcast from ALE */ 28258585661bSWingMan Kwok cpsw_ale_flush_multicast(ale, 28268585661bSWingMan Kwok GBE_PORT_MASK(gbe_dev->ale_ports), 28278585661bSWingMan Kwok -1); 28288585661bSWingMan Kwok 28298585661bSWingMan Kwok /* Flood All Unicast Packets to Host port */ 28308585661bSWingMan Kwok cpsw_ale_control_set(ale, 0, ALE_P0_UNI_FLOOD, 1); 28318585661bSWingMan Kwok dev_vdbg(gbe_dev->dev, "promiscuous mode enabled\n"); 28328585661bSWingMan Kwok return ret; 28338585661bSWingMan Kwok } 28348585661bSWingMan Kwok 28356f8d3f33SWingman Kwok static int gbe_ioctl(void *intf_priv, struct ifreq *req, int cmd) 28366f8d3f33SWingman Kwok { 28376f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv; 28386f8d3f33SWingman Kwok struct phy_device *phy = gbe_intf->slave->phy; 28396246168bSWingMan Kwok 28406246168bSWingMan Kwok if (!phy || !phy->drv->hwtstamp) { 28416246168bSWingMan Kwok switch (cmd) { 28426246168bSWingMan Kwok case SIOCGHWTSTAMP: 28436246168bSWingMan Kwok return gbe_hwtstamp_get(gbe_intf, req); 28446246168bSWingMan Kwok case SIOCSHWTSTAMP: 28456246168bSWingMan Kwok return gbe_hwtstamp_set(gbe_intf, req); 28466246168bSWingMan Kwok } 28476246168bSWingMan Kwok } 28486f8d3f33SWingman Kwok 28496f8d3f33SWingman Kwok if (phy) 28506246168bSWingMan Kwok return phy_mii_ioctl(phy, req, cmd); 28516f8d3f33SWingman Kwok 28526246168bSWingMan Kwok return -EOPNOTSUPP; 28536f8d3f33SWingman Kwok } 28546f8d3f33SWingman Kwok 2855e99e88a9SKees Cook static void netcp_ethss_timer(struct timer_list *t) 28566f8d3f33SWingman Kwok { 2857e99e88a9SKees Cook struct gbe_priv *gbe_dev = from_timer(gbe_dev, t, timer); 28586f8d3f33SWingman Kwok struct gbe_intf *gbe_intf; 28596f8d3f33SWingman Kwok struct gbe_slave *slave; 28606f8d3f33SWingman Kwok 28616f8d3f33SWingman Kwok /* Check & update SGMII link state of interfaces */ 28626f8d3f33SWingman Kwok for_each_intf(gbe_intf, gbe_dev) { 28636f8d3f33SWingman Kwok if (!gbe_intf->slave->open) 28646f8d3f33SWingman Kwok continue; 28656f8d3f33SWingman Kwok netcp_ethss_update_link_state(gbe_dev, gbe_intf->slave, 28666f8d3f33SWingman Kwok gbe_intf->ndev); 28676f8d3f33SWingman Kwok } 28686f8d3f33SWingman Kwok 28696f8d3f33SWingman Kwok /* Check & update SGMII link state of secondary ports */ 28706f8d3f33SWingman Kwok for_each_sec_slave(slave, gbe_dev) { 28716f8d3f33SWingman Kwok netcp_ethss_update_link_state(gbe_dev, slave, NULL); 28726f8d3f33SWingman Kwok } 28736f8d3f33SWingman Kwok 2874c0f54edbSWingMan Kwok /* A timer runs as a BH, no need to block them */ 2875c0f54edbSWingMan Kwok spin_lock(&gbe_dev->hw_stats_lock); 28766f8d3f33SWingman Kwok 28772953586dSMurali Karicheri if (IS_SS_ID_VER_14(gbe_dev)) 28786f8d3f33SWingman Kwok gbe_update_stats_ver14(gbe_dev, NULL); 28796f8d3f33SWingman Kwok else 28806f8d3f33SWingman Kwok gbe_update_stats(gbe_dev, NULL); 28816f8d3f33SWingman Kwok 2882c0f54edbSWingMan Kwok spin_unlock(&gbe_dev->hw_stats_lock); 28836f8d3f33SWingman Kwok 28846f8d3f33SWingman Kwok gbe_dev->timer.expires = jiffies + GBE_TIMER_INTERVAL; 28856f8d3f33SWingman Kwok add_timer(&gbe_dev->timer); 28866f8d3f33SWingman Kwok } 28876f8d3f33SWingman Kwok 28886246168bSWingMan Kwok static int gbe_txhook(int order, void *data, struct netcp_packet *p_info) 28896f8d3f33SWingman Kwok { 28906f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = data; 28916f8d3f33SWingman Kwok 28926f8d3f33SWingman Kwok p_info->tx_pipe = &gbe_intf->tx_pipe; 28936246168bSWingMan Kwok 28946246168bSWingMan Kwok return gbe_txtstamp_mark_pkt(gbe_intf, p_info); 28956246168bSWingMan Kwok } 28966246168bSWingMan Kwok 28976246168bSWingMan Kwok static int gbe_rxhook(int order, void *data, struct netcp_packet *p_info) 28986246168bSWingMan Kwok { 28996246168bSWingMan Kwok struct gbe_intf *gbe_intf = data; 29006246168bSWingMan Kwok 29016246168bSWingMan Kwok return gbe_rxtstamp(gbe_intf, p_info); 29026f8d3f33SWingman Kwok } 29036f8d3f33SWingman Kwok 29046f8d3f33SWingman Kwok static int gbe_open(void *intf_priv, struct net_device *ndev) 29056f8d3f33SWingman Kwok { 29066f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv; 29076f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 29086f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 29096f8d3f33SWingman Kwok struct gbe_slave *slave = gbe_intf->slave; 29106f8d3f33SWingman Kwok int port_num = slave->port_num; 29114cd85a61SKaricheri, Muralidharan u32 reg, val; 29126f8d3f33SWingman Kwok int ret; 29136f8d3f33SWingman Kwok 29146f8d3f33SWingman Kwok reg = readl(GBE_REG_ADDR(gbe_dev, switch_regs, id_ver)); 29156f8d3f33SWingman Kwok dev_dbg(gbe_dev->dev, "initializing gbe version %d.%d (%d) GBE identification value 0x%x\n", 29166f8d3f33SWingman Kwok GBE_MAJOR_VERSION(reg), GBE_MINOR_VERSION(reg), 29176f8d3f33SWingman Kwok GBE_RTL_VERSION(reg), GBE_IDENT(reg)); 29186f8d3f33SWingman Kwok 29199a391c7bSWingMan Kwok /* For 10G and on NetCP 1.5, use directed to port */ 29202953586dSMurali Karicheri if (IS_SS_ID_XGBE(gbe_dev) || IS_SS_ID_MU(gbe_dev)) 2921e170f409SKaricheri, Muralidharan gbe_intf->tx_pipe.flags = SWITCH_TO_PORT_IN_TAGINFO; 29226f8d3f33SWingman Kwok 2923e170f409SKaricheri, Muralidharan if (gbe_dev->enable_ale) 2924e170f409SKaricheri, Muralidharan gbe_intf->tx_pipe.switch_to_port = 0; 2925e170f409SKaricheri, Muralidharan else 2926e170f409SKaricheri, Muralidharan gbe_intf->tx_pipe.switch_to_port = port_num; 2927e170f409SKaricheri, Muralidharan 2928e170f409SKaricheri, Muralidharan dev_dbg(gbe_dev->dev, 2929e170f409SKaricheri, Muralidharan "opened TX channel %s: %p with to port %d, flags %d\n", 29306f8d3f33SWingman Kwok gbe_intf->tx_pipe.dma_chan_name, 29316f8d3f33SWingman Kwok gbe_intf->tx_pipe.dma_channel, 2932e170f409SKaricheri, Muralidharan gbe_intf->tx_pipe.switch_to_port, 2933e170f409SKaricheri, Muralidharan gbe_intf->tx_pipe.flags); 29346f8d3f33SWingman Kwok 29356f8d3f33SWingman Kwok gbe_slave_stop(gbe_intf); 29366f8d3f33SWingman Kwok 29376f8d3f33SWingman Kwok /* disable priority elevation and enable statistics on all ports */ 29386f8d3f33SWingman Kwok writel(0, GBE_REG_ADDR(gbe_dev, switch_regs, ptype)); 29396f8d3f33SWingman Kwok 29406f8d3f33SWingman Kwok /* Control register */ 29414cd85a61SKaricheri, Muralidharan val = GBE_CTL_P0_ENABLE; 29424cd85a61SKaricheri, Muralidharan if (IS_SS_ID_MU(gbe_dev)) { 29434cd85a61SKaricheri, Muralidharan val |= ETH_SW_CTL_P0_TX_CRC_REMOVE; 29444cd85a61SKaricheri, Muralidharan netcp->hw_cap = ETH_SW_CAN_REMOVE_ETH_FCS; 29454cd85a61SKaricheri, Muralidharan } 29464cd85a61SKaricheri, Muralidharan writel(val, GBE_REG_ADDR(gbe_dev, switch_regs, control)); 29476f8d3f33SWingman Kwok 29486f8d3f33SWingman Kwok /* All statistics enabled and STAT AB visible by default */ 29499a391c7bSWingMan Kwok writel(gbe_dev->stats_en_mask, GBE_REG_ADDR(gbe_dev, switch_regs, 29506f8d3f33SWingman Kwok stat_port_en)); 29516f8d3f33SWingman Kwok 29526f8d3f33SWingman Kwok ret = gbe_slave_open(gbe_intf); 29536f8d3f33SWingman Kwok if (ret) 29546f8d3f33SWingman Kwok goto fail; 29556f8d3f33SWingman Kwok 29566246168bSWingMan Kwok netcp_register_txhook(netcp, GBE_TXHOOK_ORDER, gbe_txhook, gbe_intf); 29576246168bSWingMan Kwok netcp_register_rxhook(netcp, GBE_RXHOOK_ORDER, gbe_rxhook, gbe_intf); 29586f8d3f33SWingman Kwok 29596f8d3f33SWingman Kwok slave->open = true; 29606f8d3f33SWingman Kwok netcp_ethss_update_link_state(gbe_dev, slave, ndev); 29616246168bSWingMan Kwok 29626246168bSWingMan Kwok gbe_register_cpts(gbe_dev); 29636246168bSWingMan Kwok 29646f8d3f33SWingman Kwok return 0; 29656f8d3f33SWingman Kwok 29666f8d3f33SWingman Kwok fail: 29676f8d3f33SWingman Kwok gbe_slave_stop(gbe_intf); 29686f8d3f33SWingman Kwok return ret; 29696f8d3f33SWingman Kwok } 29706f8d3f33SWingman Kwok 29716f8d3f33SWingman Kwok static int gbe_close(void *intf_priv, struct net_device *ndev) 29726f8d3f33SWingman Kwok { 29736f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv; 29746f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 29756246168bSWingMan Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 29766246168bSWingMan Kwok 29776246168bSWingMan Kwok gbe_unregister_cpts(gbe_dev); 29786f8d3f33SWingman Kwok 29796f8d3f33SWingman Kwok gbe_slave_stop(gbe_intf); 29806246168bSWingMan Kwok 29816246168bSWingMan Kwok netcp_unregister_rxhook(netcp, GBE_RXHOOK_ORDER, gbe_rxhook, gbe_intf); 29826246168bSWingMan Kwok netcp_unregister_txhook(netcp, GBE_TXHOOK_ORDER, gbe_txhook, gbe_intf); 29836f8d3f33SWingman Kwok 29846f8d3f33SWingman Kwok gbe_intf->slave->open = false; 29856f8d3f33SWingman Kwok atomic_set(&gbe_intf->slave->link_state, NETCP_LINK_STATE_INVALID); 29866f8d3f33SWingman Kwok return 0; 29876f8d3f33SWingman Kwok } 29886f8d3f33SWingman Kwok 29896246168bSWingMan Kwok #if IS_ENABLED(CONFIG_TI_CPTS) 29906246168bSWingMan Kwok static void init_slave_ts_ctl(struct gbe_slave *slave) 29916246168bSWingMan Kwok { 29926246168bSWingMan Kwok slave->ts_ctl.uni = 1; 29936246168bSWingMan Kwok slave->ts_ctl.dst_port_map = 29946246168bSWingMan Kwok (TS_CTL_DST_PORT >> TS_CTL_DST_PORT_SHIFT) & 0x3; 29956246168bSWingMan Kwok slave->ts_ctl.maddr_map = 29966246168bSWingMan Kwok (TS_CTL_MADDR_ALL >> TS_CTL_MADDR_SHIFT) & 0x1f; 29976246168bSWingMan Kwok } 29986246168bSWingMan Kwok 29996246168bSWingMan Kwok #else 30006246168bSWingMan Kwok static void init_slave_ts_ctl(struct gbe_slave *slave) 30016246168bSWingMan Kwok { 30026246168bSWingMan Kwok } 30036246168bSWingMan Kwok #endif /* CONFIG_TI_CPTS */ 30046246168bSWingMan Kwok 30056f8d3f33SWingman Kwok static int init_slave(struct gbe_priv *gbe_dev, struct gbe_slave *slave, 30066f8d3f33SWingman Kwok struct device_node *node) 30076f8d3f33SWingman Kwok { 30086f8d3f33SWingman Kwok int port_reg_num; 30096f8d3f33SWingman Kwok u32 port_reg_ofs, emac_reg_ofs; 30109a391c7bSWingMan Kwok u32 port_reg_blk_sz, emac_reg_blk_sz; 30116f8d3f33SWingman Kwok 30126f8d3f33SWingman Kwok if (of_property_read_u32(node, "slave-port", &slave->slave_num)) { 30136f8d3f33SWingman Kwok dev_err(gbe_dev->dev, "missing slave-port parameter\n"); 30146f8d3f33SWingman Kwok return -EINVAL; 30156f8d3f33SWingman Kwok } 30166f8d3f33SWingman Kwok 30176f8d3f33SWingman Kwok if (of_property_read_u32(node, "link-interface", 30186f8d3f33SWingman Kwok &slave->link_interface)) { 30196f8d3f33SWingman Kwok dev_warn(gbe_dev->dev, 30206f8d3f33SWingman Kwok "missing link-interface value defaulting to 1G mac-phy link\n"); 30216f8d3f33SWingman Kwok slave->link_interface = SGMII_LINK_MAC_PHY; 30226f8d3f33SWingman Kwok } 30236f8d3f33SWingman Kwok 30247b647b93SMurali Karicheri slave->node = node; 30256f8d3f33SWingman Kwok slave->open = false; 30260cead3a6SKaricheri, Muralidharan if ((slave->link_interface == SGMII_LINK_MAC_PHY) || 3027478e9a5fSMurali Karicheri (slave->link_interface == RGMII_LINK_MAC_PHY) || 30280cead3a6SKaricheri, Muralidharan (slave->link_interface == XGMII_LINK_MAC_PHY)) 30296f8d3f33SWingman Kwok slave->phy_node = of_parse_phandle(node, "phy-handle", 0); 30306f8d3f33SWingman Kwok slave->port_num = gbe_get_slave_port(gbe_dev, slave->slave_num); 30316f8d3f33SWingman Kwok 303290cff9e2SWingman Kwok if (slave->link_interface >= XGMII_LINK_MAC_PHY) 303390cff9e2SWingman Kwok slave->mac_control = GBE_DEF_10G_MAC_CONTROL; 303490cff9e2SWingman Kwok else 30356f8d3f33SWingman Kwok slave->mac_control = GBE_DEF_1G_MAC_CONTROL; 30366f8d3f33SWingman Kwok 30376f8d3f33SWingman Kwok /* Emac regs memmap are contiguous but port regs are not */ 30386f8d3f33SWingman Kwok port_reg_num = slave->slave_num; 30392953586dSMurali Karicheri if (IS_SS_ID_VER_14(gbe_dev)) { 30406f8d3f33SWingman Kwok if (slave->slave_num > 1) { 30416f8d3f33SWingman Kwok port_reg_ofs = GBE13_SLAVE_PORT2_OFFSET; 30426f8d3f33SWingman Kwok port_reg_num -= 2; 30436f8d3f33SWingman Kwok } else { 30446f8d3f33SWingman Kwok port_reg_ofs = GBE13_SLAVE_PORT_OFFSET; 30456f8d3f33SWingman Kwok } 30469a391c7bSWingMan Kwok emac_reg_ofs = GBE13_EMAC_OFFSET; 30479a391c7bSWingMan Kwok port_reg_blk_sz = 0x30; 30489a391c7bSWingMan Kwok emac_reg_blk_sz = 0x40; 30499a391c7bSWingMan Kwok } else if (IS_SS_ID_MU(gbe_dev)) { 30509a391c7bSWingMan Kwok port_reg_ofs = GBENU_SLAVE_PORT_OFFSET; 30519a391c7bSWingMan Kwok emac_reg_ofs = GBENU_EMAC_OFFSET; 30529a391c7bSWingMan Kwok port_reg_blk_sz = 0x1000; 30539a391c7bSWingMan Kwok emac_reg_blk_sz = 0x1000; 30542953586dSMurali Karicheri } else if (IS_SS_ID_XGBE(gbe_dev)) { 305590cff9e2SWingman Kwok port_reg_ofs = XGBE10_SLAVE_PORT_OFFSET; 30569a391c7bSWingMan Kwok emac_reg_ofs = XGBE10_EMAC_OFFSET; 30579a391c7bSWingMan Kwok port_reg_blk_sz = 0x30; 30589a391c7bSWingMan Kwok emac_reg_blk_sz = 0x40; 30596f8d3f33SWingman Kwok } else { 30606f8d3f33SWingman Kwok dev_err(gbe_dev->dev, "unknown ethss(0x%x)\n", 30616f8d3f33SWingman Kwok gbe_dev->ss_version); 30626f8d3f33SWingman Kwok return -EINVAL; 30636f8d3f33SWingman Kwok } 30646f8d3f33SWingman Kwok 306521e0e0ddSKaricheri, Muralidharan slave->port_regs = gbe_dev->switch_regs + port_reg_ofs + 30669a391c7bSWingMan Kwok (port_reg_blk_sz * port_reg_num); 306721e0e0ddSKaricheri, Muralidharan slave->emac_regs = gbe_dev->switch_regs + emac_reg_ofs + 30689a391c7bSWingMan Kwok (emac_reg_blk_sz * slave->slave_num); 30696f8d3f33SWingman Kwok 30702953586dSMurali Karicheri if (IS_SS_ID_VER_14(gbe_dev)) { 30716f8d3f33SWingman Kwok /* Initialize slave port register offsets */ 30726f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, port_vlan); 30736f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, tx_pri_map); 30746f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, sa_lo); 30756f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, sa_hi); 30766f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, ts_ctl); 30776f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, ts_seq_ltype); 30786f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, ts_vlan); 30796f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, ts_ctl_ltype2); 30806f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, ts_ctl2); 30816f8d3f33SWingman Kwok 30826f8d3f33SWingman Kwok /* Initialize EMAC register offsets */ 30836f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, emac_regs, mac_control); 30846f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, emac_regs, soft_reset); 30856f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, emac_regs, rx_maxlen); 30866f8d3f33SWingman Kwok 30879a391c7bSWingMan Kwok } else if (IS_SS_ID_MU(gbe_dev)) { 30889a391c7bSWingMan Kwok /* Initialize slave port register offsets */ 30899a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, port_vlan); 30909a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, tx_pri_map); 309165c45064SMurali Karicheri GBENU_SET_REG_OFS(slave, port_regs, rx_pri_map); 30929a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, sa_lo); 30939a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, sa_hi); 30949a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, ts_ctl); 30959a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, ts_seq_ltype); 30969a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, ts_vlan); 30979a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, ts_ctl_ltype2); 30989a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, ts_ctl2); 30999a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, rx_maxlen); 31009a391c7bSWingMan Kwok 31019a391c7bSWingMan Kwok /* Initialize EMAC register offsets */ 31029a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, emac_regs, mac_control); 31039a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, emac_regs, soft_reset); 31049a391c7bSWingMan Kwok 31052953586dSMurali Karicheri } else if (IS_SS_ID_XGBE(gbe_dev)) { 310690cff9e2SWingman Kwok /* Initialize slave port register offsets */ 310790cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, port_vlan); 310890cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, tx_pri_map); 310990cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, sa_lo); 311090cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, sa_hi); 311190cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, ts_ctl); 311290cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, ts_seq_ltype); 311390cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, ts_vlan); 311490cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, ts_ctl_ltype2); 311590cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, ts_ctl2); 311690cff9e2SWingman Kwok 311790cff9e2SWingman Kwok /* Initialize EMAC register offsets */ 311890cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, emac_regs, mac_control); 311990cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, emac_regs, soft_reset); 312090cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, emac_regs, rx_maxlen); 31216f8d3f33SWingman Kwok } 31226f8d3f33SWingman Kwok 31236f8d3f33SWingman Kwok atomic_set(&slave->link_state, NETCP_LINK_STATE_INVALID); 31246246168bSWingMan Kwok 31256246168bSWingMan Kwok init_slave_ts_ctl(slave); 31266f8d3f33SWingman Kwok return 0; 31276f8d3f33SWingman Kwok } 31286f8d3f33SWingman Kwok 31296f8d3f33SWingman Kwok static void init_secondary_ports(struct gbe_priv *gbe_dev, 31306f8d3f33SWingman Kwok struct device_node *node) 31316f8d3f33SWingman Kwok { 31326f8d3f33SWingman Kwok struct device *dev = gbe_dev->dev; 31336f8d3f33SWingman Kwok phy_interface_t phy_mode; 31346f8d3f33SWingman Kwok struct gbe_priv **priv; 31356f8d3f33SWingman Kwok struct device_node *port; 31366f8d3f33SWingman Kwok struct gbe_slave *slave; 31376f8d3f33SWingman Kwok bool mac_phy_link = false; 31386f8d3f33SWingman Kwok 31396f8d3f33SWingman Kwok for_each_child_of_node(node, port) { 31406f8d3f33SWingman Kwok slave = devm_kzalloc(dev, sizeof(*slave), GFP_KERNEL); 31416f8d3f33SWingman Kwok if (!slave) { 314221c328dcSRob Herring dev_err(dev, "memory alloc failed for secondary port(%pOFn), skipping...\n", 314321c328dcSRob Herring port); 31446f8d3f33SWingman Kwok continue; 31456f8d3f33SWingman Kwok } 31466f8d3f33SWingman Kwok 31476f8d3f33SWingman Kwok if (init_slave(gbe_dev, slave, port)) { 31486f8d3f33SWingman Kwok dev_err(dev, 314921c328dcSRob Herring "Failed to initialize secondary port(%pOFn), skipping...\n", 315021c328dcSRob Herring port); 31516f8d3f33SWingman Kwok devm_kfree(dev, slave); 31526f8d3f33SWingman Kwok continue; 31536f8d3f33SWingman Kwok } 31546f8d3f33SWingman Kwok 3155775f9535SMurali Karicheri if (!IS_SS_ID_2U(gbe_dev)) 31566f8d3f33SWingman Kwok gbe_sgmii_config(gbe_dev, slave); 31576f8d3f33SWingman Kwok gbe_port_reset(slave); 31586f8d3f33SWingman Kwok gbe_port_config(gbe_dev, slave, gbe_dev->rx_packet_max); 31596f8d3f33SWingman Kwok list_add_tail(&slave->slave_list, &gbe_dev->secondary_slaves); 31606f8d3f33SWingman Kwok gbe_dev->num_slaves++; 316190cff9e2SWingman Kwok if ((slave->link_interface == SGMII_LINK_MAC_PHY) || 316290cff9e2SWingman Kwok (slave->link_interface == XGMII_LINK_MAC_PHY)) 31636f8d3f33SWingman Kwok mac_phy_link = true; 31646f8d3f33SWingman Kwok 31656f8d3f33SWingman Kwok slave->open = true; 3166bd252796SJulia Lawall if (gbe_dev->num_slaves >= gbe_dev->max_num_slaves) { 3167bd252796SJulia Lawall of_node_put(port); 31689a391c7bSWingMan Kwok break; 31696f8d3f33SWingman Kwok } 3170bd252796SJulia Lawall } 31716f8d3f33SWingman Kwok 31726f8d3f33SWingman Kwok /* of_phy_connect() is needed only for MAC-PHY interface */ 31736f8d3f33SWingman Kwok if (!mac_phy_link) 31746f8d3f33SWingman Kwok return; 31756f8d3f33SWingman Kwok 31766f8d3f33SWingman Kwok /* Allocate dummy netdev device for attaching to phy device */ 31776f8d3f33SWingman Kwok gbe_dev->dummy_ndev = alloc_netdev(sizeof(gbe_dev), "dummy", 31786f8d3f33SWingman Kwok NET_NAME_UNKNOWN, ether_setup); 31796f8d3f33SWingman Kwok if (!gbe_dev->dummy_ndev) { 31806f8d3f33SWingman Kwok dev_err(dev, 31816f8d3f33SWingman Kwok "Failed to allocate dummy netdev for secondary ports, skipping phy_connect()...\n"); 31826f8d3f33SWingman Kwok return; 31836f8d3f33SWingman Kwok } 31846f8d3f33SWingman Kwok priv = netdev_priv(gbe_dev->dummy_ndev); 31856f8d3f33SWingman Kwok *priv = gbe_dev; 31866f8d3f33SWingman Kwok 31876f8d3f33SWingman Kwok if (slave->link_interface == SGMII_LINK_MAC_PHY) { 31886f8d3f33SWingman Kwok phy_mode = PHY_INTERFACE_MODE_SGMII; 31896f8d3f33SWingman Kwok slave->phy_port_t = PORT_MII; 3190478e9a5fSMurali Karicheri } else if (slave->link_interface == RGMII_LINK_MAC_PHY) { 3191478e9a5fSMurali Karicheri phy_mode = PHY_INTERFACE_MODE_RGMII; 3192478e9a5fSMurali Karicheri slave->phy_port_t = PORT_MII; 31936f8d3f33SWingman Kwok } else { 31946f8d3f33SWingman Kwok phy_mode = PHY_INTERFACE_MODE_NA; 31956f8d3f33SWingman Kwok slave->phy_port_t = PORT_FIBRE; 31966f8d3f33SWingman Kwok } 31976f8d3f33SWingman Kwok 31986f8d3f33SWingman Kwok for_each_sec_slave(slave, gbe_dev) { 319990cff9e2SWingman Kwok if ((slave->link_interface != SGMII_LINK_MAC_PHY) && 3200478e9a5fSMurali Karicheri (slave->link_interface != RGMII_LINK_MAC_PHY) && 320190cff9e2SWingman Kwok (slave->link_interface != XGMII_LINK_MAC_PHY)) 32026f8d3f33SWingman Kwok continue; 32036f8d3f33SWingman Kwok slave->phy = 32046f8d3f33SWingman Kwok of_phy_connect(gbe_dev->dummy_ndev, 32056f8d3f33SWingman Kwok slave->phy_node, 32066f8d3f33SWingman Kwok gbe_adjust_link_sec_slaves, 32076f8d3f33SWingman Kwok 0, phy_mode); 32086f8d3f33SWingman Kwok if (!slave->phy) { 32096f8d3f33SWingman Kwok dev_err(dev, "phy not found for slave %d\n", 32106f8d3f33SWingman Kwok slave->slave_num); 32116f8d3f33SWingman Kwok } else { 32126f8d3f33SWingman Kwok dev_dbg(dev, "phy found: id is: 0x%s\n", 321384eff6d1SAndrew Lunn phydev_name(slave->phy)); 32146f8d3f33SWingman Kwok phy_start(slave->phy); 32156f8d3f33SWingman Kwok } 32166f8d3f33SWingman Kwok } 32176f8d3f33SWingman Kwok } 32186f8d3f33SWingman Kwok 32196f8d3f33SWingman Kwok static void free_secondary_ports(struct gbe_priv *gbe_dev) 32206f8d3f33SWingman Kwok { 32216f8d3f33SWingman Kwok struct gbe_slave *slave; 32226f8d3f33SWingman Kwok 3223c20afae7SKaricheri, Muralidharan while (!list_empty(&gbe_dev->secondary_slaves)) { 32246f8d3f33SWingman Kwok slave = first_sec_slave(gbe_dev); 3225c20afae7SKaricheri, Muralidharan 32266f8d3f33SWingman Kwok if (slave->phy) 32276f8d3f33SWingman Kwok phy_disconnect(slave->phy); 32286f8d3f33SWingman Kwok list_del(&slave->slave_list); 32296f8d3f33SWingman Kwok } 32306f8d3f33SWingman Kwok if (gbe_dev->dummy_ndev) 32316f8d3f33SWingman Kwok free_netdev(gbe_dev->dummy_ndev); 32326f8d3f33SWingman Kwok } 32336f8d3f33SWingman Kwok 323490cff9e2SWingman Kwok static int set_xgbe_ethss10_priv(struct gbe_priv *gbe_dev, 323590cff9e2SWingman Kwok struct device_node *node) 323690cff9e2SWingman Kwok { 323790cff9e2SWingman Kwok struct resource res; 323890cff9e2SWingman Kwok void __iomem *regs; 323990cff9e2SWingman Kwok int ret, i; 324090cff9e2SWingman Kwok 32419a391c7bSWingMan Kwok ret = of_address_to_resource(node, XGBE_SS_REG_INDEX, &res); 324290cff9e2SWingman Kwok if (ret) { 324321e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, 324421c328dcSRob Herring "Can't xlate xgbe of node(%pOFn) ss address at %d\n", 324521c328dcSRob Herring node, XGBE_SS_REG_INDEX); 324690cff9e2SWingman Kwok return ret; 324790cff9e2SWingman Kwok } 324890cff9e2SWingman Kwok 324990cff9e2SWingman Kwok regs = devm_ioremap_resource(gbe_dev->dev, &res); 325090cff9e2SWingman Kwok if (IS_ERR(regs)) { 325121e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, "Failed to map xgbe ss register base\n"); 325290cff9e2SWingman Kwok return PTR_ERR(regs); 325390cff9e2SWingman Kwok } 325490cff9e2SWingman Kwok gbe_dev->ss_regs = regs; 325590cff9e2SWingman Kwok 325621e0e0ddSKaricheri, Muralidharan ret = of_address_to_resource(node, XGBE_SM_REG_INDEX, &res); 325721e0e0ddSKaricheri, Muralidharan if (ret) { 325821e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, 325921c328dcSRob Herring "Can't xlate xgbe of node(%pOFn) sm address at %d\n", 326021c328dcSRob Herring node, XGBE_SM_REG_INDEX); 326121e0e0ddSKaricheri, Muralidharan return ret; 326221e0e0ddSKaricheri, Muralidharan } 326321e0e0ddSKaricheri, Muralidharan 326421e0e0ddSKaricheri, Muralidharan regs = devm_ioremap_resource(gbe_dev->dev, &res); 326521e0e0ddSKaricheri, Muralidharan if (IS_ERR(regs)) { 326621e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, "Failed to map xgbe sm register base\n"); 326721e0e0ddSKaricheri, Muralidharan return PTR_ERR(regs); 326821e0e0ddSKaricheri, Muralidharan } 326921e0e0ddSKaricheri, Muralidharan gbe_dev->switch_regs = regs; 327021e0e0ddSKaricheri, Muralidharan 327190cff9e2SWingman Kwok ret = of_address_to_resource(node, XGBE_SERDES_REG_INDEX, &res); 327290cff9e2SWingman Kwok if (ret) { 327321e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, 327421c328dcSRob Herring "Can't xlate xgbe serdes of node(%pOFn) address at %d\n", 327521c328dcSRob Herring node, XGBE_SERDES_REG_INDEX); 327690cff9e2SWingman Kwok return ret; 327790cff9e2SWingman Kwok } 327890cff9e2SWingman Kwok 327990cff9e2SWingman Kwok regs = devm_ioremap_resource(gbe_dev->dev, &res); 328090cff9e2SWingman Kwok if (IS_ERR(regs)) { 328190cff9e2SWingman Kwok dev_err(gbe_dev->dev, "Failed to map xgbe serdes register base\n"); 328290cff9e2SWingman Kwok return PTR_ERR(regs); 328390cff9e2SWingman Kwok } 328490cff9e2SWingman Kwok gbe_dev->xgbe_serdes_regs = regs; 328590cff9e2SWingman Kwok 3286489e8a2fSWingMan Kwok gbe_dev->num_stats_mods = gbe_dev->max_num_ports; 3287208c6b9aSWingMan Kwok gbe_dev->et_stats = xgbe10_et_stats; 3288208c6b9aSWingMan Kwok gbe_dev->num_et_stats = ARRAY_SIZE(xgbe10_et_stats); 3289208c6b9aSWingMan Kwok 3290a86854d0SKees Cook gbe_dev->hw_stats = devm_kcalloc(gbe_dev->dev, 3291a86854d0SKees Cook gbe_dev->num_et_stats, sizeof(u64), 329290cff9e2SWingman Kwok GFP_KERNEL); 329390cff9e2SWingman Kwok if (!gbe_dev->hw_stats) { 329490cff9e2SWingman Kwok dev_err(gbe_dev->dev, "hw_stats memory allocation failed\n"); 329590cff9e2SWingman Kwok return -ENOMEM; 329690cff9e2SWingman Kwok } 329790cff9e2SWingman Kwok 3298489e8a2fSWingMan Kwok gbe_dev->hw_stats_prev = 3299a86854d0SKees Cook devm_kcalloc(gbe_dev->dev, 3300a86854d0SKees Cook gbe_dev->num_et_stats, sizeof(u32), 3301489e8a2fSWingMan Kwok GFP_KERNEL); 3302489e8a2fSWingMan Kwok if (!gbe_dev->hw_stats_prev) { 3303489e8a2fSWingMan Kwok dev_err(gbe_dev->dev, 3304489e8a2fSWingMan Kwok "hw_stats_prev memory allocation failed\n"); 3305489e8a2fSWingMan Kwok return -ENOMEM; 3306489e8a2fSWingMan Kwok } 3307489e8a2fSWingMan Kwok 330890cff9e2SWingman Kwok gbe_dev->ss_version = XGBE_SS_VERSION_10; 330990cff9e2SWingman Kwok gbe_dev->sgmii_port_regs = gbe_dev->ss_regs + 331090cff9e2SWingman Kwok XGBE10_SGMII_MODULE_OFFSET; 331190cff9e2SWingman Kwok gbe_dev->host_port_regs = gbe_dev->ss_regs + XGBE10_HOST_PORT_OFFSET; 331290cff9e2SWingman Kwok 33139a391c7bSWingMan Kwok for (i = 0; i < gbe_dev->max_num_ports; i++) 331421e0e0ddSKaricheri, Muralidharan gbe_dev->hw_stats_regs[i] = gbe_dev->switch_regs + 331590cff9e2SWingman Kwok XGBE10_HW_STATS_OFFSET + (GBE_HW_STATS_REG_MAP_SZ * i); 331690cff9e2SWingman Kwok 33179a391c7bSWingMan Kwok gbe_dev->ale_reg = gbe_dev->switch_regs + XGBE10_ALE_OFFSET; 33186246168bSWingMan Kwok gbe_dev->cpts_reg = gbe_dev->switch_regs + XGBE10_CPTS_OFFSET; 33199a391c7bSWingMan Kwok gbe_dev->ale_ports = gbe_dev->max_num_ports; 332090cff9e2SWingman Kwok gbe_dev->host_port = XGBE10_HOST_PORT_NUM; 332190cff9e2SWingman Kwok gbe_dev->ale_entries = XGBE10_NUM_ALE_ENTRIES; 33229a391c7bSWingMan Kwok gbe_dev->stats_en_mask = (1 << (gbe_dev->max_num_ports)) - 1; 332390cff9e2SWingman Kwok 332490cff9e2SWingman Kwok /* Subsystem registers */ 332590cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, ss_regs, id_ver); 332690cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, ss_regs, control); 332790cff9e2SWingman Kwok 332890cff9e2SWingman Kwok /* Switch module registers */ 332990cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, switch_regs, id_ver); 333090cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, switch_regs, control); 333190cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, switch_regs, ptype); 333290cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, switch_regs, stat_port_en); 333390cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, switch_regs, flow_control); 333490cff9e2SWingman Kwok 333590cff9e2SWingman Kwok /* Host port registers */ 333690cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, host_port_regs, port_vlan); 333790cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, host_port_regs, tx_pri_map); 333890cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, host_port_regs, rx_maxlen); 333990cff9e2SWingman Kwok return 0; 334090cff9e2SWingman Kwok } 334190cff9e2SWingman Kwok 33426f8d3f33SWingman Kwok static int get_gbe_resource_version(struct gbe_priv *gbe_dev, 33436f8d3f33SWingman Kwok struct device_node *node) 33446f8d3f33SWingman Kwok { 33456f8d3f33SWingman Kwok struct resource res; 33466f8d3f33SWingman Kwok void __iomem *regs; 33476f8d3f33SWingman Kwok int ret; 33486f8d3f33SWingman Kwok 334921e0e0ddSKaricheri, Muralidharan ret = of_address_to_resource(node, GBE_SS_REG_INDEX, &res); 33506f8d3f33SWingman Kwok if (ret) { 335121e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, 335221c328dcSRob Herring "Can't translate of node(%pOFn) of gbe ss address at %d\n", 335321c328dcSRob Herring node, GBE_SS_REG_INDEX); 33546f8d3f33SWingman Kwok return ret; 33556f8d3f33SWingman Kwok } 33566f8d3f33SWingman Kwok 33576f8d3f33SWingman Kwok regs = devm_ioremap_resource(gbe_dev->dev, &res); 33586f8d3f33SWingman Kwok if (IS_ERR(regs)) { 33596f8d3f33SWingman Kwok dev_err(gbe_dev->dev, "Failed to map gbe register base\n"); 33606f8d3f33SWingman Kwok return PTR_ERR(regs); 33616f8d3f33SWingman Kwok } 33626f8d3f33SWingman Kwok gbe_dev->ss_regs = regs; 33636f8d3f33SWingman Kwok gbe_dev->ss_version = readl(gbe_dev->ss_regs); 33646f8d3f33SWingman Kwok return 0; 33656f8d3f33SWingman Kwok } 33666f8d3f33SWingman Kwok 33676f8d3f33SWingman Kwok static int set_gbe_ethss14_priv(struct gbe_priv *gbe_dev, 33686f8d3f33SWingman Kwok struct device_node *node) 33696f8d3f33SWingman Kwok { 337021e0e0ddSKaricheri, Muralidharan struct resource res; 33716f8d3f33SWingman Kwok void __iomem *regs; 337221e0e0ddSKaricheri, Muralidharan int i, ret; 337321e0e0ddSKaricheri, Muralidharan 337421e0e0ddSKaricheri, Muralidharan ret = of_address_to_resource(node, GBE_SGMII34_REG_INDEX, &res); 337521e0e0ddSKaricheri, Muralidharan if (ret) { 337621e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, 337721c328dcSRob Herring "Can't translate of gbe node(%pOFn) address at index %d\n", 337821c328dcSRob Herring node, GBE_SGMII34_REG_INDEX); 337921e0e0ddSKaricheri, Muralidharan return ret; 338021e0e0ddSKaricheri, Muralidharan } 338121e0e0ddSKaricheri, Muralidharan 338221e0e0ddSKaricheri, Muralidharan regs = devm_ioremap_resource(gbe_dev->dev, &res); 338321e0e0ddSKaricheri, Muralidharan if (IS_ERR(regs)) { 338421e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, 338521e0e0ddSKaricheri, Muralidharan "Failed to map gbe sgmii port34 register base\n"); 338621e0e0ddSKaricheri, Muralidharan return PTR_ERR(regs); 338721e0e0ddSKaricheri, Muralidharan } 338821e0e0ddSKaricheri, Muralidharan gbe_dev->sgmii_port34_regs = regs; 338921e0e0ddSKaricheri, Muralidharan 339021e0e0ddSKaricheri, Muralidharan ret = of_address_to_resource(node, GBE_SM_REG_INDEX, &res); 339121e0e0ddSKaricheri, Muralidharan if (ret) { 339221e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, 339321c328dcSRob Herring "Can't translate of gbe node(%pOFn) address at index %d\n", 339421c328dcSRob Herring node, GBE_SM_REG_INDEX); 339521e0e0ddSKaricheri, Muralidharan return ret; 339621e0e0ddSKaricheri, Muralidharan } 339721e0e0ddSKaricheri, Muralidharan 339821e0e0ddSKaricheri, Muralidharan regs = devm_ioremap_resource(gbe_dev->dev, &res); 339921e0e0ddSKaricheri, Muralidharan if (IS_ERR(regs)) { 340021e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, 340121e0e0ddSKaricheri, Muralidharan "Failed to map gbe switch module register base\n"); 340221e0e0ddSKaricheri, Muralidharan return PTR_ERR(regs); 340321e0e0ddSKaricheri, Muralidharan } 340421e0e0ddSKaricheri, Muralidharan gbe_dev->switch_regs = regs; 34056f8d3f33SWingman Kwok 3406489e8a2fSWingMan Kwok gbe_dev->num_stats_mods = gbe_dev->max_num_slaves; 3407208c6b9aSWingMan Kwok gbe_dev->et_stats = gbe13_et_stats; 3408208c6b9aSWingMan Kwok gbe_dev->num_et_stats = ARRAY_SIZE(gbe13_et_stats); 3409208c6b9aSWingMan Kwok 3410a86854d0SKees Cook gbe_dev->hw_stats = devm_kcalloc(gbe_dev->dev, 3411a86854d0SKees Cook gbe_dev->num_et_stats, sizeof(u64), 34126f8d3f33SWingman Kwok GFP_KERNEL); 34136f8d3f33SWingman Kwok if (!gbe_dev->hw_stats) { 34146f8d3f33SWingman Kwok dev_err(gbe_dev->dev, "hw_stats memory allocation failed\n"); 34156f8d3f33SWingman Kwok return -ENOMEM; 34166f8d3f33SWingman Kwok } 34176f8d3f33SWingman Kwok 3418489e8a2fSWingMan Kwok gbe_dev->hw_stats_prev = 3419a86854d0SKees Cook devm_kcalloc(gbe_dev->dev, 3420a86854d0SKees Cook gbe_dev->num_et_stats, sizeof(u32), 3421489e8a2fSWingMan Kwok GFP_KERNEL); 3422489e8a2fSWingMan Kwok if (!gbe_dev->hw_stats_prev) { 3423489e8a2fSWingMan Kwok dev_err(gbe_dev->dev, 3424489e8a2fSWingMan Kwok "hw_stats_prev memory allocation failed\n"); 3425489e8a2fSWingMan Kwok return -ENOMEM; 3426489e8a2fSWingMan Kwok } 3427489e8a2fSWingMan Kwok 342821e0e0ddSKaricheri, Muralidharan gbe_dev->sgmii_port_regs = gbe_dev->ss_regs + GBE13_SGMII_MODULE_OFFSET; 342921e0e0ddSKaricheri, Muralidharan gbe_dev->host_port_regs = gbe_dev->switch_regs + GBE13_HOST_PORT_OFFSET; 34306f8d3f33SWingman Kwok 3431a94bcd09SWingMan Kwok /* K2HK has only 2 hw stats modules visible at a time, so 3432a94bcd09SWingMan Kwok * module 0 & 2 points to one base and 3433a94bcd09SWingMan Kwok * module 1 & 3 points to the other base 3434a94bcd09SWingMan Kwok */ 34359a391c7bSWingMan Kwok for (i = 0; i < gbe_dev->max_num_slaves; i++) { 343621e0e0ddSKaricheri, Muralidharan gbe_dev->hw_stats_regs[i] = 343721e0e0ddSKaricheri, Muralidharan gbe_dev->switch_regs + GBE13_HW_STATS_OFFSET + 3438a94bcd09SWingMan Kwok (GBE_HW_STATS_REG_MAP_SZ * (i & 0x1)); 343921e0e0ddSKaricheri, Muralidharan } 34406f8d3f33SWingman Kwok 34416246168bSWingMan Kwok gbe_dev->cpts_reg = gbe_dev->switch_regs + GBE13_CPTS_OFFSET; 344221e0e0ddSKaricheri, Muralidharan gbe_dev->ale_reg = gbe_dev->switch_regs + GBE13_ALE_OFFSET; 34439a391c7bSWingMan Kwok gbe_dev->ale_ports = gbe_dev->max_num_ports; 34446f8d3f33SWingman Kwok gbe_dev->host_port = GBE13_HOST_PORT_NUM; 34456f8d3f33SWingman Kwok gbe_dev->ale_entries = GBE13_NUM_ALE_ENTRIES; 34469a391c7bSWingMan Kwok gbe_dev->stats_en_mask = GBE13_REG_VAL_STAT_ENABLE_ALL; 34476f8d3f33SWingman Kwok 34486f8d3f33SWingman Kwok /* Subsystem registers */ 34496f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, ss_regs, id_ver); 34506f8d3f33SWingman Kwok 34516f8d3f33SWingman Kwok /* Switch module registers */ 34526f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, switch_regs, id_ver); 34536f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, switch_regs, control); 34546f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, switch_regs, soft_reset); 34556f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, switch_regs, stat_port_en); 34566f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, switch_regs, ptype); 34576f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, switch_regs, flow_control); 34586f8d3f33SWingman Kwok 34596f8d3f33SWingman Kwok /* Host port registers */ 34606f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, host_port_regs, port_vlan); 34616f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, host_port_regs, rx_maxlen); 34626f8d3f33SWingman Kwok return 0; 34636f8d3f33SWingman Kwok } 34646f8d3f33SWingman Kwok 34659a391c7bSWingMan Kwok static int set_gbenu_ethss_priv(struct gbe_priv *gbe_dev, 34669a391c7bSWingMan Kwok struct device_node *node) 34679a391c7bSWingMan Kwok { 34689a391c7bSWingMan Kwok struct resource res; 34699a391c7bSWingMan Kwok void __iomem *regs; 34709a391c7bSWingMan Kwok int i, ret; 34719a391c7bSWingMan Kwok 3472489e8a2fSWingMan Kwok gbe_dev->num_stats_mods = gbe_dev->max_num_ports; 3473208c6b9aSWingMan Kwok gbe_dev->et_stats = gbenu_et_stats; 3474208c6b9aSWingMan Kwok 3475dc07ec97SMurali Karicheri if (IS_SS_ID_MU(gbe_dev)) 3476208c6b9aSWingMan Kwok gbe_dev->num_et_stats = GBENU_ET_STATS_HOST_SIZE + 3477208c6b9aSWingMan Kwok (gbe_dev->max_num_slaves * GBENU_ET_STATS_PORT_SIZE); 3478208c6b9aSWingMan Kwok else 3479208c6b9aSWingMan Kwok gbe_dev->num_et_stats = GBENU_ET_STATS_HOST_SIZE + 3480208c6b9aSWingMan Kwok GBENU_ET_STATS_PORT_SIZE; 3481208c6b9aSWingMan Kwok 3482a86854d0SKees Cook gbe_dev->hw_stats = devm_kcalloc(gbe_dev->dev, 3483a86854d0SKees Cook gbe_dev->num_et_stats, sizeof(u64), 34849a391c7bSWingMan Kwok GFP_KERNEL); 34859a391c7bSWingMan Kwok if (!gbe_dev->hw_stats) { 34869a391c7bSWingMan Kwok dev_err(gbe_dev->dev, "hw_stats memory allocation failed\n"); 34879a391c7bSWingMan Kwok return -ENOMEM; 34889a391c7bSWingMan Kwok } 34899a391c7bSWingMan Kwok 3490489e8a2fSWingMan Kwok gbe_dev->hw_stats_prev = 3491a86854d0SKees Cook devm_kcalloc(gbe_dev->dev, 3492a86854d0SKees Cook gbe_dev->num_et_stats, sizeof(u32), 3493489e8a2fSWingMan Kwok GFP_KERNEL); 3494489e8a2fSWingMan Kwok if (!gbe_dev->hw_stats_prev) { 3495489e8a2fSWingMan Kwok dev_err(gbe_dev->dev, 3496489e8a2fSWingMan Kwok "hw_stats_prev memory allocation failed\n"); 3497489e8a2fSWingMan Kwok return -ENOMEM; 3498489e8a2fSWingMan Kwok } 3499489e8a2fSWingMan Kwok 35009a391c7bSWingMan Kwok ret = of_address_to_resource(node, GBENU_SM_REG_INDEX, &res); 35019a391c7bSWingMan Kwok if (ret) { 35029a391c7bSWingMan Kwok dev_err(gbe_dev->dev, 350321c328dcSRob Herring "Can't translate of gbenu node(%pOFn) addr at index %d\n", 350421c328dcSRob Herring node, GBENU_SM_REG_INDEX); 35059a391c7bSWingMan Kwok return ret; 35069a391c7bSWingMan Kwok } 35079a391c7bSWingMan Kwok 35089a391c7bSWingMan Kwok regs = devm_ioremap_resource(gbe_dev->dev, &res); 35099a391c7bSWingMan Kwok if (IS_ERR(regs)) { 35109a391c7bSWingMan Kwok dev_err(gbe_dev->dev, 35119a391c7bSWingMan Kwok "Failed to map gbenu switch module register base\n"); 35129a391c7bSWingMan Kwok return PTR_ERR(regs); 35139a391c7bSWingMan Kwok } 35149a391c7bSWingMan Kwok gbe_dev->switch_regs = regs; 35159a391c7bSWingMan Kwok 3516775f9535SMurali Karicheri if (!IS_SS_ID_2U(gbe_dev)) 3517775f9535SMurali Karicheri gbe_dev->sgmii_port_regs = 3518775f9535SMurali Karicheri gbe_dev->ss_regs + GBENU_SGMII_MODULE_OFFSET; 35198c85151dSWingMan Kwok 35208c85151dSWingMan Kwok /* Although sgmii modules are mem mapped to one contiguous 35218c85151dSWingMan Kwok * region on GBENU devices, setting sgmii_port34_regs allows 35228c85151dSWingMan Kwok * consistent code when accessing sgmii api 35238c85151dSWingMan Kwok */ 35248c85151dSWingMan Kwok gbe_dev->sgmii_port34_regs = gbe_dev->sgmii_port_regs + 35258c85151dSWingMan Kwok (2 * GBENU_SGMII_MODULE_SIZE); 35268c85151dSWingMan Kwok 35279a391c7bSWingMan Kwok gbe_dev->host_port_regs = gbe_dev->switch_regs + GBENU_HOST_PORT_OFFSET; 35289a391c7bSWingMan Kwok 35299a391c7bSWingMan Kwok for (i = 0; i < (gbe_dev->max_num_ports); i++) 35309a391c7bSWingMan Kwok gbe_dev->hw_stats_regs[i] = gbe_dev->switch_regs + 35319a391c7bSWingMan Kwok GBENU_HW_STATS_OFFSET + (GBENU_HW_STATS_REG_MAP_SZ * i); 35329a391c7bSWingMan Kwok 35336246168bSWingMan Kwok gbe_dev->cpts_reg = gbe_dev->switch_regs + GBENU_CPTS_OFFSET; 35349a391c7bSWingMan Kwok gbe_dev->ale_reg = gbe_dev->switch_regs + GBENU_ALE_OFFSET; 35359a391c7bSWingMan Kwok gbe_dev->ale_ports = gbe_dev->max_num_ports; 35369a391c7bSWingMan Kwok gbe_dev->host_port = GBENU_HOST_PORT_NUM; 35379a391c7bSWingMan Kwok gbe_dev->stats_en_mask = (1 << (gbe_dev->max_num_ports)) - 1; 35389a391c7bSWingMan Kwok 35399a391c7bSWingMan Kwok /* Subsystem registers */ 35409a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, ss_regs, id_ver); 35417771f2b4SMurali Karicheri /* ok to set for MU, but used by 2U only */ 35427771f2b4SMurali Karicheri GBENU_SET_REG_OFS(gbe_dev, ss_regs, rgmii_status); 35439a391c7bSWingMan Kwok 35449a391c7bSWingMan Kwok /* Switch module registers */ 35459a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, switch_regs, id_ver); 35469a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, switch_regs, control); 35479a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, switch_regs, stat_port_en); 35489a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, switch_regs, ptype); 35499a391c7bSWingMan Kwok 35509a391c7bSWingMan Kwok /* Host port registers */ 35519a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, host_port_regs, port_vlan); 35529a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, host_port_regs, rx_maxlen); 35539a391c7bSWingMan Kwok 35549a391c7bSWingMan Kwok /* For NU only. 2U does not need tx_pri_map. 35559a391c7bSWingMan Kwok * NU cppi port 0 tx pkt streaming interface has (n-1)*8 egress threads 35569a391c7bSWingMan Kwok * while 2U has only 1 such thread 35579a391c7bSWingMan Kwok */ 35589a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, host_port_regs, tx_pri_map); 35599a391c7bSWingMan Kwok return 0; 35609a391c7bSWingMan Kwok } 35619a391c7bSWingMan Kwok 35626f8d3f33SWingman Kwok static int gbe_probe(struct netcp_device *netcp_device, struct device *dev, 35636f8d3f33SWingman Kwok struct device_node *node, void **inst_priv) 35646f8d3f33SWingman Kwok { 35656f8d3f33SWingman Kwok struct device_node *interfaces, *interface; 35666f8d3f33SWingman Kwok struct device_node *secondary_ports; 35676f8d3f33SWingman Kwok struct cpsw_ale_params ale_params; 35686f8d3f33SWingman Kwok struct gbe_priv *gbe_dev; 35696f8d3f33SWingman Kwok u32 slave_num; 3570489e8a2fSWingMan Kwok int i, ret = 0; 35716f8d3f33SWingman Kwok 35726f8d3f33SWingman Kwok if (!node) { 35736f8d3f33SWingman Kwok dev_err(dev, "device tree info unavailable\n"); 35746f8d3f33SWingman Kwok return -ENODEV; 35756f8d3f33SWingman Kwok } 35766f8d3f33SWingman Kwok 35776f8d3f33SWingman Kwok gbe_dev = devm_kzalloc(dev, sizeof(struct gbe_priv), GFP_KERNEL); 35786f8d3f33SWingman Kwok if (!gbe_dev) 35796f8d3f33SWingman Kwok return -ENOMEM; 35806f8d3f33SWingman Kwok 35819a391c7bSWingMan Kwok if (of_device_is_compatible(node, "ti,netcp-gbe-5") || 35829a391c7bSWingMan Kwok of_device_is_compatible(node, "ti,netcp-gbe")) { 35839a391c7bSWingMan Kwok gbe_dev->max_num_slaves = 4; 35849a391c7bSWingMan Kwok } else if (of_device_is_compatible(node, "ti,netcp-gbe-9")) { 35859a391c7bSWingMan Kwok gbe_dev->max_num_slaves = 8; 35869a391c7bSWingMan Kwok } else if (of_device_is_compatible(node, "ti,netcp-gbe-2")) { 35879a391c7bSWingMan Kwok gbe_dev->max_num_slaves = 1; 35888585661bSWingMan Kwok gbe_module.set_rx_mode = gbe_set_rx_mode; 35899a391c7bSWingMan Kwok } else if (of_device_is_compatible(node, "ti,netcp-xgbe")) { 35909a391c7bSWingMan Kwok gbe_dev->max_num_slaves = 2; 35919a391c7bSWingMan Kwok } else { 35929a391c7bSWingMan Kwok dev_err(dev, "device tree node for unknown device\n"); 35939a391c7bSWingMan Kwok return -EINVAL; 35949a391c7bSWingMan Kwok } 35959a391c7bSWingMan Kwok gbe_dev->max_num_ports = gbe_dev->max_num_slaves + 1; 35969a391c7bSWingMan Kwok 35976f8d3f33SWingman Kwok gbe_dev->dev = dev; 35986f8d3f33SWingman Kwok gbe_dev->netcp_device = netcp_device; 35996f8d3f33SWingman Kwok gbe_dev->rx_packet_max = NETCP_MAX_FRAME_SIZE; 36006f8d3f33SWingman Kwok 36016f8d3f33SWingman Kwok /* init the hw stats lock */ 36026f8d3f33SWingman Kwok spin_lock_init(&gbe_dev->hw_stats_lock); 36036f8d3f33SWingman Kwok 36046f8d3f33SWingman Kwok if (of_find_property(node, "enable-ale", NULL)) { 36056f8d3f33SWingman Kwok gbe_dev->enable_ale = true; 36066f8d3f33SWingman Kwok dev_info(dev, "ALE enabled\n"); 36076f8d3f33SWingman Kwok } else { 36086f8d3f33SWingman Kwok gbe_dev->enable_ale = false; 36096f8d3f33SWingman Kwok dev_dbg(dev, "ALE bypass enabled*\n"); 36106f8d3f33SWingman Kwok } 36116f8d3f33SWingman Kwok 36126f8d3f33SWingman Kwok ret = of_property_read_u32(node, "tx-queue", 36136f8d3f33SWingman Kwok &gbe_dev->tx_queue_id); 36146f8d3f33SWingman Kwok if (ret < 0) { 36156f8d3f33SWingman Kwok dev_err(dev, "missing tx_queue parameter\n"); 36166f8d3f33SWingman Kwok gbe_dev->tx_queue_id = GBE_TX_QUEUE; 36176f8d3f33SWingman Kwok } 36186f8d3f33SWingman Kwok 36196f8d3f33SWingman Kwok ret = of_property_read_string(node, "tx-channel", 36206f8d3f33SWingman Kwok &gbe_dev->dma_chan_name); 36216f8d3f33SWingman Kwok if (ret < 0) { 36226f8d3f33SWingman Kwok dev_err(dev, "missing \"tx-channel\" parameter\n"); 362331a184b7SKaricheri, Muralidharan return -EINVAL; 36246f8d3f33SWingman Kwok } 36256f8d3f33SWingman Kwok 3626bf5849f1SRob Herring if (of_node_name_eq(node, "gbe")) { 36276f8d3f33SWingman Kwok ret = get_gbe_resource_version(gbe_dev, node); 36286f8d3f33SWingman Kwok if (ret) 362931a184b7SKaricheri, Muralidharan return ret; 36306f8d3f33SWingman Kwok 36319a391c7bSWingMan Kwok dev_dbg(dev, "ss_version: 0x%08x\n", gbe_dev->ss_version); 36329a391c7bSWingMan Kwok 36332953586dSMurali Karicheri if (IS_SS_ID_VER_14(gbe_dev)) 36346f8d3f33SWingman Kwok ret = set_gbe_ethss14_priv(gbe_dev, node); 36359a391c7bSWingMan Kwok else if (IS_SS_ID_MU(gbe_dev)) 36369a391c7bSWingMan Kwok ret = set_gbenu_ethss_priv(gbe_dev, node); 36379a391c7bSWingMan Kwok else 36389a391c7bSWingMan Kwok ret = -ENODEV; 36399a391c7bSWingMan Kwok 3640bf5849f1SRob Herring } else if (of_node_name_eq(node, "xgbe")) { 364190cff9e2SWingman Kwok ret = set_xgbe_ethss10_priv(gbe_dev, node); 364290cff9e2SWingman Kwok if (ret) 364331a184b7SKaricheri, Muralidharan return ret; 364490cff9e2SWingman Kwok ret = netcp_xgbe_serdes_init(gbe_dev->xgbe_serdes_regs, 364590cff9e2SWingman Kwok gbe_dev->ss_regs); 36466f8d3f33SWingman Kwok } else { 364721c328dcSRob Herring dev_err(dev, "unknown GBE node(%pOFn)\n", node); 36486f8d3f33SWingman Kwok ret = -ENODEV; 36496f8d3f33SWingman Kwok } 36506f8d3f33SWingman Kwok 365131a184b7SKaricheri, Muralidharan if (ret) 365231a184b7SKaricheri, Muralidharan return ret; 365331a184b7SKaricheri, Muralidharan 36546f8d3f33SWingman Kwok interfaces = of_get_child_by_name(node, "interfaces"); 36556f8d3f33SWingman Kwok if (!interfaces) 36566f8d3f33SWingman Kwok dev_err(dev, "could not find interfaces\n"); 36576f8d3f33SWingman Kwok 36586f8d3f33SWingman Kwok ret = netcp_txpipe_init(&gbe_dev->tx_pipe, netcp_device, 36596f8d3f33SWingman Kwok gbe_dev->dma_chan_name, gbe_dev->tx_queue_id); 366075eac7b5SWen Yang if (ret) { 366175eac7b5SWen Yang of_node_put(interfaces); 366231a184b7SKaricheri, Muralidharan return ret; 366375eac7b5SWen Yang } 36646f8d3f33SWingman Kwok 36656f8d3f33SWingman Kwok ret = netcp_txpipe_open(&gbe_dev->tx_pipe); 366675eac7b5SWen Yang if (ret) { 366775eac7b5SWen Yang of_node_put(interfaces); 366831a184b7SKaricheri, Muralidharan return ret; 366975eac7b5SWen Yang } 36706f8d3f33SWingman Kwok 36716f8d3f33SWingman Kwok /* Create network interfaces */ 36726f8d3f33SWingman Kwok INIT_LIST_HEAD(&gbe_dev->gbe_intf_head); 36736f8d3f33SWingman Kwok for_each_child_of_node(interfaces, interface) { 36746f8d3f33SWingman Kwok ret = of_property_read_u32(interface, "slave-port", &slave_num); 36756f8d3f33SWingman Kwok if (ret) { 367621c328dcSRob Herring dev_err(dev, "missing slave-port parameter, skipping interface configuration for %pOFn\n", 367721c328dcSRob Herring interface); 36786f8d3f33SWingman Kwok continue; 36796f8d3f33SWingman Kwok } 36806f8d3f33SWingman Kwok gbe_dev->num_slaves++; 3681bd252796SJulia Lawall if (gbe_dev->num_slaves >= gbe_dev->max_num_slaves) { 3682bd252796SJulia Lawall of_node_put(interface); 36839a391c7bSWingMan Kwok break; 36846f8d3f33SWingman Kwok } 3685bd252796SJulia Lawall } 368631a184b7SKaricheri, Muralidharan of_node_put(interfaces); 36876f8d3f33SWingman Kwok 36886f8d3f33SWingman Kwok if (!gbe_dev->num_slaves) 36896f8d3f33SWingman Kwok dev_warn(dev, "No network interface configured\n"); 36906f8d3f33SWingman Kwok 36916f8d3f33SWingman Kwok /* Initialize Secondary slave ports */ 36926f8d3f33SWingman Kwok secondary_ports = of_get_child_by_name(node, "secondary-slave-ports"); 36936f8d3f33SWingman Kwok INIT_LIST_HEAD(&gbe_dev->secondary_slaves); 36949a391c7bSWingMan Kwok if (secondary_ports && (gbe_dev->num_slaves < gbe_dev->max_num_slaves)) 36956f8d3f33SWingman Kwok init_secondary_ports(gbe_dev, secondary_ports); 36966f8d3f33SWingman Kwok of_node_put(secondary_ports); 36976f8d3f33SWingman Kwok 36986f8d3f33SWingman Kwok if (!gbe_dev->num_slaves) { 369931a184b7SKaricheri, Muralidharan dev_err(dev, 370031a184b7SKaricheri, Muralidharan "No network interface or secondary ports configured\n"); 37016f8d3f33SWingman Kwok ret = -ENODEV; 370231a184b7SKaricheri, Muralidharan goto free_sec_ports; 37036f8d3f33SWingman Kwok } 37046f8d3f33SWingman Kwok 37056f8d3f33SWingman Kwok memset(&ale_params, 0, sizeof(ale_params)); 37066f8d3f33SWingman Kwok ale_params.dev = gbe_dev->dev; 37076f8d3f33SWingman Kwok ale_params.ale_regs = gbe_dev->ale_reg; 37086f8d3f33SWingman Kwok ale_params.ale_ageout = GBE_DEFAULT_ALE_AGEOUT; 37096f8d3f33SWingman Kwok ale_params.ale_entries = gbe_dev->ale_entries; 37106f8d3f33SWingman Kwok ale_params.ale_ports = gbe_dev->ale_ports; 3711ca47130aSKaricheri, Muralidharan if (IS_SS_ID_MU(gbe_dev)) { 3712ca47130aSKaricheri, Muralidharan ale_params.major_ver_mask = 0x7; 3713ca47130aSKaricheri, Muralidharan ale_params.nu_switch_ale = true; 3714ca47130aSKaricheri, Muralidharan } 37156f8d3f33SWingman Kwok gbe_dev->ale = cpsw_ale_create(&ale_params); 37166f8d3f33SWingman Kwok if (!gbe_dev->ale) { 37176f8d3f33SWingman Kwok dev_err(gbe_dev->dev, "error initializing ale engine\n"); 37186f8d3f33SWingman Kwok ret = -ENODEV; 371931a184b7SKaricheri, Muralidharan goto free_sec_ports; 37206f8d3f33SWingman Kwok } else { 37216f8d3f33SWingman Kwok dev_dbg(gbe_dev->dev, "Created a gbe ale engine\n"); 37226f8d3f33SWingman Kwok } 37236f8d3f33SWingman Kwok 37246246168bSWingMan Kwok gbe_dev->cpts = cpts_create(gbe_dev->dev, gbe_dev->cpts_reg, node); 37256246168bSWingMan Kwok if (IS_ENABLED(CONFIG_TI_CPTS) && IS_ERR(gbe_dev->cpts)) { 37266246168bSWingMan Kwok ret = PTR_ERR(gbe_dev->cpts); 37276246168bSWingMan Kwok goto free_sec_ports; 37286246168bSWingMan Kwok } 37296246168bSWingMan Kwok 37306f8d3f33SWingman Kwok /* initialize host port */ 37316f8d3f33SWingman Kwok gbe_init_host_port(gbe_dev); 37326f8d3f33SWingman Kwok 3733489e8a2fSWingMan Kwok spin_lock_bh(&gbe_dev->hw_stats_lock); 3734489e8a2fSWingMan Kwok for (i = 0; i < gbe_dev->num_stats_mods; i++) { 37352953586dSMurali Karicheri if (IS_SS_ID_VER_14(gbe_dev)) 3736489e8a2fSWingMan Kwok gbe_reset_mod_stats_ver14(gbe_dev, i); 3737489e8a2fSWingMan Kwok else 3738489e8a2fSWingMan Kwok gbe_reset_mod_stats(gbe_dev, i); 3739489e8a2fSWingMan Kwok } 3740489e8a2fSWingMan Kwok spin_unlock_bh(&gbe_dev->hw_stats_lock); 3741489e8a2fSWingMan Kwok 3742e99e88a9SKees Cook timer_setup(&gbe_dev->timer, netcp_ethss_timer, 0); 37436f8d3f33SWingman Kwok gbe_dev->timer.expires = jiffies + GBE_TIMER_INTERVAL; 37446f8d3f33SWingman Kwok add_timer(&gbe_dev->timer); 37456f8d3f33SWingman Kwok *inst_priv = gbe_dev; 37466f8d3f33SWingman Kwok return 0; 37476f8d3f33SWingman Kwok 374831a184b7SKaricheri, Muralidharan free_sec_ports: 374931a184b7SKaricheri, Muralidharan free_secondary_ports(gbe_dev); 37506f8d3f33SWingman Kwok return ret; 37516f8d3f33SWingman Kwok } 37526f8d3f33SWingman Kwok 37536f8d3f33SWingman Kwok static int gbe_attach(void *inst_priv, struct net_device *ndev, 37546f8d3f33SWingman Kwok struct device_node *node, void **intf_priv) 37556f8d3f33SWingman Kwok { 37566f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = inst_priv; 37576f8d3f33SWingman Kwok struct gbe_intf *gbe_intf; 37586f8d3f33SWingman Kwok int ret; 37596f8d3f33SWingman Kwok 37606f8d3f33SWingman Kwok if (!node) { 37616f8d3f33SWingman Kwok dev_err(gbe_dev->dev, "interface node not available\n"); 37626f8d3f33SWingman Kwok return -ENODEV; 37636f8d3f33SWingman Kwok } 37646f8d3f33SWingman Kwok 37656f8d3f33SWingman Kwok gbe_intf = devm_kzalloc(gbe_dev->dev, sizeof(*gbe_intf), GFP_KERNEL); 37666f8d3f33SWingman Kwok if (!gbe_intf) 37676f8d3f33SWingman Kwok return -ENOMEM; 37686f8d3f33SWingman Kwok 37696f8d3f33SWingman Kwok gbe_intf->ndev = ndev; 37706f8d3f33SWingman Kwok gbe_intf->dev = gbe_dev->dev; 37716f8d3f33SWingman Kwok gbe_intf->gbe_dev = gbe_dev; 37726f8d3f33SWingman Kwok 37736f8d3f33SWingman Kwok gbe_intf->slave = devm_kzalloc(gbe_dev->dev, 37746f8d3f33SWingman Kwok sizeof(*gbe_intf->slave), 37756f8d3f33SWingman Kwok GFP_KERNEL); 37766f8d3f33SWingman Kwok if (!gbe_intf->slave) { 37776f8d3f33SWingman Kwok ret = -ENOMEM; 37786f8d3f33SWingman Kwok goto fail; 37796f8d3f33SWingman Kwok } 37806f8d3f33SWingman Kwok 37816f8d3f33SWingman Kwok if (init_slave(gbe_dev, gbe_intf->slave, node)) { 37826f8d3f33SWingman Kwok ret = -ENODEV; 37836f8d3f33SWingman Kwok goto fail; 37846f8d3f33SWingman Kwok } 37856f8d3f33SWingman Kwok 37866f8d3f33SWingman Kwok gbe_intf->tx_pipe = gbe_dev->tx_pipe; 37876f8d3f33SWingman Kwok ndev->ethtool_ops = &keystone_ethtool_ops; 37886f8d3f33SWingman Kwok list_add_tail(&gbe_intf->gbe_intf_list, &gbe_dev->gbe_intf_head); 37896f8d3f33SWingman Kwok *intf_priv = gbe_intf; 37906f8d3f33SWingman Kwok return 0; 37916f8d3f33SWingman Kwok 37926f8d3f33SWingman Kwok fail: 37936f8d3f33SWingman Kwok if (gbe_intf->slave) 37946f8d3f33SWingman Kwok devm_kfree(gbe_dev->dev, gbe_intf->slave); 37956f8d3f33SWingman Kwok if (gbe_intf) 37966f8d3f33SWingman Kwok devm_kfree(gbe_dev->dev, gbe_intf); 37976f8d3f33SWingman Kwok return ret; 37986f8d3f33SWingman Kwok } 37996f8d3f33SWingman Kwok 38006f8d3f33SWingman Kwok static int gbe_release(void *intf_priv) 38016f8d3f33SWingman Kwok { 38026f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv; 38036f8d3f33SWingman Kwok 38046f8d3f33SWingman Kwok gbe_intf->ndev->ethtool_ops = NULL; 38056f8d3f33SWingman Kwok list_del(&gbe_intf->gbe_intf_list); 38066f8d3f33SWingman Kwok devm_kfree(gbe_intf->dev, gbe_intf->slave); 38076f8d3f33SWingman Kwok devm_kfree(gbe_intf->dev, gbe_intf); 38086f8d3f33SWingman Kwok return 0; 38096f8d3f33SWingman Kwok } 38106f8d3f33SWingman Kwok 38116f8d3f33SWingman Kwok static int gbe_remove(struct netcp_device *netcp_device, void *inst_priv) 38126f8d3f33SWingman Kwok { 38136f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = inst_priv; 38146f8d3f33SWingman Kwok 38156f8d3f33SWingman Kwok del_timer_sync(&gbe_dev->timer); 38166246168bSWingMan Kwok cpts_release(gbe_dev->cpts); 38176f8d3f33SWingman Kwok cpsw_ale_stop(gbe_dev->ale); 38186f8d3f33SWingman Kwok netcp_txpipe_close(&gbe_dev->tx_pipe); 38196f8d3f33SWingman Kwok free_secondary_ports(gbe_dev); 38206f8d3f33SWingman Kwok 38216f8d3f33SWingman Kwok if (!list_empty(&gbe_dev->gbe_intf_head)) 382231a184b7SKaricheri, Muralidharan dev_alert(gbe_dev->dev, 382331a184b7SKaricheri, Muralidharan "unreleased ethss interfaces present\n"); 38246f8d3f33SWingman Kwok 38256f8d3f33SWingman Kwok return 0; 38266f8d3f33SWingman Kwok } 38276f8d3f33SWingman Kwok 38286f8d3f33SWingman Kwok static struct netcp_module gbe_module = { 38296f8d3f33SWingman Kwok .name = GBE_MODULE_NAME, 38306f8d3f33SWingman Kwok .owner = THIS_MODULE, 38316f8d3f33SWingman Kwok .primary = true, 38326f8d3f33SWingman Kwok .probe = gbe_probe, 38336f8d3f33SWingman Kwok .open = gbe_open, 38346f8d3f33SWingman Kwok .close = gbe_close, 38356f8d3f33SWingman Kwok .remove = gbe_remove, 38366f8d3f33SWingman Kwok .attach = gbe_attach, 38376f8d3f33SWingman Kwok .release = gbe_release, 38386f8d3f33SWingman Kwok .add_addr = gbe_add_addr, 38396f8d3f33SWingman Kwok .del_addr = gbe_del_addr, 38406f8d3f33SWingman Kwok .add_vid = gbe_add_vid, 38416f8d3f33SWingman Kwok .del_vid = gbe_del_vid, 38426f8d3f33SWingman Kwok .ioctl = gbe_ioctl, 38436f8d3f33SWingman Kwok }; 38446f8d3f33SWingman Kwok 384590cff9e2SWingman Kwok static struct netcp_module xgbe_module = { 384690cff9e2SWingman Kwok .name = XGBE_MODULE_NAME, 384790cff9e2SWingman Kwok .owner = THIS_MODULE, 384890cff9e2SWingman Kwok .primary = true, 384990cff9e2SWingman Kwok .probe = gbe_probe, 385090cff9e2SWingman Kwok .open = gbe_open, 385190cff9e2SWingman Kwok .close = gbe_close, 385290cff9e2SWingman Kwok .remove = gbe_remove, 385390cff9e2SWingman Kwok .attach = gbe_attach, 385490cff9e2SWingman Kwok .release = gbe_release, 385590cff9e2SWingman Kwok .add_addr = gbe_add_addr, 385690cff9e2SWingman Kwok .del_addr = gbe_del_addr, 385790cff9e2SWingman Kwok .add_vid = gbe_add_vid, 385890cff9e2SWingman Kwok .del_vid = gbe_del_vid, 385990cff9e2SWingman Kwok .ioctl = gbe_ioctl, 386090cff9e2SWingman Kwok }; 386190cff9e2SWingman Kwok 38626f8d3f33SWingman Kwok static int __init keystone_gbe_init(void) 38636f8d3f33SWingman Kwok { 38646f8d3f33SWingman Kwok int ret; 38656f8d3f33SWingman Kwok 38666f8d3f33SWingman Kwok ret = netcp_register_module(&gbe_module); 38676f8d3f33SWingman Kwok if (ret) 38686f8d3f33SWingman Kwok return ret; 38696f8d3f33SWingman Kwok 387090cff9e2SWingman Kwok ret = netcp_register_module(&xgbe_module); 387190cff9e2SWingman Kwok if (ret) 387290cff9e2SWingman Kwok return ret; 387390cff9e2SWingman Kwok 38746f8d3f33SWingman Kwok return 0; 38756f8d3f33SWingman Kwok } 38766f8d3f33SWingman Kwok module_init(keystone_gbe_init); 38776f8d3f33SWingman Kwok 38786f8d3f33SWingman Kwok static void __exit keystone_gbe_exit(void) 38796f8d3f33SWingman Kwok { 38806f8d3f33SWingman Kwok netcp_unregister_module(&gbe_module); 388190cff9e2SWingman Kwok netcp_unregister_module(&xgbe_module); 38826f8d3f33SWingman Kwok } 38836f8d3f33SWingman Kwok module_exit(keystone_gbe_exit); 388458c11b5fSKaricheri, Muralidharan 388558c11b5fSKaricheri, Muralidharan MODULE_LICENSE("GPL v2"); 388658c11b5fSKaricheri, Muralidharan MODULE_DESCRIPTION("TI NETCP ETHSS driver for Keystone SOCs"); 388758c11b5fSKaricheri, Muralidharan MODULE_AUTHOR("Sandeep Nair <sandeep_n@ti.com"); 3888