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> 246f8d3f33SWingman Kwok #include <linux/of_address.h> 256f8d3f33SWingman Kwok #include <linux/if_vlan.h> 266246168bSWingMan Kwok #include <linux/ptp_classify.h> 276246168bSWingMan Kwok #include <linux/net_tstamp.h> 286f8d3f33SWingman Kwok #include <linux/ethtool.h> 296f8d3f33SWingman Kwok 302733d7b8SGrygorii Strashko #include "cpsw.h" 316f8d3f33SWingman Kwok #include "cpsw_ale.h" 326f8d3f33SWingman Kwok #include "netcp.h" 336246168bSWingMan Kwok #include "cpts.h" 346f8d3f33SWingman Kwok 356f8d3f33SWingman Kwok #define NETCP_DRIVER_NAME "TI KeyStone Ethernet Driver" 366f8d3f33SWingman Kwok #define NETCP_DRIVER_VERSION "v1.0" 376f8d3f33SWingman Kwok 386f8d3f33SWingman Kwok #define GBE_IDENT(reg) ((reg >> 16) & 0xffff) 396f8d3f33SWingman Kwok #define GBE_MAJOR_VERSION(reg) (reg >> 8 & 0x7) 406f8d3f33SWingman Kwok #define GBE_MINOR_VERSION(reg) (reg & 0xff) 416f8d3f33SWingman Kwok #define GBE_RTL_VERSION(reg) ((reg >> 11) & 0x1f) 426f8d3f33SWingman Kwok 436f8d3f33SWingman Kwok /* 1G Ethernet SS defines */ 446f8d3f33SWingman Kwok #define GBE_MODULE_NAME "netcp-gbe" 452953586dSMurali Karicheri #define GBE_SS_VERSION_14 0x4ed2 466f8d3f33SWingman Kwok 4721e0e0ddSKaricheri, Muralidharan #define GBE_SS_REG_INDEX 0 4821e0e0ddSKaricheri, Muralidharan #define GBE_SGMII34_REG_INDEX 1 4921e0e0ddSKaricheri, Muralidharan #define GBE_SM_REG_INDEX 2 5021e0e0ddSKaricheri, Muralidharan /* offset relative to base of GBE_SS_REG_INDEX */ 516f8d3f33SWingman Kwok #define GBE13_SGMII_MODULE_OFFSET 0x100 5221e0e0ddSKaricheri, Muralidharan /* offset relative to base of GBE_SM_REG_INDEX */ 5321e0e0ddSKaricheri, Muralidharan #define GBE13_HOST_PORT_OFFSET 0x34 5421e0e0ddSKaricheri, Muralidharan #define GBE13_SLAVE_PORT_OFFSET 0x60 5521e0e0ddSKaricheri, Muralidharan #define GBE13_EMAC_OFFSET 0x100 5621e0e0ddSKaricheri, Muralidharan #define GBE13_SLAVE_PORT2_OFFSET 0x200 5721e0e0ddSKaricheri, Muralidharan #define GBE13_HW_STATS_OFFSET 0x300 586246168bSWingMan Kwok #define GBE13_CPTS_OFFSET 0x500 5921e0e0ddSKaricheri, Muralidharan #define GBE13_ALE_OFFSET 0x600 606f8d3f33SWingman Kwok #define GBE13_HOST_PORT_NUM 0 616f8d3f33SWingman Kwok #define GBE13_NUM_ALE_ENTRIES 1024 626f8d3f33SWingman Kwok 639a391c7bSWingMan Kwok /* 1G Ethernet NU SS defines */ 649a391c7bSWingMan Kwok #define GBENU_MODULE_NAME "netcp-gbenu" 659a391c7bSWingMan Kwok #define GBE_SS_ID_NU 0x4ee6 669a391c7bSWingMan Kwok #define GBE_SS_ID_2U 0x4ee8 679a391c7bSWingMan Kwok 689a391c7bSWingMan Kwok #define IS_SS_ID_MU(d) \ 699a391c7bSWingMan Kwok ((GBE_IDENT((d)->ss_version) == GBE_SS_ID_NU) || \ 709a391c7bSWingMan Kwok (GBE_IDENT((d)->ss_version) == GBE_SS_ID_2U)) 719a391c7bSWingMan Kwok 729a391c7bSWingMan Kwok #define IS_SS_ID_NU(d) \ 739a391c7bSWingMan Kwok (GBE_IDENT((d)->ss_version) == GBE_SS_ID_NU) 749a391c7bSWingMan Kwok 752953586dSMurali Karicheri #define IS_SS_ID_VER_14(d) \ 762953586dSMurali Karicheri (GBE_IDENT((d)->ss_version) == GBE_SS_VERSION_14) 77775f9535SMurali Karicheri #define IS_SS_ID_2U(d) \ 78775f9535SMurali Karicheri (GBE_IDENT((d)->ss_version) == GBE_SS_ID_2U) 792953586dSMurali Karicheri 809a391c7bSWingMan Kwok #define GBENU_SS_REG_INDEX 0 819a391c7bSWingMan Kwok #define GBENU_SM_REG_INDEX 1 829a391c7bSWingMan Kwok #define GBENU_SGMII_MODULE_OFFSET 0x100 839a391c7bSWingMan Kwok #define GBENU_HOST_PORT_OFFSET 0x1000 849a391c7bSWingMan Kwok #define GBENU_SLAVE_PORT_OFFSET 0x2000 859a391c7bSWingMan Kwok #define GBENU_EMAC_OFFSET 0x2330 869a391c7bSWingMan Kwok #define GBENU_HW_STATS_OFFSET 0x1a000 876246168bSWingMan Kwok #define GBENU_CPTS_OFFSET 0x1d000 889a391c7bSWingMan Kwok #define GBENU_ALE_OFFSET 0x1e000 899a391c7bSWingMan Kwok #define GBENU_HOST_PORT_NUM 0 908c85151dSWingMan Kwok #define GBENU_SGMII_MODULE_SIZE 0x100 919a391c7bSWingMan Kwok 9290cff9e2SWingman Kwok /* 10G Ethernet SS defines */ 9390cff9e2SWingman Kwok #define XGBE_MODULE_NAME "netcp-xgbe" 942953586dSMurali Karicheri #define XGBE_SS_VERSION_10 0x4ee4 9590cff9e2SWingman Kwok 9621e0e0ddSKaricheri, Muralidharan #define XGBE_SS_REG_INDEX 0 9721e0e0ddSKaricheri, Muralidharan #define XGBE_SM_REG_INDEX 1 9821e0e0ddSKaricheri, Muralidharan #define XGBE_SERDES_REG_INDEX 2 9921e0e0ddSKaricheri, Muralidharan 10021e0e0ddSKaricheri, Muralidharan /* offset relative to base of XGBE_SS_REG_INDEX */ 10190cff9e2SWingman Kwok #define XGBE10_SGMII_MODULE_OFFSET 0x100 1024c0ef231SWingMan Kwok #define IS_SS_ID_XGBE(d) ((d)->ss_version == XGBE_SS_VERSION_10) 10321e0e0ddSKaricheri, Muralidharan /* offset relative to base of XGBE_SM_REG_INDEX */ 10421e0e0ddSKaricheri, Muralidharan #define XGBE10_HOST_PORT_OFFSET 0x34 10521e0e0ddSKaricheri, Muralidharan #define XGBE10_SLAVE_PORT_OFFSET 0x64 10621e0e0ddSKaricheri, Muralidharan #define XGBE10_EMAC_OFFSET 0x400 1076246168bSWingMan Kwok #define XGBE10_CPTS_OFFSET 0x600 10821e0e0ddSKaricheri, Muralidharan #define XGBE10_ALE_OFFSET 0x700 10921e0e0ddSKaricheri, Muralidharan #define XGBE10_HW_STATS_OFFSET 0x800 11090cff9e2SWingman Kwok #define XGBE10_HOST_PORT_NUM 0 1117938a0d7SKaricheri, Muralidharan #define XGBE10_NUM_ALE_ENTRIES 2048 11290cff9e2SWingman Kwok 1136f8d3f33SWingman Kwok #define GBE_TIMER_INTERVAL (HZ / 2) 1146f8d3f33SWingman Kwok 1156f8d3f33SWingman Kwok /* Soft reset register values */ 1166f8d3f33SWingman Kwok #define SOFT_RESET_MASK BIT(0) 1176f8d3f33SWingman Kwok #define SOFT_RESET BIT(0) 1186f8d3f33SWingman Kwok #define DEVICE_EMACSL_RESET_POLL_COUNT 100 1196f8d3f33SWingman Kwok #define GMACSL_RET_WARN_RESET_INCOMPLETE -2 1206f8d3f33SWingman Kwok 1216f8d3f33SWingman Kwok #define MACSL_RX_ENABLE_CSF BIT(23) 1226f8d3f33SWingman Kwok #define MACSL_ENABLE_EXT_CTL BIT(18) 12390cff9e2SWingman Kwok #define MACSL_XGMII_ENABLE BIT(13) 12490cff9e2SWingman Kwok #define MACSL_XGIG_MODE BIT(8) 1256f8d3f33SWingman Kwok #define MACSL_GIG_MODE BIT(7) 1266f8d3f33SWingman Kwok #define MACSL_GMII_ENABLE BIT(5) 1276f8d3f33SWingman Kwok #define MACSL_FULLDUPLEX BIT(0) 1286f8d3f33SWingman Kwok 1296f8d3f33SWingman Kwok #define GBE_CTL_P0_ENABLE BIT(2) 1304cd85a61SKaricheri, Muralidharan #define ETH_SW_CTL_P0_TX_CRC_REMOVE BIT(13) 1319a391c7bSWingMan Kwok #define GBE13_REG_VAL_STAT_ENABLE_ALL 0xff 13290cff9e2SWingman Kwok #define XGBE_REG_VAL_STAT_ENABLE_ALL 0xf 1336f8d3f33SWingman Kwok #define GBE_STATS_CD_SEL BIT(28) 1346f8d3f33SWingman Kwok 1356f8d3f33SWingman Kwok #define GBE_PORT_MASK(x) (BIT(x) - 1) 1366f8d3f33SWingman Kwok #define GBE_MASK_NO_PORTS 0 1376f8d3f33SWingman Kwok 1386f8d3f33SWingman Kwok #define GBE_DEF_1G_MAC_CONTROL \ 1396f8d3f33SWingman Kwok (MACSL_GIG_MODE | MACSL_GMII_ENABLE | \ 1406f8d3f33SWingman Kwok MACSL_ENABLE_EXT_CTL | MACSL_RX_ENABLE_CSF) 1416f8d3f33SWingman Kwok 14290cff9e2SWingman Kwok #define GBE_DEF_10G_MAC_CONTROL \ 14390cff9e2SWingman Kwok (MACSL_XGIG_MODE | MACSL_XGMII_ENABLE | \ 14490cff9e2SWingman Kwok MACSL_ENABLE_EXT_CTL | MACSL_RX_ENABLE_CSF) 14590cff9e2SWingman Kwok 1466f8d3f33SWingman Kwok #define GBE_STATSA_MODULE 0 1476f8d3f33SWingman Kwok #define GBE_STATSB_MODULE 1 1486f8d3f33SWingman Kwok #define GBE_STATSC_MODULE 2 1496f8d3f33SWingman Kwok #define GBE_STATSD_MODULE 3 1506f8d3f33SWingman Kwok 1519a391c7bSWingMan Kwok #define GBENU_STATS0_MODULE 0 1529a391c7bSWingMan Kwok #define GBENU_STATS1_MODULE 1 1539a391c7bSWingMan Kwok #define GBENU_STATS2_MODULE 2 1549a391c7bSWingMan Kwok #define GBENU_STATS3_MODULE 3 1559a391c7bSWingMan Kwok #define GBENU_STATS4_MODULE 4 1569a391c7bSWingMan Kwok #define GBENU_STATS5_MODULE 5 1579a391c7bSWingMan Kwok #define GBENU_STATS6_MODULE 6 1589a391c7bSWingMan Kwok #define GBENU_STATS7_MODULE 7 1599a391c7bSWingMan Kwok #define GBENU_STATS8_MODULE 8 1609a391c7bSWingMan Kwok 16190cff9e2SWingman Kwok #define XGBE_STATS0_MODULE 0 16290cff9e2SWingman Kwok #define XGBE_STATS1_MODULE 1 16390cff9e2SWingman Kwok #define XGBE_STATS2_MODULE 2 16490cff9e2SWingman Kwok 1656f8d3f33SWingman Kwok /* s: 0-based slave_port */ 1668c85151dSWingMan Kwok #define SGMII_BASE(d, s) \ 1678c85151dSWingMan Kwok (((s) < 2) ? (d)->sgmii_port_regs : (d)->sgmii_port34_regs) 1686f8d3f33SWingman Kwok 1696f8d3f33SWingman Kwok #define GBE_TX_QUEUE 648 1706f8d3f33SWingman Kwok #define GBE_TXHOOK_ORDER 0 1716246168bSWingMan Kwok #define GBE_RXHOOK_ORDER 0 1726f8d3f33SWingman Kwok #define GBE_DEFAULT_ALE_AGEOUT 30 17390cff9e2SWingman Kwok #define SLAVE_LINK_IS_XGMII(s) ((s)->link_interface >= XGMII_LINK_MAC_PHY) 1746f8d3f33SWingman Kwok #define NETCP_LINK_STATE_INVALID -1 1756f8d3f33SWingman Kwok 1766f8d3f33SWingman Kwok #define GBE_SET_REG_OFS(p, rb, rn) p->rb##_ofs.rn = \ 1776f8d3f33SWingman Kwok offsetof(struct gbe##_##rb, rn) 1789a391c7bSWingMan Kwok #define GBENU_SET_REG_OFS(p, rb, rn) p->rb##_ofs.rn = \ 1799a391c7bSWingMan Kwok offsetof(struct gbenu##_##rb, rn) 18090cff9e2SWingman Kwok #define XGBE_SET_REG_OFS(p, rb, rn) p->rb##_ofs.rn = \ 18190cff9e2SWingman Kwok offsetof(struct xgbe##_##rb, rn) 1826f8d3f33SWingman Kwok #define GBE_REG_ADDR(p, rb, rn) (p->rb + p->rb##_ofs.rn) 1836f8d3f33SWingman Kwok 1849a391c7bSWingMan Kwok #define HOST_TX_PRI_MAP_DEFAULT 0x00000000 1859a391c7bSWingMan Kwok 1866246168bSWingMan Kwok #if IS_ENABLED(CONFIG_TI_CPTS) 1876246168bSWingMan Kwok /* Px_TS_CTL register fields */ 1886246168bSWingMan Kwok #define TS_RX_ANX_F_EN BIT(0) 1896246168bSWingMan Kwok #define TS_RX_VLAN_LT1_EN BIT(1) 1906246168bSWingMan Kwok #define TS_RX_VLAN_LT2_EN BIT(2) 1916246168bSWingMan Kwok #define TS_RX_ANX_D_EN BIT(3) 1926246168bSWingMan Kwok #define TS_TX_ANX_F_EN BIT(4) 1936246168bSWingMan Kwok #define TS_TX_VLAN_LT1_EN BIT(5) 1946246168bSWingMan Kwok #define TS_TX_VLAN_LT2_EN BIT(6) 1956246168bSWingMan Kwok #define TS_TX_ANX_D_EN BIT(7) 1966246168bSWingMan Kwok #define TS_LT2_EN BIT(8) 1976246168bSWingMan Kwok #define TS_RX_ANX_E_EN BIT(9) 1986246168bSWingMan Kwok #define TS_TX_ANX_E_EN BIT(10) 1996246168bSWingMan Kwok #define TS_MSG_TYPE_EN_SHIFT 16 2006246168bSWingMan Kwok #define TS_MSG_TYPE_EN_MASK 0xffff 2016246168bSWingMan Kwok 2026246168bSWingMan Kwok /* Px_TS_SEQ_LTYPE register fields */ 2036246168bSWingMan Kwok #define TS_SEQ_ID_OFS_SHIFT 16 2046246168bSWingMan Kwok #define TS_SEQ_ID_OFS_MASK 0x3f 2056246168bSWingMan Kwok 2066246168bSWingMan Kwok /* Px_TS_CTL_LTYPE2 register fields */ 2076246168bSWingMan Kwok #define TS_107 BIT(16) 2086246168bSWingMan Kwok #define TS_129 BIT(17) 2096246168bSWingMan Kwok #define TS_130 BIT(18) 2106246168bSWingMan Kwok #define TS_131 BIT(19) 2116246168bSWingMan Kwok #define TS_132 BIT(20) 2126246168bSWingMan Kwok #define TS_319 BIT(21) 2136246168bSWingMan Kwok #define TS_320 BIT(22) 2146246168bSWingMan Kwok #define TS_TTL_NONZERO BIT(23) 2156246168bSWingMan Kwok #define TS_UNI_EN BIT(24) 2166246168bSWingMan Kwok #define TS_UNI_EN_SHIFT 24 2176246168bSWingMan Kwok 2186246168bSWingMan Kwok #define TS_TX_ANX_ALL_EN \ 2196246168bSWingMan Kwok (TS_TX_ANX_D_EN | TS_TX_ANX_E_EN | TS_TX_ANX_F_EN) 2206246168bSWingMan Kwok 2216246168bSWingMan Kwok #define TS_RX_ANX_ALL_EN \ 2226246168bSWingMan Kwok (TS_RX_ANX_D_EN | TS_RX_ANX_E_EN | TS_RX_ANX_F_EN) 2236246168bSWingMan Kwok 2246246168bSWingMan Kwok #define TS_CTL_DST_PORT TS_319 2256246168bSWingMan Kwok #define TS_CTL_DST_PORT_SHIFT 21 2266246168bSWingMan Kwok 2276246168bSWingMan Kwok #define TS_CTL_MADDR_ALL \ 2286246168bSWingMan Kwok (TS_107 | TS_129 | TS_130 | TS_131 | TS_132) 2296246168bSWingMan Kwok 2306246168bSWingMan Kwok #define TS_CTL_MADDR_SHIFT 16 2316246168bSWingMan Kwok 2326246168bSWingMan Kwok /* The PTP event messages - Sync, Delay_Req, Pdelay_Req, and Pdelay_Resp. */ 2336246168bSWingMan Kwok #define EVENT_MSG_BITS (BIT(0) | BIT(1) | BIT(2) | BIT(3)) 2346246168bSWingMan Kwok #endif /* CONFIG_TI_CPTS */ 2356246168bSWingMan Kwok 23690cff9e2SWingman Kwok struct xgbe_ss_regs { 23790cff9e2SWingman Kwok u32 id_ver; 23890cff9e2SWingman Kwok u32 synce_count; 23990cff9e2SWingman Kwok u32 synce_mux; 24090cff9e2SWingman Kwok u32 control; 24190cff9e2SWingman Kwok }; 24290cff9e2SWingman Kwok 24390cff9e2SWingman Kwok struct xgbe_switch_regs { 24490cff9e2SWingman Kwok u32 id_ver; 24590cff9e2SWingman Kwok u32 control; 24690cff9e2SWingman Kwok u32 emcontrol; 24790cff9e2SWingman Kwok u32 stat_port_en; 24890cff9e2SWingman Kwok u32 ptype; 24990cff9e2SWingman Kwok u32 soft_idle; 25090cff9e2SWingman Kwok u32 thru_rate; 25190cff9e2SWingman Kwok u32 gap_thresh; 25290cff9e2SWingman Kwok u32 tx_start_wds; 25390cff9e2SWingman Kwok u32 flow_control; 25490cff9e2SWingman Kwok u32 cppi_thresh; 25590cff9e2SWingman Kwok }; 25690cff9e2SWingman Kwok 25790cff9e2SWingman Kwok struct xgbe_port_regs { 25890cff9e2SWingman Kwok u32 blk_cnt; 25990cff9e2SWingman Kwok u32 port_vlan; 26090cff9e2SWingman Kwok u32 tx_pri_map; 26190cff9e2SWingman Kwok u32 sa_lo; 26290cff9e2SWingman Kwok u32 sa_hi; 26390cff9e2SWingman Kwok u32 ts_ctl; 26490cff9e2SWingman Kwok u32 ts_seq_ltype; 26590cff9e2SWingman Kwok u32 ts_vlan; 26690cff9e2SWingman Kwok u32 ts_ctl_ltype2; 26790cff9e2SWingman Kwok u32 ts_ctl2; 26890cff9e2SWingman Kwok u32 control; 26990cff9e2SWingman Kwok }; 27090cff9e2SWingman Kwok 27190cff9e2SWingman Kwok struct xgbe_host_port_regs { 27290cff9e2SWingman Kwok u32 blk_cnt; 27390cff9e2SWingman Kwok u32 port_vlan; 27490cff9e2SWingman Kwok u32 tx_pri_map; 27590cff9e2SWingman Kwok u32 src_id; 27690cff9e2SWingman Kwok u32 rx_pri_map; 27790cff9e2SWingman Kwok u32 rx_maxlen; 27890cff9e2SWingman Kwok }; 27990cff9e2SWingman Kwok 28090cff9e2SWingman Kwok struct xgbe_emac_regs { 28190cff9e2SWingman Kwok u32 id_ver; 28290cff9e2SWingman Kwok u32 mac_control; 28390cff9e2SWingman Kwok u32 mac_status; 28490cff9e2SWingman Kwok u32 soft_reset; 28590cff9e2SWingman Kwok u32 rx_maxlen; 28690cff9e2SWingman Kwok u32 __reserved_0; 28790cff9e2SWingman Kwok u32 rx_pause; 28890cff9e2SWingman Kwok u32 tx_pause; 28990cff9e2SWingman Kwok u32 em_control; 29090cff9e2SWingman Kwok u32 __reserved_1; 29190cff9e2SWingman Kwok u32 tx_gap; 29290cff9e2SWingman Kwok u32 rsvd[4]; 29390cff9e2SWingman Kwok }; 29490cff9e2SWingman Kwok 29590cff9e2SWingman Kwok struct xgbe_host_hw_stats { 29690cff9e2SWingman Kwok u32 rx_good_frames; 29790cff9e2SWingman Kwok u32 rx_broadcast_frames; 29890cff9e2SWingman Kwok u32 rx_multicast_frames; 29990cff9e2SWingman Kwok u32 __rsvd_0[3]; 30090cff9e2SWingman Kwok u32 rx_oversized_frames; 30190cff9e2SWingman Kwok u32 __rsvd_1; 30290cff9e2SWingman Kwok u32 rx_undersized_frames; 30390cff9e2SWingman Kwok u32 __rsvd_2; 30490cff9e2SWingman Kwok u32 overrun_type4; 30590cff9e2SWingman Kwok u32 overrun_type5; 30690cff9e2SWingman Kwok u32 rx_bytes; 30790cff9e2SWingman Kwok u32 tx_good_frames; 30890cff9e2SWingman Kwok u32 tx_broadcast_frames; 30990cff9e2SWingman Kwok u32 tx_multicast_frames; 31090cff9e2SWingman Kwok u32 __rsvd_3[9]; 31190cff9e2SWingman Kwok u32 tx_bytes; 31290cff9e2SWingman Kwok u32 tx_64byte_frames; 31390cff9e2SWingman Kwok u32 tx_65_to_127byte_frames; 31490cff9e2SWingman Kwok u32 tx_128_to_255byte_frames; 31590cff9e2SWingman Kwok u32 tx_256_to_511byte_frames; 31690cff9e2SWingman Kwok u32 tx_512_to_1023byte_frames; 31790cff9e2SWingman Kwok u32 tx_1024byte_frames; 31890cff9e2SWingman Kwok u32 net_bytes; 31990cff9e2SWingman Kwok u32 rx_sof_overruns; 32090cff9e2SWingman Kwok u32 rx_mof_overruns; 32190cff9e2SWingman Kwok u32 rx_dma_overruns; 32290cff9e2SWingman Kwok }; 32390cff9e2SWingman Kwok 32490cff9e2SWingman Kwok struct xgbe_hw_stats { 32590cff9e2SWingman Kwok u32 rx_good_frames; 32690cff9e2SWingman Kwok u32 rx_broadcast_frames; 32790cff9e2SWingman Kwok u32 rx_multicast_frames; 32890cff9e2SWingman Kwok u32 rx_pause_frames; 32990cff9e2SWingman Kwok u32 rx_crc_errors; 33090cff9e2SWingman Kwok u32 rx_align_code_errors; 33190cff9e2SWingman Kwok u32 rx_oversized_frames; 33290cff9e2SWingman Kwok u32 rx_jabber_frames; 33390cff9e2SWingman Kwok u32 rx_undersized_frames; 33490cff9e2SWingman Kwok u32 rx_fragments; 33590cff9e2SWingman Kwok u32 overrun_type4; 33690cff9e2SWingman Kwok u32 overrun_type5; 33790cff9e2SWingman Kwok u32 rx_bytes; 33890cff9e2SWingman Kwok u32 tx_good_frames; 33990cff9e2SWingman Kwok u32 tx_broadcast_frames; 34090cff9e2SWingman Kwok u32 tx_multicast_frames; 34190cff9e2SWingman Kwok u32 tx_pause_frames; 34290cff9e2SWingman Kwok u32 tx_deferred_frames; 34390cff9e2SWingman Kwok u32 tx_collision_frames; 34490cff9e2SWingman Kwok u32 tx_single_coll_frames; 34590cff9e2SWingman Kwok u32 tx_mult_coll_frames; 34690cff9e2SWingman Kwok u32 tx_excessive_collisions; 34790cff9e2SWingman Kwok u32 tx_late_collisions; 34890cff9e2SWingman Kwok u32 tx_underrun; 34990cff9e2SWingman Kwok u32 tx_carrier_sense_errors; 35090cff9e2SWingman Kwok u32 tx_bytes; 35190cff9e2SWingman Kwok u32 tx_64byte_frames; 35290cff9e2SWingman Kwok u32 tx_65_to_127byte_frames; 35390cff9e2SWingman Kwok u32 tx_128_to_255byte_frames; 35490cff9e2SWingman Kwok u32 tx_256_to_511byte_frames; 35590cff9e2SWingman Kwok u32 tx_512_to_1023byte_frames; 35690cff9e2SWingman Kwok u32 tx_1024byte_frames; 35790cff9e2SWingman Kwok u32 net_bytes; 35890cff9e2SWingman Kwok u32 rx_sof_overruns; 35990cff9e2SWingman Kwok u32 rx_mof_overruns; 36090cff9e2SWingman Kwok u32 rx_dma_overruns; 36190cff9e2SWingman Kwok }; 36290cff9e2SWingman Kwok 3639a391c7bSWingMan Kwok struct gbenu_ss_regs { 3649a391c7bSWingMan Kwok u32 id_ver; 3659a391c7bSWingMan Kwok u32 synce_count; /* NU */ 3669a391c7bSWingMan Kwok u32 synce_mux; /* NU */ 3679a391c7bSWingMan Kwok u32 control; /* 2U */ 3689a391c7bSWingMan Kwok u32 __rsvd_0[2]; /* 2U */ 3699a391c7bSWingMan Kwok u32 rgmii_status; /* 2U */ 3709a391c7bSWingMan Kwok u32 ss_status; /* 2U */ 3719a391c7bSWingMan Kwok }; 3729a391c7bSWingMan Kwok 3739a391c7bSWingMan Kwok struct gbenu_switch_regs { 3749a391c7bSWingMan Kwok u32 id_ver; 3759a391c7bSWingMan Kwok u32 control; 3769a391c7bSWingMan Kwok u32 __rsvd_0[2]; 3779a391c7bSWingMan Kwok u32 emcontrol; 3789a391c7bSWingMan Kwok u32 stat_port_en; 3799a391c7bSWingMan Kwok u32 ptype; /* NU */ 3809a391c7bSWingMan Kwok u32 soft_idle; 3819a391c7bSWingMan Kwok u32 thru_rate; /* NU */ 3829a391c7bSWingMan Kwok u32 gap_thresh; /* NU */ 3839a391c7bSWingMan Kwok u32 tx_start_wds; /* NU */ 3849a391c7bSWingMan Kwok u32 eee_prescale; /* 2U */ 3859a391c7bSWingMan Kwok u32 tx_g_oflow_thresh_set; /* NU */ 3869a391c7bSWingMan Kwok u32 tx_g_oflow_thresh_clr; /* NU */ 3879a391c7bSWingMan Kwok u32 tx_g_buf_thresh_set_l; /* NU */ 3889a391c7bSWingMan Kwok u32 tx_g_buf_thresh_set_h; /* NU */ 3899a391c7bSWingMan Kwok u32 tx_g_buf_thresh_clr_l; /* NU */ 3909a391c7bSWingMan Kwok u32 tx_g_buf_thresh_clr_h; /* NU */ 3919a391c7bSWingMan Kwok }; 3929a391c7bSWingMan Kwok 3939a391c7bSWingMan Kwok struct gbenu_port_regs { 3949a391c7bSWingMan Kwok u32 __rsvd_0; 3959a391c7bSWingMan Kwok u32 control; 3969a391c7bSWingMan Kwok u32 max_blks; /* 2U */ 3979a391c7bSWingMan Kwok u32 mem_align1; 3989a391c7bSWingMan Kwok u32 blk_cnt; 3999a391c7bSWingMan Kwok u32 port_vlan; 4009a391c7bSWingMan Kwok u32 tx_pri_map; /* NU */ 4019a391c7bSWingMan Kwok u32 pri_ctl; /* 2U */ 4029a391c7bSWingMan Kwok u32 rx_pri_map; 4039a391c7bSWingMan Kwok u32 rx_maxlen; 4049a391c7bSWingMan Kwok u32 tx_blks_pri; /* NU */ 4059a391c7bSWingMan Kwok u32 __rsvd_1; 4069a391c7bSWingMan Kwok u32 idle2lpi; /* 2U */ 4079a391c7bSWingMan Kwok u32 lpi2idle; /* 2U */ 4089a391c7bSWingMan Kwok u32 eee_status; /* 2U */ 4099a391c7bSWingMan Kwok u32 __rsvd_2; 4109a391c7bSWingMan Kwok u32 __rsvd_3[176]; /* NU: more to add */ 4119a391c7bSWingMan Kwok u32 __rsvd_4[2]; 4129a391c7bSWingMan Kwok u32 sa_lo; 4139a391c7bSWingMan Kwok u32 sa_hi; 4149a391c7bSWingMan Kwok u32 ts_ctl; 4159a391c7bSWingMan Kwok u32 ts_seq_ltype; 4169a391c7bSWingMan Kwok u32 ts_vlan; 4179a391c7bSWingMan Kwok u32 ts_ctl_ltype2; 4189a391c7bSWingMan Kwok u32 ts_ctl2; 4199a391c7bSWingMan Kwok }; 4209a391c7bSWingMan Kwok 4219a391c7bSWingMan Kwok struct gbenu_host_port_regs { 4229a391c7bSWingMan Kwok u32 __rsvd_0; 4239a391c7bSWingMan Kwok u32 control; 4249a391c7bSWingMan Kwok u32 flow_id_offset; /* 2U */ 4259a391c7bSWingMan Kwok u32 __rsvd_1; 4269a391c7bSWingMan Kwok u32 blk_cnt; 4279a391c7bSWingMan Kwok u32 port_vlan; 4289a391c7bSWingMan Kwok u32 tx_pri_map; /* NU */ 4299a391c7bSWingMan Kwok u32 pri_ctl; 4309a391c7bSWingMan Kwok u32 rx_pri_map; 4319a391c7bSWingMan Kwok u32 rx_maxlen; 4329a391c7bSWingMan Kwok u32 tx_blks_pri; /* NU */ 4339a391c7bSWingMan Kwok u32 __rsvd_2; 4349a391c7bSWingMan Kwok u32 idle2lpi; /* 2U */ 4359a391c7bSWingMan Kwok u32 lpi2wake; /* 2U */ 4369a391c7bSWingMan Kwok u32 eee_status; /* 2U */ 4379a391c7bSWingMan Kwok u32 __rsvd_3; 4389a391c7bSWingMan Kwok u32 __rsvd_4[184]; /* NU */ 4399a391c7bSWingMan Kwok u32 host_blks_pri; /* NU */ 4409a391c7bSWingMan Kwok }; 4419a391c7bSWingMan Kwok 4429a391c7bSWingMan Kwok struct gbenu_emac_regs { 4439a391c7bSWingMan Kwok u32 mac_control; 4449a391c7bSWingMan Kwok u32 mac_status; 4459a391c7bSWingMan Kwok u32 soft_reset; 4469a391c7bSWingMan Kwok u32 boff_test; 4479a391c7bSWingMan Kwok u32 rx_pause; 4489a391c7bSWingMan Kwok u32 __rsvd_0[11]; /* NU */ 4499a391c7bSWingMan Kwok u32 tx_pause; 4509a391c7bSWingMan Kwok u32 __rsvd_1[11]; /* NU */ 4519a391c7bSWingMan Kwok u32 em_control; 4529a391c7bSWingMan Kwok u32 tx_gap; 4539a391c7bSWingMan Kwok }; 4549a391c7bSWingMan Kwok 4559a391c7bSWingMan Kwok /* Some hw stat regs are applicable to slave port only. 4569a391c7bSWingMan Kwok * This is handled by gbenu_et_stats struct. Also some 4579a391c7bSWingMan Kwok * are for SS version NU and some are for 2U. 4589a391c7bSWingMan Kwok */ 4599a391c7bSWingMan Kwok struct gbenu_hw_stats { 4609a391c7bSWingMan Kwok u32 rx_good_frames; 4619a391c7bSWingMan Kwok u32 rx_broadcast_frames; 4629a391c7bSWingMan Kwok u32 rx_multicast_frames; 4639a391c7bSWingMan Kwok u32 rx_pause_frames; /* slave */ 4649a391c7bSWingMan Kwok u32 rx_crc_errors; 4659a391c7bSWingMan Kwok u32 rx_align_code_errors; /* slave */ 4669a391c7bSWingMan Kwok u32 rx_oversized_frames; 4679a391c7bSWingMan Kwok u32 rx_jabber_frames; /* slave */ 4689a391c7bSWingMan Kwok u32 rx_undersized_frames; 4699a391c7bSWingMan Kwok u32 rx_fragments; /* slave */ 4709a391c7bSWingMan Kwok u32 ale_drop; 4719a391c7bSWingMan Kwok u32 ale_overrun_drop; 4729a391c7bSWingMan Kwok u32 rx_bytes; 4739a391c7bSWingMan Kwok u32 tx_good_frames; 4749a391c7bSWingMan Kwok u32 tx_broadcast_frames; 4759a391c7bSWingMan Kwok u32 tx_multicast_frames; 4769a391c7bSWingMan Kwok u32 tx_pause_frames; /* slave */ 4779a391c7bSWingMan Kwok u32 tx_deferred_frames; /* slave */ 4789a391c7bSWingMan Kwok u32 tx_collision_frames; /* slave */ 4799a391c7bSWingMan Kwok u32 tx_single_coll_frames; /* slave */ 4809a391c7bSWingMan Kwok u32 tx_mult_coll_frames; /* slave */ 4819a391c7bSWingMan Kwok u32 tx_excessive_collisions; /* slave */ 4829a391c7bSWingMan Kwok u32 tx_late_collisions; /* slave */ 4839a391c7bSWingMan Kwok u32 rx_ipg_error; /* slave 10G only */ 4849a391c7bSWingMan Kwok u32 tx_carrier_sense_errors; /* slave */ 4859a391c7bSWingMan Kwok u32 tx_bytes; 4869a391c7bSWingMan Kwok u32 tx_64B_frames; 4879a391c7bSWingMan Kwok u32 tx_65_to_127B_frames; 4889a391c7bSWingMan Kwok u32 tx_128_to_255B_frames; 4899a391c7bSWingMan Kwok u32 tx_256_to_511B_frames; 4909a391c7bSWingMan Kwok u32 tx_512_to_1023B_frames; 4919a391c7bSWingMan Kwok u32 tx_1024B_frames; 4929a391c7bSWingMan Kwok u32 net_bytes; 4939a391c7bSWingMan Kwok u32 rx_bottom_fifo_drop; 4949a391c7bSWingMan Kwok u32 rx_port_mask_drop; 4959a391c7bSWingMan Kwok u32 rx_top_fifo_drop; 4969a391c7bSWingMan Kwok u32 ale_rate_limit_drop; 4979a391c7bSWingMan Kwok u32 ale_vid_ingress_drop; 4989a391c7bSWingMan Kwok u32 ale_da_eq_sa_drop; 4999a391c7bSWingMan Kwok u32 __rsvd_0[3]; 5009a391c7bSWingMan Kwok u32 ale_unknown_ucast; 5019a391c7bSWingMan Kwok u32 ale_unknown_ucast_bytes; 5029a391c7bSWingMan Kwok u32 ale_unknown_mcast; 5039a391c7bSWingMan Kwok u32 ale_unknown_mcast_bytes; 5049a391c7bSWingMan Kwok u32 ale_unknown_bcast; 5059a391c7bSWingMan Kwok u32 ale_unknown_bcast_bytes; 5069a391c7bSWingMan Kwok u32 ale_pol_match; 5079a391c7bSWingMan Kwok u32 ale_pol_match_red; /* NU */ 5089a391c7bSWingMan Kwok u32 ale_pol_match_yellow; /* NU */ 5099a391c7bSWingMan Kwok u32 __rsvd_1[44]; 5109a391c7bSWingMan Kwok u32 tx_mem_protect_err; 5119a391c7bSWingMan Kwok /* following NU only */ 5129a391c7bSWingMan Kwok u32 tx_pri0; 5139a391c7bSWingMan Kwok u32 tx_pri1; 5149a391c7bSWingMan Kwok u32 tx_pri2; 5159a391c7bSWingMan Kwok u32 tx_pri3; 5169a391c7bSWingMan Kwok u32 tx_pri4; 5179a391c7bSWingMan Kwok u32 tx_pri5; 5189a391c7bSWingMan Kwok u32 tx_pri6; 5199a391c7bSWingMan Kwok u32 tx_pri7; 5209a391c7bSWingMan Kwok u32 tx_pri0_bcnt; 5219a391c7bSWingMan Kwok u32 tx_pri1_bcnt; 5229a391c7bSWingMan Kwok u32 tx_pri2_bcnt; 5239a391c7bSWingMan Kwok u32 tx_pri3_bcnt; 5249a391c7bSWingMan Kwok u32 tx_pri4_bcnt; 5259a391c7bSWingMan Kwok u32 tx_pri5_bcnt; 5269a391c7bSWingMan Kwok u32 tx_pri6_bcnt; 5279a391c7bSWingMan Kwok u32 tx_pri7_bcnt; 5289a391c7bSWingMan Kwok u32 tx_pri0_drop; 5299a391c7bSWingMan Kwok u32 tx_pri1_drop; 5309a391c7bSWingMan Kwok u32 tx_pri2_drop; 5319a391c7bSWingMan Kwok u32 tx_pri3_drop; 5329a391c7bSWingMan Kwok u32 tx_pri4_drop; 5339a391c7bSWingMan Kwok u32 tx_pri5_drop; 5349a391c7bSWingMan Kwok u32 tx_pri6_drop; 5359a391c7bSWingMan Kwok u32 tx_pri7_drop; 5369a391c7bSWingMan Kwok u32 tx_pri0_drop_bcnt; 5379a391c7bSWingMan Kwok u32 tx_pri1_drop_bcnt; 5389a391c7bSWingMan Kwok u32 tx_pri2_drop_bcnt; 5399a391c7bSWingMan Kwok u32 tx_pri3_drop_bcnt; 5409a391c7bSWingMan Kwok u32 tx_pri4_drop_bcnt; 5419a391c7bSWingMan Kwok u32 tx_pri5_drop_bcnt; 5429a391c7bSWingMan Kwok u32 tx_pri6_drop_bcnt; 5439a391c7bSWingMan Kwok u32 tx_pri7_drop_bcnt; 5449a391c7bSWingMan Kwok }; 5459a391c7bSWingMan Kwok 5469a391c7bSWingMan Kwok #define GBENU_HW_STATS_REG_MAP_SZ 0x200 5479a391c7bSWingMan Kwok 5486f8d3f33SWingman Kwok struct gbe_ss_regs { 5496f8d3f33SWingman Kwok u32 id_ver; 5506f8d3f33SWingman Kwok u32 synce_count; 5516f8d3f33SWingman Kwok u32 synce_mux; 5526f8d3f33SWingman Kwok }; 5536f8d3f33SWingman Kwok 5546f8d3f33SWingman Kwok struct gbe_ss_regs_ofs { 5556f8d3f33SWingman Kwok u16 id_ver; 5566f8d3f33SWingman Kwok u16 control; 5576f8d3f33SWingman Kwok }; 5586f8d3f33SWingman Kwok 5596f8d3f33SWingman Kwok struct gbe_switch_regs { 5606f8d3f33SWingman Kwok u32 id_ver; 5616f8d3f33SWingman Kwok u32 control; 5626f8d3f33SWingman Kwok u32 soft_reset; 5636f8d3f33SWingman Kwok u32 stat_port_en; 5646f8d3f33SWingman Kwok u32 ptype; 5656f8d3f33SWingman Kwok u32 soft_idle; 5666f8d3f33SWingman Kwok u32 thru_rate; 5676f8d3f33SWingman Kwok u32 gap_thresh; 5686f8d3f33SWingman Kwok u32 tx_start_wds; 5696f8d3f33SWingman Kwok u32 flow_control; 5706f8d3f33SWingman Kwok }; 5716f8d3f33SWingman Kwok 5726f8d3f33SWingman Kwok struct gbe_switch_regs_ofs { 5736f8d3f33SWingman Kwok u16 id_ver; 5746f8d3f33SWingman Kwok u16 control; 5756f8d3f33SWingman Kwok u16 soft_reset; 5766f8d3f33SWingman Kwok u16 emcontrol; 5776f8d3f33SWingman Kwok u16 stat_port_en; 5786f8d3f33SWingman Kwok u16 ptype; 5796f8d3f33SWingman Kwok u16 flow_control; 5806f8d3f33SWingman Kwok }; 5816f8d3f33SWingman Kwok 5826f8d3f33SWingman Kwok struct gbe_port_regs { 5836f8d3f33SWingman Kwok u32 max_blks; 5846f8d3f33SWingman Kwok u32 blk_cnt; 5856f8d3f33SWingman Kwok u32 port_vlan; 5866f8d3f33SWingman Kwok u32 tx_pri_map; 5876f8d3f33SWingman Kwok u32 sa_lo; 5886f8d3f33SWingman Kwok u32 sa_hi; 5896f8d3f33SWingman Kwok u32 ts_ctl; 5906f8d3f33SWingman Kwok u32 ts_seq_ltype; 5916f8d3f33SWingman Kwok u32 ts_vlan; 5926f8d3f33SWingman Kwok u32 ts_ctl_ltype2; 5936f8d3f33SWingman Kwok u32 ts_ctl2; 5946f8d3f33SWingman Kwok }; 5956f8d3f33SWingman Kwok 5966f8d3f33SWingman Kwok struct gbe_port_regs_ofs { 5976f8d3f33SWingman Kwok u16 port_vlan; 5986f8d3f33SWingman Kwok u16 tx_pri_map; 5996f8d3f33SWingman Kwok u16 sa_lo; 6006f8d3f33SWingman Kwok u16 sa_hi; 6016f8d3f33SWingman Kwok u16 ts_ctl; 6026f8d3f33SWingman Kwok u16 ts_seq_ltype; 6036f8d3f33SWingman Kwok u16 ts_vlan; 6046f8d3f33SWingman Kwok u16 ts_ctl_ltype2; 6056f8d3f33SWingman Kwok u16 ts_ctl2; 6069a391c7bSWingMan Kwok u16 rx_maxlen; /* 2U, NU */ 6076f8d3f33SWingman Kwok }; 6086f8d3f33SWingman Kwok 6096f8d3f33SWingman Kwok struct gbe_host_port_regs { 6106f8d3f33SWingman Kwok u32 src_id; 6116f8d3f33SWingman Kwok u32 port_vlan; 6126f8d3f33SWingman Kwok u32 rx_pri_map; 6136f8d3f33SWingman Kwok u32 rx_maxlen; 6146f8d3f33SWingman Kwok }; 6156f8d3f33SWingman Kwok 6166f8d3f33SWingman Kwok struct gbe_host_port_regs_ofs { 6176f8d3f33SWingman Kwok u16 port_vlan; 6186f8d3f33SWingman Kwok u16 tx_pri_map; 6196f8d3f33SWingman Kwok u16 rx_maxlen; 6206f8d3f33SWingman Kwok }; 6216f8d3f33SWingman Kwok 6226f8d3f33SWingman Kwok struct gbe_emac_regs { 6236f8d3f33SWingman Kwok u32 id_ver; 6246f8d3f33SWingman Kwok u32 mac_control; 6256f8d3f33SWingman Kwok u32 mac_status; 6266f8d3f33SWingman Kwok u32 soft_reset; 6276f8d3f33SWingman Kwok u32 rx_maxlen; 6286f8d3f33SWingman Kwok u32 __reserved_0; 6296f8d3f33SWingman Kwok u32 rx_pause; 6306f8d3f33SWingman Kwok u32 tx_pause; 6316f8d3f33SWingman Kwok u32 __reserved_1; 6326f8d3f33SWingman Kwok u32 rx_pri_map; 6336f8d3f33SWingman Kwok u32 rsvd[6]; 6346f8d3f33SWingman Kwok }; 6356f8d3f33SWingman Kwok 6366f8d3f33SWingman Kwok struct gbe_emac_regs_ofs { 6376f8d3f33SWingman Kwok u16 mac_control; 6386f8d3f33SWingman Kwok u16 soft_reset; 6396f8d3f33SWingman Kwok u16 rx_maxlen; 6406f8d3f33SWingman Kwok }; 6416f8d3f33SWingman Kwok 6426f8d3f33SWingman Kwok struct gbe_hw_stats { 6436f8d3f33SWingman Kwok u32 rx_good_frames; 6446f8d3f33SWingman Kwok u32 rx_broadcast_frames; 6456f8d3f33SWingman Kwok u32 rx_multicast_frames; 6466f8d3f33SWingman Kwok u32 rx_pause_frames; 6476f8d3f33SWingman Kwok u32 rx_crc_errors; 6486f8d3f33SWingman Kwok u32 rx_align_code_errors; 6496f8d3f33SWingman Kwok u32 rx_oversized_frames; 6506f8d3f33SWingman Kwok u32 rx_jabber_frames; 6516f8d3f33SWingman Kwok u32 rx_undersized_frames; 6526f8d3f33SWingman Kwok u32 rx_fragments; 6536f8d3f33SWingman Kwok u32 __pad_0[2]; 6546f8d3f33SWingman Kwok u32 rx_bytes; 6556f8d3f33SWingman Kwok u32 tx_good_frames; 6566f8d3f33SWingman Kwok u32 tx_broadcast_frames; 6576f8d3f33SWingman Kwok u32 tx_multicast_frames; 6586f8d3f33SWingman Kwok u32 tx_pause_frames; 6596f8d3f33SWingman Kwok u32 tx_deferred_frames; 6606f8d3f33SWingman Kwok u32 tx_collision_frames; 6616f8d3f33SWingman Kwok u32 tx_single_coll_frames; 6626f8d3f33SWingman Kwok u32 tx_mult_coll_frames; 6636f8d3f33SWingman Kwok u32 tx_excessive_collisions; 6646f8d3f33SWingman Kwok u32 tx_late_collisions; 6656f8d3f33SWingman Kwok u32 tx_underrun; 6666f8d3f33SWingman Kwok u32 tx_carrier_sense_errors; 6676f8d3f33SWingman Kwok u32 tx_bytes; 6686f8d3f33SWingman Kwok u32 tx_64byte_frames; 6696f8d3f33SWingman Kwok u32 tx_65_to_127byte_frames; 6706f8d3f33SWingman Kwok u32 tx_128_to_255byte_frames; 6716f8d3f33SWingman Kwok u32 tx_256_to_511byte_frames; 6726f8d3f33SWingman Kwok u32 tx_512_to_1023byte_frames; 6736f8d3f33SWingman Kwok u32 tx_1024byte_frames; 6746f8d3f33SWingman Kwok u32 net_bytes; 6756f8d3f33SWingman Kwok u32 rx_sof_overruns; 6766f8d3f33SWingman Kwok u32 rx_mof_overruns; 6776f8d3f33SWingman Kwok u32 rx_dma_overruns; 6786f8d3f33SWingman Kwok }; 6796f8d3f33SWingman Kwok 6809a391c7bSWingMan Kwok #define GBE_MAX_HW_STAT_MODS 9 6816f8d3f33SWingman Kwok #define GBE_HW_STATS_REG_MAP_SZ 0x100 6826f8d3f33SWingman Kwok 6836246168bSWingMan Kwok struct ts_ctl { 6846246168bSWingMan Kwok int uni; 6856246168bSWingMan Kwok u8 dst_port_map; 6866246168bSWingMan Kwok u8 maddr_map; 6876246168bSWingMan Kwok u8 ts_mcast_type; 6886246168bSWingMan Kwok }; 6896246168bSWingMan Kwok 6906f8d3f33SWingman Kwok struct gbe_slave { 6916f8d3f33SWingman Kwok void __iomem *port_regs; 6926f8d3f33SWingman Kwok void __iomem *emac_regs; 6936f8d3f33SWingman Kwok struct gbe_port_regs_ofs port_regs_ofs; 6946f8d3f33SWingman Kwok struct gbe_emac_regs_ofs emac_regs_ofs; 6956f8d3f33SWingman Kwok int slave_num; /* 0 based logical number */ 6966f8d3f33SWingman Kwok int port_num; /* actual port number */ 6976f8d3f33SWingman Kwok atomic_t link_state; 6986f8d3f33SWingman Kwok bool open; 6996f8d3f33SWingman Kwok struct phy_device *phy; 7006f8d3f33SWingman Kwok u32 link_interface; 7016f8d3f33SWingman Kwok u32 mac_control; 7026f8d3f33SWingman Kwok u8 phy_port_t; 7036f8d3f33SWingman Kwok struct device_node *phy_node; 7046246168bSWingMan Kwok struct ts_ctl ts_ctl; 7056f8d3f33SWingman Kwok struct list_head slave_list; 7066f8d3f33SWingman Kwok }; 7076f8d3f33SWingman Kwok 7086f8d3f33SWingman Kwok struct gbe_priv { 7096f8d3f33SWingman Kwok struct device *dev; 7106f8d3f33SWingman Kwok struct netcp_device *netcp_device; 7116f8d3f33SWingman Kwok struct timer_list timer; 7126f8d3f33SWingman Kwok u32 num_slaves; 7136f8d3f33SWingman Kwok u32 ale_entries; 7146f8d3f33SWingman Kwok u32 ale_ports; 7156f8d3f33SWingman Kwok bool enable_ale; 7169a391c7bSWingMan Kwok u8 max_num_slaves; 7179a391c7bSWingMan Kwok u8 max_num_ports; /* max_num_slaves + 1 */ 718489e8a2fSWingMan Kwok u8 num_stats_mods; 7196f8d3f33SWingman Kwok struct netcp_tx_pipe tx_pipe; 7206f8d3f33SWingman Kwok 7216f8d3f33SWingman Kwok int host_port; 7226f8d3f33SWingman Kwok u32 rx_packet_max; 7236f8d3f33SWingman Kwok u32 ss_version; 7249a391c7bSWingMan Kwok u32 stats_en_mask; 7256f8d3f33SWingman Kwok 7266f8d3f33SWingman Kwok void __iomem *ss_regs; 7276f8d3f33SWingman Kwok void __iomem *switch_regs; 7286f8d3f33SWingman Kwok void __iomem *host_port_regs; 7296f8d3f33SWingman Kwok void __iomem *ale_reg; 7306246168bSWingMan Kwok void __iomem *cpts_reg; 7316f8d3f33SWingman Kwok void __iomem *sgmii_port_regs; 7326f8d3f33SWingman Kwok void __iomem *sgmii_port34_regs; 7336f8d3f33SWingman Kwok void __iomem *xgbe_serdes_regs; 7346f8d3f33SWingman Kwok void __iomem *hw_stats_regs[GBE_MAX_HW_STAT_MODS]; 7356f8d3f33SWingman Kwok 7366f8d3f33SWingman Kwok struct gbe_ss_regs_ofs ss_regs_ofs; 7376f8d3f33SWingman Kwok struct gbe_switch_regs_ofs switch_regs_ofs; 7386f8d3f33SWingman Kwok struct gbe_host_port_regs_ofs host_port_regs_ofs; 7396f8d3f33SWingman Kwok 7406f8d3f33SWingman Kwok struct cpsw_ale *ale; 7416f8d3f33SWingman Kwok unsigned int tx_queue_id; 7426f8d3f33SWingman Kwok const char *dma_chan_name; 7436f8d3f33SWingman Kwok 7446f8d3f33SWingman Kwok struct list_head gbe_intf_head; 7456f8d3f33SWingman Kwok struct list_head secondary_slaves; 7466f8d3f33SWingman Kwok struct net_device *dummy_ndev; 7476f8d3f33SWingman Kwok 7486f8d3f33SWingman Kwok u64 *hw_stats; 749489e8a2fSWingMan Kwok u32 *hw_stats_prev; 7506f8d3f33SWingman Kwok const struct netcp_ethtool_stat *et_stats; 7516f8d3f33SWingman Kwok int num_et_stats; 7526f8d3f33SWingman Kwok /* Lock for updating the hwstats */ 7536f8d3f33SWingman Kwok spinlock_t hw_stats_lock; 7546246168bSWingMan Kwok 7556246168bSWingMan Kwok int cpts_registered; 7566246168bSWingMan Kwok struct cpts *cpts; 7576f8d3f33SWingman Kwok }; 7586f8d3f33SWingman Kwok 7596f8d3f33SWingman Kwok struct gbe_intf { 7606f8d3f33SWingman Kwok struct net_device *ndev; 7616f8d3f33SWingman Kwok struct device *dev; 7626f8d3f33SWingman Kwok struct gbe_priv *gbe_dev; 7636f8d3f33SWingman Kwok struct netcp_tx_pipe tx_pipe; 7646f8d3f33SWingman Kwok struct gbe_slave *slave; 7656f8d3f33SWingman Kwok struct list_head gbe_intf_list; 7666f8d3f33SWingman Kwok unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; 7676f8d3f33SWingman Kwok }; 7686f8d3f33SWingman Kwok 7696f8d3f33SWingman Kwok static struct netcp_module gbe_module; 77090cff9e2SWingman Kwok static struct netcp_module xgbe_module; 7716f8d3f33SWingman Kwok 7726f8d3f33SWingman Kwok /* Statistic management */ 7736f8d3f33SWingman Kwok struct netcp_ethtool_stat { 7746f8d3f33SWingman Kwok char desc[ETH_GSTRING_LEN]; 7756f8d3f33SWingman Kwok int type; 7766f8d3f33SWingman Kwok u32 size; 7776f8d3f33SWingman Kwok int offset; 7786f8d3f33SWingman Kwok }; 7796f8d3f33SWingman Kwok 780da866ba0SKaricheri, Muralidharan #define GBE_STATSA_INFO(field) \ 781da866ba0SKaricheri, Muralidharan { \ 782da866ba0SKaricheri, Muralidharan "GBE_A:"#field, GBE_STATSA_MODULE, \ 7836f8d3f33SWingman Kwok FIELD_SIZEOF(struct gbe_hw_stats, field), \ 784da866ba0SKaricheri, Muralidharan offsetof(struct gbe_hw_stats, field) \ 785da866ba0SKaricheri, Muralidharan } 7866f8d3f33SWingman Kwok 787da866ba0SKaricheri, Muralidharan #define GBE_STATSB_INFO(field) \ 788da866ba0SKaricheri, Muralidharan { \ 789da866ba0SKaricheri, Muralidharan "GBE_B:"#field, GBE_STATSB_MODULE, \ 7906f8d3f33SWingman Kwok FIELD_SIZEOF(struct gbe_hw_stats, field), \ 791da866ba0SKaricheri, Muralidharan offsetof(struct gbe_hw_stats, field) \ 792da866ba0SKaricheri, Muralidharan } 7936f8d3f33SWingman Kwok 794da866ba0SKaricheri, Muralidharan #define GBE_STATSC_INFO(field) \ 795da866ba0SKaricheri, Muralidharan { \ 796da866ba0SKaricheri, Muralidharan "GBE_C:"#field, GBE_STATSC_MODULE, \ 7976f8d3f33SWingman Kwok FIELD_SIZEOF(struct gbe_hw_stats, field), \ 798da866ba0SKaricheri, Muralidharan offsetof(struct gbe_hw_stats, field) \ 799da866ba0SKaricheri, Muralidharan } 8006f8d3f33SWingman Kwok 801da866ba0SKaricheri, Muralidharan #define GBE_STATSD_INFO(field) \ 802da866ba0SKaricheri, Muralidharan { \ 803da866ba0SKaricheri, Muralidharan "GBE_D:"#field, GBE_STATSD_MODULE, \ 8046f8d3f33SWingman Kwok FIELD_SIZEOF(struct gbe_hw_stats, field), \ 805da866ba0SKaricheri, Muralidharan offsetof(struct gbe_hw_stats, field) \ 806da866ba0SKaricheri, Muralidharan } 8076f8d3f33SWingman Kwok 8086f8d3f33SWingman Kwok static const struct netcp_ethtool_stat gbe13_et_stats[] = { 8096f8d3f33SWingman Kwok /* GBE module A */ 810da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_good_frames), 811da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_broadcast_frames), 812da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_multicast_frames), 813da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_pause_frames), 814da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_crc_errors), 815da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_align_code_errors), 816da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_oversized_frames), 817da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_jabber_frames), 818da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_undersized_frames), 819da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_fragments), 820da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_bytes), 821da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_good_frames), 822da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_broadcast_frames), 823da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_multicast_frames), 824da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_pause_frames), 825da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_deferred_frames), 826da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_collision_frames), 827da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_single_coll_frames), 828da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_mult_coll_frames), 829da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_excessive_collisions), 830da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_late_collisions), 831da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_underrun), 832da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_carrier_sense_errors), 833da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_bytes), 834da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_64byte_frames), 835da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_65_to_127byte_frames), 836da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_128_to_255byte_frames), 837da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_256_to_511byte_frames), 838da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_512_to_1023byte_frames), 839da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_1024byte_frames), 840da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(net_bytes), 841da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_sof_overruns), 842da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_mof_overruns), 843da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_dma_overruns), 8446f8d3f33SWingman Kwok /* GBE module B */ 845da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_good_frames), 846da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_broadcast_frames), 847da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_multicast_frames), 848da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_pause_frames), 849da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_crc_errors), 850da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_align_code_errors), 851da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_oversized_frames), 852da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_jabber_frames), 853da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_undersized_frames), 854da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_fragments), 855da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_bytes), 856da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_good_frames), 857da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_broadcast_frames), 858da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_multicast_frames), 859da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_pause_frames), 860da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_deferred_frames), 861da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_collision_frames), 862da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_single_coll_frames), 863da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_mult_coll_frames), 864da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_excessive_collisions), 865da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_late_collisions), 866da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_underrun), 867da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_carrier_sense_errors), 868da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_bytes), 869da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_64byte_frames), 870da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_65_to_127byte_frames), 871da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_128_to_255byte_frames), 872da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_256_to_511byte_frames), 873da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_512_to_1023byte_frames), 874da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_1024byte_frames), 875da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(net_bytes), 876da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_sof_overruns), 877da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_mof_overruns), 878da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_dma_overruns), 8796f8d3f33SWingman Kwok /* GBE module C */ 880da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_good_frames), 881da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_broadcast_frames), 882da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_multicast_frames), 883da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_pause_frames), 884da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_crc_errors), 885da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_align_code_errors), 886da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_oversized_frames), 887da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_jabber_frames), 888da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_undersized_frames), 889da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_fragments), 890da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_bytes), 891da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_good_frames), 892da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_broadcast_frames), 893da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_multicast_frames), 894da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_pause_frames), 895da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_deferred_frames), 896da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_collision_frames), 897da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_single_coll_frames), 898da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_mult_coll_frames), 899da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_excessive_collisions), 900da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_late_collisions), 901da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_underrun), 902da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_carrier_sense_errors), 903da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_bytes), 904da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_64byte_frames), 905da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_65_to_127byte_frames), 906da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_128_to_255byte_frames), 907da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_256_to_511byte_frames), 908da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_512_to_1023byte_frames), 909da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_1024byte_frames), 910da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(net_bytes), 911da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_sof_overruns), 912da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_mof_overruns), 913da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_dma_overruns), 9146f8d3f33SWingman Kwok /* GBE module D */ 915da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_good_frames), 916da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_broadcast_frames), 917da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_multicast_frames), 918da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_pause_frames), 919da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_crc_errors), 920da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_align_code_errors), 921da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_oversized_frames), 922da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_jabber_frames), 923da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_undersized_frames), 924da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_fragments), 925da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_bytes), 926da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_good_frames), 927da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_broadcast_frames), 928da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_multicast_frames), 929da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_pause_frames), 930da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_deferred_frames), 931da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_collision_frames), 932da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_single_coll_frames), 933da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_mult_coll_frames), 934da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_excessive_collisions), 935da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_late_collisions), 936da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_underrun), 937da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_carrier_sense_errors), 938da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_bytes), 939da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_64byte_frames), 940da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_65_to_127byte_frames), 941da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_128_to_255byte_frames), 942da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_256_to_511byte_frames), 943da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_512_to_1023byte_frames), 944da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_1024byte_frames), 945da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(net_bytes), 946da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_sof_overruns), 947da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_mof_overruns), 948da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_dma_overruns), 9496f8d3f33SWingman Kwok }; 9506f8d3f33SWingman Kwok 9519a391c7bSWingMan Kwok /* This is the size of entries in GBENU_STATS_HOST */ 9525be4001eSWingMan Kwok #define GBENU_ET_STATS_HOST_SIZE 52 9539a391c7bSWingMan Kwok 9549a391c7bSWingMan Kwok #define GBENU_STATS_HOST(field) \ 9559a391c7bSWingMan Kwok { \ 9569a391c7bSWingMan Kwok "GBE_HOST:"#field, GBENU_STATS0_MODULE, \ 9579a391c7bSWingMan Kwok FIELD_SIZEOF(struct gbenu_hw_stats, field), \ 9589a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \ 9599a391c7bSWingMan Kwok } 9609a391c7bSWingMan Kwok 9615be4001eSWingMan Kwok /* This is the size of entries in GBENU_STATS_PORT */ 9625be4001eSWingMan Kwok #define GBENU_ET_STATS_PORT_SIZE 65 9639a391c7bSWingMan Kwok 9649a391c7bSWingMan Kwok #define GBENU_STATS_P1(field) \ 9659a391c7bSWingMan Kwok { \ 9669a391c7bSWingMan Kwok "GBE_P1:"#field, GBENU_STATS1_MODULE, \ 9679a391c7bSWingMan Kwok FIELD_SIZEOF(struct gbenu_hw_stats, field), \ 9689a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \ 9699a391c7bSWingMan Kwok } 9709a391c7bSWingMan Kwok 9719a391c7bSWingMan Kwok #define GBENU_STATS_P2(field) \ 9729a391c7bSWingMan Kwok { \ 9739a391c7bSWingMan Kwok "GBE_P2:"#field, GBENU_STATS2_MODULE, \ 9749a391c7bSWingMan Kwok FIELD_SIZEOF(struct gbenu_hw_stats, field), \ 9759a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \ 9769a391c7bSWingMan Kwok } 9779a391c7bSWingMan Kwok 9789a391c7bSWingMan Kwok #define GBENU_STATS_P3(field) \ 9799a391c7bSWingMan Kwok { \ 9809a391c7bSWingMan Kwok "GBE_P3:"#field, GBENU_STATS3_MODULE, \ 9819a391c7bSWingMan Kwok FIELD_SIZEOF(struct gbenu_hw_stats, field), \ 9829a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \ 9839a391c7bSWingMan Kwok } 9849a391c7bSWingMan Kwok 9859a391c7bSWingMan Kwok #define GBENU_STATS_P4(field) \ 9869a391c7bSWingMan Kwok { \ 9879a391c7bSWingMan Kwok "GBE_P4:"#field, GBENU_STATS4_MODULE, \ 9889a391c7bSWingMan Kwok FIELD_SIZEOF(struct gbenu_hw_stats, field), \ 9899a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \ 9909a391c7bSWingMan Kwok } 9919a391c7bSWingMan Kwok 9929a391c7bSWingMan Kwok #define GBENU_STATS_P5(field) \ 9939a391c7bSWingMan Kwok { \ 9949a391c7bSWingMan Kwok "GBE_P5:"#field, GBENU_STATS5_MODULE, \ 9959a391c7bSWingMan Kwok FIELD_SIZEOF(struct gbenu_hw_stats, field), \ 9969a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \ 9979a391c7bSWingMan Kwok } 9989a391c7bSWingMan Kwok 9999a391c7bSWingMan Kwok #define GBENU_STATS_P6(field) \ 10009a391c7bSWingMan Kwok { \ 10019a391c7bSWingMan Kwok "GBE_P6:"#field, GBENU_STATS6_MODULE, \ 10029a391c7bSWingMan Kwok FIELD_SIZEOF(struct gbenu_hw_stats, field), \ 10039a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \ 10049a391c7bSWingMan Kwok } 10059a391c7bSWingMan Kwok 10069a391c7bSWingMan Kwok #define GBENU_STATS_P7(field) \ 10079a391c7bSWingMan Kwok { \ 10089a391c7bSWingMan Kwok "GBE_P7:"#field, GBENU_STATS7_MODULE, \ 10099a391c7bSWingMan Kwok FIELD_SIZEOF(struct gbenu_hw_stats, field), \ 10109a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \ 10119a391c7bSWingMan Kwok } 10129a391c7bSWingMan Kwok 10139a391c7bSWingMan Kwok #define GBENU_STATS_P8(field) \ 10149a391c7bSWingMan Kwok { \ 10159a391c7bSWingMan Kwok "GBE_P8:"#field, GBENU_STATS8_MODULE, \ 10169a391c7bSWingMan Kwok FIELD_SIZEOF(struct gbenu_hw_stats, field), \ 10179a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \ 10189a391c7bSWingMan Kwok } 10199a391c7bSWingMan Kwok 10209a391c7bSWingMan Kwok static const struct netcp_ethtool_stat gbenu_et_stats[] = { 10219a391c7bSWingMan Kwok /* GBENU Host Module */ 10229a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_good_frames), 10239a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_broadcast_frames), 10249a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_multicast_frames), 10259a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_crc_errors), 10269a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_oversized_frames), 10279a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_undersized_frames), 10289a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_drop), 10299a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_overrun_drop), 10309a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_bytes), 10319a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_good_frames), 10329a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_broadcast_frames), 10339a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_multicast_frames), 10349a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_bytes), 10359a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_64B_frames), 10369a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_65_to_127B_frames), 10379a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_128_to_255B_frames), 10389a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_256_to_511B_frames), 10399a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_512_to_1023B_frames), 10409a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_1024B_frames), 10419a391c7bSWingMan Kwok GBENU_STATS_HOST(net_bytes), 10429a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_bottom_fifo_drop), 10439a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_port_mask_drop), 10449a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_top_fifo_drop), 10459a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_rate_limit_drop), 10469a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_vid_ingress_drop), 10479a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_da_eq_sa_drop), 10489a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_unknown_ucast), 10499a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_unknown_ucast_bytes), 10509a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_unknown_mcast), 10519a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_unknown_mcast_bytes), 10529a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_unknown_bcast), 10539a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_unknown_bcast_bytes), 10545be4001eSWingMan Kwok GBENU_STATS_HOST(ale_pol_match), 10555be4001eSWingMan Kwok GBENU_STATS_HOST(ale_pol_match_red), 10565be4001eSWingMan Kwok GBENU_STATS_HOST(ale_pol_match_yellow), 10579a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_mem_protect_err), 10585be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri0_drop), 10595be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri1_drop), 10605be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri2_drop), 10615be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri3_drop), 10625be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri4_drop), 10635be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri5_drop), 10645be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri6_drop), 10655be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri7_drop), 10665be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri0_drop_bcnt), 10675be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri1_drop_bcnt), 10685be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri2_drop_bcnt), 10695be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri3_drop_bcnt), 10705be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri4_drop_bcnt), 10715be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri5_drop_bcnt), 10725be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri6_drop_bcnt), 10735be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri7_drop_bcnt), 10749a391c7bSWingMan Kwok /* GBENU Module 1 */ 10759a391c7bSWingMan Kwok GBENU_STATS_P1(rx_good_frames), 10769a391c7bSWingMan Kwok GBENU_STATS_P1(rx_broadcast_frames), 10779a391c7bSWingMan Kwok GBENU_STATS_P1(rx_multicast_frames), 10789a391c7bSWingMan Kwok GBENU_STATS_P1(rx_pause_frames), 10799a391c7bSWingMan Kwok GBENU_STATS_P1(rx_crc_errors), 10809a391c7bSWingMan Kwok GBENU_STATS_P1(rx_align_code_errors), 10819a391c7bSWingMan Kwok GBENU_STATS_P1(rx_oversized_frames), 10829a391c7bSWingMan Kwok GBENU_STATS_P1(rx_jabber_frames), 10839a391c7bSWingMan Kwok GBENU_STATS_P1(rx_undersized_frames), 10849a391c7bSWingMan Kwok GBENU_STATS_P1(rx_fragments), 10859a391c7bSWingMan Kwok GBENU_STATS_P1(ale_drop), 10869a391c7bSWingMan Kwok GBENU_STATS_P1(ale_overrun_drop), 10879a391c7bSWingMan Kwok GBENU_STATS_P1(rx_bytes), 10889a391c7bSWingMan Kwok GBENU_STATS_P1(tx_good_frames), 10899a391c7bSWingMan Kwok GBENU_STATS_P1(tx_broadcast_frames), 10909a391c7bSWingMan Kwok GBENU_STATS_P1(tx_multicast_frames), 10919a391c7bSWingMan Kwok GBENU_STATS_P1(tx_pause_frames), 10929a391c7bSWingMan Kwok GBENU_STATS_P1(tx_deferred_frames), 10939a391c7bSWingMan Kwok GBENU_STATS_P1(tx_collision_frames), 10949a391c7bSWingMan Kwok GBENU_STATS_P1(tx_single_coll_frames), 10959a391c7bSWingMan Kwok GBENU_STATS_P1(tx_mult_coll_frames), 10969a391c7bSWingMan Kwok GBENU_STATS_P1(tx_excessive_collisions), 10979a391c7bSWingMan Kwok GBENU_STATS_P1(tx_late_collisions), 10989a391c7bSWingMan Kwok GBENU_STATS_P1(rx_ipg_error), 10999a391c7bSWingMan Kwok GBENU_STATS_P1(tx_carrier_sense_errors), 11009a391c7bSWingMan Kwok GBENU_STATS_P1(tx_bytes), 11019a391c7bSWingMan Kwok GBENU_STATS_P1(tx_64B_frames), 11029a391c7bSWingMan Kwok GBENU_STATS_P1(tx_65_to_127B_frames), 11039a391c7bSWingMan Kwok GBENU_STATS_P1(tx_128_to_255B_frames), 11049a391c7bSWingMan Kwok GBENU_STATS_P1(tx_256_to_511B_frames), 11059a391c7bSWingMan Kwok GBENU_STATS_P1(tx_512_to_1023B_frames), 11069a391c7bSWingMan Kwok GBENU_STATS_P1(tx_1024B_frames), 11079a391c7bSWingMan Kwok GBENU_STATS_P1(net_bytes), 11089a391c7bSWingMan Kwok GBENU_STATS_P1(rx_bottom_fifo_drop), 11099a391c7bSWingMan Kwok GBENU_STATS_P1(rx_port_mask_drop), 11109a391c7bSWingMan Kwok GBENU_STATS_P1(rx_top_fifo_drop), 11119a391c7bSWingMan Kwok GBENU_STATS_P1(ale_rate_limit_drop), 11129a391c7bSWingMan Kwok GBENU_STATS_P1(ale_vid_ingress_drop), 11139a391c7bSWingMan Kwok GBENU_STATS_P1(ale_da_eq_sa_drop), 11149a391c7bSWingMan Kwok GBENU_STATS_P1(ale_unknown_ucast), 11159a391c7bSWingMan Kwok GBENU_STATS_P1(ale_unknown_ucast_bytes), 11169a391c7bSWingMan Kwok GBENU_STATS_P1(ale_unknown_mcast), 11179a391c7bSWingMan Kwok GBENU_STATS_P1(ale_unknown_mcast_bytes), 11189a391c7bSWingMan Kwok GBENU_STATS_P1(ale_unknown_bcast), 11199a391c7bSWingMan Kwok GBENU_STATS_P1(ale_unknown_bcast_bytes), 11205be4001eSWingMan Kwok GBENU_STATS_P1(ale_pol_match), 11215be4001eSWingMan Kwok GBENU_STATS_P1(ale_pol_match_red), 11225be4001eSWingMan Kwok GBENU_STATS_P1(ale_pol_match_yellow), 11239a391c7bSWingMan Kwok GBENU_STATS_P1(tx_mem_protect_err), 11245be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri0_drop), 11255be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri1_drop), 11265be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri2_drop), 11275be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri3_drop), 11285be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri4_drop), 11295be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri5_drop), 11305be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri6_drop), 11315be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri7_drop), 11325be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri0_drop_bcnt), 11335be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri1_drop_bcnt), 11345be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri2_drop_bcnt), 11355be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri3_drop_bcnt), 11365be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri4_drop_bcnt), 11375be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri5_drop_bcnt), 11385be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri6_drop_bcnt), 11395be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri7_drop_bcnt), 11409a391c7bSWingMan Kwok /* GBENU Module 2 */ 11419a391c7bSWingMan Kwok GBENU_STATS_P2(rx_good_frames), 11429a391c7bSWingMan Kwok GBENU_STATS_P2(rx_broadcast_frames), 11439a391c7bSWingMan Kwok GBENU_STATS_P2(rx_multicast_frames), 11449a391c7bSWingMan Kwok GBENU_STATS_P2(rx_pause_frames), 11459a391c7bSWingMan Kwok GBENU_STATS_P2(rx_crc_errors), 11469a391c7bSWingMan Kwok GBENU_STATS_P2(rx_align_code_errors), 11479a391c7bSWingMan Kwok GBENU_STATS_P2(rx_oversized_frames), 11489a391c7bSWingMan Kwok GBENU_STATS_P2(rx_jabber_frames), 11499a391c7bSWingMan Kwok GBENU_STATS_P2(rx_undersized_frames), 11509a391c7bSWingMan Kwok GBENU_STATS_P2(rx_fragments), 11519a391c7bSWingMan Kwok GBENU_STATS_P2(ale_drop), 11529a391c7bSWingMan Kwok GBENU_STATS_P2(ale_overrun_drop), 11539a391c7bSWingMan Kwok GBENU_STATS_P2(rx_bytes), 11549a391c7bSWingMan Kwok GBENU_STATS_P2(tx_good_frames), 11559a391c7bSWingMan Kwok GBENU_STATS_P2(tx_broadcast_frames), 11569a391c7bSWingMan Kwok GBENU_STATS_P2(tx_multicast_frames), 11579a391c7bSWingMan Kwok GBENU_STATS_P2(tx_pause_frames), 11589a391c7bSWingMan Kwok GBENU_STATS_P2(tx_deferred_frames), 11599a391c7bSWingMan Kwok GBENU_STATS_P2(tx_collision_frames), 11609a391c7bSWingMan Kwok GBENU_STATS_P2(tx_single_coll_frames), 11619a391c7bSWingMan Kwok GBENU_STATS_P2(tx_mult_coll_frames), 11629a391c7bSWingMan Kwok GBENU_STATS_P2(tx_excessive_collisions), 11639a391c7bSWingMan Kwok GBENU_STATS_P2(tx_late_collisions), 11649a391c7bSWingMan Kwok GBENU_STATS_P2(rx_ipg_error), 11659a391c7bSWingMan Kwok GBENU_STATS_P2(tx_carrier_sense_errors), 11669a391c7bSWingMan Kwok GBENU_STATS_P2(tx_bytes), 11679a391c7bSWingMan Kwok GBENU_STATS_P2(tx_64B_frames), 11689a391c7bSWingMan Kwok GBENU_STATS_P2(tx_65_to_127B_frames), 11699a391c7bSWingMan Kwok GBENU_STATS_P2(tx_128_to_255B_frames), 11709a391c7bSWingMan Kwok GBENU_STATS_P2(tx_256_to_511B_frames), 11719a391c7bSWingMan Kwok GBENU_STATS_P2(tx_512_to_1023B_frames), 11729a391c7bSWingMan Kwok GBENU_STATS_P2(tx_1024B_frames), 11739a391c7bSWingMan Kwok GBENU_STATS_P2(net_bytes), 11749a391c7bSWingMan Kwok GBENU_STATS_P2(rx_bottom_fifo_drop), 11759a391c7bSWingMan Kwok GBENU_STATS_P2(rx_port_mask_drop), 11769a391c7bSWingMan Kwok GBENU_STATS_P2(rx_top_fifo_drop), 11779a391c7bSWingMan Kwok GBENU_STATS_P2(ale_rate_limit_drop), 11789a391c7bSWingMan Kwok GBENU_STATS_P2(ale_vid_ingress_drop), 11799a391c7bSWingMan Kwok GBENU_STATS_P2(ale_da_eq_sa_drop), 11809a391c7bSWingMan Kwok GBENU_STATS_P2(ale_unknown_ucast), 11819a391c7bSWingMan Kwok GBENU_STATS_P2(ale_unknown_ucast_bytes), 11829a391c7bSWingMan Kwok GBENU_STATS_P2(ale_unknown_mcast), 11839a391c7bSWingMan Kwok GBENU_STATS_P2(ale_unknown_mcast_bytes), 11849a391c7bSWingMan Kwok GBENU_STATS_P2(ale_unknown_bcast), 11859a391c7bSWingMan Kwok GBENU_STATS_P2(ale_unknown_bcast_bytes), 11865be4001eSWingMan Kwok GBENU_STATS_P2(ale_pol_match), 11875be4001eSWingMan Kwok GBENU_STATS_P2(ale_pol_match_red), 11885be4001eSWingMan Kwok GBENU_STATS_P2(ale_pol_match_yellow), 11899a391c7bSWingMan Kwok GBENU_STATS_P2(tx_mem_protect_err), 11905be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri0_drop), 11915be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri1_drop), 11925be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri2_drop), 11935be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri3_drop), 11945be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri4_drop), 11955be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri5_drop), 11965be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri6_drop), 11975be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri7_drop), 11985be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri0_drop_bcnt), 11995be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri1_drop_bcnt), 12005be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri2_drop_bcnt), 12015be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri3_drop_bcnt), 12025be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri4_drop_bcnt), 12035be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri5_drop_bcnt), 12045be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri6_drop_bcnt), 12055be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri7_drop_bcnt), 12069a391c7bSWingMan Kwok /* GBENU Module 3 */ 12079a391c7bSWingMan Kwok GBENU_STATS_P3(rx_good_frames), 12089a391c7bSWingMan Kwok GBENU_STATS_P3(rx_broadcast_frames), 12099a391c7bSWingMan Kwok GBENU_STATS_P3(rx_multicast_frames), 12109a391c7bSWingMan Kwok GBENU_STATS_P3(rx_pause_frames), 12119a391c7bSWingMan Kwok GBENU_STATS_P3(rx_crc_errors), 12129a391c7bSWingMan Kwok GBENU_STATS_P3(rx_align_code_errors), 12139a391c7bSWingMan Kwok GBENU_STATS_P3(rx_oversized_frames), 12149a391c7bSWingMan Kwok GBENU_STATS_P3(rx_jabber_frames), 12159a391c7bSWingMan Kwok GBENU_STATS_P3(rx_undersized_frames), 12169a391c7bSWingMan Kwok GBENU_STATS_P3(rx_fragments), 12179a391c7bSWingMan Kwok GBENU_STATS_P3(ale_drop), 12189a391c7bSWingMan Kwok GBENU_STATS_P3(ale_overrun_drop), 12199a391c7bSWingMan Kwok GBENU_STATS_P3(rx_bytes), 12209a391c7bSWingMan Kwok GBENU_STATS_P3(tx_good_frames), 12219a391c7bSWingMan Kwok GBENU_STATS_P3(tx_broadcast_frames), 12229a391c7bSWingMan Kwok GBENU_STATS_P3(tx_multicast_frames), 12239a391c7bSWingMan Kwok GBENU_STATS_P3(tx_pause_frames), 12249a391c7bSWingMan Kwok GBENU_STATS_P3(tx_deferred_frames), 12259a391c7bSWingMan Kwok GBENU_STATS_P3(tx_collision_frames), 12269a391c7bSWingMan Kwok GBENU_STATS_P3(tx_single_coll_frames), 12279a391c7bSWingMan Kwok GBENU_STATS_P3(tx_mult_coll_frames), 12289a391c7bSWingMan Kwok GBENU_STATS_P3(tx_excessive_collisions), 12299a391c7bSWingMan Kwok GBENU_STATS_P3(tx_late_collisions), 12309a391c7bSWingMan Kwok GBENU_STATS_P3(rx_ipg_error), 12319a391c7bSWingMan Kwok GBENU_STATS_P3(tx_carrier_sense_errors), 12329a391c7bSWingMan Kwok GBENU_STATS_P3(tx_bytes), 12339a391c7bSWingMan Kwok GBENU_STATS_P3(tx_64B_frames), 12349a391c7bSWingMan Kwok GBENU_STATS_P3(tx_65_to_127B_frames), 12359a391c7bSWingMan Kwok GBENU_STATS_P3(tx_128_to_255B_frames), 12369a391c7bSWingMan Kwok GBENU_STATS_P3(tx_256_to_511B_frames), 12379a391c7bSWingMan Kwok GBENU_STATS_P3(tx_512_to_1023B_frames), 12389a391c7bSWingMan Kwok GBENU_STATS_P3(tx_1024B_frames), 12399a391c7bSWingMan Kwok GBENU_STATS_P3(net_bytes), 12409a391c7bSWingMan Kwok GBENU_STATS_P3(rx_bottom_fifo_drop), 12419a391c7bSWingMan Kwok GBENU_STATS_P3(rx_port_mask_drop), 12429a391c7bSWingMan Kwok GBENU_STATS_P3(rx_top_fifo_drop), 12439a391c7bSWingMan Kwok GBENU_STATS_P3(ale_rate_limit_drop), 12449a391c7bSWingMan Kwok GBENU_STATS_P3(ale_vid_ingress_drop), 12459a391c7bSWingMan Kwok GBENU_STATS_P3(ale_da_eq_sa_drop), 12469a391c7bSWingMan Kwok GBENU_STATS_P3(ale_unknown_ucast), 12479a391c7bSWingMan Kwok GBENU_STATS_P3(ale_unknown_ucast_bytes), 12489a391c7bSWingMan Kwok GBENU_STATS_P3(ale_unknown_mcast), 12499a391c7bSWingMan Kwok GBENU_STATS_P3(ale_unknown_mcast_bytes), 12509a391c7bSWingMan Kwok GBENU_STATS_P3(ale_unknown_bcast), 12519a391c7bSWingMan Kwok GBENU_STATS_P3(ale_unknown_bcast_bytes), 12525be4001eSWingMan Kwok GBENU_STATS_P3(ale_pol_match), 12535be4001eSWingMan Kwok GBENU_STATS_P3(ale_pol_match_red), 12545be4001eSWingMan Kwok GBENU_STATS_P3(ale_pol_match_yellow), 12559a391c7bSWingMan Kwok GBENU_STATS_P3(tx_mem_protect_err), 12565be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri0_drop), 12575be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri1_drop), 12585be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri2_drop), 12595be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri3_drop), 12605be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri4_drop), 12615be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri5_drop), 12625be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri6_drop), 12635be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri7_drop), 12645be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri0_drop_bcnt), 12655be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri1_drop_bcnt), 12665be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri2_drop_bcnt), 12675be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri3_drop_bcnt), 12685be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri4_drop_bcnt), 12695be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri5_drop_bcnt), 12705be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri6_drop_bcnt), 12715be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri7_drop_bcnt), 12729a391c7bSWingMan Kwok /* GBENU Module 4 */ 12739a391c7bSWingMan Kwok GBENU_STATS_P4(rx_good_frames), 12749a391c7bSWingMan Kwok GBENU_STATS_P4(rx_broadcast_frames), 12759a391c7bSWingMan Kwok GBENU_STATS_P4(rx_multicast_frames), 12769a391c7bSWingMan Kwok GBENU_STATS_P4(rx_pause_frames), 12779a391c7bSWingMan Kwok GBENU_STATS_P4(rx_crc_errors), 12789a391c7bSWingMan Kwok GBENU_STATS_P4(rx_align_code_errors), 12799a391c7bSWingMan Kwok GBENU_STATS_P4(rx_oversized_frames), 12809a391c7bSWingMan Kwok GBENU_STATS_P4(rx_jabber_frames), 12819a391c7bSWingMan Kwok GBENU_STATS_P4(rx_undersized_frames), 12829a391c7bSWingMan Kwok GBENU_STATS_P4(rx_fragments), 12839a391c7bSWingMan Kwok GBENU_STATS_P4(ale_drop), 12849a391c7bSWingMan Kwok GBENU_STATS_P4(ale_overrun_drop), 12859a391c7bSWingMan Kwok GBENU_STATS_P4(rx_bytes), 12869a391c7bSWingMan Kwok GBENU_STATS_P4(tx_good_frames), 12879a391c7bSWingMan Kwok GBENU_STATS_P4(tx_broadcast_frames), 12889a391c7bSWingMan Kwok GBENU_STATS_P4(tx_multicast_frames), 12899a391c7bSWingMan Kwok GBENU_STATS_P4(tx_pause_frames), 12909a391c7bSWingMan Kwok GBENU_STATS_P4(tx_deferred_frames), 12919a391c7bSWingMan Kwok GBENU_STATS_P4(tx_collision_frames), 12929a391c7bSWingMan Kwok GBENU_STATS_P4(tx_single_coll_frames), 12939a391c7bSWingMan Kwok GBENU_STATS_P4(tx_mult_coll_frames), 12949a391c7bSWingMan Kwok GBENU_STATS_P4(tx_excessive_collisions), 12959a391c7bSWingMan Kwok GBENU_STATS_P4(tx_late_collisions), 12969a391c7bSWingMan Kwok GBENU_STATS_P4(rx_ipg_error), 12979a391c7bSWingMan Kwok GBENU_STATS_P4(tx_carrier_sense_errors), 12989a391c7bSWingMan Kwok GBENU_STATS_P4(tx_bytes), 12999a391c7bSWingMan Kwok GBENU_STATS_P4(tx_64B_frames), 13009a391c7bSWingMan Kwok GBENU_STATS_P4(tx_65_to_127B_frames), 13019a391c7bSWingMan Kwok GBENU_STATS_P4(tx_128_to_255B_frames), 13029a391c7bSWingMan Kwok GBENU_STATS_P4(tx_256_to_511B_frames), 13039a391c7bSWingMan Kwok GBENU_STATS_P4(tx_512_to_1023B_frames), 13049a391c7bSWingMan Kwok GBENU_STATS_P4(tx_1024B_frames), 13059a391c7bSWingMan Kwok GBENU_STATS_P4(net_bytes), 13069a391c7bSWingMan Kwok GBENU_STATS_P4(rx_bottom_fifo_drop), 13079a391c7bSWingMan Kwok GBENU_STATS_P4(rx_port_mask_drop), 13089a391c7bSWingMan Kwok GBENU_STATS_P4(rx_top_fifo_drop), 13099a391c7bSWingMan Kwok GBENU_STATS_P4(ale_rate_limit_drop), 13109a391c7bSWingMan Kwok GBENU_STATS_P4(ale_vid_ingress_drop), 13119a391c7bSWingMan Kwok GBENU_STATS_P4(ale_da_eq_sa_drop), 13129a391c7bSWingMan Kwok GBENU_STATS_P4(ale_unknown_ucast), 13139a391c7bSWingMan Kwok GBENU_STATS_P4(ale_unknown_ucast_bytes), 13149a391c7bSWingMan Kwok GBENU_STATS_P4(ale_unknown_mcast), 13159a391c7bSWingMan Kwok GBENU_STATS_P4(ale_unknown_mcast_bytes), 13169a391c7bSWingMan Kwok GBENU_STATS_P4(ale_unknown_bcast), 13179a391c7bSWingMan Kwok GBENU_STATS_P4(ale_unknown_bcast_bytes), 13185be4001eSWingMan Kwok GBENU_STATS_P4(ale_pol_match), 13195be4001eSWingMan Kwok GBENU_STATS_P4(ale_pol_match_red), 13205be4001eSWingMan Kwok GBENU_STATS_P4(ale_pol_match_yellow), 13219a391c7bSWingMan Kwok GBENU_STATS_P4(tx_mem_protect_err), 13225be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri0_drop), 13235be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri1_drop), 13245be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri2_drop), 13255be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri3_drop), 13265be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri4_drop), 13275be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri5_drop), 13285be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri6_drop), 13295be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri7_drop), 13305be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri0_drop_bcnt), 13315be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri1_drop_bcnt), 13325be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri2_drop_bcnt), 13335be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri3_drop_bcnt), 13345be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri4_drop_bcnt), 13355be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri5_drop_bcnt), 13365be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri6_drop_bcnt), 13375be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri7_drop_bcnt), 13389a391c7bSWingMan Kwok /* GBENU Module 5 */ 13399a391c7bSWingMan Kwok GBENU_STATS_P5(rx_good_frames), 13409a391c7bSWingMan Kwok GBENU_STATS_P5(rx_broadcast_frames), 13419a391c7bSWingMan Kwok GBENU_STATS_P5(rx_multicast_frames), 13429a391c7bSWingMan Kwok GBENU_STATS_P5(rx_pause_frames), 13439a391c7bSWingMan Kwok GBENU_STATS_P5(rx_crc_errors), 13449a391c7bSWingMan Kwok GBENU_STATS_P5(rx_align_code_errors), 13459a391c7bSWingMan Kwok GBENU_STATS_P5(rx_oversized_frames), 13469a391c7bSWingMan Kwok GBENU_STATS_P5(rx_jabber_frames), 13479a391c7bSWingMan Kwok GBENU_STATS_P5(rx_undersized_frames), 13489a391c7bSWingMan Kwok GBENU_STATS_P5(rx_fragments), 13499a391c7bSWingMan Kwok GBENU_STATS_P5(ale_drop), 13509a391c7bSWingMan Kwok GBENU_STATS_P5(ale_overrun_drop), 13519a391c7bSWingMan Kwok GBENU_STATS_P5(rx_bytes), 13529a391c7bSWingMan Kwok GBENU_STATS_P5(tx_good_frames), 13539a391c7bSWingMan Kwok GBENU_STATS_P5(tx_broadcast_frames), 13549a391c7bSWingMan Kwok GBENU_STATS_P5(tx_multicast_frames), 13559a391c7bSWingMan Kwok GBENU_STATS_P5(tx_pause_frames), 13569a391c7bSWingMan Kwok GBENU_STATS_P5(tx_deferred_frames), 13579a391c7bSWingMan Kwok GBENU_STATS_P5(tx_collision_frames), 13589a391c7bSWingMan Kwok GBENU_STATS_P5(tx_single_coll_frames), 13599a391c7bSWingMan Kwok GBENU_STATS_P5(tx_mult_coll_frames), 13609a391c7bSWingMan Kwok GBENU_STATS_P5(tx_excessive_collisions), 13619a391c7bSWingMan Kwok GBENU_STATS_P5(tx_late_collisions), 13629a391c7bSWingMan Kwok GBENU_STATS_P5(rx_ipg_error), 13639a391c7bSWingMan Kwok GBENU_STATS_P5(tx_carrier_sense_errors), 13649a391c7bSWingMan Kwok GBENU_STATS_P5(tx_bytes), 13659a391c7bSWingMan Kwok GBENU_STATS_P5(tx_64B_frames), 13669a391c7bSWingMan Kwok GBENU_STATS_P5(tx_65_to_127B_frames), 13679a391c7bSWingMan Kwok GBENU_STATS_P5(tx_128_to_255B_frames), 13689a391c7bSWingMan Kwok GBENU_STATS_P5(tx_256_to_511B_frames), 13699a391c7bSWingMan Kwok GBENU_STATS_P5(tx_512_to_1023B_frames), 13709a391c7bSWingMan Kwok GBENU_STATS_P5(tx_1024B_frames), 13719a391c7bSWingMan Kwok GBENU_STATS_P5(net_bytes), 13729a391c7bSWingMan Kwok GBENU_STATS_P5(rx_bottom_fifo_drop), 13739a391c7bSWingMan Kwok GBENU_STATS_P5(rx_port_mask_drop), 13749a391c7bSWingMan Kwok GBENU_STATS_P5(rx_top_fifo_drop), 13759a391c7bSWingMan Kwok GBENU_STATS_P5(ale_rate_limit_drop), 13769a391c7bSWingMan Kwok GBENU_STATS_P5(ale_vid_ingress_drop), 13779a391c7bSWingMan Kwok GBENU_STATS_P5(ale_da_eq_sa_drop), 13789a391c7bSWingMan Kwok GBENU_STATS_P5(ale_unknown_ucast), 13799a391c7bSWingMan Kwok GBENU_STATS_P5(ale_unknown_ucast_bytes), 13809a391c7bSWingMan Kwok GBENU_STATS_P5(ale_unknown_mcast), 13819a391c7bSWingMan Kwok GBENU_STATS_P5(ale_unknown_mcast_bytes), 13829a391c7bSWingMan Kwok GBENU_STATS_P5(ale_unknown_bcast), 13839a391c7bSWingMan Kwok GBENU_STATS_P5(ale_unknown_bcast_bytes), 13845be4001eSWingMan Kwok GBENU_STATS_P5(ale_pol_match), 13855be4001eSWingMan Kwok GBENU_STATS_P5(ale_pol_match_red), 13865be4001eSWingMan Kwok GBENU_STATS_P5(ale_pol_match_yellow), 13879a391c7bSWingMan Kwok GBENU_STATS_P5(tx_mem_protect_err), 13885be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri0_drop), 13895be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri1_drop), 13905be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri2_drop), 13915be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri3_drop), 13925be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri4_drop), 13935be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri5_drop), 13945be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri6_drop), 13955be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri7_drop), 13965be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri0_drop_bcnt), 13975be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri1_drop_bcnt), 13985be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri2_drop_bcnt), 13995be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri3_drop_bcnt), 14005be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri4_drop_bcnt), 14015be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri5_drop_bcnt), 14025be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri6_drop_bcnt), 14035be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri7_drop_bcnt), 14049a391c7bSWingMan Kwok /* GBENU Module 6 */ 14059a391c7bSWingMan Kwok GBENU_STATS_P6(rx_good_frames), 14069a391c7bSWingMan Kwok GBENU_STATS_P6(rx_broadcast_frames), 14079a391c7bSWingMan Kwok GBENU_STATS_P6(rx_multicast_frames), 14089a391c7bSWingMan Kwok GBENU_STATS_P6(rx_pause_frames), 14099a391c7bSWingMan Kwok GBENU_STATS_P6(rx_crc_errors), 14109a391c7bSWingMan Kwok GBENU_STATS_P6(rx_align_code_errors), 14119a391c7bSWingMan Kwok GBENU_STATS_P6(rx_oversized_frames), 14129a391c7bSWingMan Kwok GBENU_STATS_P6(rx_jabber_frames), 14139a391c7bSWingMan Kwok GBENU_STATS_P6(rx_undersized_frames), 14149a391c7bSWingMan Kwok GBENU_STATS_P6(rx_fragments), 14159a391c7bSWingMan Kwok GBENU_STATS_P6(ale_drop), 14169a391c7bSWingMan Kwok GBENU_STATS_P6(ale_overrun_drop), 14179a391c7bSWingMan Kwok GBENU_STATS_P6(rx_bytes), 14189a391c7bSWingMan Kwok GBENU_STATS_P6(tx_good_frames), 14199a391c7bSWingMan Kwok GBENU_STATS_P6(tx_broadcast_frames), 14209a391c7bSWingMan Kwok GBENU_STATS_P6(tx_multicast_frames), 14219a391c7bSWingMan Kwok GBENU_STATS_P6(tx_pause_frames), 14229a391c7bSWingMan Kwok GBENU_STATS_P6(tx_deferred_frames), 14239a391c7bSWingMan Kwok GBENU_STATS_P6(tx_collision_frames), 14249a391c7bSWingMan Kwok GBENU_STATS_P6(tx_single_coll_frames), 14259a391c7bSWingMan Kwok GBENU_STATS_P6(tx_mult_coll_frames), 14269a391c7bSWingMan Kwok GBENU_STATS_P6(tx_excessive_collisions), 14279a391c7bSWingMan Kwok GBENU_STATS_P6(tx_late_collisions), 14289a391c7bSWingMan Kwok GBENU_STATS_P6(rx_ipg_error), 14299a391c7bSWingMan Kwok GBENU_STATS_P6(tx_carrier_sense_errors), 14309a391c7bSWingMan Kwok GBENU_STATS_P6(tx_bytes), 14319a391c7bSWingMan Kwok GBENU_STATS_P6(tx_64B_frames), 14329a391c7bSWingMan Kwok GBENU_STATS_P6(tx_65_to_127B_frames), 14339a391c7bSWingMan Kwok GBENU_STATS_P6(tx_128_to_255B_frames), 14349a391c7bSWingMan Kwok GBENU_STATS_P6(tx_256_to_511B_frames), 14359a391c7bSWingMan Kwok GBENU_STATS_P6(tx_512_to_1023B_frames), 14369a391c7bSWingMan Kwok GBENU_STATS_P6(tx_1024B_frames), 14379a391c7bSWingMan Kwok GBENU_STATS_P6(net_bytes), 14389a391c7bSWingMan Kwok GBENU_STATS_P6(rx_bottom_fifo_drop), 14399a391c7bSWingMan Kwok GBENU_STATS_P6(rx_port_mask_drop), 14409a391c7bSWingMan Kwok GBENU_STATS_P6(rx_top_fifo_drop), 14419a391c7bSWingMan Kwok GBENU_STATS_P6(ale_rate_limit_drop), 14429a391c7bSWingMan Kwok GBENU_STATS_P6(ale_vid_ingress_drop), 14439a391c7bSWingMan Kwok GBENU_STATS_P6(ale_da_eq_sa_drop), 14449a391c7bSWingMan Kwok GBENU_STATS_P6(ale_unknown_ucast), 14459a391c7bSWingMan Kwok GBENU_STATS_P6(ale_unknown_ucast_bytes), 14469a391c7bSWingMan Kwok GBENU_STATS_P6(ale_unknown_mcast), 14479a391c7bSWingMan Kwok GBENU_STATS_P6(ale_unknown_mcast_bytes), 14489a391c7bSWingMan Kwok GBENU_STATS_P6(ale_unknown_bcast), 14499a391c7bSWingMan Kwok GBENU_STATS_P6(ale_unknown_bcast_bytes), 14505be4001eSWingMan Kwok GBENU_STATS_P6(ale_pol_match), 14515be4001eSWingMan Kwok GBENU_STATS_P6(ale_pol_match_red), 14525be4001eSWingMan Kwok GBENU_STATS_P6(ale_pol_match_yellow), 14539a391c7bSWingMan Kwok GBENU_STATS_P6(tx_mem_protect_err), 14545be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri0_drop), 14555be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri1_drop), 14565be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri2_drop), 14575be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri3_drop), 14585be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri4_drop), 14595be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri5_drop), 14605be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri6_drop), 14615be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri7_drop), 14625be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri0_drop_bcnt), 14635be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri1_drop_bcnt), 14645be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri2_drop_bcnt), 14655be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri3_drop_bcnt), 14665be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri4_drop_bcnt), 14675be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri5_drop_bcnt), 14685be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri6_drop_bcnt), 14695be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri7_drop_bcnt), 14709a391c7bSWingMan Kwok /* GBENU Module 7 */ 14719a391c7bSWingMan Kwok GBENU_STATS_P7(rx_good_frames), 14729a391c7bSWingMan Kwok GBENU_STATS_P7(rx_broadcast_frames), 14739a391c7bSWingMan Kwok GBENU_STATS_P7(rx_multicast_frames), 14749a391c7bSWingMan Kwok GBENU_STATS_P7(rx_pause_frames), 14759a391c7bSWingMan Kwok GBENU_STATS_P7(rx_crc_errors), 14769a391c7bSWingMan Kwok GBENU_STATS_P7(rx_align_code_errors), 14779a391c7bSWingMan Kwok GBENU_STATS_P7(rx_oversized_frames), 14789a391c7bSWingMan Kwok GBENU_STATS_P7(rx_jabber_frames), 14799a391c7bSWingMan Kwok GBENU_STATS_P7(rx_undersized_frames), 14809a391c7bSWingMan Kwok GBENU_STATS_P7(rx_fragments), 14819a391c7bSWingMan Kwok GBENU_STATS_P7(ale_drop), 14829a391c7bSWingMan Kwok GBENU_STATS_P7(ale_overrun_drop), 14839a391c7bSWingMan Kwok GBENU_STATS_P7(rx_bytes), 14849a391c7bSWingMan Kwok GBENU_STATS_P7(tx_good_frames), 14859a391c7bSWingMan Kwok GBENU_STATS_P7(tx_broadcast_frames), 14869a391c7bSWingMan Kwok GBENU_STATS_P7(tx_multicast_frames), 14879a391c7bSWingMan Kwok GBENU_STATS_P7(tx_pause_frames), 14889a391c7bSWingMan Kwok GBENU_STATS_P7(tx_deferred_frames), 14899a391c7bSWingMan Kwok GBENU_STATS_P7(tx_collision_frames), 14909a391c7bSWingMan Kwok GBENU_STATS_P7(tx_single_coll_frames), 14919a391c7bSWingMan Kwok GBENU_STATS_P7(tx_mult_coll_frames), 14929a391c7bSWingMan Kwok GBENU_STATS_P7(tx_excessive_collisions), 14939a391c7bSWingMan Kwok GBENU_STATS_P7(tx_late_collisions), 14949a391c7bSWingMan Kwok GBENU_STATS_P7(rx_ipg_error), 14959a391c7bSWingMan Kwok GBENU_STATS_P7(tx_carrier_sense_errors), 14969a391c7bSWingMan Kwok GBENU_STATS_P7(tx_bytes), 14979a391c7bSWingMan Kwok GBENU_STATS_P7(tx_64B_frames), 14989a391c7bSWingMan Kwok GBENU_STATS_P7(tx_65_to_127B_frames), 14999a391c7bSWingMan Kwok GBENU_STATS_P7(tx_128_to_255B_frames), 15009a391c7bSWingMan Kwok GBENU_STATS_P7(tx_256_to_511B_frames), 15019a391c7bSWingMan Kwok GBENU_STATS_P7(tx_512_to_1023B_frames), 15029a391c7bSWingMan Kwok GBENU_STATS_P7(tx_1024B_frames), 15039a391c7bSWingMan Kwok GBENU_STATS_P7(net_bytes), 15049a391c7bSWingMan Kwok GBENU_STATS_P7(rx_bottom_fifo_drop), 15059a391c7bSWingMan Kwok GBENU_STATS_P7(rx_port_mask_drop), 15069a391c7bSWingMan Kwok GBENU_STATS_P7(rx_top_fifo_drop), 15079a391c7bSWingMan Kwok GBENU_STATS_P7(ale_rate_limit_drop), 15089a391c7bSWingMan Kwok GBENU_STATS_P7(ale_vid_ingress_drop), 15099a391c7bSWingMan Kwok GBENU_STATS_P7(ale_da_eq_sa_drop), 15109a391c7bSWingMan Kwok GBENU_STATS_P7(ale_unknown_ucast), 15119a391c7bSWingMan Kwok GBENU_STATS_P7(ale_unknown_ucast_bytes), 15129a391c7bSWingMan Kwok GBENU_STATS_P7(ale_unknown_mcast), 15139a391c7bSWingMan Kwok GBENU_STATS_P7(ale_unknown_mcast_bytes), 15149a391c7bSWingMan Kwok GBENU_STATS_P7(ale_unknown_bcast), 15159a391c7bSWingMan Kwok GBENU_STATS_P7(ale_unknown_bcast_bytes), 15165be4001eSWingMan Kwok GBENU_STATS_P7(ale_pol_match), 15175be4001eSWingMan Kwok GBENU_STATS_P7(ale_pol_match_red), 15185be4001eSWingMan Kwok GBENU_STATS_P7(ale_pol_match_yellow), 15199a391c7bSWingMan Kwok GBENU_STATS_P7(tx_mem_protect_err), 15205be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri0_drop), 15215be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri1_drop), 15225be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri2_drop), 15235be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri3_drop), 15245be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri4_drop), 15255be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri5_drop), 15265be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri6_drop), 15275be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri7_drop), 15285be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri0_drop_bcnt), 15295be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri1_drop_bcnt), 15305be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri2_drop_bcnt), 15315be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri3_drop_bcnt), 15325be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri4_drop_bcnt), 15335be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri5_drop_bcnt), 15345be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri6_drop_bcnt), 15355be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri7_drop_bcnt), 15369a391c7bSWingMan Kwok /* GBENU Module 8 */ 15379a391c7bSWingMan Kwok GBENU_STATS_P8(rx_good_frames), 15389a391c7bSWingMan Kwok GBENU_STATS_P8(rx_broadcast_frames), 15399a391c7bSWingMan Kwok GBENU_STATS_P8(rx_multicast_frames), 15409a391c7bSWingMan Kwok GBENU_STATS_P8(rx_pause_frames), 15419a391c7bSWingMan Kwok GBENU_STATS_P8(rx_crc_errors), 15429a391c7bSWingMan Kwok GBENU_STATS_P8(rx_align_code_errors), 15439a391c7bSWingMan Kwok GBENU_STATS_P8(rx_oversized_frames), 15449a391c7bSWingMan Kwok GBENU_STATS_P8(rx_jabber_frames), 15459a391c7bSWingMan Kwok GBENU_STATS_P8(rx_undersized_frames), 15469a391c7bSWingMan Kwok GBENU_STATS_P8(rx_fragments), 15479a391c7bSWingMan Kwok GBENU_STATS_P8(ale_drop), 15489a391c7bSWingMan Kwok GBENU_STATS_P8(ale_overrun_drop), 15499a391c7bSWingMan Kwok GBENU_STATS_P8(rx_bytes), 15509a391c7bSWingMan Kwok GBENU_STATS_P8(tx_good_frames), 15519a391c7bSWingMan Kwok GBENU_STATS_P8(tx_broadcast_frames), 15529a391c7bSWingMan Kwok GBENU_STATS_P8(tx_multicast_frames), 15539a391c7bSWingMan Kwok GBENU_STATS_P8(tx_pause_frames), 15549a391c7bSWingMan Kwok GBENU_STATS_P8(tx_deferred_frames), 15559a391c7bSWingMan Kwok GBENU_STATS_P8(tx_collision_frames), 15569a391c7bSWingMan Kwok GBENU_STATS_P8(tx_single_coll_frames), 15579a391c7bSWingMan Kwok GBENU_STATS_P8(tx_mult_coll_frames), 15589a391c7bSWingMan Kwok GBENU_STATS_P8(tx_excessive_collisions), 15599a391c7bSWingMan Kwok GBENU_STATS_P8(tx_late_collisions), 15609a391c7bSWingMan Kwok GBENU_STATS_P8(rx_ipg_error), 15619a391c7bSWingMan Kwok GBENU_STATS_P8(tx_carrier_sense_errors), 15629a391c7bSWingMan Kwok GBENU_STATS_P8(tx_bytes), 15639a391c7bSWingMan Kwok GBENU_STATS_P8(tx_64B_frames), 15649a391c7bSWingMan Kwok GBENU_STATS_P8(tx_65_to_127B_frames), 15659a391c7bSWingMan Kwok GBENU_STATS_P8(tx_128_to_255B_frames), 15669a391c7bSWingMan Kwok GBENU_STATS_P8(tx_256_to_511B_frames), 15679a391c7bSWingMan Kwok GBENU_STATS_P8(tx_512_to_1023B_frames), 15689a391c7bSWingMan Kwok GBENU_STATS_P8(tx_1024B_frames), 15699a391c7bSWingMan Kwok GBENU_STATS_P8(net_bytes), 15709a391c7bSWingMan Kwok GBENU_STATS_P8(rx_bottom_fifo_drop), 15719a391c7bSWingMan Kwok GBENU_STATS_P8(rx_port_mask_drop), 15729a391c7bSWingMan Kwok GBENU_STATS_P8(rx_top_fifo_drop), 15739a391c7bSWingMan Kwok GBENU_STATS_P8(ale_rate_limit_drop), 15749a391c7bSWingMan Kwok GBENU_STATS_P8(ale_vid_ingress_drop), 15759a391c7bSWingMan Kwok GBENU_STATS_P8(ale_da_eq_sa_drop), 15769a391c7bSWingMan Kwok GBENU_STATS_P8(ale_unknown_ucast), 15779a391c7bSWingMan Kwok GBENU_STATS_P8(ale_unknown_ucast_bytes), 15789a391c7bSWingMan Kwok GBENU_STATS_P8(ale_unknown_mcast), 15799a391c7bSWingMan Kwok GBENU_STATS_P8(ale_unknown_mcast_bytes), 15809a391c7bSWingMan Kwok GBENU_STATS_P8(ale_unknown_bcast), 15819a391c7bSWingMan Kwok GBENU_STATS_P8(ale_unknown_bcast_bytes), 15825be4001eSWingMan Kwok GBENU_STATS_P8(ale_pol_match), 15835be4001eSWingMan Kwok GBENU_STATS_P8(ale_pol_match_red), 15845be4001eSWingMan Kwok GBENU_STATS_P8(ale_pol_match_yellow), 15859a391c7bSWingMan Kwok GBENU_STATS_P8(tx_mem_protect_err), 15865be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri0_drop), 15875be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri1_drop), 15885be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri2_drop), 15895be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri3_drop), 15905be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri4_drop), 15915be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri5_drop), 15925be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri6_drop), 15935be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri7_drop), 15945be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri0_drop_bcnt), 15955be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri1_drop_bcnt), 15965be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri2_drop_bcnt), 15975be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri3_drop_bcnt), 15985be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri4_drop_bcnt), 15995be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri5_drop_bcnt), 16005be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri6_drop_bcnt), 16015be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri7_drop_bcnt), 16029a391c7bSWingMan Kwok }; 16039a391c7bSWingMan Kwok 1604da866ba0SKaricheri, Muralidharan #define XGBE_STATS0_INFO(field) \ 1605da866ba0SKaricheri, Muralidharan { \ 1606da866ba0SKaricheri, Muralidharan "GBE_0:"#field, XGBE_STATS0_MODULE, \ 160790cff9e2SWingman Kwok FIELD_SIZEOF(struct xgbe_hw_stats, field), \ 1608da866ba0SKaricheri, Muralidharan offsetof(struct xgbe_hw_stats, field) \ 1609da866ba0SKaricheri, Muralidharan } 161090cff9e2SWingman Kwok 1611da866ba0SKaricheri, Muralidharan #define XGBE_STATS1_INFO(field) \ 1612da866ba0SKaricheri, Muralidharan { \ 1613da866ba0SKaricheri, Muralidharan "GBE_1:"#field, XGBE_STATS1_MODULE, \ 161490cff9e2SWingman Kwok FIELD_SIZEOF(struct xgbe_hw_stats, field), \ 1615da866ba0SKaricheri, Muralidharan offsetof(struct xgbe_hw_stats, field) \ 1616da866ba0SKaricheri, Muralidharan } 161790cff9e2SWingman Kwok 1618da866ba0SKaricheri, Muralidharan #define XGBE_STATS2_INFO(field) \ 1619da866ba0SKaricheri, Muralidharan { \ 1620da866ba0SKaricheri, Muralidharan "GBE_2:"#field, XGBE_STATS2_MODULE, \ 162190cff9e2SWingman Kwok FIELD_SIZEOF(struct xgbe_hw_stats, field), \ 1622da866ba0SKaricheri, Muralidharan offsetof(struct xgbe_hw_stats, field) \ 1623da866ba0SKaricheri, Muralidharan } 162490cff9e2SWingman Kwok 162590cff9e2SWingman Kwok static const struct netcp_ethtool_stat xgbe10_et_stats[] = { 162690cff9e2SWingman Kwok /* GBE module 0 */ 1627da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_good_frames), 1628da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_broadcast_frames), 1629da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_multicast_frames), 1630da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_oversized_frames), 1631da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_undersized_frames), 1632da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(overrun_type4), 1633da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(overrun_type5), 1634da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_bytes), 1635da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_good_frames), 1636da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_broadcast_frames), 1637da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_multicast_frames), 1638da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_bytes), 1639da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_64byte_frames), 1640da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_65_to_127byte_frames), 1641da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_128_to_255byte_frames), 1642da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_256_to_511byte_frames), 1643da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_512_to_1023byte_frames), 1644da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_1024byte_frames), 1645da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(net_bytes), 1646da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_sof_overruns), 1647da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_mof_overruns), 1648da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_dma_overruns), 164990cff9e2SWingman Kwok /* XGBE module 1 */ 1650da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_good_frames), 1651da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_broadcast_frames), 1652da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_multicast_frames), 1653da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_pause_frames), 1654da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_crc_errors), 1655da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_align_code_errors), 1656da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_oversized_frames), 1657da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_jabber_frames), 1658da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_undersized_frames), 1659da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_fragments), 1660da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(overrun_type4), 1661da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(overrun_type5), 1662da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_bytes), 1663da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_good_frames), 1664da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_broadcast_frames), 1665da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_multicast_frames), 1666da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_pause_frames), 1667da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_deferred_frames), 1668da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_collision_frames), 1669da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_single_coll_frames), 1670da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_mult_coll_frames), 1671da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_excessive_collisions), 1672da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_late_collisions), 1673da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_underrun), 1674da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_carrier_sense_errors), 1675da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_bytes), 1676da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_64byte_frames), 1677da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_65_to_127byte_frames), 1678da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_128_to_255byte_frames), 1679da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_256_to_511byte_frames), 1680da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_512_to_1023byte_frames), 1681da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_1024byte_frames), 1682da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(net_bytes), 1683da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_sof_overruns), 1684da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_mof_overruns), 1685da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_dma_overruns), 168690cff9e2SWingman Kwok /* XGBE module 2 */ 1687da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_good_frames), 1688da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_broadcast_frames), 1689da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_multicast_frames), 1690da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_pause_frames), 1691da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_crc_errors), 1692da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_align_code_errors), 1693da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_oversized_frames), 1694da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_jabber_frames), 1695da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_undersized_frames), 1696da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_fragments), 1697da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(overrun_type4), 1698da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(overrun_type5), 1699da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_bytes), 1700da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_good_frames), 1701da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_broadcast_frames), 1702da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_multicast_frames), 1703da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_pause_frames), 1704da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_deferred_frames), 1705da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_collision_frames), 1706da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_single_coll_frames), 1707da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_mult_coll_frames), 1708da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_excessive_collisions), 1709da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_late_collisions), 1710da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_underrun), 1711da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_carrier_sense_errors), 1712da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_bytes), 1713da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_64byte_frames), 1714da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_65_to_127byte_frames), 1715da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_128_to_255byte_frames), 1716da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_256_to_511byte_frames), 1717da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_512_to_1023byte_frames), 1718da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_1024byte_frames), 1719da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(net_bytes), 1720da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_sof_overruns), 1721da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_mof_overruns), 1722da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_dma_overruns), 172390cff9e2SWingman Kwok }; 172490cff9e2SWingman Kwok 17256f8d3f33SWingman Kwok #define for_each_intf(i, priv) \ 17266f8d3f33SWingman Kwok list_for_each_entry((i), &(priv)->gbe_intf_head, gbe_intf_list) 17276f8d3f33SWingman Kwok 17286f8d3f33SWingman Kwok #define for_each_sec_slave(slave, priv) \ 17296f8d3f33SWingman Kwok list_for_each_entry((slave), &(priv)->secondary_slaves, slave_list) 17306f8d3f33SWingman Kwok 17316f8d3f33SWingman Kwok #define first_sec_slave(priv) \ 17326f8d3f33SWingman Kwok list_first_entry(&priv->secondary_slaves, \ 17336f8d3f33SWingman Kwok struct gbe_slave, slave_list) 17346f8d3f33SWingman Kwok 17356f8d3f33SWingman Kwok static void keystone_get_drvinfo(struct net_device *ndev, 17366f8d3f33SWingman Kwok struct ethtool_drvinfo *info) 17376f8d3f33SWingman Kwok { 17386f8d3f33SWingman Kwok strncpy(info->driver, NETCP_DRIVER_NAME, sizeof(info->driver)); 17396f8d3f33SWingman Kwok strncpy(info->version, NETCP_DRIVER_VERSION, sizeof(info->version)); 17406f8d3f33SWingman Kwok } 17416f8d3f33SWingman Kwok 17426f8d3f33SWingman Kwok static u32 keystone_get_msglevel(struct net_device *ndev) 17436f8d3f33SWingman Kwok { 17446f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 17456f8d3f33SWingman Kwok 17466f8d3f33SWingman Kwok return netcp->msg_enable; 17476f8d3f33SWingman Kwok } 17486f8d3f33SWingman Kwok 17496f8d3f33SWingman Kwok static void keystone_set_msglevel(struct net_device *ndev, u32 value) 17506f8d3f33SWingman Kwok { 17516f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 17526f8d3f33SWingman Kwok 17536f8d3f33SWingman Kwok netcp->msg_enable = value; 17546f8d3f33SWingman Kwok } 17556f8d3f33SWingman Kwok 1756e9838ef2SWingMan Kwok static struct gbe_intf *keystone_get_intf_data(struct netcp_intf *netcp) 1757e9838ef2SWingMan Kwok { 1758e9838ef2SWingMan Kwok struct gbe_intf *gbe_intf; 1759e9838ef2SWingMan Kwok 1760e9838ef2SWingMan Kwok gbe_intf = netcp_module_get_intf_data(&gbe_module, netcp); 1761e9838ef2SWingMan Kwok if (!gbe_intf) 1762e9838ef2SWingMan Kwok gbe_intf = netcp_module_get_intf_data(&xgbe_module, netcp); 1763e9838ef2SWingMan Kwok 1764e9838ef2SWingMan Kwok return gbe_intf; 1765e9838ef2SWingMan Kwok } 1766e9838ef2SWingMan Kwok 17676f8d3f33SWingman Kwok static void keystone_get_stat_strings(struct net_device *ndev, 17686f8d3f33SWingman Kwok uint32_t stringset, uint8_t *data) 17696f8d3f33SWingman Kwok { 17706f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 17716f8d3f33SWingman Kwok struct gbe_intf *gbe_intf; 17726f8d3f33SWingman Kwok struct gbe_priv *gbe_dev; 17736f8d3f33SWingman Kwok int i; 17746f8d3f33SWingman Kwok 1775e9838ef2SWingMan Kwok gbe_intf = keystone_get_intf_data(netcp); 17766f8d3f33SWingman Kwok if (!gbe_intf) 17776f8d3f33SWingman Kwok return; 17786f8d3f33SWingman Kwok gbe_dev = gbe_intf->gbe_dev; 17796f8d3f33SWingman Kwok 17806f8d3f33SWingman Kwok switch (stringset) { 17816f8d3f33SWingman Kwok case ETH_SS_STATS: 17826f8d3f33SWingman Kwok for (i = 0; i < gbe_dev->num_et_stats; i++) { 17836f8d3f33SWingman Kwok memcpy(data, gbe_dev->et_stats[i].desc, 17846f8d3f33SWingman Kwok ETH_GSTRING_LEN); 17856f8d3f33SWingman Kwok data += ETH_GSTRING_LEN; 17866f8d3f33SWingman Kwok } 17876f8d3f33SWingman Kwok break; 17886f8d3f33SWingman Kwok case ETH_SS_TEST: 17896f8d3f33SWingman Kwok break; 17906f8d3f33SWingman Kwok } 17916f8d3f33SWingman Kwok } 17926f8d3f33SWingman Kwok 17936f8d3f33SWingman Kwok static int keystone_get_sset_count(struct net_device *ndev, int stringset) 17946f8d3f33SWingman Kwok { 17956f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 17966f8d3f33SWingman Kwok struct gbe_intf *gbe_intf; 17976f8d3f33SWingman Kwok struct gbe_priv *gbe_dev; 17986f8d3f33SWingman Kwok 1799e9838ef2SWingMan Kwok gbe_intf = keystone_get_intf_data(netcp); 18006f8d3f33SWingman Kwok if (!gbe_intf) 18016f8d3f33SWingman Kwok return -EINVAL; 18026f8d3f33SWingman Kwok gbe_dev = gbe_intf->gbe_dev; 18036f8d3f33SWingman Kwok 18046f8d3f33SWingman Kwok switch (stringset) { 18056f8d3f33SWingman Kwok case ETH_SS_TEST: 18066f8d3f33SWingman Kwok return 0; 18076f8d3f33SWingman Kwok case ETH_SS_STATS: 18086f8d3f33SWingman Kwok return gbe_dev->num_et_stats; 18096f8d3f33SWingman Kwok default: 18106f8d3f33SWingman Kwok return -EINVAL; 18116f8d3f33SWingman Kwok } 18126f8d3f33SWingman Kwok } 18136f8d3f33SWingman Kwok 1814489e8a2fSWingMan Kwok static void gbe_reset_mod_stats(struct gbe_priv *gbe_dev, int stats_mod) 1815489e8a2fSWingMan Kwok { 1816489e8a2fSWingMan Kwok void __iomem *base = gbe_dev->hw_stats_regs[stats_mod]; 1817489e8a2fSWingMan Kwok u32 __iomem *p_stats_entry; 1818489e8a2fSWingMan Kwok int i; 1819489e8a2fSWingMan Kwok 1820489e8a2fSWingMan Kwok for (i = 0; i < gbe_dev->num_et_stats; i++) { 1821489e8a2fSWingMan Kwok if (gbe_dev->et_stats[i].type == stats_mod) { 1822489e8a2fSWingMan Kwok p_stats_entry = base + gbe_dev->et_stats[i].offset; 1823489e8a2fSWingMan Kwok gbe_dev->hw_stats[i] = 0; 1824489e8a2fSWingMan Kwok gbe_dev->hw_stats_prev[i] = readl(p_stats_entry); 1825489e8a2fSWingMan Kwok } 1826489e8a2fSWingMan Kwok } 1827489e8a2fSWingMan Kwok } 1828489e8a2fSWingMan Kwok 1829fbf64c19SWingMan Kwok static inline void gbe_update_hw_stats_entry(struct gbe_priv *gbe_dev, 1830fbf64c19SWingMan Kwok int et_stats_entry) 18316f8d3f33SWingman Kwok { 18326f8d3f33SWingman Kwok void __iomem *base = NULL; 1833489e8a2fSWingMan Kwok u32 __iomem *p_stats_entry; 1834489e8a2fSWingMan Kwok u32 curr, delta; 18356f8d3f33SWingman Kwok 1836fbf64c19SWingMan Kwok /* The hw_stats_regs pointers are already 1837fbf64c19SWingMan Kwok * properly set to point to the right base: 1838fbf64c19SWingMan Kwok */ 1839fbf64c19SWingMan Kwok base = gbe_dev->hw_stats_regs[gbe_dev->et_stats[et_stats_entry].type]; 1840489e8a2fSWingMan Kwok p_stats_entry = base + gbe_dev->et_stats[et_stats_entry].offset; 1841489e8a2fSWingMan Kwok curr = readl(p_stats_entry); 1842489e8a2fSWingMan Kwok delta = curr - gbe_dev->hw_stats_prev[et_stats_entry]; 1843489e8a2fSWingMan Kwok gbe_dev->hw_stats_prev[et_stats_entry] = curr; 1844489e8a2fSWingMan Kwok gbe_dev->hw_stats[et_stats_entry] += delta; 18456f8d3f33SWingman Kwok } 1846fbf64c19SWingMan Kwok 1847fbf64c19SWingMan Kwok static void gbe_update_stats(struct gbe_priv *gbe_dev, uint64_t *data) 1848fbf64c19SWingMan Kwok { 1849fbf64c19SWingMan Kwok int i; 1850fbf64c19SWingMan Kwok 1851fbf64c19SWingMan Kwok for (i = 0; i < gbe_dev->num_et_stats; i++) { 1852fbf64c19SWingMan Kwok gbe_update_hw_stats_entry(gbe_dev, i); 1853fbf64c19SWingMan Kwok 1854fbf64c19SWingMan Kwok if (data) 1855fbf64c19SWingMan Kwok data[i] = gbe_dev->hw_stats[i]; 1856fbf64c19SWingMan Kwok } 1857fbf64c19SWingMan Kwok } 1858fbf64c19SWingMan Kwok 1859fbf64c19SWingMan Kwok static inline void gbe_stats_mod_visible_ver14(struct gbe_priv *gbe_dev, 1860fbf64c19SWingMan Kwok int stats_mod) 1861fbf64c19SWingMan Kwok { 1862fbf64c19SWingMan Kwok u32 val; 1863fbf64c19SWingMan Kwok 1864fbf64c19SWingMan Kwok val = readl(GBE_REG_ADDR(gbe_dev, switch_regs, stat_port_en)); 1865fbf64c19SWingMan Kwok 1866fbf64c19SWingMan Kwok switch (stats_mod) { 1867fbf64c19SWingMan Kwok case GBE_STATSA_MODULE: 1868fbf64c19SWingMan Kwok case GBE_STATSB_MODULE: 1869fbf64c19SWingMan Kwok val &= ~GBE_STATS_CD_SEL; 1870fbf64c19SWingMan Kwok break; 1871fbf64c19SWingMan Kwok case GBE_STATSC_MODULE: 1872fbf64c19SWingMan Kwok case GBE_STATSD_MODULE: 1873fbf64c19SWingMan Kwok val |= GBE_STATS_CD_SEL; 1874fbf64c19SWingMan Kwok break; 1875fbf64c19SWingMan Kwok default: 1876fbf64c19SWingMan Kwok return; 1877fbf64c19SWingMan Kwok } 1878fbf64c19SWingMan Kwok 1879fbf64c19SWingMan Kwok /* make the stat module visible */ 1880fbf64c19SWingMan Kwok writel(val, GBE_REG_ADDR(gbe_dev, switch_regs, stat_port_en)); 18816f8d3f33SWingman Kwok } 18826f8d3f33SWingman Kwok 1883489e8a2fSWingMan Kwok static void gbe_reset_mod_stats_ver14(struct gbe_priv *gbe_dev, int stats_mod) 1884489e8a2fSWingMan Kwok { 1885489e8a2fSWingMan Kwok gbe_stats_mod_visible_ver14(gbe_dev, stats_mod); 1886489e8a2fSWingMan Kwok gbe_reset_mod_stats(gbe_dev, stats_mod); 1887489e8a2fSWingMan Kwok } 1888489e8a2fSWingMan Kwok 18896f8d3f33SWingman Kwok static void gbe_update_stats_ver14(struct gbe_priv *gbe_dev, uint64_t *data) 18906f8d3f33SWingman Kwok { 1891fbf64c19SWingMan Kwok u32 half_num_et_stats = (gbe_dev->num_et_stats / 2); 1892fbf64c19SWingMan Kwok int et_entry, j, pair; 18936f8d3f33SWingman Kwok 18946f8d3f33SWingman Kwok for (pair = 0; pair < 2; pair++) { 1895fbf64c19SWingMan Kwok gbe_stats_mod_visible_ver14(gbe_dev, (pair ? 1896fbf64c19SWingMan Kwok GBE_STATSC_MODULE : 1897fbf64c19SWingMan Kwok GBE_STATSA_MODULE)); 18986f8d3f33SWingman Kwok 1899fbf64c19SWingMan Kwok for (j = 0; j < half_num_et_stats; j++) { 1900fbf64c19SWingMan Kwok et_entry = pair * half_num_et_stats + j; 1901fbf64c19SWingMan Kwok gbe_update_hw_stats_entry(gbe_dev, et_entry); 19026f8d3f33SWingman Kwok 19036f8d3f33SWingman Kwok if (data) 1904fbf64c19SWingMan Kwok data[et_entry] = gbe_dev->hw_stats[et_entry]; 19056f8d3f33SWingman Kwok } 19066f8d3f33SWingman Kwok } 19076f8d3f33SWingman Kwok } 19086f8d3f33SWingman Kwok 19096f8d3f33SWingman Kwok static void keystone_get_ethtool_stats(struct net_device *ndev, 19106f8d3f33SWingman Kwok struct ethtool_stats *stats, 19116f8d3f33SWingman Kwok uint64_t *data) 19126f8d3f33SWingman Kwok { 19136f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 19146f8d3f33SWingman Kwok struct gbe_intf *gbe_intf; 19156f8d3f33SWingman Kwok struct gbe_priv *gbe_dev; 19166f8d3f33SWingman Kwok 1917e9838ef2SWingMan Kwok gbe_intf = keystone_get_intf_data(netcp); 19186f8d3f33SWingman Kwok if (!gbe_intf) 19196f8d3f33SWingman Kwok return; 19206f8d3f33SWingman Kwok 19216f8d3f33SWingman Kwok gbe_dev = gbe_intf->gbe_dev; 19226f8d3f33SWingman Kwok spin_lock_bh(&gbe_dev->hw_stats_lock); 19232953586dSMurali Karicheri if (IS_SS_ID_VER_14(gbe_dev)) 19246f8d3f33SWingman Kwok gbe_update_stats_ver14(gbe_dev, data); 192590cff9e2SWingman Kwok else 192690cff9e2SWingman Kwok gbe_update_stats(gbe_dev, data); 19276f8d3f33SWingman Kwok spin_unlock_bh(&gbe_dev->hw_stats_lock); 19286f8d3f33SWingman Kwok } 19296f8d3f33SWingman Kwok 193086e3a040SPhilippe Reynes static int keystone_get_link_ksettings(struct net_device *ndev, 193186e3a040SPhilippe Reynes struct ethtool_link_ksettings *cmd) 19326f8d3f33SWingman Kwok { 19336f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 19346f8d3f33SWingman Kwok struct phy_device *phy = ndev->phydev; 19356f8d3f33SWingman Kwok struct gbe_intf *gbe_intf; 19366f8d3f33SWingman Kwok 19376f8d3f33SWingman Kwok if (!phy) 19386f8d3f33SWingman Kwok return -EINVAL; 19396f8d3f33SWingman Kwok 1940e9838ef2SWingMan Kwok gbe_intf = keystone_get_intf_data(netcp); 19416f8d3f33SWingman Kwok if (!gbe_intf) 19426f8d3f33SWingman Kwok return -EINVAL; 19436f8d3f33SWingman Kwok 19446f8d3f33SWingman Kwok if (!gbe_intf->slave) 19456f8d3f33SWingman Kwok return -EINVAL; 19466f8d3f33SWingman Kwok 19475514174fSyuval.shaia@oracle.com phy_ethtool_ksettings_get(phy, cmd); 194886e3a040SPhilippe Reynes cmd->base.port = gbe_intf->slave->phy_port_t; 19496f8d3f33SWingman Kwok 19505514174fSyuval.shaia@oracle.com return 0; 19516f8d3f33SWingman Kwok } 19526f8d3f33SWingman Kwok 195386e3a040SPhilippe Reynes static int keystone_set_link_ksettings(struct net_device *ndev, 195486e3a040SPhilippe Reynes const struct ethtool_link_ksettings *cmd) 19556f8d3f33SWingman Kwok { 19566f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 19576f8d3f33SWingman Kwok struct phy_device *phy = ndev->phydev; 19586f8d3f33SWingman Kwok struct gbe_intf *gbe_intf; 195986e3a040SPhilippe Reynes u8 port = cmd->base.port; 196086e3a040SPhilippe Reynes u32 advertising, supported; 196186e3a040SPhilippe Reynes u32 features; 196286e3a040SPhilippe Reynes 196386e3a040SPhilippe Reynes ethtool_convert_link_mode_to_legacy_u32(&advertising, 196486e3a040SPhilippe Reynes cmd->link_modes.advertising); 196586e3a040SPhilippe Reynes ethtool_convert_link_mode_to_legacy_u32(&supported, 196686e3a040SPhilippe Reynes cmd->link_modes.supported); 196786e3a040SPhilippe Reynes features = advertising & supported; 19686f8d3f33SWingman Kwok 19696f8d3f33SWingman Kwok if (!phy) 19706f8d3f33SWingman Kwok return -EINVAL; 19716f8d3f33SWingman Kwok 1972e9838ef2SWingMan Kwok gbe_intf = keystone_get_intf_data(netcp); 19736f8d3f33SWingman Kwok if (!gbe_intf) 19746f8d3f33SWingman Kwok return -EINVAL; 19756f8d3f33SWingman Kwok 19766f8d3f33SWingman Kwok if (!gbe_intf->slave) 19776f8d3f33SWingman Kwok return -EINVAL; 19786f8d3f33SWingman Kwok 197986e3a040SPhilippe Reynes if (port != gbe_intf->slave->phy_port_t) { 198086e3a040SPhilippe Reynes if ((port == PORT_TP) && !(features & ADVERTISED_TP)) 19816f8d3f33SWingman Kwok return -EINVAL; 19826f8d3f33SWingman Kwok 198386e3a040SPhilippe Reynes if ((port == PORT_AUI) && !(features & ADVERTISED_AUI)) 19846f8d3f33SWingman Kwok return -EINVAL; 19856f8d3f33SWingman Kwok 198686e3a040SPhilippe Reynes if ((port == PORT_BNC) && !(features & ADVERTISED_BNC)) 19876f8d3f33SWingman Kwok return -EINVAL; 19886f8d3f33SWingman Kwok 198986e3a040SPhilippe Reynes if ((port == PORT_MII) && !(features & ADVERTISED_MII)) 19906f8d3f33SWingman Kwok return -EINVAL; 19916f8d3f33SWingman Kwok 199286e3a040SPhilippe Reynes if ((port == PORT_FIBRE) && !(features & ADVERTISED_FIBRE)) 19936f8d3f33SWingman Kwok return -EINVAL; 19946f8d3f33SWingman Kwok } 19956f8d3f33SWingman Kwok 199686e3a040SPhilippe Reynes gbe_intf->slave->phy_port_t = port; 199786e3a040SPhilippe Reynes return phy_ethtool_ksettings_set(phy, cmd); 19986f8d3f33SWingman Kwok } 19996f8d3f33SWingman Kwok 20006246168bSWingMan Kwok #if IS_ENABLED(CONFIG_TI_CPTS) 20016246168bSWingMan Kwok static int keystone_get_ts_info(struct net_device *ndev, 20026246168bSWingMan Kwok struct ethtool_ts_info *info) 20036246168bSWingMan Kwok { 20046246168bSWingMan Kwok struct netcp_intf *netcp = netdev_priv(ndev); 20056246168bSWingMan Kwok struct gbe_intf *gbe_intf; 20066246168bSWingMan Kwok 20076246168bSWingMan Kwok gbe_intf = netcp_module_get_intf_data(&gbe_module, netcp); 20086246168bSWingMan Kwok if (!gbe_intf || !gbe_intf->gbe_dev->cpts) 20096246168bSWingMan Kwok return -EINVAL; 20106246168bSWingMan Kwok 20116246168bSWingMan Kwok info->so_timestamping = 20126246168bSWingMan Kwok SOF_TIMESTAMPING_TX_HARDWARE | 20136246168bSWingMan Kwok SOF_TIMESTAMPING_TX_SOFTWARE | 20146246168bSWingMan Kwok SOF_TIMESTAMPING_RX_HARDWARE | 20156246168bSWingMan Kwok SOF_TIMESTAMPING_RX_SOFTWARE | 20166246168bSWingMan Kwok SOF_TIMESTAMPING_SOFTWARE | 20176246168bSWingMan Kwok SOF_TIMESTAMPING_RAW_HARDWARE; 20186246168bSWingMan Kwok info->phc_index = gbe_intf->gbe_dev->cpts->phc_index; 20196246168bSWingMan Kwok info->tx_types = 20206246168bSWingMan Kwok (1 << HWTSTAMP_TX_OFF) | 20216246168bSWingMan Kwok (1 << HWTSTAMP_TX_ON); 20226246168bSWingMan Kwok info->rx_filters = 20236246168bSWingMan Kwok (1 << HWTSTAMP_FILTER_NONE) | 20246246168bSWingMan Kwok (1 << HWTSTAMP_FILTER_PTP_V1_L4_EVENT) | 20256246168bSWingMan Kwok (1 << HWTSTAMP_FILTER_PTP_V2_EVENT); 20266246168bSWingMan Kwok return 0; 20276246168bSWingMan Kwok } 20286246168bSWingMan Kwok #else 20296246168bSWingMan Kwok static int keystone_get_ts_info(struct net_device *ndev, 20306246168bSWingMan Kwok struct ethtool_ts_info *info) 20316246168bSWingMan Kwok { 20326246168bSWingMan Kwok info->so_timestamping = 20336246168bSWingMan Kwok SOF_TIMESTAMPING_TX_SOFTWARE | 20346246168bSWingMan Kwok SOF_TIMESTAMPING_RX_SOFTWARE | 20356246168bSWingMan Kwok SOF_TIMESTAMPING_SOFTWARE; 20366246168bSWingMan Kwok info->phc_index = -1; 20376246168bSWingMan Kwok info->tx_types = 0; 20386246168bSWingMan Kwok info->rx_filters = 0; 20396246168bSWingMan Kwok return 0; 20406246168bSWingMan Kwok } 20416246168bSWingMan Kwok #endif /* CONFIG_TI_CPTS */ 20426246168bSWingMan Kwok 20436f8d3f33SWingman Kwok static const struct ethtool_ops keystone_ethtool_ops = { 20446f8d3f33SWingman Kwok .get_drvinfo = keystone_get_drvinfo, 20456f8d3f33SWingman Kwok .get_link = ethtool_op_get_link, 20466f8d3f33SWingman Kwok .get_msglevel = keystone_get_msglevel, 20476f8d3f33SWingman Kwok .set_msglevel = keystone_set_msglevel, 20486f8d3f33SWingman Kwok .get_strings = keystone_get_stat_strings, 20496f8d3f33SWingman Kwok .get_sset_count = keystone_get_sset_count, 20506f8d3f33SWingman Kwok .get_ethtool_stats = keystone_get_ethtool_stats, 205186e3a040SPhilippe Reynes .get_link_ksettings = keystone_get_link_ksettings, 205286e3a040SPhilippe Reynes .set_link_ksettings = keystone_set_link_ksettings, 20536246168bSWingMan Kwok .get_ts_info = keystone_get_ts_info, 20546f8d3f33SWingman Kwok }; 20556f8d3f33SWingman Kwok 20566f8d3f33SWingman Kwok static void gbe_set_slave_mac(struct gbe_slave *slave, 20576f8d3f33SWingman Kwok struct gbe_intf *gbe_intf) 20586f8d3f33SWingman Kwok { 20596f8d3f33SWingman Kwok struct net_device *ndev = gbe_intf->ndev; 20606f8d3f33SWingman Kwok 20616f8d3f33SWingman Kwok writel(mac_hi(ndev->dev_addr), GBE_REG_ADDR(slave, port_regs, sa_hi)); 20626f8d3f33SWingman Kwok writel(mac_lo(ndev->dev_addr), GBE_REG_ADDR(slave, port_regs, sa_lo)); 20636f8d3f33SWingman Kwok } 20646f8d3f33SWingman Kwok 20656f8d3f33SWingman Kwok static int gbe_get_slave_port(struct gbe_priv *priv, u32 slave_num) 20666f8d3f33SWingman Kwok { 20676f8d3f33SWingman Kwok if (priv->host_port == 0) 20686f8d3f33SWingman Kwok return slave_num + 1; 20696f8d3f33SWingman Kwok 20706f8d3f33SWingman Kwok return slave_num; 20716f8d3f33SWingman Kwok } 20726f8d3f33SWingman Kwok 20736f8d3f33SWingman Kwok static void netcp_ethss_link_state_action(struct gbe_priv *gbe_dev, 20746f8d3f33SWingman Kwok struct net_device *ndev, 20756f8d3f33SWingman Kwok struct gbe_slave *slave, 20766f8d3f33SWingman Kwok int up) 20776f8d3f33SWingman Kwok { 20786f8d3f33SWingman Kwok struct phy_device *phy = slave->phy; 20796f8d3f33SWingman Kwok u32 mac_control = 0; 20806f8d3f33SWingman Kwok 20816f8d3f33SWingman Kwok if (up) { 20826f8d3f33SWingman Kwok mac_control = slave->mac_control; 208390cff9e2SWingman Kwok if (phy && (phy->speed == SPEED_1000)) { 20846f8d3f33SWingman Kwok mac_control |= MACSL_GIG_MODE; 208590cff9e2SWingman Kwok mac_control &= ~MACSL_XGIG_MODE; 208690cff9e2SWingman Kwok } else if (phy && (phy->speed == SPEED_10000)) { 208790cff9e2SWingman Kwok mac_control |= MACSL_XGIG_MODE; 208890cff9e2SWingman Kwok mac_control &= ~MACSL_GIG_MODE; 208990cff9e2SWingman Kwok } 20906f8d3f33SWingman Kwok 20916f8d3f33SWingman Kwok writel(mac_control, GBE_REG_ADDR(slave, emac_regs, 20926f8d3f33SWingman Kwok mac_control)); 20936f8d3f33SWingman Kwok 20946f8d3f33SWingman Kwok cpsw_ale_control_set(gbe_dev->ale, slave->port_num, 20956f8d3f33SWingman Kwok ALE_PORT_STATE, 20966f8d3f33SWingman Kwok ALE_PORT_STATE_FORWARD); 20976f8d3f33SWingman Kwok 20988e046d68SKaricheri, Muralidharan if (ndev && slave->open && 2099478e9a5fSMurali Karicheri ((slave->link_interface != SGMII_LINK_MAC_PHY) && 2100478e9a5fSMurali Karicheri (slave->link_interface != RGMII_LINK_MAC_PHY) && 2101478e9a5fSMurali Karicheri (slave->link_interface != XGMII_LINK_MAC_PHY))) 21026f8d3f33SWingman Kwok netif_carrier_on(ndev); 21036f8d3f33SWingman Kwok } else { 21046f8d3f33SWingman Kwok writel(mac_control, GBE_REG_ADDR(slave, emac_regs, 21056f8d3f33SWingman Kwok mac_control)); 21066f8d3f33SWingman Kwok cpsw_ale_control_set(gbe_dev->ale, slave->port_num, 21076f8d3f33SWingman Kwok ALE_PORT_STATE, 21086f8d3f33SWingman Kwok ALE_PORT_STATE_DISABLE); 21098e046d68SKaricheri, Muralidharan if (ndev && 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_off(ndev); 21146f8d3f33SWingman Kwok } 21156f8d3f33SWingman Kwok 21166f8d3f33SWingman Kwok if (phy) 21176f8d3f33SWingman Kwok phy_print_status(phy); 21186f8d3f33SWingman Kwok } 21196f8d3f33SWingman Kwok 21206f8d3f33SWingman Kwok static bool gbe_phy_link_status(struct gbe_slave *slave) 21216f8d3f33SWingman Kwok { 21226f8d3f33SWingman Kwok return !slave->phy || slave->phy->link; 21236f8d3f33SWingman Kwok } 21246f8d3f33SWingman Kwok 21256f8d3f33SWingman Kwok static void netcp_ethss_update_link_state(struct gbe_priv *gbe_dev, 21266f8d3f33SWingman Kwok struct gbe_slave *slave, 21276f8d3f33SWingman Kwok struct net_device *ndev) 21286f8d3f33SWingman Kwok { 21296f8d3f33SWingman Kwok int sp = slave->slave_num; 21306f8d3f33SWingman Kwok int phy_link_state, sgmii_link_state = 1, link_state; 21316f8d3f33SWingman Kwok 21326f8d3f33SWingman Kwok if (!slave->open) 21336f8d3f33SWingman Kwok return; 21346f8d3f33SWingman Kwok 21359a391c7bSWingMan Kwok if (!SLAVE_LINK_IS_XGMII(slave)) { 21369a391c7bSWingMan Kwok sgmii_link_state = 21378c85151dSWingMan Kwok netcp_sgmii_get_port_link(SGMII_BASE(gbe_dev, sp), sp); 21389a391c7bSWingMan Kwok } 21399a391c7bSWingMan Kwok 21406f8d3f33SWingman Kwok phy_link_state = gbe_phy_link_status(slave); 21416f8d3f33SWingman Kwok link_state = phy_link_state & sgmii_link_state; 21426f8d3f33SWingman Kwok 21436f8d3f33SWingman Kwok if (atomic_xchg(&slave->link_state, link_state) != link_state) 21446f8d3f33SWingman Kwok netcp_ethss_link_state_action(gbe_dev, ndev, slave, 21456f8d3f33SWingman Kwok link_state); 21466f8d3f33SWingman Kwok } 21476f8d3f33SWingman Kwok 214890cff9e2SWingman Kwok static void xgbe_adjust_link(struct net_device *ndev) 214990cff9e2SWingman Kwok { 215090cff9e2SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 215190cff9e2SWingman Kwok struct gbe_intf *gbe_intf; 215290cff9e2SWingman Kwok 215390cff9e2SWingman Kwok gbe_intf = netcp_module_get_intf_data(&xgbe_module, netcp); 215490cff9e2SWingman Kwok if (!gbe_intf) 215590cff9e2SWingman Kwok return; 215690cff9e2SWingman Kwok 215790cff9e2SWingman Kwok netcp_ethss_update_link_state(gbe_intf->gbe_dev, gbe_intf->slave, 215890cff9e2SWingman Kwok ndev); 215990cff9e2SWingman Kwok } 216090cff9e2SWingman Kwok 21616f8d3f33SWingman Kwok static void gbe_adjust_link(struct net_device *ndev) 21626f8d3f33SWingman Kwok { 21636f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 21646f8d3f33SWingman Kwok struct gbe_intf *gbe_intf; 21656f8d3f33SWingman Kwok 21666f8d3f33SWingman Kwok gbe_intf = netcp_module_get_intf_data(&gbe_module, netcp); 21676f8d3f33SWingman Kwok if (!gbe_intf) 21686f8d3f33SWingman Kwok return; 21696f8d3f33SWingman Kwok 21706f8d3f33SWingman Kwok netcp_ethss_update_link_state(gbe_intf->gbe_dev, gbe_intf->slave, 21716f8d3f33SWingman Kwok ndev); 21726f8d3f33SWingman Kwok } 21736f8d3f33SWingman Kwok 21746f8d3f33SWingman Kwok static void gbe_adjust_link_sec_slaves(struct net_device *ndev) 21756f8d3f33SWingman Kwok { 21766f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = netdev_priv(ndev); 21776f8d3f33SWingman Kwok struct gbe_slave *slave; 21786f8d3f33SWingman Kwok 21796f8d3f33SWingman Kwok for_each_sec_slave(slave, gbe_dev) 21806f8d3f33SWingman Kwok netcp_ethss_update_link_state(gbe_dev, slave, NULL); 21816f8d3f33SWingman Kwok } 21826f8d3f33SWingman Kwok 21836f8d3f33SWingman Kwok /* Reset EMAC 21846f8d3f33SWingman Kwok * Soft reset is set and polled until clear, or until a timeout occurs 21856f8d3f33SWingman Kwok */ 21866f8d3f33SWingman Kwok static int gbe_port_reset(struct gbe_slave *slave) 21876f8d3f33SWingman Kwok { 21886f8d3f33SWingman Kwok u32 i, v; 21896f8d3f33SWingman Kwok 21906f8d3f33SWingman Kwok /* Set the soft reset bit */ 21916f8d3f33SWingman Kwok writel(SOFT_RESET, GBE_REG_ADDR(slave, emac_regs, soft_reset)); 21926f8d3f33SWingman Kwok 21936f8d3f33SWingman Kwok /* Wait for the bit to clear */ 21946f8d3f33SWingman Kwok for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) { 21956f8d3f33SWingman Kwok v = readl(GBE_REG_ADDR(slave, emac_regs, soft_reset)); 21966f8d3f33SWingman Kwok if ((v & SOFT_RESET_MASK) != SOFT_RESET) 21976f8d3f33SWingman Kwok return 0; 21986f8d3f33SWingman Kwok } 21996f8d3f33SWingman Kwok 22006f8d3f33SWingman Kwok /* Timeout on the reset */ 22016f8d3f33SWingman Kwok return GMACSL_RET_WARN_RESET_INCOMPLETE; 22026f8d3f33SWingman Kwok } 22036f8d3f33SWingman Kwok 22046f8d3f33SWingman Kwok /* Configure EMAC */ 22056f8d3f33SWingman Kwok static void gbe_port_config(struct gbe_priv *gbe_dev, struct gbe_slave *slave, 22066f8d3f33SWingman Kwok int max_rx_len) 22076f8d3f33SWingman Kwok { 22089a391c7bSWingMan Kwok void __iomem *rx_maxlen_reg; 220990cff9e2SWingman Kwok u32 xgmii_mode; 221090cff9e2SWingman Kwok 22116f8d3f33SWingman Kwok if (max_rx_len > NETCP_MAX_FRAME_SIZE) 22126f8d3f33SWingman Kwok max_rx_len = NETCP_MAX_FRAME_SIZE; 22136f8d3f33SWingman Kwok 221490cff9e2SWingman Kwok /* Enable correct MII mode at SS level */ 22152953586dSMurali Karicheri if (IS_SS_ID_XGBE(gbe_dev) && 221690cff9e2SWingman Kwok (slave->link_interface >= XGMII_LINK_MAC_PHY)) { 221790cff9e2SWingman Kwok xgmii_mode = readl(GBE_REG_ADDR(gbe_dev, ss_regs, control)); 221890cff9e2SWingman Kwok xgmii_mode |= (1 << slave->slave_num); 221990cff9e2SWingman Kwok writel(xgmii_mode, GBE_REG_ADDR(gbe_dev, ss_regs, control)); 222090cff9e2SWingman Kwok } 222190cff9e2SWingman Kwok 22229a391c7bSWingMan Kwok if (IS_SS_ID_MU(gbe_dev)) 22239a391c7bSWingMan Kwok rx_maxlen_reg = GBE_REG_ADDR(slave, port_regs, rx_maxlen); 22249a391c7bSWingMan Kwok else 22259a391c7bSWingMan Kwok rx_maxlen_reg = GBE_REG_ADDR(slave, emac_regs, rx_maxlen); 22269a391c7bSWingMan Kwok 22279a391c7bSWingMan Kwok writel(max_rx_len, rx_maxlen_reg); 22286f8d3f33SWingman Kwok writel(slave->mac_control, GBE_REG_ADDR(slave, emac_regs, mac_control)); 22296f8d3f33SWingman Kwok } 22306f8d3f33SWingman Kwok 22317025e88aSWingMan Kwok static void gbe_sgmii_rtreset(struct gbe_priv *priv, 22327025e88aSWingMan Kwok struct gbe_slave *slave, bool set) 22337025e88aSWingMan Kwok { 22347025e88aSWingMan Kwok if (SLAVE_LINK_IS_XGMII(slave)) 22357025e88aSWingMan Kwok return; 22367025e88aSWingMan Kwok 22378c85151dSWingMan Kwok netcp_sgmii_rtreset(SGMII_BASE(priv, slave->slave_num), 22388c85151dSWingMan Kwok slave->slave_num, set); 22397025e88aSWingMan Kwok } 22407025e88aSWingMan Kwok 22416f8d3f33SWingman Kwok static void gbe_slave_stop(struct gbe_intf *intf) 22426f8d3f33SWingman Kwok { 22436f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = intf->gbe_dev; 22446f8d3f33SWingman Kwok struct gbe_slave *slave = intf->slave; 22456f8d3f33SWingman Kwok 2246775f9535SMurali Karicheri if (!IS_SS_ID_2U(gbe_dev)) 22477025e88aSWingMan Kwok gbe_sgmii_rtreset(gbe_dev, slave, true); 22486f8d3f33SWingman Kwok gbe_port_reset(slave); 22496f8d3f33SWingman Kwok /* Disable forwarding */ 22506f8d3f33SWingman Kwok cpsw_ale_control_set(gbe_dev->ale, slave->port_num, 22516f8d3f33SWingman Kwok ALE_PORT_STATE, ALE_PORT_STATE_DISABLE); 22526f8d3f33SWingman Kwok cpsw_ale_del_mcast(gbe_dev->ale, intf->ndev->broadcast, 22536f8d3f33SWingman Kwok 1 << slave->port_num, 0, 0); 22546f8d3f33SWingman Kwok 22556f8d3f33SWingman Kwok if (!slave->phy) 22566f8d3f33SWingman Kwok return; 22576f8d3f33SWingman Kwok 22586f8d3f33SWingman Kwok phy_stop(slave->phy); 22596f8d3f33SWingman Kwok phy_disconnect(slave->phy); 22606f8d3f33SWingman Kwok slave->phy = NULL; 22616f8d3f33SWingman Kwok } 22626f8d3f33SWingman Kwok 22636f8d3f33SWingman Kwok static void gbe_sgmii_config(struct gbe_priv *priv, struct gbe_slave *slave) 22646f8d3f33SWingman Kwok { 22658c85151dSWingMan Kwok if (SLAVE_LINK_IS_XGMII(slave)) 22668c85151dSWingMan Kwok return; 22676f8d3f33SWingman Kwok 22688c85151dSWingMan Kwok netcp_sgmii_reset(SGMII_BASE(priv, slave->slave_num), slave->slave_num); 22698c85151dSWingMan Kwok netcp_sgmii_config(SGMII_BASE(priv, slave->slave_num), slave->slave_num, 22706f8d3f33SWingman Kwok slave->link_interface); 22716f8d3f33SWingman Kwok } 22726f8d3f33SWingman Kwok 22736f8d3f33SWingman Kwok static int gbe_slave_open(struct gbe_intf *gbe_intf) 22746f8d3f33SWingman Kwok { 22756f8d3f33SWingman Kwok struct gbe_priv *priv = gbe_intf->gbe_dev; 22766f8d3f33SWingman Kwok struct gbe_slave *slave = gbe_intf->slave; 22776f8d3f33SWingman Kwok phy_interface_t phy_mode; 22786f8d3f33SWingman Kwok bool has_phy = false; 22796f8d3f33SWingman Kwok 22806f8d3f33SWingman Kwok void (*hndlr)(struct net_device *) = gbe_adjust_link; 22816f8d3f33SWingman Kwok 2282775f9535SMurali Karicheri if (!IS_SS_ID_2U(priv)) 22836f8d3f33SWingman Kwok gbe_sgmii_config(priv, slave); 22846f8d3f33SWingman Kwok gbe_port_reset(slave); 2285775f9535SMurali Karicheri if (!IS_SS_ID_2U(priv)) 22867025e88aSWingMan Kwok gbe_sgmii_rtreset(priv, slave, false); 22876f8d3f33SWingman Kwok gbe_port_config(priv, slave, priv->rx_packet_max); 22886f8d3f33SWingman Kwok gbe_set_slave_mac(slave, gbe_intf); 22896f8d3f33SWingman Kwok /* enable forwarding */ 22906f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, slave->port_num, 22916f8d3f33SWingman Kwok ALE_PORT_STATE, ALE_PORT_STATE_FORWARD); 22926f8d3f33SWingman Kwok cpsw_ale_add_mcast(priv->ale, gbe_intf->ndev->broadcast, 22936f8d3f33SWingman Kwok 1 << slave->port_num, 0, 0, ALE_MCAST_FWD_2); 22946f8d3f33SWingman Kwok 22956f8d3f33SWingman Kwok if (slave->link_interface == SGMII_LINK_MAC_PHY) { 22966f8d3f33SWingman Kwok has_phy = true; 22976f8d3f33SWingman Kwok phy_mode = PHY_INTERFACE_MODE_SGMII; 22986f8d3f33SWingman Kwok slave->phy_port_t = PORT_MII; 22996f8d3f33SWingman Kwok } else if (slave->link_interface == XGMII_LINK_MAC_PHY) { 23006f8d3f33SWingman Kwok has_phy = true; 23016f8d3f33SWingman Kwok phy_mode = PHY_INTERFACE_MODE_NA; 23026f8d3f33SWingman Kwok slave->phy_port_t = PORT_FIBRE; 23036f8d3f33SWingman Kwok } 23046f8d3f33SWingman Kwok 23056f8d3f33SWingman Kwok if (has_phy) { 23062953586dSMurali Karicheri if (IS_SS_ID_XGBE(priv)) 230790cff9e2SWingman Kwok hndlr = xgbe_adjust_link; 230890cff9e2SWingman Kwok 23096f8d3f33SWingman Kwok slave->phy = of_phy_connect(gbe_intf->ndev, 23106f8d3f33SWingman Kwok slave->phy_node, 23116f8d3f33SWingman Kwok hndlr, 0, 23126f8d3f33SWingman Kwok phy_mode); 23136f8d3f33SWingman Kwok if (!slave->phy) { 23146f8d3f33SWingman Kwok dev_err(priv->dev, "phy not found on slave %d\n", 23156f8d3f33SWingman Kwok slave->slave_num); 23166f8d3f33SWingman Kwok return -ENODEV; 23176f8d3f33SWingman Kwok } 23186f8d3f33SWingman Kwok dev_dbg(priv->dev, "phy found: id is: 0x%s\n", 231984eff6d1SAndrew Lunn phydev_name(slave->phy)); 23206f8d3f33SWingman Kwok phy_start(slave->phy); 23216f8d3f33SWingman Kwok } 23226f8d3f33SWingman Kwok return 0; 23236f8d3f33SWingman Kwok } 23246f8d3f33SWingman Kwok 23256f8d3f33SWingman Kwok static void gbe_init_host_port(struct gbe_priv *priv) 23266f8d3f33SWingman Kwok { 23276f8d3f33SWingman Kwok int bypass_en = 1; 23289a391c7bSWingMan Kwok 23299a391c7bSWingMan Kwok /* Host Tx Pri */ 23304c0ef231SWingMan Kwok if (IS_SS_ID_NU(priv) || IS_SS_ID_XGBE(priv)) 23319a391c7bSWingMan Kwok writel(HOST_TX_PRI_MAP_DEFAULT, 23329a391c7bSWingMan Kwok GBE_REG_ADDR(priv, host_port_regs, tx_pri_map)); 23339a391c7bSWingMan Kwok 23346f8d3f33SWingman Kwok /* Max length register */ 23356f8d3f33SWingman Kwok writel(NETCP_MAX_FRAME_SIZE, GBE_REG_ADDR(priv, host_port_regs, 23366f8d3f33SWingman Kwok rx_maxlen)); 23376f8d3f33SWingman Kwok 23386f8d3f33SWingman Kwok cpsw_ale_start(priv->ale); 23396f8d3f33SWingman Kwok 23406f8d3f33SWingman Kwok if (priv->enable_ale) 23416f8d3f33SWingman Kwok bypass_en = 0; 23426f8d3f33SWingman Kwok 23436f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, 0, ALE_BYPASS, bypass_en); 23446f8d3f33SWingman Kwok 23456f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, 0, ALE_NO_PORT_VLAN, 1); 23466f8d3f33SWingman Kwok 23476f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, priv->host_port, 23486f8d3f33SWingman Kwok ALE_PORT_STATE, ALE_PORT_STATE_FORWARD); 23496f8d3f33SWingman Kwok 23506f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, 0, 23516f8d3f33SWingman Kwok ALE_PORT_UNKNOWN_VLAN_MEMBER, 23526f8d3f33SWingman Kwok GBE_PORT_MASK(priv->ale_ports)); 23536f8d3f33SWingman Kwok 23546f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, 0, 23556f8d3f33SWingman Kwok ALE_PORT_UNKNOWN_MCAST_FLOOD, 23566f8d3f33SWingman Kwok GBE_PORT_MASK(priv->ale_ports - 1)); 23576f8d3f33SWingman Kwok 23586f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, 0, 23596f8d3f33SWingman Kwok ALE_PORT_UNKNOWN_REG_MCAST_FLOOD, 23606f8d3f33SWingman Kwok GBE_PORT_MASK(priv->ale_ports)); 23616f8d3f33SWingman Kwok 23626f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, 0, 23636f8d3f33SWingman Kwok ALE_PORT_UNTAGGED_EGRESS, 23646f8d3f33SWingman Kwok GBE_PORT_MASK(priv->ale_ports)); 23656f8d3f33SWingman Kwok } 23666f8d3f33SWingman Kwok 23676f8d3f33SWingman Kwok static void gbe_add_mcast_addr(struct gbe_intf *gbe_intf, u8 *addr) 23686f8d3f33SWingman Kwok { 23696f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 23706f8d3f33SWingman Kwok u16 vlan_id; 23716f8d3f33SWingman Kwok 23726f8d3f33SWingman Kwok cpsw_ale_add_mcast(gbe_dev->ale, addr, 23736f8d3f33SWingman Kwok GBE_PORT_MASK(gbe_dev->ale_ports), 0, 0, 23746f8d3f33SWingman Kwok ALE_MCAST_FWD_2); 23756f8d3f33SWingman Kwok for_each_set_bit(vlan_id, gbe_intf->active_vlans, VLAN_N_VID) { 23766f8d3f33SWingman Kwok cpsw_ale_add_mcast(gbe_dev->ale, addr, 23776f8d3f33SWingman Kwok GBE_PORT_MASK(gbe_dev->ale_ports), 23786f8d3f33SWingman Kwok ALE_VLAN, vlan_id, ALE_MCAST_FWD_2); 23796f8d3f33SWingman Kwok } 23806f8d3f33SWingman Kwok } 23816f8d3f33SWingman Kwok 23826f8d3f33SWingman Kwok static void gbe_add_ucast_addr(struct gbe_intf *gbe_intf, u8 *addr) 23836f8d3f33SWingman Kwok { 23846f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 23856f8d3f33SWingman Kwok u16 vlan_id; 23866f8d3f33SWingman Kwok 23876f8d3f33SWingman Kwok cpsw_ale_add_ucast(gbe_dev->ale, addr, gbe_dev->host_port, 0, 0); 23886f8d3f33SWingman Kwok 23896f8d3f33SWingman Kwok for_each_set_bit(vlan_id, gbe_intf->active_vlans, VLAN_N_VID) 23906f8d3f33SWingman Kwok cpsw_ale_add_ucast(gbe_dev->ale, addr, gbe_dev->host_port, 23916f8d3f33SWingman Kwok ALE_VLAN, vlan_id); 23926f8d3f33SWingman Kwok } 23936f8d3f33SWingman Kwok 23946f8d3f33SWingman Kwok static void gbe_del_mcast_addr(struct gbe_intf *gbe_intf, u8 *addr) 23956f8d3f33SWingman Kwok { 23966f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 23976f8d3f33SWingman Kwok u16 vlan_id; 23986f8d3f33SWingman Kwok 23996f8d3f33SWingman Kwok cpsw_ale_del_mcast(gbe_dev->ale, addr, 0, 0, 0); 24006f8d3f33SWingman Kwok 24016f8d3f33SWingman Kwok for_each_set_bit(vlan_id, gbe_intf->active_vlans, VLAN_N_VID) { 24026f8d3f33SWingman Kwok cpsw_ale_del_mcast(gbe_dev->ale, addr, 0, ALE_VLAN, vlan_id); 24036f8d3f33SWingman Kwok } 24046f8d3f33SWingman Kwok } 24056f8d3f33SWingman Kwok 24066f8d3f33SWingman Kwok static void gbe_del_ucast_addr(struct gbe_intf *gbe_intf, u8 *addr) 24076f8d3f33SWingman Kwok { 24086f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 24096f8d3f33SWingman Kwok u16 vlan_id; 24106f8d3f33SWingman Kwok 24116f8d3f33SWingman Kwok cpsw_ale_del_ucast(gbe_dev->ale, addr, gbe_dev->host_port, 0, 0); 24126f8d3f33SWingman Kwok 24136f8d3f33SWingman Kwok for_each_set_bit(vlan_id, gbe_intf->active_vlans, VLAN_N_VID) { 24146f8d3f33SWingman Kwok cpsw_ale_del_ucast(gbe_dev->ale, addr, gbe_dev->host_port, 24156f8d3f33SWingman Kwok ALE_VLAN, vlan_id); 24166f8d3f33SWingman Kwok } 24176f8d3f33SWingman Kwok } 24186f8d3f33SWingman Kwok 24196f8d3f33SWingman Kwok static int gbe_add_addr(void *intf_priv, struct netcp_addr *naddr) 24206f8d3f33SWingman Kwok { 24216f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv; 24226f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 24236f8d3f33SWingman Kwok 24246f8d3f33SWingman Kwok dev_dbg(gbe_dev->dev, "ethss adding address %pM, type %d\n", 24256f8d3f33SWingman Kwok naddr->addr, naddr->type); 24266f8d3f33SWingman Kwok 24276f8d3f33SWingman Kwok switch (naddr->type) { 24286f8d3f33SWingman Kwok case ADDR_MCAST: 24296f8d3f33SWingman Kwok case ADDR_BCAST: 24306f8d3f33SWingman Kwok gbe_add_mcast_addr(gbe_intf, naddr->addr); 24316f8d3f33SWingman Kwok break; 24326f8d3f33SWingman Kwok case ADDR_UCAST: 24336f8d3f33SWingman Kwok case ADDR_DEV: 24346f8d3f33SWingman Kwok gbe_add_ucast_addr(gbe_intf, naddr->addr); 24356f8d3f33SWingman Kwok break; 24366f8d3f33SWingman Kwok case ADDR_ANY: 24376f8d3f33SWingman Kwok /* nothing to do for promiscuous */ 24386f8d3f33SWingman Kwok default: 24396f8d3f33SWingman Kwok break; 24406f8d3f33SWingman Kwok } 24416f8d3f33SWingman Kwok 24426f8d3f33SWingman Kwok return 0; 24436f8d3f33SWingman Kwok } 24446f8d3f33SWingman Kwok 24456f8d3f33SWingman Kwok static int gbe_del_addr(void *intf_priv, struct netcp_addr *naddr) 24466f8d3f33SWingman Kwok { 24476f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv; 24486f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 24496f8d3f33SWingman Kwok 24506f8d3f33SWingman Kwok dev_dbg(gbe_dev->dev, "ethss deleting address %pM, type %d\n", 24516f8d3f33SWingman Kwok naddr->addr, naddr->type); 24526f8d3f33SWingman Kwok 24536f8d3f33SWingman Kwok switch (naddr->type) { 24546f8d3f33SWingman Kwok case ADDR_MCAST: 24556f8d3f33SWingman Kwok case ADDR_BCAST: 24566f8d3f33SWingman Kwok gbe_del_mcast_addr(gbe_intf, naddr->addr); 24576f8d3f33SWingman Kwok break; 24586f8d3f33SWingman Kwok case ADDR_UCAST: 24596f8d3f33SWingman Kwok case ADDR_DEV: 24606f8d3f33SWingman Kwok gbe_del_ucast_addr(gbe_intf, naddr->addr); 24616f8d3f33SWingman Kwok break; 24626f8d3f33SWingman Kwok case ADDR_ANY: 24636f8d3f33SWingman Kwok /* nothing to do for promiscuous */ 24646f8d3f33SWingman Kwok default: 24656f8d3f33SWingman Kwok break; 24666f8d3f33SWingman Kwok } 24676f8d3f33SWingman Kwok 24686f8d3f33SWingman Kwok return 0; 24696f8d3f33SWingman Kwok } 24706f8d3f33SWingman Kwok 24716f8d3f33SWingman Kwok static int gbe_add_vid(void *intf_priv, int vid) 24726f8d3f33SWingman Kwok { 24736f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv; 24746f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 24756f8d3f33SWingman Kwok 24766f8d3f33SWingman Kwok set_bit(vid, gbe_intf->active_vlans); 24776f8d3f33SWingman Kwok 24786f8d3f33SWingman Kwok cpsw_ale_add_vlan(gbe_dev->ale, vid, 24796f8d3f33SWingman Kwok GBE_PORT_MASK(gbe_dev->ale_ports), 24806f8d3f33SWingman Kwok GBE_MASK_NO_PORTS, 24816f8d3f33SWingman Kwok GBE_PORT_MASK(gbe_dev->ale_ports), 24826f8d3f33SWingman Kwok GBE_PORT_MASK(gbe_dev->ale_ports - 1)); 24836f8d3f33SWingman Kwok 24846f8d3f33SWingman Kwok return 0; 24856f8d3f33SWingman Kwok } 24866f8d3f33SWingman Kwok 24876f8d3f33SWingman Kwok static int gbe_del_vid(void *intf_priv, int vid) 24886f8d3f33SWingman Kwok { 24896f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv; 24906f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 24916f8d3f33SWingman Kwok 24926f8d3f33SWingman Kwok cpsw_ale_del_vlan(gbe_dev->ale, vid, 0); 24936f8d3f33SWingman Kwok clear_bit(vid, gbe_intf->active_vlans); 24946f8d3f33SWingman Kwok return 0; 24956f8d3f33SWingman Kwok } 24966f8d3f33SWingman Kwok 24976246168bSWingMan Kwok #if IS_ENABLED(CONFIG_TI_CPTS) 24986246168bSWingMan Kwok #define HAS_PHY_TXTSTAMP(p) ((p)->drv && (p)->drv->txtstamp) 24996246168bSWingMan Kwok #define HAS_PHY_RXTSTAMP(p) ((p)->drv && (p)->drv->rxtstamp) 25006246168bSWingMan Kwok 25016246168bSWingMan Kwok static void gbe_txtstamp(void *context, struct sk_buff *skb) 25026246168bSWingMan Kwok { 25036246168bSWingMan Kwok struct gbe_intf *gbe_intf = context; 25046246168bSWingMan Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 25056246168bSWingMan Kwok 25066246168bSWingMan Kwok cpts_tx_timestamp(gbe_dev->cpts, skb); 25076246168bSWingMan Kwok } 25086246168bSWingMan Kwok 25096246168bSWingMan Kwok static bool gbe_need_txtstamp(struct gbe_intf *gbe_intf, 25106246168bSWingMan Kwok const struct netcp_packet *p_info) 25116246168bSWingMan Kwok { 25126246168bSWingMan Kwok struct sk_buff *skb = p_info->skb; 25136246168bSWingMan Kwok 25140ccf59baSIvan Khoronzhuk return cpts_can_timestamp(gbe_intf->gbe_dev->cpts, skb); 25156246168bSWingMan Kwok } 25166246168bSWingMan Kwok 25176246168bSWingMan Kwok static int gbe_txtstamp_mark_pkt(struct gbe_intf *gbe_intf, 25186246168bSWingMan Kwok struct netcp_packet *p_info) 25196246168bSWingMan Kwok { 25206246168bSWingMan Kwok struct phy_device *phydev = p_info->skb->dev->phydev; 25216246168bSWingMan Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 25226246168bSWingMan Kwok 25236246168bSWingMan Kwok if (!(skb_shinfo(p_info->skb)->tx_flags & SKBTX_HW_TSTAMP) || 25246246168bSWingMan Kwok !cpts_is_tx_enabled(gbe_dev->cpts)) 25256246168bSWingMan Kwok return 0; 25266246168bSWingMan Kwok 25276246168bSWingMan Kwok /* If phy has the txtstamp api, assume it will do it. 25286246168bSWingMan Kwok * We mark it here because skb_tx_timestamp() is called 25296246168bSWingMan Kwok * after all the txhooks are called. 25306246168bSWingMan Kwok */ 25316246168bSWingMan Kwok if (phydev && HAS_PHY_TXTSTAMP(phydev)) { 25326246168bSWingMan Kwok skb_shinfo(p_info->skb)->tx_flags |= SKBTX_IN_PROGRESS; 25336246168bSWingMan Kwok return 0; 25346246168bSWingMan Kwok } 25356246168bSWingMan Kwok 25366246168bSWingMan Kwok if (gbe_need_txtstamp(gbe_intf, p_info)) { 25376246168bSWingMan Kwok p_info->txtstamp = gbe_txtstamp; 25386246168bSWingMan Kwok p_info->ts_context = (void *)gbe_intf; 25396246168bSWingMan Kwok skb_shinfo(p_info->skb)->tx_flags |= SKBTX_IN_PROGRESS; 25406246168bSWingMan Kwok } 25416246168bSWingMan Kwok 25426246168bSWingMan Kwok return 0; 25436246168bSWingMan Kwok } 25446246168bSWingMan Kwok 25456246168bSWingMan Kwok static int gbe_rxtstamp(struct gbe_intf *gbe_intf, struct netcp_packet *p_info) 25466246168bSWingMan Kwok { 25476246168bSWingMan Kwok struct phy_device *phydev = p_info->skb->dev->phydev; 25486246168bSWingMan Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 25496246168bSWingMan Kwok 25506246168bSWingMan Kwok if (p_info->rxtstamp_complete) 25516246168bSWingMan Kwok return 0; 25526246168bSWingMan Kwok 25536246168bSWingMan Kwok if (phydev && HAS_PHY_RXTSTAMP(phydev)) { 25546246168bSWingMan Kwok p_info->rxtstamp_complete = true; 25556246168bSWingMan Kwok return 0; 25566246168bSWingMan Kwok } 25576246168bSWingMan Kwok 25586246168bSWingMan Kwok cpts_rx_timestamp(gbe_dev->cpts, p_info->skb); 25596246168bSWingMan Kwok p_info->rxtstamp_complete = true; 25606246168bSWingMan Kwok 25616246168bSWingMan Kwok return 0; 25626246168bSWingMan Kwok } 25636246168bSWingMan Kwok 25646246168bSWingMan Kwok static int gbe_hwtstamp_get(struct gbe_intf *gbe_intf, struct ifreq *ifr) 25656246168bSWingMan Kwok { 25666246168bSWingMan Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 25676246168bSWingMan Kwok struct cpts *cpts = gbe_dev->cpts; 25686246168bSWingMan Kwok struct hwtstamp_config cfg; 25696246168bSWingMan Kwok 25706246168bSWingMan Kwok if (!cpts) 25716246168bSWingMan Kwok return -EOPNOTSUPP; 25726246168bSWingMan Kwok 25736246168bSWingMan Kwok cfg.flags = 0; 25746246168bSWingMan Kwok cfg.tx_type = cpts_is_tx_enabled(cpts) ? 25756246168bSWingMan Kwok HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF; 25766246168bSWingMan Kwok cfg.rx_filter = (cpts_is_rx_enabled(cpts) ? 25776246168bSWingMan Kwok cpts->rx_enable : HWTSTAMP_FILTER_NONE); 25786246168bSWingMan Kwok 25796246168bSWingMan Kwok return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0; 25806246168bSWingMan Kwok } 25816246168bSWingMan Kwok 25826246168bSWingMan Kwok static void gbe_hwtstamp(struct gbe_intf *gbe_intf) 25836246168bSWingMan Kwok { 25846246168bSWingMan Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 25856246168bSWingMan Kwok struct gbe_slave *slave = gbe_intf->slave; 25866246168bSWingMan Kwok u32 ts_en, seq_id, ctl; 25876246168bSWingMan Kwok 25886246168bSWingMan Kwok if (!cpts_is_rx_enabled(gbe_dev->cpts) && 25896246168bSWingMan Kwok !cpts_is_tx_enabled(gbe_dev->cpts)) { 25906246168bSWingMan Kwok writel(0, GBE_REG_ADDR(slave, port_regs, ts_ctl)); 25916246168bSWingMan Kwok return; 25926246168bSWingMan Kwok } 25936246168bSWingMan Kwok 25946246168bSWingMan Kwok seq_id = (30 << TS_SEQ_ID_OFS_SHIFT) | ETH_P_1588; 25956246168bSWingMan Kwok ts_en = EVENT_MSG_BITS << TS_MSG_TYPE_EN_SHIFT; 25966246168bSWingMan Kwok ctl = ETH_P_1588 | TS_TTL_NONZERO | 25976246168bSWingMan Kwok (slave->ts_ctl.dst_port_map << TS_CTL_DST_PORT_SHIFT) | 25986246168bSWingMan Kwok (slave->ts_ctl.uni ? TS_UNI_EN : 25996246168bSWingMan Kwok slave->ts_ctl.maddr_map << TS_CTL_MADDR_SHIFT); 26006246168bSWingMan Kwok 26016246168bSWingMan Kwok if (cpts_is_tx_enabled(gbe_dev->cpts)) 26026246168bSWingMan Kwok ts_en |= (TS_TX_ANX_ALL_EN | TS_TX_VLAN_LT1_EN); 26036246168bSWingMan Kwok 26046246168bSWingMan Kwok if (cpts_is_rx_enabled(gbe_dev->cpts)) 26056246168bSWingMan Kwok ts_en |= (TS_RX_ANX_ALL_EN | TS_RX_VLAN_LT1_EN); 26066246168bSWingMan Kwok 26076246168bSWingMan Kwok writel(ts_en, GBE_REG_ADDR(slave, port_regs, ts_ctl)); 26086246168bSWingMan Kwok writel(seq_id, GBE_REG_ADDR(slave, port_regs, ts_seq_ltype)); 26096246168bSWingMan Kwok writel(ctl, GBE_REG_ADDR(slave, port_regs, ts_ctl_ltype2)); 26106246168bSWingMan Kwok } 26116246168bSWingMan Kwok 26126246168bSWingMan Kwok static int gbe_hwtstamp_set(struct gbe_intf *gbe_intf, struct ifreq *ifr) 26136246168bSWingMan Kwok { 26146246168bSWingMan Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 26156246168bSWingMan Kwok struct cpts *cpts = gbe_dev->cpts; 26166246168bSWingMan Kwok struct hwtstamp_config cfg; 26176246168bSWingMan Kwok 26186246168bSWingMan Kwok if (!cpts) 26196246168bSWingMan Kwok return -EOPNOTSUPP; 26206246168bSWingMan Kwok 26216246168bSWingMan Kwok if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg))) 26226246168bSWingMan Kwok return -EFAULT; 26236246168bSWingMan Kwok 26246246168bSWingMan Kwok /* reserved for future extensions */ 26256246168bSWingMan Kwok if (cfg.flags) 26266246168bSWingMan Kwok return -EINVAL; 26276246168bSWingMan Kwok 26286246168bSWingMan Kwok switch (cfg.tx_type) { 26296246168bSWingMan Kwok case HWTSTAMP_TX_OFF: 26306246168bSWingMan Kwok cpts_tx_enable(cpts, 0); 26316246168bSWingMan Kwok break; 26326246168bSWingMan Kwok case HWTSTAMP_TX_ON: 26336246168bSWingMan Kwok cpts_tx_enable(cpts, 1); 26346246168bSWingMan Kwok break; 26356246168bSWingMan Kwok default: 26366246168bSWingMan Kwok return -ERANGE; 26376246168bSWingMan Kwok } 26386246168bSWingMan Kwok 26396246168bSWingMan Kwok switch (cfg.rx_filter) { 26406246168bSWingMan Kwok case HWTSTAMP_FILTER_NONE: 26416246168bSWingMan Kwok cpts_rx_enable(cpts, 0); 26426246168bSWingMan Kwok break; 26436246168bSWingMan Kwok case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: 26446246168bSWingMan Kwok case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: 26456246168bSWingMan Kwok case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: 26466246168bSWingMan Kwok cpts_rx_enable(cpts, HWTSTAMP_FILTER_PTP_V1_L4_EVENT); 26476246168bSWingMan Kwok cfg.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; 26486246168bSWingMan Kwok break; 26496246168bSWingMan Kwok case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: 26506246168bSWingMan Kwok case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: 26516246168bSWingMan Kwok case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: 26526246168bSWingMan Kwok case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: 26536246168bSWingMan Kwok case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: 26546246168bSWingMan Kwok case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: 26556246168bSWingMan Kwok case HWTSTAMP_FILTER_PTP_V2_EVENT: 26566246168bSWingMan Kwok case HWTSTAMP_FILTER_PTP_V2_SYNC: 26576246168bSWingMan Kwok case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: 26586246168bSWingMan Kwok cpts_rx_enable(cpts, HWTSTAMP_FILTER_PTP_V2_EVENT); 26596246168bSWingMan Kwok cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; 26606246168bSWingMan Kwok break; 26616246168bSWingMan Kwok default: 26626246168bSWingMan Kwok return -ERANGE; 26636246168bSWingMan Kwok } 26646246168bSWingMan Kwok 26656246168bSWingMan Kwok gbe_hwtstamp(gbe_intf); 26666246168bSWingMan Kwok 26676246168bSWingMan Kwok return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0; 26686246168bSWingMan Kwok } 26696246168bSWingMan Kwok 26706246168bSWingMan Kwok static void gbe_register_cpts(struct gbe_priv *gbe_dev) 26716246168bSWingMan Kwok { 26726246168bSWingMan Kwok if (!gbe_dev->cpts) 26736246168bSWingMan Kwok return; 26746246168bSWingMan Kwok 26756246168bSWingMan Kwok if (gbe_dev->cpts_registered > 0) 26766246168bSWingMan Kwok goto done; 26776246168bSWingMan Kwok 26786246168bSWingMan Kwok if (cpts_register(gbe_dev->cpts)) { 26796246168bSWingMan Kwok dev_err(gbe_dev->dev, "error registering cpts device\n"); 26806246168bSWingMan Kwok return; 26816246168bSWingMan Kwok } 26826246168bSWingMan Kwok 26836246168bSWingMan Kwok done: 26846246168bSWingMan Kwok ++gbe_dev->cpts_registered; 26856246168bSWingMan Kwok } 26866246168bSWingMan Kwok 26876246168bSWingMan Kwok static void gbe_unregister_cpts(struct gbe_priv *gbe_dev) 26886246168bSWingMan Kwok { 26896246168bSWingMan Kwok if (!gbe_dev->cpts || (gbe_dev->cpts_registered <= 0)) 26906246168bSWingMan Kwok return; 26916246168bSWingMan Kwok 26926246168bSWingMan Kwok if (--gbe_dev->cpts_registered) 26936246168bSWingMan Kwok return; 26946246168bSWingMan Kwok 26956246168bSWingMan Kwok cpts_unregister(gbe_dev->cpts); 26966246168bSWingMan Kwok } 26976246168bSWingMan Kwok #else 26986246168bSWingMan Kwok static inline int gbe_txtstamp_mark_pkt(struct gbe_intf *gbe_intf, 26996246168bSWingMan Kwok struct netcp_packet *p_info) 27006246168bSWingMan Kwok { 27016246168bSWingMan Kwok return 0; 27026246168bSWingMan Kwok } 27036246168bSWingMan Kwok 27046246168bSWingMan Kwok static inline int gbe_rxtstamp(struct gbe_intf *gbe_intf, 27056246168bSWingMan Kwok struct netcp_packet *p_info) 27066246168bSWingMan Kwok { 27076246168bSWingMan Kwok return 0; 27086246168bSWingMan Kwok } 27096246168bSWingMan Kwok 27106246168bSWingMan Kwok static inline int gbe_hwtstamp(struct gbe_intf *gbe_intf, 27116246168bSWingMan Kwok struct ifreq *ifr, int cmd) 27126246168bSWingMan Kwok { 27136246168bSWingMan Kwok return -EOPNOTSUPP; 27146246168bSWingMan Kwok } 27156246168bSWingMan Kwok 27166246168bSWingMan Kwok static inline void gbe_register_cpts(struct gbe_priv *gbe_dev) 27176246168bSWingMan Kwok { 27186246168bSWingMan Kwok } 27196246168bSWingMan Kwok 27206246168bSWingMan Kwok static inline void gbe_unregister_cpts(struct gbe_priv *gbe_dev) 27216246168bSWingMan Kwok { 27226246168bSWingMan Kwok } 27236246168bSWingMan Kwok 27246246168bSWingMan Kwok static inline int gbe_hwtstamp_get(struct gbe_intf *gbe_intf, struct ifreq *req) 27256246168bSWingMan Kwok { 27266246168bSWingMan Kwok return -EOPNOTSUPP; 27276246168bSWingMan Kwok } 27286246168bSWingMan Kwok 27296246168bSWingMan Kwok static inline int gbe_hwtstamp_set(struct gbe_intf *gbe_intf, struct ifreq *req) 27306246168bSWingMan Kwok { 27316246168bSWingMan Kwok return -EOPNOTSUPP; 27326246168bSWingMan Kwok } 27336246168bSWingMan Kwok #endif /* CONFIG_TI_CPTS */ 27346246168bSWingMan Kwok 27356f8d3f33SWingman Kwok static int gbe_ioctl(void *intf_priv, struct ifreq *req, int cmd) 27366f8d3f33SWingman Kwok { 27376f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv; 27386f8d3f33SWingman Kwok struct phy_device *phy = gbe_intf->slave->phy; 27396246168bSWingMan Kwok 27406246168bSWingMan Kwok if (!phy || !phy->drv->hwtstamp) { 27416246168bSWingMan Kwok switch (cmd) { 27426246168bSWingMan Kwok case SIOCGHWTSTAMP: 27436246168bSWingMan Kwok return gbe_hwtstamp_get(gbe_intf, req); 27446246168bSWingMan Kwok case SIOCSHWTSTAMP: 27456246168bSWingMan Kwok return gbe_hwtstamp_set(gbe_intf, req); 27466246168bSWingMan Kwok } 27476246168bSWingMan Kwok } 27486f8d3f33SWingman Kwok 27496f8d3f33SWingman Kwok if (phy) 27506246168bSWingMan Kwok return phy_mii_ioctl(phy, req, cmd); 27516f8d3f33SWingman Kwok 27526246168bSWingMan Kwok return -EOPNOTSUPP; 27536f8d3f33SWingman Kwok } 27546f8d3f33SWingman Kwok 2755e99e88a9SKees Cook static void netcp_ethss_timer(struct timer_list *t) 27566f8d3f33SWingman Kwok { 2757e99e88a9SKees Cook struct gbe_priv *gbe_dev = from_timer(gbe_dev, t, timer); 27586f8d3f33SWingman Kwok struct gbe_intf *gbe_intf; 27596f8d3f33SWingman Kwok struct gbe_slave *slave; 27606f8d3f33SWingman Kwok 27616f8d3f33SWingman Kwok /* Check & update SGMII link state of interfaces */ 27626f8d3f33SWingman Kwok for_each_intf(gbe_intf, gbe_dev) { 27636f8d3f33SWingman Kwok if (!gbe_intf->slave->open) 27646f8d3f33SWingman Kwok continue; 27656f8d3f33SWingman Kwok netcp_ethss_update_link_state(gbe_dev, gbe_intf->slave, 27666f8d3f33SWingman Kwok gbe_intf->ndev); 27676f8d3f33SWingman Kwok } 27686f8d3f33SWingman Kwok 27696f8d3f33SWingman Kwok /* Check & update SGMII link state of secondary ports */ 27706f8d3f33SWingman Kwok for_each_sec_slave(slave, gbe_dev) { 27716f8d3f33SWingman Kwok netcp_ethss_update_link_state(gbe_dev, slave, NULL); 27726f8d3f33SWingman Kwok } 27736f8d3f33SWingman Kwok 2774c0f54edbSWingMan Kwok /* A timer runs as a BH, no need to block them */ 2775c0f54edbSWingMan Kwok spin_lock(&gbe_dev->hw_stats_lock); 27766f8d3f33SWingman Kwok 27772953586dSMurali Karicheri if (IS_SS_ID_VER_14(gbe_dev)) 27786f8d3f33SWingman Kwok gbe_update_stats_ver14(gbe_dev, NULL); 27796f8d3f33SWingman Kwok else 27806f8d3f33SWingman Kwok gbe_update_stats(gbe_dev, NULL); 27816f8d3f33SWingman Kwok 2782c0f54edbSWingMan Kwok spin_unlock(&gbe_dev->hw_stats_lock); 27836f8d3f33SWingman Kwok 27846f8d3f33SWingman Kwok gbe_dev->timer.expires = jiffies + GBE_TIMER_INTERVAL; 27856f8d3f33SWingman Kwok add_timer(&gbe_dev->timer); 27866f8d3f33SWingman Kwok } 27876f8d3f33SWingman Kwok 27886246168bSWingMan Kwok static int gbe_txhook(int order, void *data, struct netcp_packet *p_info) 27896f8d3f33SWingman Kwok { 27906f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = data; 27916f8d3f33SWingman Kwok 27926f8d3f33SWingman Kwok p_info->tx_pipe = &gbe_intf->tx_pipe; 27936246168bSWingMan Kwok 27946246168bSWingMan Kwok return gbe_txtstamp_mark_pkt(gbe_intf, p_info); 27956246168bSWingMan Kwok } 27966246168bSWingMan Kwok 27976246168bSWingMan Kwok static int gbe_rxhook(int order, void *data, struct netcp_packet *p_info) 27986246168bSWingMan Kwok { 27996246168bSWingMan Kwok struct gbe_intf *gbe_intf = data; 28006246168bSWingMan Kwok 28016246168bSWingMan Kwok return gbe_rxtstamp(gbe_intf, p_info); 28026f8d3f33SWingman Kwok } 28036f8d3f33SWingman Kwok 28046f8d3f33SWingman Kwok static int gbe_open(void *intf_priv, struct net_device *ndev) 28056f8d3f33SWingman Kwok { 28066f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv; 28076f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 28086f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 28096f8d3f33SWingman Kwok struct gbe_slave *slave = gbe_intf->slave; 28106f8d3f33SWingman Kwok int port_num = slave->port_num; 28114cd85a61SKaricheri, Muralidharan u32 reg, val; 28126f8d3f33SWingman Kwok int ret; 28136f8d3f33SWingman Kwok 28146f8d3f33SWingman Kwok reg = readl(GBE_REG_ADDR(gbe_dev, switch_regs, id_ver)); 28156f8d3f33SWingman Kwok dev_dbg(gbe_dev->dev, "initializing gbe version %d.%d (%d) GBE identification value 0x%x\n", 28166f8d3f33SWingman Kwok GBE_MAJOR_VERSION(reg), GBE_MINOR_VERSION(reg), 28176f8d3f33SWingman Kwok GBE_RTL_VERSION(reg), GBE_IDENT(reg)); 28186f8d3f33SWingman Kwok 28199a391c7bSWingMan Kwok /* For 10G and on NetCP 1.5, use directed to port */ 28202953586dSMurali Karicheri if (IS_SS_ID_XGBE(gbe_dev) || IS_SS_ID_MU(gbe_dev)) 2821e170f409SKaricheri, Muralidharan gbe_intf->tx_pipe.flags = SWITCH_TO_PORT_IN_TAGINFO; 28226f8d3f33SWingman Kwok 2823e170f409SKaricheri, Muralidharan if (gbe_dev->enable_ale) 2824e170f409SKaricheri, Muralidharan gbe_intf->tx_pipe.switch_to_port = 0; 2825e170f409SKaricheri, Muralidharan else 2826e170f409SKaricheri, Muralidharan gbe_intf->tx_pipe.switch_to_port = port_num; 2827e170f409SKaricheri, Muralidharan 2828e170f409SKaricheri, Muralidharan dev_dbg(gbe_dev->dev, 2829e170f409SKaricheri, Muralidharan "opened TX channel %s: %p with to port %d, flags %d\n", 28306f8d3f33SWingman Kwok gbe_intf->tx_pipe.dma_chan_name, 28316f8d3f33SWingman Kwok gbe_intf->tx_pipe.dma_channel, 2832e170f409SKaricheri, Muralidharan gbe_intf->tx_pipe.switch_to_port, 2833e170f409SKaricheri, Muralidharan gbe_intf->tx_pipe.flags); 28346f8d3f33SWingman Kwok 28356f8d3f33SWingman Kwok gbe_slave_stop(gbe_intf); 28366f8d3f33SWingman Kwok 28376f8d3f33SWingman Kwok /* disable priority elevation and enable statistics on all ports */ 28386f8d3f33SWingman Kwok writel(0, GBE_REG_ADDR(gbe_dev, switch_regs, ptype)); 28396f8d3f33SWingman Kwok 28406f8d3f33SWingman Kwok /* Control register */ 28414cd85a61SKaricheri, Muralidharan val = GBE_CTL_P0_ENABLE; 28424cd85a61SKaricheri, Muralidharan if (IS_SS_ID_MU(gbe_dev)) { 28434cd85a61SKaricheri, Muralidharan val |= ETH_SW_CTL_P0_TX_CRC_REMOVE; 28444cd85a61SKaricheri, Muralidharan netcp->hw_cap = ETH_SW_CAN_REMOVE_ETH_FCS; 28454cd85a61SKaricheri, Muralidharan } 28464cd85a61SKaricheri, Muralidharan writel(val, GBE_REG_ADDR(gbe_dev, switch_regs, control)); 28476f8d3f33SWingman Kwok 28486f8d3f33SWingman Kwok /* All statistics enabled and STAT AB visible by default */ 28499a391c7bSWingMan Kwok writel(gbe_dev->stats_en_mask, GBE_REG_ADDR(gbe_dev, switch_regs, 28506f8d3f33SWingman Kwok stat_port_en)); 28516f8d3f33SWingman Kwok 28526f8d3f33SWingman Kwok ret = gbe_slave_open(gbe_intf); 28536f8d3f33SWingman Kwok if (ret) 28546f8d3f33SWingman Kwok goto fail; 28556f8d3f33SWingman Kwok 28566246168bSWingMan Kwok netcp_register_txhook(netcp, GBE_TXHOOK_ORDER, gbe_txhook, gbe_intf); 28576246168bSWingMan Kwok netcp_register_rxhook(netcp, GBE_RXHOOK_ORDER, gbe_rxhook, gbe_intf); 28586f8d3f33SWingman Kwok 28596f8d3f33SWingman Kwok slave->open = true; 28606f8d3f33SWingman Kwok netcp_ethss_update_link_state(gbe_dev, slave, ndev); 28616246168bSWingMan Kwok 28626246168bSWingMan Kwok gbe_register_cpts(gbe_dev); 28636246168bSWingMan Kwok 28646f8d3f33SWingman Kwok return 0; 28656f8d3f33SWingman Kwok 28666f8d3f33SWingman Kwok fail: 28676f8d3f33SWingman Kwok gbe_slave_stop(gbe_intf); 28686f8d3f33SWingman Kwok return ret; 28696f8d3f33SWingman Kwok } 28706f8d3f33SWingman Kwok 28716f8d3f33SWingman Kwok static int gbe_close(void *intf_priv, struct net_device *ndev) 28726f8d3f33SWingman Kwok { 28736f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv; 28746f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 28756246168bSWingMan Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 28766246168bSWingMan Kwok 28776246168bSWingMan Kwok gbe_unregister_cpts(gbe_dev); 28786f8d3f33SWingman Kwok 28796f8d3f33SWingman Kwok gbe_slave_stop(gbe_intf); 28806246168bSWingMan Kwok 28816246168bSWingMan Kwok netcp_unregister_rxhook(netcp, GBE_RXHOOK_ORDER, gbe_rxhook, gbe_intf); 28826246168bSWingMan Kwok netcp_unregister_txhook(netcp, GBE_TXHOOK_ORDER, gbe_txhook, gbe_intf); 28836f8d3f33SWingman Kwok 28846f8d3f33SWingman Kwok gbe_intf->slave->open = false; 28856f8d3f33SWingman Kwok atomic_set(&gbe_intf->slave->link_state, NETCP_LINK_STATE_INVALID); 28866f8d3f33SWingman Kwok return 0; 28876f8d3f33SWingman Kwok } 28886f8d3f33SWingman Kwok 28896246168bSWingMan Kwok #if IS_ENABLED(CONFIG_TI_CPTS) 28906246168bSWingMan Kwok static void init_slave_ts_ctl(struct gbe_slave *slave) 28916246168bSWingMan Kwok { 28926246168bSWingMan Kwok slave->ts_ctl.uni = 1; 28936246168bSWingMan Kwok slave->ts_ctl.dst_port_map = 28946246168bSWingMan Kwok (TS_CTL_DST_PORT >> TS_CTL_DST_PORT_SHIFT) & 0x3; 28956246168bSWingMan Kwok slave->ts_ctl.maddr_map = 28966246168bSWingMan Kwok (TS_CTL_MADDR_ALL >> TS_CTL_MADDR_SHIFT) & 0x1f; 28976246168bSWingMan Kwok } 28986246168bSWingMan Kwok 28996246168bSWingMan Kwok #else 29006246168bSWingMan Kwok static void init_slave_ts_ctl(struct gbe_slave *slave) 29016246168bSWingMan Kwok { 29026246168bSWingMan Kwok } 29036246168bSWingMan Kwok #endif /* CONFIG_TI_CPTS */ 29046246168bSWingMan Kwok 29056f8d3f33SWingman Kwok static int init_slave(struct gbe_priv *gbe_dev, struct gbe_slave *slave, 29066f8d3f33SWingman Kwok struct device_node *node) 29076f8d3f33SWingman Kwok { 29086f8d3f33SWingman Kwok int port_reg_num; 29096f8d3f33SWingman Kwok u32 port_reg_ofs, emac_reg_ofs; 29109a391c7bSWingMan Kwok u32 port_reg_blk_sz, emac_reg_blk_sz; 29116f8d3f33SWingman Kwok 29126f8d3f33SWingman Kwok if (of_property_read_u32(node, "slave-port", &slave->slave_num)) { 29136f8d3f33SWingman Kwok dev_err(gbe_dev->dev, "missing slave-port parameter\n"); 29146f8d3f33SWingman Kwok return -EINVAL; 29156f8d3f33SWingman Kwok } 29166f8d3f33SWingman Kwok 29176f8d3f33SWingman Kwok if (of_property_read_u32(node, "link-interface", 29186f8d3f33SWingman Kwok &slave->link_interface)) { 29196f8d3f33SWingman Kwok dev_warn(gbe_dev->dev, 29206f8d3f33SWingman Kwok "missing link-interface value defaulting to 1G mac-phy link\n"); 29216f8d3f33SWingman Kwok slave->link_interface = SGMII_LINK_MAC_PHY; 29226f8d3f33SWingman Kwok } 29236f8d3f33SWingman Kwok 29246f8d3f33SWingman Kwok slave->open = false; 29250cead3a6SKaricheri, Muralidharan if ((slave->link_interface == SGMII_LINK_MAC_PHY) || 2926478e9a5fSMurali Karicheri (slave->link_interface == RGMII_LINK_MAC_PHY) || 29270cead3a6SKaricheri, Muralidharan (slave->link_interface == XGMII_LINK_MAC_PHY)) 29286f8d3f33SWingman Kwok slave->phy_node = of_parse_phandle(node, "phy-handle", 0); 29296f8d3f33SWingman Kwok slave->port_num = gbe_get_slave_port(gbe_dev, slave->slave_num); 29306f8d3f33SWingman Kwok 293190cff9e2SWingman Kwok if (slave->link_interface >= XGMII_LINK_MAC_PHY) 293290cff9e2SWingman Kwok slave->mac_control = GBE_DEF_10G_MAC_CONTROL; 293390cff9e2SWingman Kwok else 29346f8d3f33SWingman Kwok slave->mac_control = GBE_DEF_1G_MAC_CONTROL; 29356f8d3f33SWingman Kwok 29366f8d3f33SWingman Kwok /* Emac regs memmap are contiguous but port regs are not */ 29376f8d3f33SWingman Kwok port_reg_num = slave->slave_num; 29382953586dSMurali Karicheri if (IS_SS_ID_VER_14(gbe_dev)) { 29396f8d3f33SWingman Kwok if (slave->slave_num > 1) { 29406f8d3f33SWingman Kwok port_reg_ofs = GBE13_SLAVE_PORT2_OFFSET; 29416f8d3f33SWingman Kwok port_reg_num -= 2; 29426f8d3f33SWingman Kwok } else { 29436f8d3f33SWingman Kwok port_reg_ofs = GBE13_SLAVE_PORT_OFFSET; 29446f8d3f33SWingman Kwok } 29459a391c7bSWingMan Kwok emac_reg_ofs = GBE13_EMAC_OFFSET; 29469a391c7bSWingMan Kwok port_reg_blk_sz = 0x30; 29479a391c7bSWingMan Kwok emac_reg_blk_sz = 0x40; 29489a391c7bSWingMan Kwok } else if (IS_SS_ID_MU(gbe_dev)) { 29499a391c7bSWingMan Kwok port_reg_ofs = GBENU_SLAVE_PORT_OFFSET; 29509a391c7bSWingMan Kwok emac_reg_ofs = GBENU_EMAC_OFFSET; 29519a391c7bSWingMan Kwok port_reg_blk_sz = 0x1000; 29529a391c7bSWingMan Kwok emac_reg_blk_sz = 0x1000; 29532953586dSMurali Karicheri } else if (IS_SS_ID_XGBE(gbe_dev)) { 295490cff9e2SWingman Kwok port_reg_ofs = XGBE10_SLAVE_PORT_OFFSET; 29559a391c7bSWingMan Kwok emac_reg_ofs = XGBE10_EMAC_OFFSET; 29569a391c7bSWingMan Kwok port_reg_blk_sz = 0x30; 29579a391c7bSWingMan Kwok emac_reg_blk_sz = 0x40; 29586f8d3f33SWingman Kwok } else { 29596f8d3f33SWingman Kwok dev_err(gbe_dev->dev, "unknown ethss(0x%x)\n", 29606f8d3f33SWingman Kwok gbe_dev->ss_version); 29616f8d3f33SWingman Kwok return -EINVAL; 29626f8d3f33SWingman Kwok } 29636f8d3f33SWingman Kwok 296421e0e0ddSKaricheri, Muralidharan slave->port_regs = gbe_dev->switch_regs + port_reg_ofs + 29659a391c7bSWingMan Kwok (port_reg_blk_sz * port_reg_num); 296621e0e0ddSKaricheri, Muralidharan slave->emac_regs = gbe_dev->switch_regs + emac_reg_ofs + 29679a391c7bSWingMan Kwok (emac_reg_blk_sz * slave->slave_num); 29686f8d3f33SWingman Kwok 29692953586dSMurali Karicheri if (IS_SS_ID_VER_14(gbe_dev)) { 29706f8d3f33SWingman Kwok /* Initialize slave port register offsets */ 29716f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, port_vlan); 29726f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, tx_pri_map); 29736f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, sa_lo); 29746f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, sa_hi); 29756f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, ts_ctl); 29766f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, ts_seq_ltype); 29776f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, ts_vlan); 29786f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, ts_ctl_ltype2); 29796f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, ts_ctl2); 29806f8d3f33SWingman Kwok 29816f8d3f33SWingman Kwok /* Initialize EMAC register offsets */ 29826f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, emac_regs, mac_control); 29836f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, emac_regs, soft_reset); 29846f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, emac_regs, rx_maxlen); 29856f8d3f33SWingman Kwok 29869a391c7bSWingMan Kwok } else if (IS_SS_ID_MU(gbe_dev)) { 29879a391c7bSWingMan Kwok /* Initialize slave port register offsets */ 29889a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, port_vlan); 29899a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, tx_pri_map); 29909a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, sa_lo); 29919a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, sa_hi); 29929a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, ts_ctl); 29939a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, ts_seq_ltype); 29949a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, ts_vlan); 29959a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, ts_ctl_ltype2); 29969a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, ts_ctl2); 29979a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, rx_maxlen); 29989a391c7bSWingMan Kwok 29999a391c7bSWingMan Kwok /* Initialize EMAC register offsets */ 30009a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, emac_regs, mac_control); 30019a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, emac_regs, soft_reset); 30029a391c7bSWingMan Kwok 30032953586dSMurali Karicheri } else if (IS_SS_ID_XGBE(gbe_dev)) { 300490cff9e2SWingman Kwok /* Initialize slave port register offsets */ 300590cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, port_vlan); 300690cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, tx_pri_map); 300790cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, sa_lo); 300890cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, sa_hi); 300990cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, ts_ctl); 301090cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, ts_seq_ltype); 301190cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, ts_vlan); 301290cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, ts_ctl_ltype2); 301390cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, ts_ctl2); 301490cff9e2SWingman Kwok 301590cff9e2SWingman Kwok /* Initialize EMAC register offsets */ 301690cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, emac_regs, mac_control); 301790cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, emac_regs, soft_reset); 301890cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, emac_regs, rx_maxlen); 30196f8d3f33SWingman Kwok } 30206f8d3f33SWingman Kwok 30216f8d3f33SWingman Kwok atomic_set(&slave->link_state, NETCP_LINK_STATE_INVALID); 30226246168bSWingMan Kwok 30236246168bSWingMan Kwok init_slave_ts_ctl(slave); 30246f8d3f33SWingman Kwok return 0; 30256f8d3f33SWingman Kwok } 30266f8d3f33SWingman Kwok 30276f8d3f33SWingman Kwok static void init_secondary_ports(struct gbe_priv *gbe_dev, 30286f8d3f33SWingman Kwok struct device_node *node) 30296f8d3f33SWingman Kwok { 30306f8d3f33SWingman Kwok struct device *dev = gbe_dev->dev; 30316f8d3f33SWingman Kwok phy_interface_t phy_mode; 30326f8d3f33SWingman Kwok struct gbe_priv **priv; 30336f8d3f33SWingman Kwok struct device_node *port; 30346f8d3f33SWingman Kwok struct gbe_slave *slave; 30356f8d3f33SWingman Kwok bool mac_phy_link = false; 30366f8d3f33SWingman Kwok 30376f8d3f33SWingman Kwok for_each_child_of_node(node, port) { 30386f8d3f33SWingman Kwok slave = devm_kzalloc(dev, sizeof(*slave), GFP_KERNEL); 30396f8d3f33SWingman Kwok if (!slave) { 304011a9ec43SColin Ian King dev_err(dev, "memory alloc failed for secondary port(%s), skipping...\n", 30416f8d3f33SWingman Kwok port->name); 30426f8d3f33SWingman Kwok continue; 30436f8d3f33SWingman Kwok } 30446f8d3f33SWingman Kwok 30456f8d3f33SWingman Kwok if (init_slave(gbe_dev, slave, port)) { 30466f8d3f33SWingman Kwok dev_err(dev, 30476f8d3f33SWingman Kwok "Failed to initialize secondary port(%s), skipping...\n", 30486f8d3f33SWingman Kwok port->name); 30496f8d3f33SWingman Kwok devm_kfree(dev, slave); 30506f8d3f33SWingman Kwok continue; 30516f8d3f33SWingman Kwok } 30526f8d3f33SWingman Kwok 3053775f9535SMurali Karicheri if (!IS_SS_ID_2U(gbe_dev)) 30546f8d3f33SWingman Kwok gbe_sgmii_config(gbe_dev, slave); 30556f8d3f33SWingman Kwok gbe_port_reset(slave); 30566f8d3f33SWingman Kwok gbe_port_config(gbe_dev, slave, gbe_dev->rx_packet_max); 30576f8d3f33SWingman Kwok list_add_tail(&slave->slave_list, &gbe_dev->secondary_slaves); 30586f8d3f33SWingman Kwok gbe_dev->num_slaves++; 305990cff9e2SWingman Kwok if ((slave->link_interface == SGMII_LINK_MAC_PHY) || 306090cff9e2SWingman Kwok (slave->link_interface == XGMII_LINK_MAC_PHY)) 30616f8d3f33SWingman Kwok mac_phy_link = true; 30626f8d3f33SWingman Kwok 30636f8d3f33SWingman Kwok slave->open = true; 3064bd252796SJulia Lawall if (gbe_dev->num_slaves >= gbe_dev->max_num_slaves) { 3065bd252796SJulia Lawall of_node_put(port); 30669a391c7bSWingMan Kwok break; 30676f8d3f33SWingman Kwok } 3068bd252796SJulia Lawall } 30696f8d3f33SWingman Kwok 30706f8d3f33SWingman Kwok /* of_phy_connect() is needed only for MAC-PHY interface */ 30716f8d3f33SWingman Kwok if (!mac_phy_link) 30726f8d3f33SWingman Kwok return; 30736f8d3f33SWingman Kwok 30746f8d3f33SWingman Kwok /* Allocate dummy netdev device for attaching to phy device */ 30756f8d3f33SWingman Kwok gbe_dev->dummy_ndev = alloc_netdev(sizeof(gbe_dev), "dummy", 30766f8d3f33SWingman Kwok NET_NAME_UNKNOWN, ether_setup); 30776f8d3f33SWingman Kwok if (!gbe_dev->dummy_ndev) { 30786f8d3f33SWingman Kwok dev_err(dev, 30796f8d3f33SWingman Kwok "Failed to allocate dummy netdev for secondary ports, skipping phy_connect()...\n"); 30806f8d3f33SWingman Kwok return; 30816f8d3f33SWingman Kwok } 30826f8d3f33SWingman Kwok priv = netdev_priv(gbe_dev->dummy_ndev); 30836f8d3f33SWingman Kwok *priv = gbe_dev; 30846f8d3f33SWingman Kwok 30856f8d3f33SWingman Kwok if (slave->link_interface == SGMII_LINK_MAC_PHY) { 30866f8d3f33SWingman Kwok phy_mode = PHY_INTERFACE_MODE_SGMII; 30876f8d3f33SWingman Kwok slave->phy_port_t = PORT_MII; 3088478e9a5fSMurali Karicheri } else if (slave->link_interface == RGMII_LINK_MAC_PHY) { 3089478e9a5fSMurali Karicheri phy_mode = PHY_INTERFACE_MODE_RGMII; 3090478e9a5fSMurali Karicheri slave->phy_port_t = PORT_MII; 30916f8d3f33SWingman Kwok } else { 30926f8d3f33SWingman Kwok phy_mode = PHY_INTERFACE_MODE_NA; 30936f8d3f33SWingman Kwok slave->phy_port_t = PORT_FIBRE; 30946f8d3f33SWingman Kwok } 30956f8d3f33SWingman Kwok 30966f8d3f33SWingman Kwok for_each_sec_slave(slave, gbe_dev) { 309790cff9e2SWingman Kwok if ((slave->link_interface != SGMII_LINK_MAC_PHY) && 3098478e9a5fSMurali Karicheri (slave->link_interface != RGMII_LINK_MAC_PHY) && 309990cff9e2SWingman Kwok (slave->link_interface != XGMII_LINK_MAC_PHY)) 31006f8d3f33SWingman Kwok continue; 31016f8d3f33SWingman Kwok slave->phy = 31026f8d3f33SWingman Kwok of_phy_connect(gbe_dev->dummy_ndev, 31036f8d3f33SWingman Kwok slave->phy_node, 31046f8d3f33SWingman Kwok gbe_adjust_link_sec_slaves, 31056f8d3f33SWingman Kwok 0, phy_mode); 31066f8d3f33SWingman Kwok if (!slave->phy) { 31076f8d3f33SWingman Kwok dev_err(dev, "phy not found for slave %d\n", 31086f8d3f33SWingman Kwok slave->slave_num); 31096f8d3f33SWingman Kwok slave->phy = NULL; 31106f8d3f33SWingman Kwok } else { 31116f8d3f33SWingman Kwok dev_dbg(dev, "phy found: id is: 0x%s\n", 311284eff6d1SAndrew Lunn phydev_name(slave->phy)); 31136f8d3f33SWingman Kwok phy_start(slave->phy); 31146f8d3f33SWingman Kwok } 31156f8d3f33SWingman Kwok } 31166f8d3f33SWingman Kwok } 31176f8d3f33SWingman Kwok 31186f8d3f33SWingman Kwok static void free_secondary_ports(struct gbe_priv *gbe_dev) 31196f8d3f33SWingman Kwok { 31206f8d3f33SWingman Kwok struct gbe_slave *slave; 31216f8d3f33SWingman Kwok 3122c20afae7SKaricheri, Muralidharan while (!list_empty(&gbe_dev->secondary_slaves)) { 31236f8d3f33SWingman Kwok slave = first_sec_slave(gbe_dev); 3124c20afae7SKaricheri, Muralidharan 31256f8d3f33SWingman Kwok if (slave->phy) 31266f8d3f33SWingman Kwok phy_disconnect(slave->phy); 31276f8d3f33SWingman Kwok list_del(&slave->slave_list); 31286f8d3f33SWingman Kwok } 31296f8d3f33SWingman Kwok if (gbe_dev->dummy_ndev) 31306f8d3f33SWingman Kwok free_netdev(gbe_dev->dummy_ndev); 31316f8d3f33SWingman Kwok } 31326f8d3f33SWingman Kwok 313390cff9e2SWingman Kwok static int set_xgbe_ethss10_priv(struct gbe_priv *gbe_dev, 313490cff9e2SWingman Kwok struct device_node *node) 313590cff9e2SWingman Kwok { 313690cff9e2SWingman Kwok struct resource res; 313790cff9e2SWingman Kwok void __iomem *regs; 313890cff9e2SWingman Kwok int ret, i; 313990cff9e2SWingman Kwok 31409a391c7bSWingMan Kwok ret = of_address_to_resource(node, XGBE_SS_REG_INDEX, &res); 314190cff9e2SWingman Kwok if (ret) { 314221e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, 314321e0e0ddSKaricheri, Muralidharan "Can't xlate xgbe of node(%s) ss address at %d\n", 314421e0e0ddSKaricheri, Muralidharan node->name, XGBE_SS_REG_INDEX); 314590cff9e2SWingman Kwok return ret; 314690cff9e2SWingman Kwok } 314790cff9e2SWingman Kwok 314890cff9e2SWingman Kwok regs = devm_ioremap_resource(gbe_dev->dev, &res); 314990cff9e2SWingman Kwok if (IS_ERR(regs)) { 315021e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, "Failed to map xgbe ss register base\n"); 315190cff9e2SWingman Kwok return PTR_ERR(regs); 315290cff9e2SWingman Kwok } 315390cff9e2SWingman Kwok gbe_dev->ss_regs = regs; 315490cff9e2SWingman Kwok 315521e0e0ddSKaricheri, Muralidharan ret = of_address_to_resource(node, XGBE_SM_REG_INDEX, &res); 315621e0e0ddSKaricheri, Muralidharan if (ret) { 315721e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, 315821e0e0ddSKaricheri, Muralidharan "Can't xlate xgbe of node(%s) sm address at %d\n", 315921e0e0ddSKaricheri, Muralidharan node->name, XGBE_SM_REG_INDEX); 316021e0e0ddSKaricheri, Muralidharan return ret; 316121e0e0ddSKaricheri, Muralidharan } 316221e0e0ddSKaricheri, Muralidharan 316321e0e0ddSKaricheri, Muralidharan regs = devm_ioremap_resource(gbe_dev->dev, &res); 316421e0e0ddSKaricheri, Muralidharan if (IS_ERR(regs)) { 316521e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, "Failed to map xgbe sm register base\n"); 316621e0e0ddSKaricheri, Muralidharan return PTR_ERR(regs); 316721e0e0ddSKaricheri, Muralidharan } 316821e0e0ddSKaricheri, Muralidharan gbe_dev->switch_regs = regs; 316921e0e0ddSKaricheri, Muralidharan 317090cff9e2SWingman Kwok ret = of_address_to_resource(node, XGBE_SERDES_REG_INDEX, &res); 317190cff9e2SWingman Kwok if (ret) { 317221e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, 317321e0e0ddSKaricheri, Muralidharan "Can't xlate xgbe serdes of node(%s) address at %d\n", 317421e0e0ddSKaricheri, Muralidharan node->name, XGBE_SERDES_REG_INDEX); 317590cff9e2SWingman Kwok return ret; 317690cff9e2SWingman Kwok } 317790cff9e2SWingman Kwok 317890cff9e2SWingman Kwok regs = devm_ioremap_resource(gbe_dev->dev, &res); 317990cff9e2SWingman Kwok if (IS_ERR(regs)) { 318090cff9e2SWingman Kwok dev_err(gbe_dev->dev, "Failed to map xgbe serdes register base\n"); 318190cff9e2SWingman Kwok return PTR_ERR(regs); 318290cff9e2SWingman Kwok } 318390cff9e2SWingman Kwok gbe_dev->xgbe_serdes_regs = regs; 318490cff9e2SWingman Kwok 3185489e8a2fSWingMan Kwok gbe_dev->num_stats_mods = gbe_dev->max_num_ports; 3186208c6b9aSWingMan Kwok gbe_dev->et_stats = xgbe10_et_stats; 3187208c6b9aSWingMan Kwok gbe_dev->num_et_stats = ARRAY_SIZE(xgbe10_et_stats); 3188208c6b9aSWingMan Kwok 318990cff9e2SWingman Kwok gbe_dev->hw_stats = devm_kzalloc(gbe_dev->dev, 3190208c6b9aSWingMan Kwok gbe_dev->num_et_stats * sizeof(u64), 319190cff9e2SWingman Kwok GFP_KERNEL); 319290cff9e2SWingman Kwok if (!gbe_dev->hw_stats) { 319390cff9e2SWingman Kwok dev_err(gbe_dev->dev, "hw_stats memory allocation failed\n"); 319490cff9e2SWingman Kwok return -ENOMEM; 319590cff9e2SWingman Kwok } 319690cff9e2SWingman Kwok 3197489e8a2fSWingMan Kwok gbe_dev->hw_stats_prev = 3198489e8a2fSWingMan Kwok devm_kzalloc(gbe_dev->dev, 3199489e8a2fSWingMan Kwok gbe_dev->num_et_stats * sizeof(u32), 3200489e8a2fSWingMan Kwok GFP_KERNEL); 3201489e8a2fSWingMan Kwok if (!gbe_dev->hw_stats_prev) { 3202489e8a2fSWingMan Kwok dev_err(gbe_dev->dev, 3203489e8a2fSWingMan Kwok "hw_stats_prev memory allocation failed\n"); 3204489e8a2fSWingMan Kwok return -ENOMEM; 3205489e8a2fSWingMan Kwok } 3206489e8a2fSWingMan Kwok 320790cff9e2SWingman Kwok gbe_dev->ss_version = XGBE_SS_VERSION_10; 320890cff9e2SWingman Kwok gbe_dev->sgmii_port_regs = gbe_dev->ss_regs + 320990cff9e2SWingman Kwok XGBE10_SGMII_MODULE_OFFSET; 321090cff9e2SWingman Kwok gbe_dev->host_port_regs = gbe_dev->ss_regs + XGBE10_HOST_PORT_OFFSET; 321190cff9e2SWingman Kwok 32129a391c7bSWingMan Kwok for (i = 0; i < gbe_dev->max_num_ports; i++) 321321e0e0ddSKaricheri, Muralidharan gbe_dev->hw_stats_regs[i] = gbe_dev->switch_regs + 321490cff9e2SWingman Kwok XGBE10_HW_STATS_OFFSET + (GBE_HW_STATS_REG_MAP_SZ * i); 321590cff9e2SWingman Kwok 32169a391c7bSWingMan Kwok gbe_dev->ale_reg = gbe_dev->switch_regs + XGBE10_ALE_OFFSET; 32176246168bSWingMan Kwok gbe_dev->cpts_reg = gbe_dev->switch_regs + XGBE10_CPTS_OFFSET; 32189a391c7bSWingMan Kwok gbe_dev->ale_ports = gbe_dev->max_num_ports; 321990cff9e2SWingman Kwok gbe_dev->host_port = XGBE10_HOST_PORT_NUM; 322090cff9e2SWingman Kwok gbe_dev->ale_entries = XGBE10_NUM_ALE_ENTRIES; 32219a391c7bSWingMan Kwok gbe_dev->stats_en_mask = (1 << (gbe_dev->max_num_ports)) - 1; 322290cff9e2SWingman Kwok 322390cff9e2SWingman Kwok /* Subsystem registers */ 322490cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, ss_regs, id_ver); 322590cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, ss_regs, control); 322690cff9e2SWingman Kwok 322790cff9e2SWingman Kwok /* Switch module registers */ 322890cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, switch_regs, id_ver); 322990cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, switch_regs, control); 323090cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, switch_regs, ptype); 323190cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, switch_regs, stat_port_en); 323290cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, switch_regs, flow_control); 323390cff9e2SWingman Kwok 323490cff9e2SWingman Kwok /* Host port registers */ 323590cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, host_port_regs, port_vlan); 323690cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, host_port_regs, tx_pri_map); 323790cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, host_port_regs, rx_maxlen); 323890cff9e2SWingman Kwok return 0; 323990cff9e2SWingman Kwok } 324090cff9e2SWingman Kwok 32416f8d3f33SWingman Kwok static int get_gbe_resource_version(struct gbe_priv *gbe_dev, 32426f8d3f33SWingman Kwok struct device_node *node) 32436f8d3f33SWingman Kwok { 32446f8d3f33SWingman Kwok struct resource res; 32456f8d3f33SWingman Kwok void __iomem *regs; 32466f8d3f33SWingman Kwok int ret; 32476f8d3f33SWingman Kwok 324821e0e0ddSKaricheri, Muralidharan ret = of_address_to_resource(node, GBE_SS_REG_INDEX, &res); 32496f8d3f33SWingman Kwok if (ret) { 325021e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, 325121e0e0ddSKaricheri, Muralidharan "Can't translate of node(%s) of gbe ss address at %d\n", 325221e0e0ddSKaricheri, Muralidharan node->name, GBE_SS_REG_INDEX); 32536f8d3f33SWingman Kwok return ret; 32546f8d3f33SWingman Kwok } 32556f8d3f33SWingman Kwok 32566f8d3f33SWingman Kwok regs = devm_ioremap_resource(gbe_dev->dev, &res); 32576f8d3f33SWingman Kwok if (IS_ERR(regs)) { 32586f8d3f33SWingman Kwok dev_err(gbe_dev->dev, "Failed to map gbe register base\n"); 32596f8d3f33SWingman Kwok return PTR_ERR(regs); 32606f8d3f33SWingman Kwok } 32616f8d3f33SWingman Kwok gbe_dev->ss_regs = regs; 32626f8d3f33SWingman Kwok gbe_dev->ss_version = readl(gbe_dev->ss_regs); 32636f8d3f33SWingman Kwok return 0; 32646f8d3f33SWingman Kwok } 32656f8d3f33SWingman Kwok 32666f8d3f33SWingman Kwok static int set_gbe_ethss14_priv(struct gbe_priv *gbe_dev, 32676f8d3f33SWingman Kwok struct device_node *node) 32686f8d3f33SWingman Kwok { 326921e0e0ddSKaricheri, Muralidharan struct resource res; 32706f8d3f33SWingman Kwok void __iomem *regs; 327121e0e0ddSKaricheri, Muralidharan int i, ret; 327221e0e0ddSKaricheri, Muralidharan 327321e0e0ddSKaricheri, Muralidharan ret = of_address_to_resource(node, GBE_SGMII34_REG_INDEX, &res); 327421e0e0ddSKaricheri, Muralidharan if (ret) { 327521e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, 327621e0e0ddSKaricheri, Muralidharan "Can't translate of gbe node(%s) address at index %d\n", 327721e0e0ddSKaricheri, Muralidharan node->name, GBE_SGMII34_REG_INDEX); 327821e0e0ddSKaricheri, Muralidharan return ret; 327921e0e0ddSKaricheri, Muralidharan } 328021e0e0ddSKaricheri, Muralidharan 328121e0e0ddSKaricheri, Muralidharan regs = devm_ioremap_resource(gbe_dev->dev, &res); 328221e0e0ddSKaricheri, Muralidharan if (IS_ERR(regs)) { 328321e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, 328421e0e0ddSKaricheri, Muralidharan "Failed to map gbe sgmii port34 register base\n"); 328521e0e0ddSKaricheri, Muralidharan return PTR_ERR(regs); 328621e0e0ddSKaricheri, Muralidharan } 328721e0e0ddSKaricheri, Muralidharan gbe_dev->sgmii_port34_regs = regs; 328821e0e0ddSKaricheri, Muralidharan 328921e0e0ddSKaricheri, Muralidharan ret = of_address_to_resource(node, GBE_SM_REG_INDEX, &res); 329021e0e0ddSKaricheri, Muralidharan if (ret) { 329121e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, 329221e0e0ddSKaricheri, Muralidharan "Can't translate of gbe node(%s) address at index %d\n", 329321e0e0ddSKaricheri, Muralidharan node->name, GBE_SM_REG_INDEX); 329421e0e0ddSKaricheri, Muralidharan return ret; 329521e0e0ddSKaricheri, Muralidharan } 329621e0e0ddSKaricheri, Muralidharan 329721e0e0ddSKaricheri, Muralidharan regs = devm_ioremap_resource(gbe_dev->dev, &res); 329821e0e0ddSKaricheri, Muralidharan if (IS_ERR(regs)) { 329921e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, 330021e0e0ddSKaricheri, Muralidharan "Failed to map gbe switch module register base\n"); 330121e0e0ddSKaricheri, Muralidharan return PTR_ERR(regs); 330221e0e0ddSKaricheri, Muralidharan } 330321e0e0ddSKaricheri, Muralidharan gbe_dev->switch_regs = regs; 33046f8d3f33SWingman Kwok 3305489e8a2fSWingMan Kwok gbe_dev->num_stats_mods = gbe_dev->max_num_slaves; 3306208c6b9aSWingMan Kwok gbe_dev->et_stats = gbe13_et_stats; 3307208c6b9aSWingMan Kwok gbe_dev->num_et_stats = ARRAY_SIZE(gbe13_et_stats); 3308208c6b9aSWingMan Kwok 33096f8d3f33SWingman Kwok gbe_dev->hw_stats = devm_kzalloc(gbe_dev->dev, 3310208c6b9aSWingMan Kwok gbe_dev->num_et_stats * sizeof(u64), 33116f8d3f33SWingman Kwok GFP_KERNEL); 33126f8d3f33SWingman Kwok if (!gbe_dev->hw_stats) { 33136f8d3f33SWingman Kwok dev_err(gbe_dev->dev, "hw_stats memory allocation failed\n"); 33146f8d3f33SWingman Kwok return -ENOMEM; 33156f8d3f33SWingman Kwok } 33166f8d3f33SWingman Kwok 3317489e8a2fSWingMan Kwok gbe_dev->hw_stats_prev = 3318489e8a2fSWingMan Kwok devm_kzalloc(gbe_dev->dev, 3319489e8a2fSWingMan Kwok gbe_dev->num_et_stats * sizeof(u32), 3320489e8a2fSWingMan Kwok GFP_KERNEL); 3321489e8a2fSWingMan Kwok if (!gbe_dev->hw_stats_prev) { 3322489e8a2fSWingMan Kwok dev_err(gbe_dev->dev, 3323489e8a2fSWingMan Kwok "hw_stats_prev memory allocation failed\n"); 3324489e8a2fSWingMan Kwok return -ENOMEM; 3325489e8a2fSWingMan Kwok } 3326489e8a2fSWingMan Kwok 332721e0e0ddSKaricheri, Muralidharan gbe_dev->sgmii_port_regs = gbe_dev->ss_regs + GBE13_SGMII_MODULE_OFFSET; 332821e0e0ddSKaricheri, Muralidharan gbe_dev->host_port_regs = gbe_dev->switch_regs + GBE13_HOST_PORT_OFFSET; 33296f8d3f33SWingman Kwok 3330a94bcd09SWingMan Kwok /* K2HK has only 2 hw stats modules visible at a time, so 3331a94bcd09SWingMan Kwok * module 0 & 2 points to one base and 3332a94bcd09SWingMan Kwok * module 1 & 3 points to the other base 3333a94bcd09SWingMan Kwok */ 33349a391c7bSWingMan Kwok for (i = 0; i < gbe_dev->max_num_slaves; i++) { 333521e0e0ddSKaricheri, Muralidharan gbe_dev->hw_stats_regs[i] = 333621e0e0ddSKaricheri, Muralidharan gbe_dev->switch_regs + GBE13_HW_STATS_OFFSET + 3337a94bcd09SWingMan Kwok (GBE_HW_STATS_REG_MAP_SZ * (i & 0x1)); 333821e0e0ddSKaricheri, Muralidharan } 33396f8d3f33SWingman Kwok 33406246168bSWingMan Kwok gbe_dev->cpts_reg = gbe_dev->switch_regs + GBE13_CPTS_OFFSET; 334121e0e0ddSKaricheri, Muralidharan gbe_dev->ale_reg = gbe_dev->switch_regs + GBE13_ALE_OFFSET; 33429a391c7bSWingMan Kwok gbe_dev->ale_ports = gbe_dev->max_num_ports; 33436f8d3f33SWingman Kwok gbe_dev->host_port = GBE13_HOST_PORT_NUM; 33446f8d3f33SWingman Kwok gbe_dev->ale_entries = GBE13_NUM_ALE_ENTRIES; 33459a391c7bSWingMan Kwok gbe_dev->stats_en_mask = GBE13_REG_VAL_STAT_ENABLE_ALL; 33466f8d3f33SWingman Kwok 33476f8d3f33SWingman Kwok /* Subsystem registers */ 33486f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, ss_regs, id_ver); 33496f8d3f33SWingman Kwok 33506f8d3f33SWingman Kwok /* Switch module registers */ 33516f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, switch_regs, id_ver); 33526f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, switch_regs, control); 33536f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, switch_regs, soft_reset); 33546f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, switch_regs, stat_port_en); 33556f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, switch_regs, ptype); 33566f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, switch_regs, flow_control); 33576f8d3f33SWingman Kwok 33586f8d3f33SWingman Kwok /* Host port registers */ 33596f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, host_port_regs, port_vlan); 33606f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, host_port_regs, rx_maxlen); 33616f8d3f33SWingman Kwok return 0; 33626f8d3f33SWingman Kwok } 33636f8d3f33SWingman Kwok 33649a391c7bSWingMan Kwok static int set_gbenu_ethss_priv(struct gbe_priv *gbe_dev, 33659a391c7bSWingMan Kwok struct device_node *node) 33669a391c7bSWingMan Kwok { 33679a391c7bSWingMan Kwok struct resource res; 33689a391c7bSWingMan Kwok void __iomem *regs; 33699a391c7bSWingMan Kwok int i, ret; 33709a391c7bSWingMan Kwok 3371489e8a2fSWingMan Kwok gbe_dev->num_stats_mods = gbe_dev->max_num_ports; 3372208c6b9aSWingMan Kwok gbe_dev->et_stats = gbenu_et_stats; 3373208c6b9aSWingMan Kwok 3374208c6b9aSWingMan Kwok if (IS_SS_ID_NU(gbe_dev)) 3375208c6b9aSWingMan Kwok gbe_dev->num_et_stats = GBENU_ET_STATS_HOST_SIZE + 3376208c6b9aSWingMan Kwok (gbe_dev->max_num_slaves * GBENU_ET_STATS_PORT_SIZE); 3377208c6b9aSWingMan Kwok else 3378208c6b9aSWingMan Kwok gbe_dev->num_et_stats = GBENU_ET_STATS_HOST_SIZE + 3379208c6b9aSWingMan Kwok GBENU_ET_STATS_PORT_SIZE; 3380208c6b9aSWingMan Kwok 33819a391c7bSWingMan Kwok gbe_dev->hw_stats = devm_kzalloc(gbe_dev->dev, 3382208c6b9aSWingMan Kwok gbe_dev->num_et_stats * sizeof(u64), 33839a391c7bSWingMan Kwok GFP_KERNEL); 33849a391c7bSWingMan Kwok if (!gbe_dev->hw_stats) { 33859a391c7bSWingMan Kwok dev_err(gbe_dev->dev, "hw_stats memory allocation failed\n"); 33869a391c7bSWingMan Kwok return -ENOMEM; 33879a391c7bSWingMan Kwok } 33889a391c7bSWingMan Kwok 3389489e8a2fSWingMan Kwok gbe_dev->hw_stats_prev = 3390489e8a2fSWingMan Kwok devm_kzalloc(gbe_dev->dev, 3391489e8a2fSWingMan Kwok gbe_dev->num_et_stats * sizeof(u32), 3392489e8a2fSWingMan Kwok GFP_KERNEL); 3393489e8a2fSWingMan Kwok if (!gbe_dev->hw_stats_prev) { 3394489e8a2fSWingMan Kwok dev_err(gbe_dev->dev, 3395489e8a2fSWingMan Kwok "hw_stats_prev memory allocation failed\n"); 3396489e8a2fSWingMan Kwok return -ENOMEM; 3397489e8a2fSWingMan Kwok } 3398489e8a2fSWingMan Kwok 33999a391c7bSWingMan Kwok ret = of_address_to_resource(node, GBENU_SM_REG_INDEX, &res); 34009a391c7bSWingMan Kwok if (ret) { 34019a391c7bSWingMan Kwok dev_err(gbe_dev->dev, 34029a391c7bSWingMan Kwok "Can't translate of gbenu node(%s) addr at index %d\n", 34039a391c7bSWingMan Kwok node->name, GBENU_SM_REG_INDEX); 34049a391c7bSWingMan Kwok return ret; 34059a391c7bSWingMan Kwok } 34069a391c7bSWingMan Kwok 34079a391c7bSWingMan Kwok regs = devm_ioremap_resource(gbe_dev->dev, &res); 34089a391c7bSWingMan Kwok if (IS_ERR(regs)) { 34099a391c7bSWingMan Kwok dev_err(gbe_dev->dev, 34109a391c7bSWingMan Kwok "Failed to map gbenu switch module register base\n"); 34119a391c7bSWingMan Kwok return PTR_ERR(regs); 34129a391c7bSWingMan Kwok } 34139a391c7bSWingMan Kwok gbe_dev->switch_regs = regs; 34149a391c7bSWingMan Kwok 3415775f9535SMurali Karicheri if (!IS_SS_ID_2U(gbe_dev)) 3416775f9535SMurali Karicheri gbe_dev->sgmii_port_regs = 3417775f9535SMurali Karicheri gbe_dev->ss_regs + GBENU_SGMII_MODULE_OFFSET; 34188c85151dSWingMan Kwok 34198c85151dSWingMan Kwok /* Although sgmii modules are mem mapped to one contiguous 34208c85151dSWingMan Kwok * region on GBENU devices, setting sgmii_port34_regs allows 34218c85151dSWingMan Kwok * consistent code when accessing sgmii api 34228c85151dSWingMan Kwok */ 34238c85151dSWingMan Kwok gbe_dev->sgmii_port34_regs = gbe_dev->sgmii_port_regs + 34248c85151dSWingMan Kwok (2 * GBENU_SGMII_MODULE_SIZE); 34258c85151dSWingMan Kwok 34269a391c7bSWingMan Kwok gbe_dev->host_port_regs = gbe_dev->switch_regs + GBENU_HOST_PORT_OFFSET; 34279a391c7bSWingMan Kwok 34289a391c7bSWingMan Kwok for (i = 0; i < (gbe_dev->max_num_ports); i++) 34299a391c7bSWingMan Kwok gbe_dev->hw_stats_regs[i] = gbe_dev->switch_regs + 34309a391c7bSWingMan Kwok GBENU_HW_STATS_OFFSET + (GBENU_HW_STATS_REG_MAP_SZ * i); 34319a391c7bSWingMan Kwok 34326246168bSWingMan Kwok gbe_dev->cpts_reg = gbe_dev->switch_regs + GBENU_CPTS_OFFSET; 34339a391c7bSWingMan Kwok gbe_dev->ale_reg = gbe_dev->switch_regs + GBENU_ALE_OFFSET; 34349a391c7bSWingMan Kwok gbe_dev->ale_ports = gbe_dev->max_num_ports; 34359a391c7bSWingMan Kwok gbe_dev->host_port = GBENU_HOST_PORT_NUM; 34369a391c7bSWingMan Kwok gbe_dev->stats_en_mask = (1 << (gbe_dev->max_num_ports)) - 1; 34379a391c7bSWingMan Kwok 34389a391c7bSWingMan Kwok /* Subsystem registers */ 34399a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, ss_regs, id_ver); 34409a391c7bSWingMan Kwok 34419a391c7bSWingMan Kwok /* Switch module registers */ 34429a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, switch_regs, id_ver); 34439a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, switch_regs, control); 34449a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, switch_regs, stat_port_en); 34459a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, switch_regs, ptype); 34469a391c7bSWingMan Kwok 34479a391c7bSWingMan Kwok /* Host port registers */ 34489a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, host_port_regs, port_vlan); 34499a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, host_port_regs, rx_maxlen); 34509a391c7bSWingMan Kwok 34519a391c7bSWingMan Kwok /* For NU only. 2U does not need tx_pri_map. 34529a391c7bSWingMan Kwok * NU cppi port 0 tx pkt streaming interface has (n-1)*8 egress threads 34539a391c7bSWingMan Kwok * while 2U has only 1 such thread 34549a391c7bSWingMan Kwok */ 34559a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, host_port_regs, tx_pri_map); 34569a391c7bSWingMan Kwok return 0; 34579a391c7bSWingMan Kwok } 34589a391c7bSWingMan Kwok 34596f8d3f33SWingman Kwok static int gbe_probe(struct netcp_device *netcp_device, struct device *dev, 34606f8d3f33SWingman Kwok struct device_node *node, void **inst_priv) 34616f8d3f33SWingman Kwok { 34626f8d3f33SWingman Kwok struct device_node *interfaces, *interface; 34636f8d3f33SWingman Kwok struct device_node *secondary_ports; 34646f8d3f33SWingman Kwok struct cpsw_ale_params ale_params; 34656f8d3f33SWingman Kwok struct gbe_priv *gbe_dev; 34666f8d3f33SWingman Kwok u32 slave_num; 3467489e8a2fSWingMan Kwok int i, ret = 0; 34686f8d3f33SWingman Kwok 34696f8d3f33SWingman Kwok if (!node) { 34706f8d3f33SWingman Kwok dev_err(dev, "device tree info unavailable\n"); 34716f8d3f33SWingman Kwok return -ENODEV; 34726f8d3f33SWingman Kwok } 34736f8d3f33SWingman Kwok 34746f8d3f33SWingman Kwok gbe_dev = devm_kzalloc(dev, sizeof(struct gbe_priv), GFP_KERNEL); 34756f8d3f33SWingman Kwok if (!gbe_dev) 34766f8d3f33SWingman Kwok return -ENOMEM; 34776f8d3f33SWingman Kwok 34789a391c7bSWingMan Kwok if (of_device_is_compatible(node, "ti,netcp-gbe-5") || 34799a391c7bSWingMan Kwok of_device_is_compatible(node, "ti,netcp-gbe")) { 34809a391c7bSWingMan Kwok gbe_dev->max_num_slaves = 4; 34819a391c7bSWingMan Kwok } else if (of_device_is_compatible(node, "ti,netcp-gbe-9")) { 34829a391c7bSWingMan Kwok gbe_dev->max_num_slaves = 8; 34839a391c7bSWingMan Kwok } else if (of_device_is_compatible(node, "ti,netcp-gbe-2")) { 34849a391c7bSWingMan Kwok gbe_dev->max_num_slaves = 1; 34859a391c7bSWingMan Kwok } else if (of_device_is_compatible(node, "ti,netcp-xgbe")) { 34869a391c7bSWingMan Kwok gbe_dev->max_num_slaves = 2; 34879a391c7bSWingMan Kwok } else { 34889a391c7bSWingMan Kwok dev_err(dev, "device tree node for unknown device\n"); 34899a391c7bSWingMan Kwok return -EINVAL; 34909a391c7bSWingMan Kwok } 34919a391c7bSWingMan Kwok gbe_dev->max_num_ports = gbe_dev->max_num_slaves + 1; 34929a391c7bSWingMan Kwok 34936f8d3f33SWingman Kwok gbe_dev->dev = dev; 34946f8d3f33SWingman Kwok gbe_dev->netcp_device = netcp_device; 34956f8d3f33SWingman Kwok gbe_dev->rx_packet_max = NETCP_MAX_FRAME_SIZE; 34966f8d3f33SWingman Kwok 34976f8d3f33SWingman Kwok /* init the hw stats lock */ 34986f8d3f33SWingman Kwok spin_lock_init(&gbe_dev->hw_stats_lock); 34996f8d3f33SWingman Kwok 35006f8d3f33SWingman Kwok if (of_find_property(node, "enable-ale", NULL)) { 35016f8d3f33SWingman Kwok gbe_dev->enable_ale = true; 35026f8d3f33SWingman Kwok dev_info(dev, "ALE enabled\n"); 35036f8d3f33SWingman Kwok } else { 35046f8d3f33SWingman Kwok gbe_dev->enable_ale = false; 35056f8d3f33SWingman Kwok dev_dbg(dev, "ALE bypass enabled*\n"); 35066f8d3f33SWingman Kwok } 35076f8d3f33SWingman Kwok 35086f8d3f33SWingman Kwok ret = of_property_read_u32(node, "tx-queue", 35096f8d3f33SWingman Kwok &gbe_dev->tx_queue_id); 35106f8d3f33SWingman Kwok if (ret < 0) { 35116f8d3f33SWingman Kwok dev_err(dev, "missing tx_queue parameter\n"); 35126f8d3f33SWingman Kwok gbe_dev->tx_queue_id = GBE_TX_QUEUE; 35136f8d3f33SWingman Kwok } 35146f8d3f33SWingman Kwok 35156f8d3f33SWingman Kwok ret = of_property_read_string(node, "tx-channel", 35166f8d3f33SWingman Kwok &gbe_dev->dma_chan_name); 35176f8d3f33SWingman Kwok if (ret < 0) { 35186f8d3f33SWingman Kwok dev_err(dev, "missing \"tx-channel\" parameter\n"); 351931a184b7SKaricheri, Muralidharan return -EINVAL; 35206f8d3f33SWingman Kwok } 35216f8d3f33SWingman Kwok 35226f8d3f33SWingman Kwok if (!strcmp(node->name, "gbe")) { 35236f8d3f33SWingman Kwok ret = get_gbe_resource_version(gbe_dev, node); 35246f8d3f33SWingman Kwok if (ret) 352531a184b7SKaricheri, Muralidharan return ret; 35266f8d3f33SWingman Kwok 35279a391c7bSWingMan Kwok dev_dbg(dev, "ss_version: 0x%08x\n", gbe_dev->ss_version); 35289a391c7bSWingMan Kwok 35292953586dSMurali Karicheri if (IS_SS_ID_VER_14(gbe_dev)) 35306f8d3f33SWingman Kwok ret = set_gbe_ethss14_priv(gbe_dev, node); 35319a391c7bSWingMan Kwok else if (IS_SS_ID_MU(gbe_dev)) 35329a391c7bSWingMan Kwok ret = set_gbenu_ethss_priv(gbe_dev, node); 35339a391c7bSWingMan Kwok else 35349a391c7bSWingMan Kwok ret = -ENODEV; 35359a391c7bSWingMan Kwok 353690cff9e2SWingman Kwok } else if (!strcmp(node->name, "xgbe")) { 353790cff9e2SWingman Kwok ret = set_xgbe_ethss10_priv(gbe_dev, node); 353890cff9e2SWingman Kwok if (ret) 353931a184b7SKaricheri, Muralidharan return ret; 354090cff9e2SWingman Kwok ret = netcp_xgbe_serdes_init(gbe_dev->xgbe_serdes_regs, 354190cff9e2SWingman Kwok gbe_dev->ss_regs); 35426f8d3f33SWingman Kwok } else { 35436f8d3f33SWingman Kwok dev_err(dev, "unknown GBE node(%s)\n", node->name); 35446f8d3f33SWingman Kwok ret = -ENODEV; 35456f8d3f33SWingman Kwok } 35466f8d3f33SWingman Kwok 354731a184b7SKaricheri, Muralidharan if (ret) 354831a184b7SKaricheri, Muralidharan return ret; 354931a184b7SKaricheri, Muralidharan 35506f8d3f33SWingman Kwok interfaces = of_get_child_by_name(node, "interfaces"); 35516f8d3f33SWingman Kwok if (!interfaces) 35526f8d3f33SWingman Kwok dev_err(dev, "could not find interfaces\n"); 35536f8d3f33SWingman Kwok 35546f8d3f33SWingman Kwok ret = netcp_txpipe_init(&gbe_dev->tx_pipe, netcp_device, 35556f8d3f33SWingman Kwok gbe_dev->dma_chan_name, gbe_dev->tx_queue_id); 35566f8d3f33SWingman Kwok if (ret) 355731a184b7SKaricheri, Muralidharan return ret; 35586f8d3f33SWingman Kwok 35596f8d3f33SWingman Kwok ret = netcp_txpipe_open(&gbe_dev->tx_pipe); 35606f8d3f33SWingman Kwok if (ret) 356131a184b7SKaricheri, Muralidharan return ret; 35626f8d3f33SWingman Kwok 35636f8d3f33SWingman Kwok /* Create network interfaces */ 35646f8d3f33SWingman Kwok INIT_LIST_HEAD(&gbe_dev->gbe_intf_head); 35656f8d3f33SWingman Kwok for_each_child_of_node(interfaces, interface) { 35666f8d3f33SWingman Kwok ret = of_property_read_u32(interface, "slave-port", &slave_num); 35676f8d3f33SWingman Kwok if (ret) { 35686f8d3f33SWingman Kwok dev_err(dev, "missing slave-port parameter, skipping interface configuration for %s\n", 35696f8d3f33SWingman Kwok interface->name); 35706f8d3f33SWingman Kwok continue; 35716f8d3f33SWingman Kwok } 35726f8d3f33SWingman Kwok gbe_dev->num_slaves++; 3573bd252796SJulia Lawall if (gbe_dev->num_slaves >= gbe_dev->max_num_slaves) { 3574bd252796SJulia Lawall of_node_put(interface); 35759a391c7bSWingMan Kwok break; 35766f8d3f33SWingman Kwok } 3577bd252796SJulia Lawall } 357831a184b7SKaricheri, Muralidharan of_node_put(interfaces); 35796f8d3f33SWingman Kwok 35806f8d3f33SWingman Kwok if (!gbe_dev->num_slaves) 35816f8d3f33SWingman Kwok dev_warn(dev, "No network interface configured\n"); 35826f8d3f33SWingman Kwok 35836f8d3f33SWingman Kwok /* Initialize Secondary slave ports */ 35846f8d3f33SWingman Kwok secondary_ports = of_get_child_by_name(node, "secondary-slave-ports"); 35856f8d3f33SWingman Kwok INIT_LIST_HEAD(&gbe_dev->secondary_slaves); 35869a391c7bSWingMan Kwok if (secondary_ports && (gbe_dev->num_slaves < gbe_dev->max_num_slaves)) 35876f8d3f33SWingman Kwok init_secondary_ports(gbe_dev, secondary_ports); 35886f8d3f33SWingman Kwok of_node_put(secondary_ports); 35896f8d3f33SWingman Kwok 35906f8d3f33SWingman Kwok if (!gbe_dev->num_slaves) { 359131a184b7SKaricheri, Muralidharan dev_err(dev, 359231a184b7SKaricheri, Muralidharan "No network interface or secondary ports configured\n"); 35936f8d3f33SWingman Kwok ret = -ENODEV; 359431a184b7SKaricheri, Muralidharan goto free_sec_ports; 35956f8d3f33SWingman Kwok } 35966f8d3f33SWingman Kwok 35976f8d3f33SWingman Kwok memset(&ale_params, 0, sizeof(ale_params)); 35986f8d3f33SWingman Kwok ale_params.dev = gbe_dev->dev; 35996f8d3f33SWingman Kwok ale_params.ale_regs = gbe_dev->ale_reg; 36006f8d3f33SWingman Kwok ale_params.ale_ageout = GBE_DEFAULT_ALE_AGEOUT; 36016f8d3f33SWingman Kwok ale_params.ale_entries = gbe_dev->ale_entries; 36026f8d3f33SWingman Kwok ale_params.ale_ports = gbe_dev->ale_ports; 3603ca47130aSKaricheri, Muralidharan if (IS_SS_ID_MU(gbe_dev)) { 3604ca47130aSKaricheri, Muralidharan ale_params.major_ver_mask = 0x7; 3605ca47130aSKaricheri, Muralidharan ale_params.nu_switch_ale = true; 3606ca47130aSKaricheri, Muralidharan } 36076f8d3f33SWingman Kwok gbe_dev->ale = cpsw_ale_create(&ale_params); 36086f8d3f33SWingman Kwok if (!gbe_dev->ale) { 36096f8d3f33SWingman Kwok dev_err(gbe_dev->dev, "error initializing ale engine\n"); 36106f8d3f33SWingman Kwok ret = -ENODEV; 361131a184b7SKaricheri, Muralidharan goto free_sec_ports; 36126f8d3f33SWingman Kwok } else { 36136f8d3f33SWingman Kwok dev_dbg(gbe_dev->dev, "Created a gbe ale engine\n"); 36146f8d3f33SWingman Kwok } 36156f8d3f33SWingman Kwok 36166246168bSWingMan Kwok gbe_dev->cpts = cpts_create(gbe_dev->dev, gbe_dev->cpts_reg, node); 36176246168bSWingMan Kwok if (IS_ENABLED(CONFIG_TI_CPTS) && IS_ERR(gbe_dev->cpts)) { 36186246168bSWingMan Kwok ret = PTR_ERR(gbe_dev->cpts); 36196246168bSWingMan Kwok goto free_sec_ports; 36206246168bSWingMan Kwok } 36216246168bSWingMan Kwok 36226f8d3f33SWingman Kwok /* initialize host port */ 36236f8d3f33SWingman Kwok gbe_init_host_port(gbe_dev); 36246f8d3f33SWingman Kwok 3625489e8a2fSWingMan Kwok spin_lock_bh(&gbe_dev->hw_stats_lock); 3626489e8a2fSWingMan Kwok for (i = 0; i < gbe_dev->num_stats_mods; i++) { 36272953586dSMurali Karicheri if (IS_SS_ID_VER_14(gbe_dev)) 3628489e8a2fSWingMan Kwok gbe_reset_mod_stats_ver14(gbe_dev, i); 3629489e8a2fSWingMan Kwok else 3630489e8a2fSWingMan Kwok gbe_reset_mod_stats(gbe_dev, i); 3631489e8a2fSWingMan Kwok } 3632489e8a2fSWingMan Kwok spin_unlock_bh(&gbe_dev->hw_stats_lock); 3633489e8a2fSWingMan Kwok 3634e99e88a9SKees Cook timer_setup(&gbe_dev->timer, netcp_ethss_timer, 0); 36356f8d3f33SWingman Kwok gbe_dev->timer.expires = jiffies + GBE_TIMER_INTERVAL; 36366f8d3f33SWingman Kwok add_timer(&gbe_dev->timer); 36376f8d3f33SWingman Kwok *inst_priv = gbe_dev; 36386f8d3f33SWingman Kwok return 0; 36396f8d3f33SWingman Kwok 364031a184b7SKaricheri, Muralidharan free_sec_ports: 364131a184b7SKaricheri, Muralidharan free_secondary_ports(gbe_dev); 36426f8d3f33SWingman Kwok return ret; 36436f8d3f33SWingman Kwok } 36446f8d3f33SWingman Kwok 36456f8d3f33SWingman Kwok static int gbe_attach(void *inst_priv, struct net_device *ndev, 36466f8d3f33SWingman Kwok struct device_node *node, void **intf_priv) 36476f8d3f33SWingman Kwok { 36486f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = inst_priv; 36496f8d3f33SWingman Kwok struct gbe_intf *gbe_intf; 36506f8d3f33SWingman Kwok int ret; 36516f8d3f33SWingman Kwok 36526f8d3f33SWingman Kwok if (!node) { 36536f8d3f33SWingman Kwok dev_err(gbe_dev->dev, "interface node not available\n"); 36546f8d3f33SWingman Kwok return -ENODEV; 36556f8d3f33SWingman Kwok } 36566f8d3f33SWingman Kwok 36576f8d3f33SWingman Kwok gbe_intf = devm_kzalloc(gbe_dev->dev, sizeof(*gbe_intf), GFP_KERNEL); 36586f8d3f33SWingman Kwok if (!gbe_intf) 36596f8d3f33SWingman Kwok return -ENOMEM; 36606f8d3f33SWingman Kwok 36616f8d3f33SWingman Kwok gbe_intf->ndev = ndev; 36626f8d3f33SWingman Kwok gbe_intf->dev = gbe_dev->dev; 36636f8d3f33SWingman Kwok gbe_intf->gbe_dev = gbe_dev; 36646f8d3f33SWingman Kwok 36656f8d3f33SWingman Kwok gbe_intf->slave = devm_kzalloc(gbe_dev->dev, 36666f8d3f33SWingman Kwok sizeof(*gbe_intf->slave), 36676f8d3f33SWingman Kwok GFP_KERNEL); 36686f8d3f33SWingman Kwok if (!gbe_intf->slave) { 36696f8d3f33SWingman Kwok ret = -ENOMEM; 36706f8d3f33SWingman Kwok goto fail; 36716f8d3f33SWingman Kwok } 36726f8d3f33SWingman Kwok 36736f8d3f33SWingman Kwok if (init_slave(gbe_dev, gbe_intf->slave, node)) { 36746f8d3f33SWingman Kwok ret = -ENODEV; 36756f8d3f33SWingman Kwok goto fail; 36766f8d3f33SWingman Kwok } 36776f8d3f33SWingman Kwok 36786f8d3f33SWingman Kwok gbe_intf->tx_pipe = gbe_dev->tx_pipe; 36796f8d3f33SWingman Kwok ndev->ethtool_ops = &keystone_ethtool_ops; 36806f8d3f33SWingman Kwok list_add_tail(&gbe_intf->gbe_intf_list, &gbe_dev->gbe_intf_head); 36816f8d3f33SWingman Kwok *intf_priv = gbe_intf; 36826f8d3f33SWingman Kwok return 0; 36836f8d3f33SWingman Kwok 36846f8d3f33SWingman Kwok fail: 36856f8d3f33SWingman Kwok if (gbe_intf->slave) 36866f8d3f33SWingman Kwok devm_kfree(gbe_dev->dev, gbe_intf->slave); 36876f8d3f33SWingman Kwok if (gbe_intf) 36886f8d3f33SWingman Kwok devm_kfree(gbe_dev->dev, gbe_intf); 36896f8d3f33SWingman Kwok return ret; 36906f8d3f33SWingman Kwok } 36916f8d3f33SWingman Kwok 36926f8d3f33SWingman Kwok static int gbe_release(void *intf_priv) 36936f8d3f33SWingman Kwok { 36946f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv; 36956f8d3f33SWingman Kwok 36966f8d3f33SWingman Kwok gbe_intf->ndev->ethtool_ops = NULL; 36976f8d3f33SWingman Kwok list_del(&gbe_intf->gbe_intf_list); 36986f8d3f33SWingman Kwok devm_kfree(gbe_intf->dev, gbe_intf->slave); 36996f8d3f33SWingman Kwok devm_kfree(gbe_intf->dev, gbe_intf); 37006f8d3f33SWingman Kwok return 0; 37016f8d3f33SWingman Kwok } 37026f8d3f33SWingman Kwok 37036f8d3f33SWingman Kwok static int gbe_remove(struct netcp_device *netcp_device, void *inst_priv) 37046f8d3f33SWingman Kwok { 37056f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = inst_priv; 37066f8d3f33SWingman Kwok 37076f8d3f33SWingman Kwok del_timer_sync(&gbe_dev->timer); 37086246168bSWingMan Kwok cpts_release(gbe_dev->cpts); 37096f8d3f33SWingman Kwok cpsw_ale_stop(gbe_dev->ale); 37106f8d3f33SWingman Kwok netcp_txpipe_close(&gbe_dev->tx_pipe); 37116f8d3f33SWingman Kwok free_secondary_ports(gbe_dev); 37126f8d3f33SWingman Kwok 37136f8d3f33SWingman Kwok if (!list_empty(&gbe_dev->gbe_intf_head)) 371431a184b7SKaricheri, Muralidharan dev_alert(gbe_dev->dev, 371531a184b7SKaricheri, Muralidharan "unreleased ethss interfaces present\n"); 37166f8d3f33SWingman Kwok 37176f8d3f33SWingman Kwok return 0; 37186f8d3f33SWingman Kwok } 37196f8d3f33SWingman Kwok 37206f8d3f33SWingman Kwok static struct netcp_module gbe_module = { 37216f8d3f33SWingman Kwok .name = GBE_MODULE_NAME, 37226f8d3f33SWingman Kwok .owner = THIS_MODULE, 37236f8d3f33SWingman Kwok .primary = true, 37246f8d3f33SWingman Kwok .probe = gbe_probe, 37256f8d3f33SWingman Kwok .open = gbe_open, 37266f8d3f33SWingman Kwok .close = gbe_close, 37276f8d3f33SWingman Kwok .remove = gbe_remove, 37286f8d3f33SWingman Kwok .attach = gbe_attach, 37296f8d3f33SWingman Kwok .release = gbe_release, 37306f8d3f33SWingman Kwok .add_addr = gbe_add_addr, 37316f8d3f33SWingman Kwok .del_addr = gbe_del_addr, 37326f8d3f33SWingman Kwok .add_vid = gbe_add_vid, 37336f8d3f33SWingman Kwok .del_vid = gbe_del_vid, 37346f8d3f33SWingman Kwok .ioctl = gbe_ioctl, 37356f8d3f33SWingman Kwok }; 37366f8d3f33SWingman Kwok 373790cff9e2SWingman Kwok static struct netcp_module xgbe_module = { 373890cff9e2SWingman Kwok .name = XGBE_MODULE_NAME, 373990cff9e2SWingman Kwok .owner = THIS_MODULE, 374090cff9e2SWingman Kwok .primary = true, 374190cff9e2SWingman Kwok .probe = gbe_probe, 374290cff9e2SWingman Kwok .open = gbe_open, 374390cff9e2SWingman Kwok .close = gbe_close, 374490cff9e2SWingman Kwok .remove = gbe_remove, 374590cff9e2SWingman Kwok .attach = gbe_attach, 374690cff9e2SWingman Kwok .release = gbe_release, 374790cff9e2SWingman Kwok .add_addr = gbe_add_addr, 374890cff9e2SWingman Kwok .del_addr = gbe_del_addr, 374990cff9e2SWingman Kwok .add_vid = gbe_add_vid, 375090cff9e2SWingman Kwok .del_vid = gbe_del_vid, 375190cff9e2SWingman Kwok .ioctl = gbe_ioctl, 375290cff9e2SWingman Kwok }; 375390cff9e2SWingman Kwok 37546f8d3f33SWingman Kwok static int __init keystone_gbe_init(void) 37556f8d3f33SWingman Kwok { 37566f8d3f33SWingman Kwok int ret; 37576f8d3f33SWingman Kwok 37586f8d3f33SWingman Kwok ret = netcp_register_module(&gbe_module); 37596f8d3f33SWingman Kwok if (ret) 37606f8d3f33SWingman Kwok return ret; 37616f8d3f33SWingman Kwok 376290cff9e2SWingman Kwok ret = netcp_register_module(&xgbe_module); 376390cff9e2SWingman Kwok if (ret) 376490cff9e2SWingman Kwok return ret; 376590cff9e2SWingman Kwok 37666f8d3f33SWingman Kwok return 0; 37676f8d3f33SWingman Kwok } 37686f8d3f33SWingman Kwok module_init(keystone_gbe_init); 37696f8d3f33SWingman Kwok 37706f8d3f33SWingman Kwok static void __exit keystone_gbe_exit(void) 37716f8d3f33SWingman Kwok { 37726f8d3f33SWingman Kwok netcp_unregister_module(&gbe_module); 377390cff9e2SWingman Kwok netcp_unregister_module(&xgbe_module); 37746f8d3f33SWingman Kwok } 37756f8d3f33SWingman Kwok module_exit(keystone_gbe_exit); 377658c11b5fSKaricheri, Muralidharan 377758c11b5fSKaricheri, Muralidharan MODULE_LICENSE("GPL v2"); 377858c11b5fSKaricheri, Muralidharan MODULE_DESCRIPTION("TI NETCP ETHSS driver for Keystone SOCs"); 377958c11b5fSKaricheri, Muralidharan MODULE_AUTHOR("Sandeep Nair <sandeep_n@ti.com"); 3780