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> 266f8d3f33SWingman Kwok #include <linux/ethtool.h> 276f8d3f33SWingman Kwok 286f8d3f33SWingman Kwok #include "cpsw_ale.h" 296f8d3f33SWingman Kwok #include "netcp.h" 306f8d3f33SWingman Kwok 316f8d3f33SWingman Kwok #define NETCP_DRIVER_NAME "TI KeyStone Ethernet Driver" 326f8d3f33SWingman Kwok #define NETCP_DRIVER_VERSION "v1.0" 336f8d3f33SWingman Kwok 346f8d3f33SWingman Kwok #define GBE_IDENT(reg) ((reg >> 16) & 0xffff) 356f8d3f33SWingman Kwok #define GBE_MAJOR_VERSION(reg) (reg >> 8 & 0x7) 366f8d3f33SWingman Kwok #define GBE_MINOR_VERSION(reg) (reg & 0xff) 376f8d3f33SWingman Kwok #define GBE_RTL_VERSION(reg) ((reg >> 11) & 0x1f) 386f8d3f33SWingman Kwok 396f8d3f33SWingman Kwok /* 1G Ethernet SS defines */ 406f8d3f33SWingman Kwok #define GBE_MODULE_NAME "netcp-gbe" 416f8d3f33SWingman Kwok #define GBE_SS_VERSION_14 0x4ed21104 426f8d3f33SWingman Kwok 4321e0e0ddSKaricheri, Muralidharan #define GBE_SS_REG_INDEX 0 4421e0e0ddSKaricheri, Muralidharan #define GBE_SGMII34_REG_INDEX 1 4521e0e0ddSKaricheri, Muralidharan #define GBE_SM_REG_INDEX 2 4621e0e0ddSKaricheri, Muralidharan /* offset relative to base of GBE_SS_REG_INDEX */ 476f8d3f33SWingman Kwok #define GBE13_SGMII_MODULE_OFFSET 0x100 4821e0e0ddSKaricheri, Muralidharan /* offset relative to base of GBE_SM_REG_INDEX */ 4921e0e0ddSKaricheri, Muralidharan #define GBE13_HOST_PORT_OFFSET 0x34 5021e0e0ddSKaricheri, Muralidharan #define GBE13_SLAVE_PORT_OFFSET 0x60 5121e0e0ddSKaricheri, Muralidharan #define GBE13_EMAC_OFFSET 0x100 5221e0e0ddSKaricheri, Muralidharan #define GBE13_SLAVE_PORT2_OFFSET 0x200 5321e0e0ddSKaricheri, Muralidharan #define GBE13_HW_STATS_OFFSET 0x300 5421e0e0ddSKaricheri, Muralidharan #define GBE13_ALE_OFFSET 0x600 556f8d3f33SWingman Kwok #define GBE13_HOST_PORT_NUM 0 566f8d3f33SWingman Kwok #define GBE13_NUM_ALE_ENTRIES 1024 576f8d3f33SWingman Kwok 589a391c7bSWingMan Kwok /* 1G Ethernet NU SS defines */ 599a391c7bSWingMan Kwok #define GBENU_MODULE_NAME "netcp-gbenu" 609a391c7bSWingMan Kwok #define GBE_SS_ID_NU 0x4ee6 619a391c7bSWingMan Kwok #define GBE_SS_ID_2U 0x4ee8 629a391c7bSWingMan Kwok 639a391c7bSWingMan Kwok #define IS_SS_ID_MU(d) \ 649a391c7bSWingMan Kwok ((GBE_IDENT((d)->ss_version) == GBE_SS_ID_NU) || \ 659a391c7bSWingMan Kwok (GBE_IDENT((d)->ss_version) == GBE_SS_ID_2U)) 669a391c7bSWingMan Kwok 679a391c7bSWingMan Kwok #define IS_SS_ID_NU(d) \ 689a391c7bSWingMan Kwok (GBE_IDENT((d)->ss_version) == GBE_SS_ID_NU) 699a391c7bSWingMan Kwok 709a391c7bSWingMan Kwok #define GBENU_SS_REG_INDEX 0 719a391c7bSWingMan Kwok #define GBENU_SM_REG_INDEX 1 729a391c7bSWingMan Kwok #define GBENU_SGMII_MODULE_OFFSET 0x100 739a391c7bSWingMan Kwok #define GBENU_HOST_PORT_OFFSET 0x1000 749a391c7bSWingMan Kwok #define GBENU_SLAVE_PORT_OFFSET 0x2000 759a391c7bSWingMan Kwok #define GBENU_EMAC_OFFSET 0x2330 769a391c7bSWingMan Kwok #define GBENU_HW_STATS_OFFSET 0x1a000 779a391c7bSWingMan Kwok #define GBENU_ALE_OFFSET 0x1e000 789a391c7bSWingMan Kwok #define GBENU_HOST_PORT_NUM 0 799a391c7bSWingMan Kwok #define GBENU_NUM_ALE_ENTRIES 1024 809a391c7bSWingMan Kwok 8190cff9e2SWingman Kwok /* 10G Ethernet SS defines */ 8290cff9e2SWingman Kwok #define XGBE_MODULE_NAME "netcp-xgbe" 8390cff9e2SWingman Kwok #define XGBE_SS_VERSION_10 0x4ee42100 8490cff9e2SWingman Kwok 8521e0e0ddSKaricheri, Muralidharan #define XGBE_SS_REG_INDEX 0 8621e0e0ddSKaricheri, Muralidharan #define XGBE_SM_REG_INDEX 1 8721e0e0ddSKaricheri, Muralidharan #define XGBE_SERDES_REG_INDEX 2 8821e0e0ddSKaricheri, Muralidharan 8921e0e0ddSKaricheri, Muralidharan /* offset relative to base of XGBE_SS_REG_INDEX */ 9090cff9e2SWingman Kwok #define XGBE10_SGMII_MODULE_OFFSET 0x100 9121e0e0ddSKaricheri, Muralidharan /* offset relative to base of XGBE_SM_REG_INDEX */ 9221e0e0ddSKaricheri, Muralidharan #define XGBE10_HOST_PORT_OFFSET 0x34 9321e0e0ddSKaricheri, Muralidharan #define XGBE10_SLAVE_PORT_OFFSET 0x64 9421e0e0ddSKaricheri, Muralidharan #define XGBE10_EMAC_OFFSET 0x400 9521e0e0ddSKaricheri, Muralidharan #define XGBE10_ALE_OFFSET 0x700 9621e0e0ddSKaricheri, Muralidharan #define XGBE10_HW_STATS_OFFSET 0x800 9790cff9e2SWingman Kwok #define XGBE10_HOST_PORT_NUM 0 9890cff9e2SWingman Kwok #define XGBE10_NUM_ALE_ENTRIES 1024 9990cff9e2SWingman Kwok 1006f8d3f33SWingman Kwok #define GBE_TIMER_INTERVAL (HZ / 2) 1016f8d3f33SWingman Kwok 1026f8d3f33SWingman Kwok /* Soft reset register values */ 1036f8d3f33SWingman Kwok #define SOFT_RESET_MASK BIT(0) 1046f8d3f33SWingman Kwok #define SOFT_RESET BIT(0) 1056f8d3f33SWingman Kwok #define DEVICE_EMACSL_RESET_POLL_COUNT 100 1066f8d3f33SWingman Kwok #define GMACSL_RET_WARN_RESET_INCOMPLETE -2 1076f8d3f33SWingman Kwok 1086f8d3f33SWingman Kwok #define MACSL_RX_ENABLE_CSF BIT(23) 1096f8d3f33SWingman Kwok #define MACSL_ENABLE_EXT_CTL BIT(18) 11090cff9e2SWingman Kwok #define MACSL_XGMII_ENABLE BIT(13) 11190cff9e2SWingman Kwok #define MACSL_XGIG_MODE BIT(8) 1126f8d3f33SWingman Kwok #define MACSL_GIG_MODE BIT(7) 1136f8d3f33SWingman Kwok #define MACSL_GMII_ENABLE BIT(5) 1146f8d3f33SWingman Kwok #define MACSL_FULLDUPLEX BIT(0) 1156f8d3f33SWingman Kwok 1166f8d3f33SWingman Kwok #define GBE_CTL_P0_ENABLE BIT(2) 1179a391c7bSWingMan Kwok #define GBE13_REG_VAL_STAT_ENABLE_ALL 0xff 11890cff9e2SWingman Kwok #define XGBE_REG_VAL_STAT_ENABLE_ALL 0xf 1196f8d3f33SWingman Kwok #define GBE_STATS_CD_SEL BIT(28) 1206f8d3f33SWingman Kwok 1216f8d3f33SWingman Kwok #define GBE_PORT_MASK(x) (BIT(x) - 1) 1226f8d3f33SWingman Kwok #define GBE_MASK_NO_PORTS 0 1236f8d3f33SWingman Kwok 1246f8d3f33SWingman Kwok #define GBE_DEF_1G_MAC_CONTROL \ 1256f8d3f33SWingman Kwok (MACSL_GIG_MODE | MACSL_GMII_ENABLE | \ 1266f8d3f33SWingman Kwok MACSL_ENABLE_EXT_CTL | MACSL_RX_ENABLE_CSF) 1276f8d3f33SWingman Kwok 12890cff9e2SWingman Kwok #define GBE_DEF_10G_MAC_CONTROL \ 12990cff9e2SWingman Kwok (MACSL_XGIG_MODE | MACSL_XGMII_ENABLE | \ 13090cff9e2SWingman Kwok MACSL_ENABLE_EXT_CTL | MACSL_RX_ENABLE_CSF) 13190cff9e2SWingman Kwok 1326f8d3f33SWingman Kwok #define GBE_STATSA_MODULE 0 1336f8d3f33SWingman Kwok #define GBE_STATSB_MODULE 1 1346f8d3f33SWingman Kwok #define GBE_STATSC_MODULE 2 1356f8d3f33SWingman Kwok #define GBE_STATSD_MODULE 3 1366f8d3f33SWingman Kwok 1379a391c7bSWingMan Kwok #define GBENU_STATS0_MODULE 0 1389a391c7bSWingMan Kwok #define GBENU_STATS1_MODULE 1 1399a391c7bSWingMan Kwok #define GBENU_STATS2_MODULE 2 1409a391c7bSWingMan Kwok #define GBENU_STATS3_MODULE 3 1419a391c7bSWingMan Kwok #define GBENU_STATS4_MODULE 4 1429a391c7bSWingMan Kwok #define GBENU_STATS5_MODULE 5 1439a391c7bSWingMan Kwok #define GBENU_STATS6_MODULE 6 1449a391c7bSWingMan Kwok #define GBENU_STATS7_MODULE 7 1459a391c7bSWingMan Kwok #define GBENU_STATS8_MODULE 8 1469a391c7bSWingMan Kwok 14790cff9e2SWingman Kwok #define XGBE_STATS0_MODULE 0 14890cff9e2SWingman Kwok #define XGBE_STATS1_MODULE 1 14990cff9e2SWingman Kwok #define XGBE_STATS2_MODULE 2 15090cff9e2SWingman Kwok 1516f8d3f33SWingman Kwok /* s: 0-based slave_port */ 1526f8d3f33SWingman Kwok #define SGMII_BASE(s) \ 1536f8d3f33SWingman Kwok (((s) < 2) ? gbe_dev->sgmii_port_regs : gbe_dev->sgmii_port34_regs) 1546f8d3f33SWingman Kwok 1556f8d3f33SWingman Kwok #define GBE_TX_QUEUE 648 1566f8d3f33SWingman Kwok #define GBE_TXHOOK_ORDER 0 1576f8d3f33SWingman Kwok #define GBE_DEFAULT_ALE_AGEOUT 30 15890cff9e2SWingman Kwok #define SLAVE_LINK_IS_XGMII(s) ((s)->link_interface >= XGMII_LINK_MAC_PHY) 1596f8d3f33SWingman Kwok #define NETCP_LINK_STATE_INVALID -1 1606f8d3f33SWingman Kwok 1616f8d3f33SWingman Kwok #define GBE_SET_REG_OFS(p, rb, rn) p->rb##_ofs.rn = \ 1626f8d3f33SWingman Kwok offsetof(struct gbe##_##rb, rn) 1639a391c7bSWingMan Kwok #define GBENU_SET_REG_OFS(p, rb, rn) p->rb##_ofs.rn = \ 1649a391c7bSWingMan Kwok offsetof(struct gbenu##_##rb, rn) 16590cff9e2SWingman Kwok #define XGBE_SET_REG_OFS(p, rb, rn) p->rb##_ofs.rn = \ 16690cff9e2SWingman Kwok offsetof(struct xgbe##_##rb, rn) 1676f8d3f33SWingman Kwok #define GBE_REG_ADDR(p, rb, rn) (p->rb + p->rb##_ofs.rn) 1686f8d3f33SWingman Kwok 1699a391c7bSWingMan Kwok #define HOST_TX_PRI_MAP_DEFAULT 0x00000000 1709a391c7bSWingMan Kwok 17190cff9e2SWingman Kwok struct xgbe_ss_regs { 17290cff9e2SWingman Kwok u32 id_ver; 17390cff9e2SWingman Kwok u32 synce_count; 17490cff9e2SWingman Kwok u32 synce_mux; 17590cff9e2SWingman Kwok u32 control; 17690cff9e2SWingman Kwok }; 17790cff9e2SWingman Kwok 17890cff9e2SWingman Kwok struct xgbe_switch_regs { 17990cff9e2SWingman Kwok u32 id_ver; 18090cff9e2SWingman Kwok u32 control; 18190cff9e2SWingman Kwok u32 emcontrol; 18290cff9e2SWingman Kwok u32 stat_port_en; 18390cff9e2SWingman Kwok u32 ptype; 18490cff9e2SWingman Kwok u32 soft_idle; 18590cff9e2SWingman Kwok u32 thru_rate; 18690cff9e2SWingman Kwok u32 gap_thresh; 18790cff9e2SWingman Kwok u32 tx_start_wds; 18890cff9e2SWingman Kwok u32 flow_control; 18990cff9e2SWingman Kwok u32 cppi_thresh; 19090cff9e2SWingman Kwok }; 19190cff9e2SWingman Kwok 19290cff9e2SWingman Kwok struct xgbe_port_regs { 19390cff9e2SWingman Kwok u32 blk_cnt; 19490cff9e2SWingman Kwok u32 port_vlan; 19590cff9e2SWingman Kwok u32 tx_pri_map; 19690cff9e2SWingman Kwok u32 sa_lo; 19790cff9e2SWingman Kwok u32 sa_hi; 19890cff9e2SWingman Kwok u32 ts_ctl; 19990cff9e2SWingman Kwok u32 ts_seq_ltype; 20090cff9e2SWingman Kwok u32 ts_vlan; 20190cff9e2SWingman Kwok u32 ts_ctl_ltype2; 20290cff9e2SWingman Kwok u32 ts_ctl2; 20390cff9e2SWingman Kwok u32 control; 20490cff9e2SWingman Kwok }; 20590cff9e2SWingman Kwok 20690cff9e2SWingman Kwok struct xgbe_host_port_regs { 20790cff9e2SWingman Kwok u32 blk_cnt; 20890cff9e2SWingman Kwok u32 port_vlan; 20990cff9e2SWingman Kwok u32 tx_pri_map; 21090cff9e2SWingman Kwok u32 src_id; 21190cff9e2SWingman Kwok u32 rx_pri_map; 21290cff9e2SWingman Kwok u32 rx_maxlen; 21390cff9e2SWingman Kwok }; 21490cff9e2SWingman Kwok 21590cff9e2SWingman Kwok struct xgbe_emac_regs { 21690cff9e2SWingman Kwok u32 id_ver; 21790cff9e2SWingman Kwok u32 mac_control; 21890cff9e2SWingman Kwok u32 mac_status; 21990cff9e2SWingman Kwok u32 soft_reset; 22090cff9e2SWingman Kwok u32 rx_maxlen; 22190cff9e2SWingman Kwok u32 __reserved_0; 22290cff9e2SWingman Kwok u32 rx_pause; 22390cff9e2SWingman Kwok u32 tx_pause; 22490cff9e2SWingman Kwok u32 em_control; 22590cff9e2SWingman Kwok u32 __reserved_1; 22690cff9e2SWingman Kwok u32 tx_gap; 22790cff9e2SWingman Kwok u32 rsvd[4]; 22890cff9e2SWingman Kwok }; 22990cff9e2SWingman Kwok 23090cff9e2SWingman Kwok struct xgbe_host_hw_stats { 23190cff9e2SWingman Kwok u32 rx_good_frames; 23290cff9e2SWingman Kwok u32 rx_broadcast_frames; 23390cff9e2SWingman Kwok u32 rx_multicast_frames; 23490cff9e2SWingman Kwok u32 __rsvd_0[3]; 23590cff9e2SWingman Kwok u32 rx_oversized_frames; 23690cff9e2SWingman Kwok u32 __rsvd_1; 23790cff9e2SWingman Kwok u32 rx_undersized_frames; 23890cff9e2SWingman Kwok u32 __rsvd_2; 23990cff9e2SWingman Kwok u32 overrun_type4; 24090cff9e2SWingman Kwok u32 overrun_type5; 24190cff9e2SWingman Kwok u32 rx_bytes; 24290cff9e2SWingman Kwok u32 tx_good_frames; 24390cff9e2SWingman Kwok u32 tx_broadcast_frames; 24490cff9e2SWingman Kwok u32 tx_multicast_frames; 24590cff9e2SWingman Kwok u32 __rsvd_3[9]; 24690cff9e2SWingman Kwok u32 tx_bytes; 24790cff9e2SWingman Kwok u32 tx_64byte_frames; 24890cff9e2SWingman Kwok u32 tx_65_to_127byte_frames; 24990cff9e2SWingman Kwok u32 tx_128_to_255byte_frames; 25090cff9e2SWingman Kwok u32 tx_256_to_511byte_frames; 25190cff9e2SWingman Kwok u32 tx_512_to_1023byte_frames; 25290cff9e2SWingman Kwok u32 tx_1024byte_frames; 25390cff9e2SWingman Kwok u32 net_bytes; 25490cff9e2SWingman Kwok u32 rx_sof_overruns; 25590cff9e2SWingman Kwok u32 rx_mof_overruns; 25690cff9e2SWingman Kwok u32 rx_dma_overruns; 25790cff9e2SWingman Kwok }; 25890cff9e2SWingman Kwok 25990cff9e2SWingman Kwok struct xgbe_hw_stats { 26090cff9e2SWingman Kwok u32 rx_good_frames; 26190cff9e2SWingman Kwok u32 rx_broadcast_frames; 26290cff9e2SWingman Kwok u32 rx_multicast_frames; 26390cff9e2SWingman Kwok u32 rx_pause_frames; 26490cff9e2SWingman Kwok u32 rx_crc_errors; 26590cff9e2SWingman Kwok u32 rx_align_code_errors; 26690cff9e2SWingman Kwok u32 rx_oversized_frames; 26790cff9e2SWingman Kwok u32 rx_jabber_frames; 26890cff9e2SWingman Kwok u32 rx_undersized_frames; 26990cff9e2SWingman Kwok u32 rx_fragments; 27090cff9e2SWingman Kwok u32 overrun_type4; 27190cff9e2SWingman Kwok u32 overrun_type5; 27290cff9e2SWingman Kwok u32 rx_bytes; 27390cff9e2SWingman Kwok u32 tx_good_frames; 27490cff9e2SWingman Kwok u32 tx_broadcast_frames; 27590cff9e2SWingman Kwok u32 tx_multicast_frames; 27690cff9e2SWingman Kwok u32 tx_pause_frames; 27790cff9e2SWingman Kwok u32 tx_deferred_frames; 27890cff9e2SWingman Kwok u32 tx_collision_frames; 27990cff9e2SWingman Kwok u32 tx_single_coll_frames; 28090cff9e2SWingman Kwok u32 tx_mult_coll_frames; 28190cff9e2SWingman Kwok u32 tx_excessive_collisions; 28290cff9e2SWingman Kwok u32 tx_late_collisions; 28390cff9e2SWingman Kwok u32 tx_underrun; 28490cff9e2SWingman Kwok u32 tx_carrier_sense_errors; 28590cff9e2SWingman Kwok u32 tx_bytes; 28690cff9e2SWingman Kwok u32 tx_64byte_frames; 28790cff9e2SWingman Kwok u32 tx_65_to_127byte_frames; 28890cff9e2SWingman Kwok u32 tx_128_to_255byte_frames; 28990cff9e2SWingman Kwok u32 tx_256_to_511byte_frames; 29090cff9e2SWingman Kwok u32 tx_512_to_1023byte_frames; 29190cff9e2SWingman Kwok u32 tx_1024byte_frames; 29290cff9e2SWingman Kwok u32 net_bytes; 29390cff9e2SWingman Kwok u32 rx_sof_overruns; 29490cff9e2SWingman Kwok u32 rx_mof_overruns; 29590cff9e2SWingman Kwok u32 rx_dma_overruns; 29690cff9e2SWingman Kwok }; 29790cff9e2SWingman Kwok 2989a391c7bSWingMan Kwok struct gbenu_ss_regs { 2999a391c7bSWingMan Kwok u32 id_ver; 3009a391c7bSWingMan Kwok u32 synce_count; /* NU */ 3019a391c7bSWingMan Kwok u32 synce_mux; /* NU */ 3029a391c7bSWingMan Kwok u32 control; /* 2U */ 3039a391c7bSWingMan Kwok u32 __rsvd_0[2]; /* 2U */ 3049a391c7bSWingMan Kwok u32 rgmii_status; /* 2U */ 3059a391c7bSWingMan Kwok u32 ss_status; /* 2U */ 3069a391c7bSWingMan Kwok }; 3079a391c7bSWingMan Kwok 3089a391c7bSWingMan Kwok struct gbenu_switch_regs { 3099a391c7bSWingMan Kwok u32 id_ver; 3109a391c7bSWingMan Kwok u32 control; 3119a391c7bSWingMan Kwok u32 __rsvd_0[2]; 3129a391c7bSWingMan Kwok u32 emcontrol; 3139a391c7bSWingMan Kwok u32 stat_port_en; 3149a391c7bSWingMan Kwok u32 ptype; /* NU */ 3159a391c7bSWingMan Kwok u32 soft_idle; 3169a391c7bSWingMan Kwok u32 thru_rate; /* NU */ 3179a391c7bSWingMan Kwok u32 gap_thresh; /* NU */ 3189a391c7bSWingMan Kwok u32 tx_start_wds; /* NU */ 3199a391c7bSWingMan Kwok u32 eee_prescale; /* 2U */ 3209a391c7bSWingMan Kwok u32 tx_g_oflow_thresh_set; /* NU */ 3219a391c7bSWingMan Kwok u32 tx_g_oflow_thresh_clr; /* NU */ 3229a391c7bSWingMan Kwok u32 tx_g_buf_thresh_set_l; /* NU */ 3239a391c7bSWingMan Kwok u32 tx_g_buf_thresh_set_h; /* NU */ 3249a391c7bSWingMan Kwok u32 tx_g_buf_thresh_clr_l; /* NU */ 3259a391c7bSWingMan Kwok u32 tx_g_buf_thresh_clr_h; /* NU */ 3269a391c7bSWingMan Kwok }; 3279a391c7bSWingMan Kwok 3289a391c7bSWingMan Kwok struct gbenu_port_regs { 3299a391c7bSWingMan Kwok u32 __rsvd_0; 3309a391c7bSWingMan Kwok u32 control; 3319a391c7bSWingMan Kwok u32 max_blks; /* 2U */ 3329a391c7bSWingMan Kwok u32 mem_align1; 3339a391c7bSWingMan Kwok u32 blk_cnt; 3349a391c7bSWingMan Kwok u32 port_vlan; 3359a391c7bSWingMan Kwok u32 tx_pri_map; /* NU */ 3369a391c7bSWingMan Kwok u32 pri_ctl; /* 2U */ 3379a391c7bSWingMan Kwok u32 rx_pri_map; 3389a391c7bSWingMan Kwok u32 rx_maxlen; 3399a391c7bSWingMan Kwok u32 tx_blks_pri; /* NU */ 3409a391c7bSWingMan Kwok u32 __rsvd_1; 3419a391c7bSWingMan Kwok u32 idle2lpi; /* 2U */ 3429a391c7bSWingMan Kwok u32 lpi2idle; /* 2U */ 3439a391c7bSWingMan Kwok u32 eee_status; /* 2U */ 3449a391c7bSWingMan Kwok u32 __rsvd_2; 3459a391c7bSWingMan Kwok u32 __rsvd_3[176]; /* NU: more to add */ 3469a391c7bSWingMan Kwok u32 __rsvd_4[2]; 3479a391c7bSWingMan Kwok u32 sa_lo; 3489a391c7bSWingMan Kwok u32 sa_hi; 3499a391c7bSWingMan Kwok u32 ts_ctl; 3509a391c7bSWingMan Kwok u32 ts_seq_ltype; 3519a391c7bSWingMan Kwok u32 ts_vlan; 3529a391c7bSWingMan Kwok u32 ts_ctl_ltype2; 3539a391c7bSWingMan Kwok u32 ts_ctl2; 3549a391c7bSWingMan Kwok }; 3559a391c7bSWingMan Kwok 3569a391c7bSWingMan Kwok struct gbenu_host_port_regs { 3579a391c7bSWingMan Kwok u32 __rsvd_0; 3589a391c7bSWingMan Kwok u32 control; 3599a391c7bSWingMan Kwok u32 flow_id_offset; /* 2U */ 3609a391c7bSWingMan Kwok u32 __rsvd_1; 3619a391c7bSWingMan Kwok u32 blk_cnt; 3629a391c7bSWingMan Kwok u32 port_vlan; 3639a391c7bSWingMan Kwok u32 tx_pri_map; /* NU */ 3649a391c7bSWingMan Kwok u32 pri_ctl; 3659a391c7bSWingMan Kwok u32 rx_pri_map; 3669a391c7bSWingMan Kwok u32 rx_maxlen; 3679a391c7bSWingMan Kwok u32 tx_blks_pri; /* NU */ 3689a391c7bSWingMan Kwok u32 __rsvd_2; 3699a391c7bSWingMan Kwok u32 idle2lpi; /* 2U */ 3709a391c7bSWingMan Kwok u32 lpi2wake; /* 2U */ 3719a391c7bSWingMan Kwok u32 eee_status; /* 2U */ 3729a391c7bSWingMan Kwok u32 __rsvd_3; 3739a391c7bSWingMan Kwok u32 __rsvd_4[184]; /* NU */ 3749a391c7bSWingMan Kwok u32 host_blks_pri; /* NU */ 3759a391c7bSWingMan Kwok }; 3769a391c7bSWingMan Kwok 3779a391c7bSWingMan Kwok struct gbenu_emac_regs { 3789a391c7bSWingMan Kwok u32 mac_control; 3799a391c7bSWingMan Kwok u32 mac_status; 3809a391c7bSWingMan Kwok u32 soft_reset; 3819a391c7bSWingMan Kwok u32 boff_test; 3829a391c7bSWingMan Kwok u32 rx_pause; 3839a391c7bSWingMan Kwok u32 __rsvd_0[11]; /* NU */ 3849a391c7bSWingMan Kwok u32 tx_pause; 3859a391c7bSWingMan Kwok u32 __rsvd_1[11]; /* NU */ 3869a391c7bSWingMan Kwok u32 em_control; 3879a391c7bSWingMan Kwok u32 tx_gap; 3889a391c7bSWingMan Kwok }; 3899a391c7bSWingMan Kwok 3909a391c7bSWingMan Kwok /* Some hw stat regs are applicable to slave port only. 3919a391c7bSWingMan Kwok * This is handled by gbenu_et_stats struct. Also some 3929a391c7bSWingMan Kwok * are for SS version NU and some are for 2U. 3939a391c7bSWingMan Kwok */ 3949a391c7bSWingMan Kwok struct gbenu_hw_stats { 3959a391c7bSWingMan Kwok u32 rx_good_frames; 3969a391c7bSWingMan Kwok u32 rx_broadcast_frames; 3979a391c7bSWingMan Kwok u32 rx_multicast_frames; 3989a391c7bSWingMan Kwok u32 rx_pause_frames; /* slave */ 3999a391c7bSWingMan Kwok u32 rx_crc_errors; 4009a391c7bSWingMan Kwok u32 rx_align_code_errors; /* slave */ 4019a391c7bSWingMan Kwok u32 rx_oversized_frames; 4029a391c7bSWingMan Kwok u32 rx_jabber_frames; /* slave */ 4039a391c7bSWingMan Kwok u32 rx_undersized_frames; 4049a391c7bSWingMan Kwok u32 rx_fragments; /* slave */ 4059a391c7bSWingMan Kwok u32 ale_drop; 4069a391c7bSWingMan Kwok u32 ale_overrun_drop; 4079a391c7bSWingMan Kwok u32 rx_bytes; 4089a391c7bSWingMan Kwok u32 tx_good_frames; 4099a391c7bSWingMan Kwok u32 tx_broadcast_frames; 4109a391c7bSWingMan Kwok u32 tx_multicast_frames; 4119a391c7bSWingMan Kwok u32 tx_pause_frames; /* slave */ 4129a391c7bSWingMan Kwok u32 tx_deferred_frames; /* slave */ 4139a391c7bSWingMan Kwok u32 tx_collision_frames; /* slave */ 4149a391c7bSWingMan Kwok u32 tx_single_coll_frames; /* slave */ 4159a391c7bSWingMan Kwok u32 tx_mult_coll_frames; /* slave */ 4169a391c7bSWingMan Kwok u32 tx_excessive_collisions; /* slave */ 4179a391c7bSWingMan Kwok u32 tx_late_collisions; /* slave */ 4189a391c7bSWingMan Kwok u32 rx_ipg_error; /* slave 10G only */ 4199a391c7bSWingMan Kwok u32 tx_carrier_sense_errors; /* slave */ 4209a391c7bSWingMan Kwok u32 tx_bytes; 4219a391c7bSWingMan Kwok u32 tx_64B_frames; 4229a391c7bSWingMan Kwok u32 tx_65_to_127B_frames; 4239a391c7bSWingMan Kwok u32 tx_128_to_255B_frames; 4249a391c7bSWingMan Kwok u32 tx_256_to_511B_frames; 4259a391c7bSWingMan Kwok u32 tx_512_to_1023B_frames; 4269a391c7bSWingMan Kwok u32 tx_1024B_frames; 4279a391c7bSWingMan Kwok u32 net_bytes; 4289a391c7bSWingMan Kwok u32 rx_bottom_fifo_drop; 4299a391c7bSWingMan Kwok u32 rx_port_mask_drop; 4309a391c7bSWingMan Kwok u32 rx_top_fifo_drop; 4319a391c7bSWingMan Kwok u32 ale_rate_limit_drop; 4329a391c7bSWingMan Kwok u32 ale_vid_ingress_drop; 4339a391c7bSWingMan Kwok u32 ale_da_eq_sa_drop; 4349a391c7bSWingMan Kwok u32 __rsvd_0[3]; 4359a391c7bSWingMan Kwok u32 ale_unknown_ucast; 4369a391c7bSWingMan Kwok u32 ale_unknown_ucast_bytes; 4379a391c7bSWingMan Kwok u32 ale_unknown_mcast; 4389a391c7bSWingMan Kwok u32 ale_unknown_mcast_bytes; 4399a391c7bSWingMan Kwok u32 ale_unknown_bcast; 4409a391c7bSWingMan Kwok u32 ale_unknown_bcast_bytes; 4419a391c7bSWingMan Kwok u32 ale_pol_match; 4429a391c7bSWingMan Kwok u32 ale_pol_match_red; /* NU */ 4439a391c7bSWingMan Kwok u32 ale_pol_match_yellow; /* NU */ 4449a391c7bSWingMan Kwok u32 __rsvd_1[44]; 4459a391c7bSWingMan Kwok u32 tx_mem_protect_err; 4469a391c7bSWingMan Kwok /* following NU only */ 4479a391c7bSWingMan Kwok u32 tx_pri0; 4489a391c7bSWingMan Kwok u32 tx_pri1; 4499a391c7bSWingMan Kwok u32 tx_pri2; 4509a391c7bSWingMan Kwok u32 tx_pri3; 4519a391c7bSWingMan Kwok u32 tx_pri4; 4529a391c7bSWingMan Kwok u32 tx_pri5; 4539a391c7bSWingMan Kwok u32 tx_pri6; 4549a391c7bSWingMan Kwok u32 tx_pri7; 4559a391c7bSWingMan Kwok u32 tx_pri0_bcnt; 4569a391c7bSWingMan Kwok u32 tx_pri1_bcnt; 4579a391c7bSWingMan Kwok u32 tx_pri2_bcnt; 4589a391c7bSWingMan Kwok u32 tx_pri3_bcnt; 4599a391c7bSWingMan Kwok u32 tx_pri4_bcnt; 4609a391c7bSWingMan Kwok u32 tx_pri5_bcnt; 4619a391c7bSWingMan Kwok u32 tx_pri6_bcnt; 4629a391c7bSWingMan Kwok u32 tx_pri7_bcnt; 4639a391c7bSWingMan Kwok u32 tx_pri0_drop; 4649a391c7bSWingMan Kwok u32 tx_pri1_drop; 4659a391c7bSWingMan Kwok u32 tx_pri2_drop; 4669a391c7bSWingMan Kwok u32 tx_pri3_drop; 4679a391c7bSWingMan Kwok u32 tx_pri4_drop; 4689a391c7bSWingMan Kwok u32 tx_pri5_drop; 4699a391c7bSWingMan Kwok u32 tx_pri6_drop; 4709a391c7bSWingMan Kwok u32 tx_pri7_drop; 4719a391c7bSWingMan Kwok u32 tx_pri0_drop_bcnt; 4729a391c7bSWingMan Kwok u32 tx_pri1_drop_bcnt; 4739a391c7bSWingMan Kwok u32 tx_pri2_drop_bcnt; 4749a391c7bSWingMan Kwok u32 tx_pri3_drop_bcnt; 4759a391c7bSWingMan Kwok u32 tx_pri4_drop_bcnt; 4769a391c7bSWingMan Kwok u32 tx_pri5_drop_bcnt; 4779a391c7bSWingMan Kwok u32 tx_pri6_drop_bcnt; 4789a391c7bSWingMan Kwok u32 tx_pri7_drop_bcnt; 4799a391c7bSWingMan Kwok }; 4809a391c7bSWingMan Kwok 4819a391c7bSWingMan Kwok #define GBENU_HW_STATS_REG_MAP_SZ 0x200 4829a391c7bSWingMan Kwok 4836f8d3f33SWingman Kwok struct gbe_ss_regs { 4846f8d3f33SWingman Kwok u32 id_ver; 4856f8d3f33SWingman Kwok u32 synce_count; 4866f8d3f33SWingman Kwok u32 synce_mux; 4876f8d3f33SWingman Kwok }; 4886f8d3f33SWingman Kwok 4896f8d3f33SWingman Kwok struct gbe_ss_regs_ofs { 4906f8d3f33SWingman Kwok u16 id_ver; 4916f8d3f33SWingman Kwok u16 control; 4926f8d3f33SWingman Kwok }; 4936f8d3f33SWingman Kwok 4946f8d3f33SWingman Kwok struct gbe_switch_regs { 4956f8d3f33SWingman Kwok u32 id_ver; 4966f8d3f33SWingman Kwok u32 control; 4976f8d3f33SWingman Kwok u32 soft_reset; 4986f8d3f33SWingman Kwok u32 stat_port_en; 4996f8d3f33SWingman Kwok u32 ptype; 5006f8d3f33SWingman Kwok u32 soft_idle; 5016f8d3f33SWingman Kwok u32 thru_rate; 5026f8d3f33SWingman Kwok u32 gap_thresh; 5036f8d3f33SWingman Kwok u32 tx_start_wds; 5046f8d3f33SWingman Kwok u32 flow_control; 5056f8d3f33SWingman Kwok }; 5066f8d3f33SWingman Kwok 5076f8d3f33SWingman Kwok struct gbe_switch_regs_ofs { 5086f8d3f33SWingman Kwok u16 id_ver; 5096f8d3f33SWingman Kwok u16 control; 5106f8d3f33SWingman Kwok u16 soft_reset; 5116f8d3f33SWingman Kwok u16 emcontrol; 5126f8d3f33SWingman Kwok u16 stat_port_en; 5136f8d3f33SWingman Kwok u16 ptype; 5146f8d3f33SWingman Kwok u16 flow_control; 5156f8d3f33SWingman Kwok }; 5166f8d3f33SWingman Kwok 5176f8d3f33SWingman Kwok struct gbe_port_regs { 5186f8d3f33SWingman Kwok u32 max_blks; 5196f8d3f33SWingman Kwok u32 blk_cnt; 5206f8d3f33SWingman Kwok u32 port_vlan; 5216f8d3f33SWingman Kwok u32 tx_pri_map; 5226f8d3f33SWingman Kwok u32 sa_lo; 5236f8d3f33SWingman Kwok u32 sa_hi; 5246f8d3f33SWingman Kwok u32 ts_ctl; 5256f8d3f33SWingman Kwok u32 ts_seq_ltype; 5266f8d3f33SWingman Kwok u32 ts_vlan; 5276f8d3f33SWingman Kwok u32 ts_ctl_ltype2; 5286f8d3f33SWingman Kwok u32 ts_ctl2; 5296f8d3f33SWingman Kwok }; 5306f8d3f33SWingman Kwok 5316f8d3f33SWingman Kwok struct gbe_port_regs_ofs { 5326f8d3f33SWingman Kwok u16 port_vlan; 5336f8d3f33SWingman Kwok u16 tx_pri_map; 5346f8d3f33SWingman Kwok u16 sa_lo; 5356f8d3f33SWingman Kwok u16 sa_hi; 5366f8d3f33SWingman Kwok u16 ts_ctl; 5376f8d3f33SWingman Kwok u16 ts_seq_ltype; 5386f8d3f33SWingman Kwok u16 ts_vlan; 5396f8d3f33SWingman Kwok u16 ts_ctl_ltype2; 5406f8d3f33SWingman Kwok u16 ts_ctl2; 5419a391c7bSWingMan Kwok u16 rx_maxlen; /* 2U, NU */ 5426f8d3f33SWingman Kwok }; 5436f8d3f33SWingman Kwok 5446f8d3f33SWingman Kwok struct gbe_host_port_regs { 5456f8d3f33SWingman Kwok u32 src_id; 5466f8d3f33SWingman Kwok u32 port_vlan; 5476f8d3f33SWingman Kwok u32 rx_pri_map; 5486f8d3f33SWingman Kwok u32 rx_maxlen; 5496f8d3f33SWingman Kwok }; 5506f8d3f33SWingman Kwok 5516f8d3f33SWingman Kwok struct gbe_host_port_regs_ofs { 5526f8d3f33SWingman Kwok u16 port_vlan; 5536f8d3f33SWingman Kwok u16 tx_pri_map; 5546f8d3f33SWingman Kwok u16 rx_maxlen; 5556f8d3f33SWingman Kwok }; 5566f8d3f33SWingman Kwok 5576f8d3f33SWingman Kwok struct gbe_emac_regs { 5586f8d3f33SWingman Kwok u32 id_ver; 5596f8d3f33SWingman Kwok u32 mac_control; 5606f8d3f33SWingman Kwok u32 mac_status; 5616f8d3f33SWingman Kwok u32 soft_reset; 5626f8d3f33SWingman Kwok u32 rx_maxlen; 5636f8d3f33SWingman Kwok u32 __reserved_0; 5646f8d3f33SWingman Kwok u32 rx_pause; 5656f8d3f33SWingman Kwok u32 tx_pause; 5666f8d3f33SWingman Kwok u32 __reserved_1; 5676f8d3f33SWingman Kwok u32 rx_pri_map; 5686f8d3f33SWingman Kwok u32 rsvd[6]; 5696f8d3f33SWingman Kwok }; 5706f8d3f33SWingman Kwok 5716f8d3f33SWingman Kwok struct gbe_emac_regs_ofs { 5726f8d3f33SWingman Kwok u16 mac_control; 5736f8d3f33SWingman Kwok u16 soft_reset; 5746f8d3f33SWingman Kwok u16 rx_maxlen; 5756f8d3f33SWingman Kwok }; 5766f8d3f33SWingman Kwok 5776f8d3f33SWingman Kwok struct gbe_hw_stats { 5786f8d3f33SWingman Kwok u32 rx_good_frames; 5796f8d3f33SWingman Kwok u32 rx_broadcast_frames; 5806f8d3f33SWingman Kwok u32 rx_multicast_frames; 5816f8d3f33SWingman Kwok u32 rx_pause_frames; 5826f8d3f33SWingman Kwok u32 rx_crc_errors; 5836f8d3f33SWingman Kwok u32 rx_align_code_errors; 5846f8d3f33SWingman Kwok u32 rx_oversized_frames; 5856f8d3f33SWingman Kwok u32 rx_jabber_frames; 5866f8d3f33SWingman Kwok u32 rx_undersized_frames; 5876f8d3f33SWingman Kwok u32 rx_fragments; 5886f8d3f33SWingman Kwok u32 __pad_0[2]; 5896f8d3f33SWingman Kwok u32 rx_bytes; 5906f8d3f33SWingman Kwok u32 tx_good_frames; 5916f8d3f33SWingman Kwok u32 tx_broadcast_frames; 5926f8d3f33SWingman Kwok u32 tx_multicast_frames; 5936f8d3f33SWingman Kwok u32 tx_pause_frames; 5946f8d3f33SWingman Kwok u32 tx_deferred_frames; 5956f8d3f33SWingman Kwok u32 tx_collision_frames; 5966f8d3f33SWingman Kwok u32 tx_single_coll_frames; 5976f8d3f33SWingman Kwok u32 tx_mult_coll_frames; 5986f8d3f33SWingman Kwok u32 tx_excessive_collisions; 5996f8d3f33SWingman Kwok u32 tx_late_collisions; 6006f8d3f33SWingman Kwok u32 tx_underrun; 6016f8d3f33SWingman Kwok u32 tx_carrier_sense_errors; 6026f8d3f33SWingman Kwok u32 tx_bytes; 6036f8d3f33SWingman Kwok u32 tx_64byte_frames; 6046f8d3f33SWingman Kwok u32 tx_65_to_127byte_frames; 6056f8d3f33SWingman Kwok u32 tx_128_to_255byte_frames; 6066f8d3f33SWingman Kwok u32 tx_256_to_511byte_frames; 6076f8d3f33SWingman Kwok u32 tx_512_to_1023byte_frames; 6086f8d3f33SWingman Kwok u32 tx_1024byte_frames; 6096f8d3f33SWingman Kwok u32 net_bytes; 6106f8d3f33SWingman Kwok u32 rx_sof_overruns; 6116f8d3f33SWingman Kwok u32 rx_mof_overruns; 6126f8d3f33SWingman Kwok u32 rx_dma_overruns; 6136f8d3f33SWingman Kwok }; 6146f8d3f33SWingman Kwok 6159a391c7bSWingMan Kwok #define GBE_MAX_HW_STAT_MODS 9 6166f8d3f33SWingman Kwok #define GBE_HW_STATS_REG_MAP_SZ 0x100 6176f8d3f33SWingman Kwok 6186f8d3f33SWingman Kwok struct gbe_slave { 6196f8d3f33SWingman Kwok void __iomem *port_regs; 6206f8d3f33SWingman Kwok void __iomem *emac_regs; 6216f8d3f33SWingman Kwok struct gbe_port_regs_ofs port_regs_ofs; 6226f8d3f33SWingman Kwok struct gbe_emac_regs_ofs emac_regs_ofs; 6236f8d3f33SWingman Kwok int slave_num; /* 0 based logical number */ 6246f8d3f33SWingman Kwok int port_num; /* actual port number */ 6256f8d3f33SWingman Kwok atomic_t link_state; 6266f8d3f33SWingman Kwok bool open; 6276f8d3f33SWingman Kwok struct phy_device *phy; 6286f8d3f33SWingman Kwok u32 link_interface; 6296f8d3f33SWingman Kwok u32 mac_control; 6306f8d3f33SWingman Kwok u8 phy_port_t; 6316f8d3f33SWingman Kwok struct device_node *phy_node; 6326f8d3f33SWingman Kwok struct list_head slave_list; 6336f8d3f33SWingman Kwok }; 6346f8d3f33SWingman Kwok 6356f8d3f33SWingman Kwok struct gbe_priv { 6366f8d3f33SWingman Kwok struct device *dev; 6376f8d3f33SWingman Kwok struct netcp_device *netcp_device; 6386f8d3f33SWingman Kwok struct timer_list timer; 6396f8d3f33SWingman Kwok u32 num_slaves; 6406f8d3f33SWingman Kwok u32 ale_entries; 6416f8d3f33SWingman Kwok u32 ale_ports; 6426f8d3f33SWingman Kwok bool enable_ale; 6439a391c7bSWingMan Kwok u8 max_num_slaves; 6449a391c7bSWingMan Kwok u8 max_num_ports; /* max_num_slaves + 1 */ 645489e8a2fSWingMan Kwok u8 num_stats_mods; 6466f8d3f33SWingman Kwok struct netcp_tx_pipe tx_pipe; 6476f8d3f33SWingman Kwok 6486f8d3f33SWingman Kwok int host_port; 6496f8d3f33SWingman Kwok u32 rx_packet_max; 6506f8d3f33SWingman Kwok u32 ss_version; 6519a391c7bSWingMan Kwok u32 stats_en_mask; 6526f8d3f33SWingman Kwok 6536f8d3f33SWingman Kwok void __iomem *ss_regs; 6546f8d3f33SWingman Kwok void __iomem *switch_regs; 6556f8d3f33SWingman Kwok void __iomem *host_port_regs; 6566f8d3f33SWingman Kwok void __iomem *ale_reg; 6576f8d3f33SWingman Kwok void __iomem *sgmii_port_regs; 6586f8d3f33SWingman Kwok void __iomem *sgmii_port34_regs; 6596f8d3f33SWingman Kwok void __iomem *xgbe_serdes_regs; 6606f8d3f33SWingman Kwok void __iomem *hw_stats_regs[GBE_MAX_HW_STAT_MODS]; 6616f8d3f33SWingman Kwok 6626f8d3f33SWingman Kwok struct gbe_ss_regs_ofs ss_regs_ofs; 6636f8d3f33SWingman Kwok struct gbe_switch_regs_ofs switch_regs_ofs; 6646f8d3f33SWingman Kwok struct gbe_host_port_regs_ofs host_port_regs_ofs; 6656f8d3f33SWingman Kwok 6666f8d3f33SWingman Kwok struct cpsw_ale *ale; 6676f8d3f33SWingman Kwok unsigned int tx_queue_id; 6686f8d3f33SWingman Kwok const char *dma_chan_name; 6696f8d3f33SWingman Kwok 6706f8d3f33SWingman Kwok struct list_head gbe_intf_head; 6716f8d3f33SWingman Kwok struct list_head secondary_slaves; 6726f8d3f33SWingman Kwok struct net_device *dummy_ndev; 6736f8d3f33SWingman Kwok 6746f8d3f33SWingman Kwok u64 *hw_stats; 675489e8a2fSWingMan Kwok u32 *hw_stats_prev; 6766f8d3f33SWingman Kwok const struct netcp_ethtool_stat *et_stats; 6776f8d3f33SWingman Kwok int num_et_stats; 6786f8d3f33SWingman Kwok /* Lock for updating the hwstats */ 6796f8d3f33SWingman Kwok spinlock_t hw_stats_lock; 6806f8d3f33SWingman Kwok }; 6816f8d3f33SWingman Kwok 6826f8d3f33SWingman Kwok struct gbe_intf { 6836f8d3f33SWingman Kwok struct net_device *ndev; 6846f8d3f33SWingman Kwok struct device *dev; 6856f8d3f33SWingman Kwok struct gbe_priv *gbe_dev; 6866f8d3f33SWingman Kwok struct netcp_tx_pipe tx_pipe; 6876f8d3f33SWingman Kwok struct gbe_slave *slave; 6886f8d3f33SWingman Kwok struct list_head gbe_intf_list; 6896f8d3f33SWingman Kwok unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; 6906f8d3f33SWingman Kwok }; 6916f8d3f33SWingman Kwok 6926f8d3f33SWingman Kwok static struct netcp_module gbe_module; 69390cff9e2SWingman Kwok static struct netcp_module xgbe_module; 6946f8d3f33SWingman Kwok 6956f8d3f33SWingman Kwok /* Statistic management */ 6966f8d3f33SWingman Kwok struct netcp_ethtool_stat { 6976f8d3f33SWingman Kwok char desc[ETH_GSTRING_LEN]; 6986f8d3f33SWingman Kwok int type; 6996f8d3f33SWingman Kwok u32 size; 7006f8d3f33SWingman Kwok int offset; 7016f8d3f33SWingman Kwok }; 7026f8d3f33SWingman Kwok 703da866ba0SKaricheri, Muralidharan #define GBE_STATSA_INFO(field) \ 704da866ba0SKaricheri, Muralidharan { \ 705da866ba0SKaricheri, Muralidharan "GBE_A:"#field, GBE_STATSA_MODULE, \ 7066f8d3f33SWingman Kwok FIELD_SIZEOF(struct gbe_hw_stats, field), \ 707da866ba0SKaricheri, Muralidharan offsetof(struct gbe_hw_stats, field) \ 708da866ba0SKaricheri, Muralidharan } 7096f8d3f33SWingman Kwok 710da866ba0SKaricheri, Muralidharan #define GBE_STATSB_INFO(field) \ 711da866ba0SKaricheri, Muralidharan { \ 712da866ba0SKaricheri, Muralidharan "GBE_B:"#field, GBE_STATSB_MODULE, \ 7136f8d3f33SWingman Kwok FIELD_SIZEOF(struct gbe_hw_stats, field), \ 714da866ba0SKaricheri, Muralidharan offsetof(struct gbe_hw_stats, field) \ 715da866ba0SKaricheri, Muralidharan } 7166f8d3f33SWingman Kwok 717da866ba0SKaricheri, Muralidharan #define GBE_STATSC_INFO(field) \ 718da866ba0SKaricheri, Muralidharan { \ 719da866ba0SKaricheri, Muralidharan "GBE_C:"#field, GBE_STATSC_MODULE, \ 7206f8d3f33SWingman Kwok FIELD_SIZEOF(struct gbe_hw_stats, field), \ 721da866ba0SKaricheri, Muralidharan offsetof(struct gbe_hw_stats, field) \ 722da866ba0SKaricheri, Muralidharan } 7236f8d3f33SWingman Kwok 724da866ba0SKaricheri, Muralidharan #define GBE_STATSD_INFO(field) \ 725da866ba0SKaricheri, Muralidharan { \ 726da866ba0SKaricheri, Muralidharan "GBE_D:"#field, GBE_STATSD_MODULE, \ 7276f8d3f33SWingman Kwok FIELD_SIZEOF(struct gbe_hw_stats, field), \ 728da866ba0SKaricheri, Muralidharan offsetof(struct gbe_hw_stats, field) \ 729da866ba0SKaricheri, Muralidharan } 7306f8d3f33SWingman Kwok 7316f8d3f33SWingman Kwok static const struct netcp_ethtool_stat gbe13_et_stats[] = { 7326f8d3f33SWingman Kwok /* GBE module A */ 733da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_good_frames), 734da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_broadcast_frames), 735da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_multicast_frames), 736da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_pause_frames), 737da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_crc_errors), 738da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_align_code_errors), 739da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_oversized_frames), 740da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_jabber_frames), 741da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_undersized_frames), 742da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_fragments), 743da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_bytes), 744da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_good_frames), 745da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_broadcast_frames), 746da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_multicast_frames), 747da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_pause_frames), 748da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_deferred_frames), 749da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_collision_frames), 750da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_single_coll_frames), 751da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_mult_coll_frames), 752da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_excessive_collisions), 753da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_late_collisions), 754da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_underrun), 755da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_carrier_sense_errors), 756da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_bytes), 757da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_64byte_frames), 758da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_65_to_127byte_frames), 759da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_128_to_255byte_frames), 760da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_256_to_511byte_frames), 761da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_512_to_1023byte_frames), 762da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_1024byte_frames), 763da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(net_bytes), 764da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_sof_overruns), 765da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_mof_overruns), 766da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_dma_overruns), 7676f8d3f33SWingman Kwok /* GBE module B */ 768da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_good_frames), 769da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_broadcast_frames), 770da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_multicast_frames), 771da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_pause_frames), 772da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_crc_errors), 773da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_align_code_errors), 774da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_oversized_frames), 775da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_jabber_frames), 776da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_undersized_frames), 777da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_fragments), 778da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_bytes), 779da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_good_frames), 780da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_broadcast_frames), 781da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_multicast_frames), 782da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_pause_frames), 783da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_deferred_frames), 784da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_collision_frames), 785da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_single_coll_frames), 786da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_mult_coll_frames), 787da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_excessive_collisions), 788da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_late_collisions), 789da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_underrun), 790da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_carrier_sense_errors), 791da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_bytes), 792da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_64byte_frames), 793da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_65_to_127byte_frames), 794da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_128_to_255byte_frames), 795da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_256_to_511byte_frames), 796da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_512_to_1023byte_frames), 797da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_1024byte_frames), 798da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(net_bytes), 799da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_sof_overruns), 800da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_mof_overruns), 801da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_dma_overruns), 8026f8d3f33SWingman Kwok /* GBE module C */ 803da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_good_frames), 804da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_broadcast_frames), 805da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_multicast_frames), 806da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_pause_frames), 807da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_crc_errors), 808da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_align_code_errors), 809da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_oversized_frames), 810da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_jabber_frames), 811da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_undersized_frames), 812da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_fragments), 813da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_bytes), 814da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_good_frames), 815da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_broadcast_frames), 816da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_multicast_frames), 817da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_pause_frames), 818da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_deferred_frames), 819da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_collision_frames), 820da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_single_coll_frames), 821da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_mult_coll_frames), 822da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_excessive_collisions), 823da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_late_collisions), 824da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_underrun), 825da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_carrier_sense_errors), 826da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_bytes), 827da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_64byte_frames), 828da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_65_to_127byte_frames), 829da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_128_to_255byte_frames), 830da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_256_to_511byte_frames), 831da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_512_to_1023byte_frames), 832da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_1024byte_frames), 833da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(net_bytes), 834da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_sof_overruns), 835da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_mof_overruns), 836da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_dma_overruns), 8376f8d3f33SWingman Kwok /* GBE module D */ 838da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_good_frames), 839da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_broadcast_frames), 840da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_multicast_frames), 841da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_pause_frames), 842da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_crc_errors), 843da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_align_code_errors), 844da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_oversized_frames), 845da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_jabber_frames), 846da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_undersized_frames), 847da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_fragments), 848da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_bytes), 849da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_good_frames), 850da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_broadcast_frames), 851da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_multicast_frames), 852da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_pause_frames), 853da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_deferred_frames), 854da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_collision_frames), 855da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_single_coll_frames), 856da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_mult_coll_frames), 857da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_excessive_collisions), 858da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_late_collisions), 859da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_underrun), 860da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_carrier_sense_errors), 861da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_bytes), 862da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_64byte_frames), 863da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_65_to_127byte_frames), 864da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_128_to_255byte_frames), 865da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_256_to_511byte_frames), 866da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_512_to_1023byte_frames), 867da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_1024byte_frames), 868da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(net_bytes), 869da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_sof_overruns), 870da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_mof_overruns), 871da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_dma_overruns), 8726f8d3f33SWingman Kwok }; 8736f8d3f33SWingman Kwok 8749a391c7bSWingMan Kwok /* This is the size of entries in GBENU_STATS_HOST */ 8755be4001eSWingMan Kwok #define GBENU_ET_STATS_HOST_SIZE 52 8769a391c7bSWingMan Kwok 8779a391c7bSWingMan Kwok #define GBENU_STATS_HOST(field) \ 8789a391c7bSWingMan Kwok { \ 8799a391c7bSWingMan Kwok "GBE_HOST:"#field, GBENU_STATS0_MODULE, \ 8809a391c7bSWingMan Kwok FIELD_SIZEOF(struct gbenu_hw_stats, field), \ 8819a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \ 8829a391c7bSWingMan Kwok } 8839a391c7bSWingMan Kwok 8845be4001eSWingMan Kwok /* This is the size of entries in GBENU_STATS_PORT */ 8855be4001eSWingMan Kwok #define GBENU_ET_STATS_PORT_SIZE 65 8869a391c7bSWingMan Kwok 8879a391c7bSWingMan Kwok #define GBENU_STATS_P1(field) \ 8889a391c7bSWingMan Kwok { \ 8899a391c7bSWingMan Kwok "GBE_P1:"#field, GBENU_STATS1_MODULE, \ 8909a391c7bSWingMan Kwok FIELD_SIZEOF(struct gbenu_hw_stats, field), \ 8919a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \ 8929a391c7bSWingMan Kwok } 8939a391c7bSWingMan Kwok 8949a391c7bSWingMan Kwok #define GBENU_STATS_P2(field) \ 8959a391c7bSWingMan Kwok { \ 8969a391c7bSWingMan Kwok "GBE_P2:"#field, GBENU_STATS2_MODULE, \ 8979a391c7bSWingMan Kwok FIELD_SIZEOF(struct gbenu_hw_stats, field), \ 8989a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \ 8999a391c7bSWingMan Kwok } 9009a391c7bSWingMan Kwok 9019a391c7bSWingMan Kwok #define GBENU_STATS_P3(field) \ 9029a391c7bSWingMan Kwok { \ 9039a391c7bSWingMan Kwok "GBE_P3:"#field, GBENU_STATS3_MODULE, \ 9049a391c7bSWingMan Kwok FIELD_SIZEOF(struct gbenu_hw_stats, field), \ 9059a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \ 9069a391c7bSWingMan Kwok } 9079a391c7bSWingMan Kwok 9089a391c7bSWingMan Kwok #define GBENU_STATS_P4(field) \ 9099a391c7bSWingMan Kwok { \ 9109a391c7bSWingMan Kwok "GBE_P4:"#field, GBENU_STATS4_MODULE, \ 9119a391c7bSWingMan Kwok FIELD_SIZEOF(struct gbenu_hw_stats, field), \ 9129a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \ 9139a391c7bSWingMan Kwok } 9149a391c7bSWingMan Kwok 9159a391c7bSWingMan Kwok #define GBENU_STATS_P5(field) \ 9169a391c7bSWingMan Kwok { \ 9179a391c7bSWingMan Kwok "GBE_P5:"#field, GBENU_STATS5_MODULE, \ 9189a391c7bSWingMan Kwok FIELD_SIZEOF(struct gbenu_hw_stats, field), \ 9199a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \ 9209a391c7bSWingMan Kwok } 9219a391c7bSWingMan Kwok 9229a391c7bSWingMan Kwok #define GBENU_STATS_P6(field) \ 9239a391c7bSWingMan Kwok { \ 9249a391c7bSWingMan Kwok "GBE_P6:"#field, GBENU_STATS6_MODULE, \ 9259a391c7bSWingMan Kwok FIELD_SIZEOF(struct gbenu_hw_stats, field), \ 9269a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \ 9279a391c7bSWingMan Kwok } 9289a391c7bSWingMan Kwok 9299a391c7bSWingMan Kwok #define GBENU_STATS_P7(field) \ 9309a391c7bSWingMan Kwok { \ 9319a391c7bSWingMan Kwok "GBE_P7:"#field, GBENU_STATS7_MODULE, \ 9329a391c7bSWingMan Kwok FIELD_SIZEOF(struct gbenu_hw_stats, field), \ 9339a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \ 9349a391c7bSWingMan Kwok } 9359a391c7bSWingMan Kwok 9369a391c7bSWingMan Kwok #define GBENU_STATS_P8(field) \ 9379a391c7bSWingMan Kwok { \ 9389a391c7bSWingMan Kwok "GBE_P8:"#field, GBENU_STATS8_MODULE, \ 9399a391c7bSWingMan Kwok FIELD_SIZEOF(struct gbenu_hw_stats, field), \ 9409a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \ 9419a391c7bSWingMan Kwok } 9429a391c7bSWingMan Kwok 9439a391c7bSWingMan Kwok static const struct netcp_ethtool_stat gbenu_et_stats[] = { 9449a391c7bSWingMan Kwok /* GBENU Host Module */ 9459a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_good_frames), 9469a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_broadcast_frames), 9479a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_multicast_frames), 9489a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_crc_errors), 9499a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_oversized_frames), 9509a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_undersized_frames), 9519a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_drop), 9529a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_overrun_drop), 9539a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_bytes), 9549a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_good_frames), 9559a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_broadcast_frames), 9569a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_multicast_frames), 9579a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_bytes), 9589a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_64B_frames), 9599a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_65_to_127B_frames), 9609a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_128_to_255B_frames), 9619a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_256_to_511B_frames), 9629a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_512_to_1023B_frames), 9639a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_1024B_frames), 9649a391c7bSWingMan Kwok GBENU_STATS_HOST(net_bytes), 9659a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_bottom_fifo_drop), 9669a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_port_mask_drop), 9679a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_top_fifo_drop), 9689a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_rate_limit_drop), 9699a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_vid_ingress_drop), 9709a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_da_eq_sa_drop), 9719a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_unknown_ucast), 9729a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_unknown_ucast_bytes), 9739a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_unknown_mcast), 9749a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_unknown_mcast_bytes), 9759a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_unknown_bcast), 9769a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_unknown_bcast_bytes), 9775be4001eSWingMan Kwok GBENU_STATS_HOST(ale_pol_match), 9785be4001eSWingMan Kwok GBENU_STATS_HOST(ale_pol_match_red), 9795be4001eSWingMan Kwok GBENU_STATS_HOST(ale_pol_match_yellow), 9809a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_mem_protect_err), 9815be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri0_drop), 9825be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri1_drop), 9835be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri2_drop), 9845be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri3_drop), 9855be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri4_drop), 9865be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri5_drop), 9875be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri6_drop), 9885be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri7_drop), 9895be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri0_drop_bcnt), 9905be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri1_drop_bcnt), 9915be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri2_drop_bcnt), 9925be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri3_drop_bcnt), 9935be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri4_drop_bcnt), 9945be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri5_drop_bcnt), 9955be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri6_drop_bcnt), 9965be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri7_drop_bcnt), 9979a391c7bSWingMan Kwok /* GBENU Module 1 */ 9989a391c7bSWingMan Kwok GBENU_STATS_P1(rx_good_frames), 9999a391c7bSWingMan Kwok GBENU_STATS_P1(rx_broadcast_frames), 10009a391c7bSWingMan Kwok GBENU_STATS_P1(rx_multicast_frames), 10019a391c7bSWingMan Kwok GBENU_STATS_P1(rx_pause_frames), 10029a391c7bSWingMan Kwok GBENU_STATS_P1(rx_crc_errors), 10039a391c7bSWingMan Kwok GBENU_STATS_P1(rx_align_code_errors), 10049a391c7bSWingMan Kwok GBENU_STATS_P1(rx_oversized_frames), 10059a391c7bSWingMan Kwok GBENU_STATS_P1(rx_jabber_frames), 10069a391c7bSWingMan Kwok GBENU_STATS_P1(rx_undersized_frames), 10079a391c7bSWingMan Kwok GBENU_STATS_P1(rx_fragments), 10089a391c7bSWingMan Kwok GBENU_STATS_P1(ale_drop), 10099a391c7bSWingMan Kwok GBENU_STATS_P1(ale_overrun_drop), 10109a391c7bSWingMan Kwok GBENU_STATS_P1(rx_bytes), 10119a391c7bSWingMan Kwok GBENU_STATS_P1(tx_good_frames), 10129a391c7bSWingMan Kwok GBENU_STATS_P1(tx_broadcast_frames), 10139a391c7bSWingMan Kwok GBENU_STATS_P1(tx_multicast_frames), 10149a391c7bSWingMan Kwok GBENU_STATS_P1(tx_pause_frames), 10159a391c7bSWingMan Kwok GBENU_STATS_P1(tx_deferred_frames), 10169a391c7bSWingMan Kwok GBENU_STATS_P1(tx_collision_frames), 10179a391c7bSWingMan Kwok GBENU_STATS_P1(tx_single_coll_frames), 10189a391c7bSWingMan Kwok GBENU_STATS_P1(tx_mult_coll_frames), 10199a391c7bSWingMan Kwok GBENU_STATS_P1(tx_excessive_collisions), 10209a391c7bSWingMan Kwok GBENU_STATS_P1(tx_late_collisions), 10219a391c7bSWingMan Kwok GBENU_STATS_P1(rx_ipg_error), 10229a391c7bSWingMan Kwok GBENU_STATS_P1(tx_carrier_sense_errors), 10239a391c7bSWingMan Kwok GBENU_STATS_P1(tx_bytes), 10249a391c7bSWingMan Kwok GBENU_STATS_P1(tx_64B_frames), 10259a391c7bSWingMan Kwok GBENU_STATS_P1(tx_65_to_127B_frames), 10269a391c7bSWingMan Kwok GBENU_STATS_P1(tx_128_to_255B_frames), 10279a391c7bSWingMan Kwok GBENU_STATS_P1(tx_256_to_511B_frames), 10289a391c7bSWingMan Kwok GBENU_STATS_P1(tx_512_to_1023B_frames), 10299a391c7bSWingMan Kwok GBENU_STATS_P1(tx_1024B_frames), 10309a391c7bSWingMan Kwok GBENU_STATS_P1(net_bytes), 10319a391c7bSWingMan Kwok GBENU_STATS_P1(rx_bottom_fifo_drop), 10329a391c7bSWingMan Kwok GBENU_STATS_P1(rx_port_mask_drop), 10339a391c7bSWingMan Kwok GBENU_STATS_P1(rx_top_fifo_drop), 10349a391c7bSWingMan Kwok GBENU_STATS_P1(ale_rate_limit_drop), 10359a391c7bSWingMan Kwok GBENU_STATS_P1(ale_vid_ingress_drop), 10369a391c7bSWingMan Kwok GBENU_STATS_P1(ale_da_eq_sa_drop), 10379a391c7bSWingMan Kwok GBENU_STATS_P1(ale_unknown_ucast), 10389a391c7bSWingMan Kwok GBENU_STATS_P1(ale_unknown_ucast_bytes), 10399a391c7bSWingMan Kwok GBENU_STATS_P1(ale_unknown_mcast), 10409a391c7bSWingMan Kwok GBENU_STATS_P1(ale_unknown_mcast_bytes), 10419a391c7bSWingMan Kwok GBENU_STATS_P1(ale_unknown_bcast), 10429a391c7bSWingMan Kwok GBENU_STATS_P1(ale_unknown_bcast_bytes), 10435be4001eSWingMan Kwok GBENU_STATS_P1(ale_pol_match), 10445be4001eSWingMan Kwok GBENU_STATS_P1(ale_pol_match_red), 10455be4001eSWingMan Kwok GBENU_STATS_P1(ale_pol_match_yellow), 10469a391c7bSWingMan Kwok GBENU_STATS_P1(tx_mem_protect_err), 10475be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri0_drop), 10485be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri1_drop), 10495be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri2_drop), 10505be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri3_drop), 10515be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri4_drop), 10525be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri5_drop), 10535be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri6_drop), 10545be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri7_drop), 10555be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri0_drop_bcnt), 10565be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri1_drop_bcnt), 10575be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri2_drop_bcnt), 10585be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri3_drop_bcnt), 10595be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri4_drop_bcnt), 10605be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri5_drop_bcnt), 10615be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri6_drop_bcnt), 10625be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri7_drop_bcnt), 10639a391c7bSWingMan Kwok /* GBENU Module 2 */ 10649a391c7bSWingMan Kwok GBENU_STATS_P2(rx_good_frames), 10659a391c7bSWingMan Kwok GBENU_STATS_P2(rx_broadcast_frames), 10669a391c7bSWingMan Kwok GBENU_STATS_P2(rx_multicast_frames), 10679a391c7bSWingMan Kwok GBENU_STATS_P2(rx_pause_frames), 10689a391c7bSWingMan Kwok GBENU_STATS_P2(rx_crc_errors), 10699a391c7bSWingMan Kwok GBENU_STATS_P2(rx_align_code_errors), 10709a391c7bSWingMan Kwok GBENU_STATS_P2(rx_oversized_frames), 10719a391c7bSWingMan Kwok GBENU_STATS_P2(rx_jabber_frames), 10729a391c7bSWingMan Kwok GBENU_STATS_P2(rx_undersized_frames), 10739a391c7bSWingMan Kwok GBENU_STATS_P2(rx_fragments), 10749a391c7bSWingMan Kwok GBENU_STATS_P2(ale_drop), 10759a391c7bSWingMan Kwok GBENU_STATS_P2(ale_overrun_drop), 10769a391c7bSWingMan Kwok GBENU_STATS_P2(rx_bytes), 10779a391c7bSWingMan Kwok GBENU_STATS_P2(tx_good_frames), 10789a391c7bSWingMan Kwok GBENU_STATS_P2(tx_broadcast_frames), 10799a391c7bSWingMan Kwok GBENU_STATS_P2(tx_multicast_frames), 10809a391c7bSWingMan Kwok GBENU_STATS_P2(tx_pause_frames), 10819a391c7bSWingMan Kwok GBENU_STATS_P2(tx_deferred_frames), 10829a391c7bSWingMan Kwok GBENU_STATS_P2(tx_collision_frames), 10839a391c7bSWingMan Kwok GBENU_STATS_P2(tx_single_coll_frames), 10849a391c7bSWingMan Kwok GBENU_STATS_P2(tx_mult_coll_frames), 10859a391c7bSWingMan Kwok GBENU_STATS_P2(tx_excessive_collisions), 10869a391c7bSWingMan Kwok GBENU_STATS_P2(tx_late_collisions), 10879a391c7bSWingMan Kwok GBENU_STATS_P2(rx_ipg_error), 10889a391c7bSWingMan Kwok GBENU_STATS_P2(tx_carrier_sense_errors), 10899a391c7bSWingMan Kwok GBENU_STATS_P2(tx_bytes), 10909a391c7bSWingMan Kwok GBENU_STATS_P2(tx_64B_frames), 10919a391c7bSWingMan Kwok GBENU_STATS_P2(tx_65_to_127B_frames), 10929a391c7bSWingMan Kwok GBENU_STATS_P2(tx_128_to_255B_frames), 10939a391c7bSWingMan Kwok GBENU_STATS_P2(tx_256_to_511B_frames), 10949a391c7bSWingMan Kwok GBENU_STATS_P2(tx_512_to_1023B_frames), 10959a391c7bSWingMan Kwok GBENU_STATS_P2(tx_1024B_frames), 10969a391c7bSWingMan Kwok GBENU_STATS_P2(net_bytes), 10979a391c7bSWingMan Kwok GBENU_STATS_P2(rx_bottom_fifo_drop), 10989a391c7bSWingMan Kwok GBENU_STATS_P2(rx_port_mask_drop), 10999a391c7bSWingMan Kwok GBENU_STATS_P2(rx_top_fifo_drop), 11009a391c7bSWingMan Kwok GBENU_STATS_P2(ale_rate_limit_drop), 11019a391c7bSWingMan Kwok GBENU_STATS_P2(ale_vid_ingress_drop), 11029a391c7bSWingMan Kwok GBENU_STATS_P2(ale_da_eq_sa_drop), 11039a391c7bSWingMan Kwok GBENU_STATS_P2(ale_unknown_ucast), 11049a391c7bSWingMan Kwok GBENU_STATS_P2(ale_unknown_ucast_bytes), 11059a391c7bSWingMan Kwok GBENU_STATS_P2(ale_unknown_mcast), 11069a391c7bSWingMan Kwok GBENU_STATS_P2(ale_unknown_mcast_bytes), 11079a391c7bSWingMan Kwok GBENU_STATS_P2(ale_unknown_bcast), 11089a391c7bSWingMan Kwok GBENU_STATS_P2(ale_unknown_bcast_bytes), 11095be4001eSWingMan Kwok GBENU_STATS_P2(ale_pol_match), 11105be4001eSWingMan Kwok GBENU_STATS_P2(ale_pol_match_red), 11115be4001eSWingMan Kwok GBENU_STATS_P2(ale_pol_match_yellow), 11129a391c7bSWingMan Kwok GBENU_STATS_P2(tx_mem_protect_err), 11135be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri0_drop), 11145be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri1_drop), 11155be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri2_drop), 11165be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri3_drop), 11175be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri4_drop), 11185be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri5_drop), 11195be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri6_drop), 11205be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri7_drop), 11215be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri0_drop_bcnt), 11225be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri1_drop_bcnt), 11235be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri2_drop_bcnt), 11245be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri3_drop_bcnt), 11255be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri4_drop_bcnt), 11265be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri5_drop_bcnt), 11275be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri6_drop_bcnt), 11285be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri7_drop_bcnt), 11299a391c7bSWingMan Kwok /* GBENU Module 3 */ 11309a391c7bSWingMan Kwok GBENU_STATS_P3(rx_good_frames), 11319a391c7bSWingMan Kwok GBENU_STATS_P3(rx_broadcast_frames), 11329a391c7bSWingMan Kwok GBENU_STATS_P3(rx_multicast_frames), 11339a391c7bSWingMan Kwok GBENU_STATS_P3(rx_pause_frames), 11349a391c7bSWingMan Kwok GBENU_STATS_P3(rx_crc_errors), 11359a391c7bSWingMan Kwok GBENU_STATS_P3(rx_align_code_errors), 11369a391c7bSWingMan Kwok GBENU_STATS_P3(rx_oversized_frames), 11379a391c7bSWingMan Kwok GBENU_STATS_P3(rx_jabber_frames), 11389a391c7bSWingMan Kwok GBENU_STATS_P3(rx_undersized_frames), 11399a391c7bSWingMan Kwok GBENU_STATS_P3(rx_fragments), 11409a391c7bSWingMan Kwok GBENU_STATS_P3(ale_drop), 11419a391c7bSWingMan Kwok GBENU_STATS_P3(ale_overrun_drop), 11429a391c7bSWingMan Kwok GBENU_STATS_P3(rx_bytes), 11439a391c7bSWingMan Kwok GBENU_STATS_P3(tx_good_frames), 11449a391c7bSWingMan Kwok GBENU_STATS_P3(tx_broadcast_frames), 11459a391c7bSWingMan Kwok GBENU_STATS_P3(tx_multicast_frames), 11469a391c7bSWingMan Kwok GBENU_STATS_P3(tx_pause_frames), 11479a391c7bSWingMan Kwok GBENU_STATS_P3(tx_deferred_frames), 11489a391c7bSWingMan Kwok GBENU_STATS_P3(tx_collision_frames), 11499a391c7bSWingMan Kwok GBENU_STATS_P3(tx_single_coll_frames), 11509a391c7bSWingMan Kwok GBENU_STATS_P3(tx_mult_coll_frames), 11519a391c7bSWingMan Kwok GBENU_STATS_P3(tx_excessive_collisions), 11529a391c7bSWingMan Kwok GBENU_STATS_P3(tx_late_collisions), 11539a391c7bSWingMan Kwok GBENU_STATS_P3(rx_ipg_error), 11549a391c7bSWingMan Kwok GBENU_STATS_P3(tx_carrier_sense_errors), 11559a391c7bSWingMan Kwok GBENU_STATS_P3(tx_bytes), 11569a391c7bSWingMan Kwok GBENU_STATS_P3(tx_64B_frames), 11579a391c7bSWingMan Kwok GBENU_STATS_P3(tx_65_to_127B_frames), 11589a391c7bSWingMan Kwok GBENU_STATS_P3(tx_128_to_255B_frames), 11599a391c7bSWingMan Kwok GBENU_STATS_P3(tx_256_to_511B_frames), 11609a391c7bSWingMan Kwok GBENU_STATS_P3(tx_512_to_1023B_frames), 11619a391c7bSWingMan Kwok GBENU_STATS_P3(tx_1024B_frames), 11629a391c7bSWingMan Kwok GBENU_STATS_P3(net_bytes), 11639a391c7bSWingMan Kwok GBENU_STATS_P3(rx_bottom_fifo_drop), 11649a391c7bSWingMan Kwok GBENU_STATS_P3(rx_port_mask_drop), 11659a391c7bSWingMan Kwok GBENU_STATS_P3(rx_top_fifo_drop), 11669a391c7bSWingMan Kwok GBENU_STATS_P3(ale_rate_limit_drop), 11679a391c7bSWingMan Kwok GBENU_STATS_P3(ale_vid_ingress_drop), 11689a391c7bSWingMan Kwok GBENU_STATS_P3(ale_da_eq_sa_drop), 11699a391c7bSWingMan Kwok GBENU_STATS_P3(ale_unknown_ucast), 11709a391c7bSWingMan Kwok GBENU_STATS_P3(ale_unknown_ucast_bytes), 11719a391c7bSWingMan Kwok GBENU_STATS_P3(ale_unknown_mcast), 11729a391c7bSWingMan Kwok GBENU_STATS_P3(ale_unknown_mcast_bytes), 11739a391c7bSWingMan Kwok GBENU_STATS_P3(ale_unknown_bcast), 11749a391c7bSWingMan Kwok GBENU_STATS_P3(ale_unknown_bcast_bytes), 11755be4001eSWingMan Kwok GBENU_STATS_P3(ale_pol_match), 11765be4001eSWingMan Kwok GBENU_STATS_P3(ale_pol_match_red), 11775be4001eSWingMan Kwok GBENU_STATS_P3(ale_pol_match_yellow), 11789a391c7bSWingMan Kwok GBENU_STATS_P3(tx_mem_protect_err), 11795be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri0_drop), 11805be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri1_drop), 11815be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri2_drop), 11825be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri3_drop), 11835be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri4_drop), 11845be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri5_drop), 11855be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri6_drop), 11865be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri7_drop), 11875be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri0_drop_bcnt), 11885be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri1_drop_bcnt), 11895be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri2_drop_bcnt), 11905be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri3_drop_bcnt), 11915be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri4_drop_bcnt), 11925be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri5_drop_bcnt), 11935be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri6_drop_bcnt), 11945be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri7_drop_bcnt), 11959a391c7bSWingMan Kwok /* GBENU Module 4 */ 11969a391c7bSWingMan Kwok GBENU_STATS_P4(rx_good_frames), 11979a391c7bSWingMan Kwok GBENU_STATS_P4(rx_broadcast_frames), 11989a391c7bSWingMan Kwok GBENU_STATS_P4(rx_multicast_frames), 11999a391c7bSWingMan Kwok GBENU_STATS_P4(rx_pause_frames), 12009a391c7bSWingMan Kwok GBENU_STATS_P4(rx_crc_errors), 12019a391c7bSWingMan Kwok GBENU_STATS_P4(rx_align_code_errors), 12029a391c7bSWingMan Kwok GBENU_STATS_P4(rx_oversized_frames), 12039a391c7bSWingMan Kwok GBENU_STATS_P4(rx_jabber_frames), 12049a391c7bSWingMan Kwok GBENU_STATS_P4(rx_undersized_frames), 12059a391c7bSWingMan Kwok GBENU_STATS_P4(rx_fragments), 12069a391c7bSWingMan Kwok GBENU_STATS_P4(ale_drop), 12079a391c7bSWingMan Kwok GBENU_STATS_P4(ale_overrun_drop), 12089a391c7bSWingMan Kwok GBENU_STATS_P4(rx_bytes), 12099a391c7bSWingMan Kwok GBENU_STATS_P4(tx_good_frames), 12109a391c7bSWingMan Kwok GBENU_STATS_P4(tx_broadcast_frames), 12119a391c7bSWingMan Kwok GBENU_STATS_P4(tx_multicast_frames), 12129a391c7bSWingMan Kwok GBENU_STATS_P4(tx_pause_frames), 12139a391c7bSWingMan Kwok GBENU_STATS_P4(tx_deferred_frames), 12149a391c7bSWingMan Kwok GBENU_STATS_P4(tx_collision_frames), 12159a391c7bSWingMan Kwok GBENU_STATS_P4(tx_single_coll_frames), 12169a391c7bSWingMan Kwok GBENU_STATS_P4(tx_mult_coll_frames), 12179a391c7bSWingMan Kwok GBENU_STATS_P4(tx_excessive_collisions), 12189a391c7bSWingMan Kwok GBENU_STATS_P4(tx_late_collisions), 12199a391c7bSWingMan Kwok GBENU_STATS_P4(rx_ipg_error), 12209a391c7bSWingMan Kwok GBENU_STATS_P4(tx_carrier_sense_errors), 12219a391c7bSWingMan Kwok GBENU_STATS_P4(tx_bytes), 12229a391c7bSWingMan Kwok GBENU_STATS_P4(tx_64B_frames), 12239a391c7bSWingMan Kwok GBENU_STATS_P4(tx_65_to_127B_frames), 12249a391c7bSWingMan Kwok GBENU_STATS_P4(tx_128_to_255B_frames), 12259a391c7bSWingMan Kwok GBENU_STATS_P4(tx_256_to_511B_frames), 12269a391c7bSWingMan Kwok GBENU_STATS_P4(tx_512_to_1023B_frames), 12279a391c7bSWingMan Kwok GBENU_STATS_P4(tx_1024B_frames), 12289a391c7bSWingMan Kwok GBENU_STATS_P4(net_bytes), 12299a391c7bSWingMan Kwok GBENU_STATS_P4(rx_bottom_fifo_drop), 12309a391c7bSWingMan Kwok GBENU_STATS_P4(rx_port_mask_drop), 12319a391c7bSWingMan Kwok GBENU_STATS_P4(rx_top_fifo_drop), 12329a391c7bSWingMan Kwok GBENU_STATS_P4(ale_rate_limit_drop), 12339a391c7bSWingMan Kwok GBENU_STATS_P4(ale_vid_ingress_drop), 12349a391c7bSWingMan Kwok GBENU_STATS_P4(ale_da_eq_sa_drop), 12359a391c7bSWingMan Kwok GBENU_STATS_P4(ale_unknown_ucast), 12369a391c7bSWingMan Kwok GBENU_STATS_P4(ale_unknown_ucast_bytes), 12379a391c7bSWingMan Kwok GBENU_STATS_P4(ale_unknown_mcast), 12389a391c7bSWingMan Kwok GBENU_STATS_P4(ale_unknown_mcast_bytes), 12399a391c7bSWingMan Kwok GBENU_STATS_P4(ale_unknown_bcast), 12409a391c7bSWingMan Kwok GBENU_STATS_P4(ale_unknown_bcast_bytes), 12415be4001eSWingMan Kwok GBENU_STATS_P4(ale_pol_match), 12425be4001eSWingMan Kwok GBENU_STATS_P4(ale_pol_match_red), 12435be4001eSWingMan Kwok GBENU_STATS_P4(ale_pol_match_yellow), 12449a391c7bSWingMan Kwok GBENU_STATS_P4(tx_mem_protect_err), 12455be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri0_drop), 12465be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri1_drop), 12475be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri2_drop), 12485be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri3_drop), 12495be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri4_drop), 12505be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri5_drop), 12515be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri6_drop), 12525be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri7_drop), 12535be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri0_drop_bcnt), 12545be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri1_drop_bcnt), 12555be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri2_drop_bcnt), 12565be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri3_drop_bcnt), 12575be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri4_drop_bcnt), 12585be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri5_drop_bcnt), 12595be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri6_drop_bcnt), 12605be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri7_drop_bcnt), 12619a391c7bSWingMan Kwok /* GBENU Module 5 */ 12629a391c7bSWingMan Kwok GBENU_STATS_P5(rx_good_frames), 12639a391c7bSWingMan Kwok GBENU_STATS_P5(rx_broadcast_frames), 12649a391c7bSWingMan Kwok GBENU_STATS_P5(rx_multicast_frames), 12659a391c7bSWingMan Kwok GBENU_STATS_P5(rx_pause_frames), 12669a391c7bSWingMan Kwok GBENU_STATS_P5(rx_crc_errors), 12679a391c7bSWingMan Kwok GBENU_STATS_P5(rx_align_code_errors), 12689a391c7bSWingMan Kwok GBENU_STATS_P5(rx_oversized_frames), 12699a391c7bSWingMan Kwok GBENU_STATS_P5(rx_jabber_frames), 12709a391c7bSWingMan Kwok GBENU_STATS_P5(rx_undersized_frames), 12719a391c7bSWingMan Kwok GBENU_STATS_P5(rx_fragments), 12729a391c7bSWingMan Kwok GBENU_STATS_P5(ale_drop), 12739a391c7bSWingMan Kwok GBENU_STATS_P5(ale_overrun_drop), 12749a391c7bSWingMan Kwok GBENU_STATS_P5(rx_bytes), 12759a391c7bSWingMan Kwok GBENU_STATS_P5(tx_good_frames), 12769a391c7bSWingMan Kwok GBENU_STATS_P5(tx_broadcast_frames), 12779a391c7bSWingMan Kwok GBENU_STATS_P5(tx_multicast_frames), 12789a391c7bSWingMan Kwok GBENU_STATS_P5(tx_pause_frames), 12799a391c7bSWingMan Kwok GBENU_STATS_P5(tx_deferred_frames), 12809a391c7bSWingMan Kwok GBENU_STATS_P5(tx_collision_frames), 12819a391c7bSWingMan Kwok GBENU_STATS_P5(tx_single_coll_frames), 12829a391c7bSWingMan Kwok GBENU_STATS_P5(tx_mult_coll_frames), 12839a391c7bSWingMan Kwok GBENU_STATS_P5(tx_excessive_collisions), 12849a391c7bSWingMan Kwok GBENU_STATS_P5(tx_late_collisions), 12859a391c7bSWingMan Kwok GBENU_STATS_P5(rx_ipg_error), 12869a391c7bSWingMan Kwok GBENU_STATS_P5(tx_carrier_sense_errors), 12879a391c7bSWingMan Kwok GBENU_STATS_P5(tx_bytes), 12889a391c7bSWingMan Kwok GBENU_STATS_P5(tx_64B_frames), 12899a391c7bSWingMan Kwok GBENU_STATS_P5(tx_65_to_127B_frames), 12909a391c7bSWingMan Kwok GBENU_STATS_P5(tx_128_to_255B_frames), 12919a391c7bSWingMan Kwok GBENU_STATS_P5(tx_256_to_511B_frames), 12929a391c7bSWingMan Kwok GBENU_STATS_P5(tx_512_to_1023B_frames), 12939a391c7bSWingMan Kwok GBENU_STATS_P5(tx_1024B_frames), 12949a391c7bSWingMan Kwok GBENU_STATS_P5(net_bytes), 12959a391c7bSWingMan Kwok GBENU_STATS_P5(rx_bottom_fifo_drop), 12969a391c7bSWingMan Kwok GBENU_STATS_P5(rx_port_mask_drop), 12979a391c7bSWingMan Kwok GBENU_STATS_P5(rx_top_fifo_drop), 12989a391c7bSWingMan Kwok GBENU_STATS_P5(ale_rate_limit_drop), 12999a391c7bSWingMan Kwok GBENU_STATS_P5(ale_vid_ingress_drop), 13009a391c7bSWingMan Kwok GBENU_STATS_P5(ale_da_eq_sa_drop), 13019a391c7bSWingMan Kwok GBENU_STATS_P5(ale_unknown_ucast), 13029a391c7bSWingMan Kwok GBENU_STATS_P5(ale_unknown_ucast_bytes), 13039a391c7bSWingMan Kwok GBENU_STATS_P5(ale_unknown_mcast), 13049a391c7bSWingMan Kwok GBENU_STATS_P5(ale_unknown_mcast_bytes), 13059a391c7bSWingMan Kwok GBENU_STATS_P5(ale_unknown_bcast), 13069a391c7bSWingMan Kwok GBENU_STATS_P5(ale_unknown_bcast_bytes), 13075be4001eSWingMan Kwok GBENU_STATS_P5(ale_pol_match), 13085be4001eSWingMan Kwok GBENU_STATS_P5(ale_pol_match_red), 13095be4001eSWingMan Kwok GBENU_STATS_P5(ale_pol_match_yellow), 13109a391c7bSWingMan Kwok GBENU_STATS_P5(tx_mem_protect_err), 13115be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri0_drop), 13125be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri1_drop), 13135be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri2_drop), 13145be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri3_drop), 13155be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri4_drop), 13165be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri5_drop), 13175be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri6_drop), 13185be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri7_drop), 13195be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri0_drop_bcnt), 13205be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri1_drop_bcnt), 13215be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri2_drop_bcnt), 13225be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri3_drop_bcnt), 13235be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri4_drop_bcnt), 13245be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri5_drop_bcnt), 13255be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri6_drop_bcnt), 13265be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri7_drop_bcnt), 13279a391c7bSWingMan Kwok /* GBENU Module 6 */ 13289a391c7bSWingMan Kwok GBENU_STATS_P6(rx_good_frames), 13299a391c7bSWingMan Kwok GBENU_STATS_P6(rx_broadcast_frames), 13309a391c7bSWingMan Kwok GBENU_STATS_P6(rx_multicast_frames), 13319a391c7bSWingMan Kwok GBENU_STATS_P6(rx_pause_frames), 13329a391c7bSWingMan Kwok GBENU_STATS_P6(rx_crc_errors), 13339a391c7bSWingMan Kwok GBENU_STATS_P6(rx_align_code_errors), 13349a391c7bSWingMan Kwok GBENU_STATS_P6(rx_oversized_frames), 13359a391c7bSWingMan Kwok GBENU_STATS_P6(rx_jabber_frames), 13369a391c7bSWingMan Kwok GBENU_STATS_P6(rx_undersized_frames), 13379a391c7bSWingMan Kwok GBENU_STATS_P6(rx_fragments), 13389a391c7bSWingMan Kwok GBENU_STATS_P6(ale_drop), 13399a391c7bSWingMan Kwok GBENU_STATS_P6(ale_overrun_drop), 13409a391c7bSWingMan Kwok GBENU_STATS_P6(rx_bytes), 13419a391c7bSWingMan Kwok GBENU_STATS_P6(tx_good_frames), 13429a391c7bSWingMan Kwok GBENU_STATS_P6(tx_broadcast_frames), 13439a391c7bSWingMan Kwok GBENU_STATS_P6(tx_multicast_frames), 13449a391c7bSWingMan Kwok GBENU_STATS_P6(tx_pause_frames), 13459a391c7bSWingMan Kwok GBENU_STATS_P6(tx_deferred_frames), 13469a391c7bSWingMan Kwok GBENU_STATS_P6(tx_collision_frames), 13479a391c7bSWingMan Kwok GBENU_STATS_P6(tx_single_coll_frames), 13489a391c7bSWingMan Kwok GBENU_STATS_P6(tx_mult_coll_frames), 13499a391c7bSWingMan Kwok GBENU_STATS_P6(tx_excessive_collisions), 13509a391c7bSWingMan Kwok GBENU_STATS_P6(tx_late_collisions), 13519a391c7bSWingMan Kwok GBENU_STATS_P6(rx_ipg_error), 13529a391c7bSWingMan Kwok GBENU_STATS_P6(tx_carrier_sense_errors), 13539a391c7bSWingMan Kwok GBENU_STATS_P6(tx_bytes), 13549a391c7bSWingMan Kwok GBENU_STATS_P6(tx_64B_frames), 13559a391c7bSWingMan Kwok GBENU_STATS_P6(tx_65_to_127B_frames), 13569a391c7bSWingMan Kwok GBENU_STATS_P6(tx_128_to_255B_frames), 13579a391c7bSWingMan Kwok GBENU_STATS_P6(tx_256_to_511B_frames), 13589a391c7bSWingMan Kwok GBENU_STATS_P6(tx_512_to_1023B_frames), 13599a391c7bSWingMan Kwok GBENU_STATS_P6(tx_1024B_frames), 13609a391c7bSWingMan Kwok GBENU_STATS_P6(net_bytes), 13619a391c7bSWingMan Kwok GBENU_STATS_P6(rx_bottom_fifo_drop), 13629a391c7bSWingMan Kwok GBENU_STATS_P6(rx_port_mask_drop), 13639a391c7bSWingMan Kwok GBENU_STATS_P6(rx_top_fifo_drop), 13649a391c7bSWingMan Kwok GBENU_STATS_P6(ale_rate_limit_drop), 13659a391c7bSWingMan Kwok GBENU_STATS_P6(ale_vid_ingress_drop), 13669a391c7bSWingMan Kwok GBENU_STATS_P6(ale_da_eq_sa_drop), 13679a391c7bSWingMan Kwok GBENU_STATS_P6(ale_unknown_ucast), 13689a391c7bSWingMan Kwok GBENU_STATS_P6(ale_unknown_ucast_bytes), 13699a391c7bSWingMan Kwok GBENU_STATS_P6(ale_unknown_mcast), 13709a391c7bSWingMan Kwok GBENU_STATS_P6(ale_unknown_mcast_bytes), 13719a391c7bSWingMan Kwok GBENU_STATS_P6(ale_unknown_bcast), 13729a391c7bSWingMan Kwok GBENU_STATS_P6(ale_unknown_bcast_bytes), 13735be4001eSWingMan Kwok GBENU_STATS_P6(ale_pol_match), 13745be4001eSWingMan Kwok GBENU_STATS_P6(ale_pol_match_red), 13755be4001eSWingMan Kwok GBENU_STATS_P6(ale_pol_match_yellow), 13769a391c7bSWingMan Kwok GBENU_STATS_P6(tx_mem_protect_err), 13775be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri0_drop), 13785be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri1_drop), 13795be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri2_drop), 13805be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri3_drop), 13815be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri4_drop), 13825be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri5_drop), 13835be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri6_drop), 13845be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri7_drop), 13855be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri0_drop_bcnt), 13865be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri1_drop_bcnt), 13875be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri2_drop_bcnt), 13885be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri3_drop_bcnt), 13895be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri4_drop_bcnt), 13905be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri5_drop_bcnt), 13915be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri6_drop_bcnt), 13925be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri7_drop_bcnt), 13939a391c7bSWingMan Kwok /* GBENU Module 7 */ 13949a391c7bSWingMan Kwok GBENU_STATS_P7(rx_good_frames), 13959a391c7bSWingMan Kwok GBENU_STATS_P7(rx_broadcast_frames), 13969a391c7bSWingMan Kwok GBENU_STATS_P7(rx_multicast_frames), 13979a391c7bSWingMan Kwok GBENU_STATS_P7(rx_pause_frames), 13989a391c7bSWingMan Kwok GBENU_STATS_P7(rx_crc_errors), 13999a391c7bSWingMan Kwok GBENU_STATS_P7(rx_align_code_errors), 14009a391c7bSWingMan Kwok GBENU_STATS_P7(rx_oversized_frames), 14019a391c7bSWingMan Kwok GBENU_STATS_P7(rx_jabber_frames), 14029a391c7bSWingMan Kwok GBENU_STATS_P7(rx_undersized_frames), 14039a391c7bSWingMan Kwok GBENU_STATS_P7(rx_fragments), 14049a391c7bSWingMan Kwok GBENU_STATS_P7(ale_drop), 14059a391c7bSWingMan Kwok GBENU_STATS_P7(ale_overrun_drop), 14069a391c7bSWingMan Kwok GBENU_STATS_P7(rx_bytes), 14079a391c7bSWingMan Kwok GBENU_STATS_P7(tx_good_frames), 14089a391c7bSWingMan Kwok GBENU_STATS_P7(tx_broadcast_frames), 14099a391c7bSWingMan Kwok GBENU_STATS_P7(tx_multicast_frames), 14109a391c7bSWingMan Kwok GBENU_STATS_P7(tx_pause_frames), 14119a391c7bSWingMan Kwok GBENU_STATS_P7(tx_deferred_frames), 14129a391c7bSWingMan Kwok GBENU_STATS_P7(tx_collision_frames), 14139a391c7bSWingMan Kwok GBENU_STATS_P7(tx_single_coll_frames), 14149a391c7bSWingMan Kwok GBENU_STATS_P7(tx_mult_coll_frames), 14159a391c7bSWingMan Kwok GBENU_STATS_P7(tx_excessive_collisions), 14169a391c7bSWingMan Kwok GBENU_STATS_P7(tx_late_collisions), 14179a391c7bSWingMan Kwok GBENU_STATS_P7(rx_ipg_error), 14189a391c7bSWingMan Kwok GBENU_STATS_P7(tx_carrier_sense_errors), 14199a391c7bSWingMan Kwok GBENU_STATS_P7(tx_bytes), 14209a391c7bSWingMan Kwok GBENU_STATS_P7(tx_64B_frames), 14219a391c7bSWingMan Kwok GBENU_STATS_P7(tx_65_to_127B_frames), 14229a391c7bSWingMan Kwok GBENU_STATS_P7(tx_128_to_255B_frames), 14239a391c7bSWingMan Kwok GBENU_STATS_P7(tx_256_to_511B_frames), 14249a391c7bSWingMan Kwok GBENU_STATS_P7(tx_512_to_1023B_frames), 14259a391c7bSWingMan Kwok GBENU_STATS_P7(tx_1024B_frames), 14269a391c7bSWingMan Kwok GBENU_STATS_P7(net_bytes), 14279a391c7bSWingMan Kwok GBENU_STATS_P7(rx_bottom_fifo_drop), 14289a391c7bSWingMan Kwok GBENU_STATS_P7(rx_port_mask_drop), 14299a391c7bSWingMan Kwok GBENU_STATS_P7(rx_top_fifo_drop), 14309a391c7bSWingMan Kwok GBENU_STATS_P7(ale_rate_limit_drop), 14319a391c7bSWingMan Kwok GBENU_STATS_P7(ale_vid_ingress_drop), 14329a391c7bSWingMan Kwok GBENU_STATS_P7(ale_da_eq_sa_drop), 14339a391c7bSWingMan Kwok GBENU_STATS_P7(ale_unknown_ucast), 14349a391c7bSWingMan Kwok GBENU_STATS_P7(ale_unknown_ucast_bytes), 14359a391c7bSWingMan Kwok GBENU_STATS_P7(ale_unknown_mcast), 14369a391c7bSWingMan Kwok GBENU_STATS_P7(ale_unknown_mcast_bytes), 14379a391c7bSWingMan Kwok GBENU_STATS_P7(ale_unknown_bcast), 14389a391c7bSWingMan Kwok GBENU_STATS_P7(ale_unknown_bcast_bytes), 14395be4001eSWingMan Kwok GBENU_STATS_P7(ale_pol_match), 14405be4001eSWingMan Kwok GBENU_STATS_P7(ale_pol_match_red), 14415be4001eSWingMan Kwok GBENU_STATS_P7(ale_pol_match_yellow), 14429a391c7bSWingMan Kwok GBENU_STATS_P7(tx_mem_protect_err), 14435be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri0_drop), 14445be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri1_drop), 14455be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri2_drop), 14465be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri3_drop), 14475be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri4_drop), 14485be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri5_drop), 14495be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri6_drop), 14505be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri7_drop), 14515be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri0_drop_bcnt), 14525be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri1_drop_bcnt), 14535be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri2_drop_bcnt), 14545be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri3_drop_bcnt), 14555be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri4_drop_bcnt), 14565be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri5_drop_bcnt), 14575be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri6_drop_bcnt), 14585be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri7_drop_bcnt), 14599a391c7bSWingMan Kwok /* GBENU Module 8 */ 14609a391c7bSWingMan Kwok GBENU_STATS_P8(rx_good_frames), 14619a391c7bSWingMan Kwok GBENU_STATS_P8(rx_broadcast_frames), 14629a391c7bSWingMan Kwok GBENU_STATS_P8(rx_multicast_frames), 14639a391c7bSWingMan Kwok GBENU_STATS_P8(rx_pause_frames), 14649a391c7bSWingMan Kwok GBENU_STATS_P8(rx_crc_errors), 14659a391c7bSWingMan Kwok GBENU_STATS_P8(rx_align_code_errors), 14669a391c7bSWingMan Kwok GBENU_STATS_P8(rx_oversized_frames), 14679a391c7bSWingMan Kwok GBENU_STATS_P8(rx_jabber_frames), 14689a391c7bSWingMan Kwok GBENU_STATS_P8(rx_undersized_frames), 14699a391c7bSWingMan Kwok GBENU_STATS_P8(rx_fragments), 14709a391c7bSWingMan Kwok GBENU_STATS_P8(ale_drop), 14719a391c7bSWingMan Kwok GBENU_STATS_P8(ale_overrun_drop), 14729a391c7bSWingMan Kwok GBENU_STATS_P8(rx_bytes), 14739a391c7bSWingMan Kwok GBENU_STATS_P8(tx_good_frames), 14749a391c7bSWingMan Kwok GBENU_STATS_P8(tx_broadcast_frames), 14759a391c7bSWingMan Kwok GBENU_STATS_P8(tx_multicast_frames), 14769a391c7bSWingMan Kwok GBENU_STATS_P8(tx_pause_frames), 14779a391c7bSWingMan Kwok GBENU_STATS_P8(tx_deferred_frames), 14789a391c7bSWingMan Kwok GBENU_STATS_P8(tx_collision_frames), 14799a391c7bSWingMan Kwok GBENU_STATS_P8(tx_single_coll_frames), 14809a391c7bSWingMan Kwok GBENU_STATS_P8(tx_mult_coll_frames), 14819a391c7bSWingMan Kwok GBENU_STATS_P8(tx_excessive_collisions), 14829a391c7bSWingMan Kwok GBENU_STATS_P8(tx_late_collisions), 14839a391c7bSWingMan Kwok GBENU_STATS_P8(rx_ipg_error), 14849a391c7bSWingMan Kwok GBENU_STATS_P8(tx_carrier_sense_errors), 14859a391c7bSWingMan Kwok GBENU_STATS_P8(tx_bytes), 14869a391c7bSWingMan Kwok GBENU_STATS_P8(tx_64B_frames), 14879a391c7bSWingMan Kwok GBENU_STATS_P8(tx_65_to_127B_frames), 14889a391c7bSWingMan Kwok GBENU_STATS_P8(tx_128_to_255B_frames), 14899a391c7bSWingMan Kwok GBENU_STATS_P8(tx_256_to_511B_frames), 14909a391c7bSWingMan Kwok GBENU_STATS_P8(tx_512_to_1023B_frames), 14919a391c7bSWingMan Kwok GBENU_STATS_P8(tx_1024B_frames), 14929a391c7bSWingMan Kwok GBENU_STATS_P8(net_bytes), 14939a391c7bSWingMan Kwok GBENU_STATS_P8(rx_bottom_fifo_drop), 14949a391c7bSWingMan Kwok GBENU_STATS_P8(rx_port_mask_drop), 14959a391c7bSWingMan Kwok GBENU_STATS_P8(rx_top_fifo_drop), 14969a391c7bSWingMan Kwok GBENU_STATS_P8(ale_rate_limit_drop), 14979a391c7bSWingMan Kwok GBENU_STATS_P8(ale_vid_ingress_drop), 14989a391c7bSWingMan Kwok GBENU_STATS_P8(ale_da_eq_sa_drop), 14999a391c7bSWingMan Kwok GBENU_STATS_P8(ale_unknown_ucast), 15009a391c7bSWingMan Kwok GBENU_STATS_P8(ale_unknown_ucast_bytes), 15019a391c7bSWingMan Kwok GBENU_STATS_P8(ale_unknown_mcast), 15029a391c7bSWingMan Kwok GBENU_STATS_P8(ale_unknown_mcast_bytes), 15039a391c7bSWingMan Kwok GBENU_STATS_P8(ale_unknown_bcast), 15049a391c7bSWingMan Kwok GBENU_STATS_P8(ale_unknown_bcast_bytes), 15055be4001eSWingMan Kwok GBENU_STATS_P8(ale_pol_match), 15065be4001eSWingMan Kwok GBENU_STATS_P8(ale_pol_match_red), 15075be4001eSWingMan Kwok GBENU_STATS_P8(ale_pol_match_yellow), 15089a391c7bSWingMan Kwok GBENU_STATS_P8(tx_mem_protect_err), 15095be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri0_drop), 15105be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri1_drop), 15115be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri2_drop), 15125be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri3_drop), 15135be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri4_drop), 15145be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri5_drop), 15155be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri6_drop), 15165be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri7_drop), 15175be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri0_drop_bcnt), 15185be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri1_drop_bcnt), 15195be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri2_drop_bcnt), 15205be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri3_drop_bcnt), 15215be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri4_drop_bcnt), 15225be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri5_drop_bcnt), 15235be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri6_drop_bcnt), 15245be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri7_drop_bcnt), 15259a391c7bSWingMan Kwok }; 15269a391c7bSWingMan Kwok 1527da866ba0SKaricheri, Muralidharan #define XGBE_STATS0_INFO(field) \ 1528da866ba0SKaricheri, Muralidharan { \ 1529da866ba0SKaricheri, Muralidharan "GBE_0:"#field, XGBE_STATS0_MODULE, \ 153090cff9e2SWingman Kwok FIELD_SIZEOF(struct xgbe_hw_stats, field), \ 1531da866ba0SKaricheri, Muralidharan offsetof(struct xgbe_hw_stats, field) \ 1532da866ba0SKaricheri, Muralidharan } 153390cff9e2SWingman Kwok 1534da866ba0SKaricheri, Muralidharan #define XGBE_STATS1_INFO(field) \ 1535da866ba0SKaricheri, Muralidharan { \ 1536da866ba0SKaricheri, Muralidharan "GBE_1:"#field, XGBE_STATS1_MODULE, \ 153790cff9e2SWingman Kwok FIELD_SIZEOF(struct xgbe_hw_stats, field), \ 1538da866ba0SKaricheri, Muralidharan offsetof(struct xgbe_hw_stats, field) \ 1539da866ba0SKaricheri, Muralidharan } 154090cff9e2SWingman Kwok 1541da866ba0SKaricheri, Muralidharan #define XGBE_STATS2_INFO(field) \ 1542da866ba0SKaricheri, Muralidharan { \ 1543da866ba0SKaricheri, Muralidharan "GBE_2:"#field, XGBE_STATS2_MODULE, \ 154490cff9e2SWingman Kwok FIELD_SIZEOF(struct xgbe_hw_stats, field), \ 1545da866ba0SKaricheri, Muralidharan offsetof(struct xgbe_hw_stats, field) \ 1546da866ba0SKaricheri, Muralidharan } 154790cff9e2SWingman Kwok 154890cff9e2SWingman Kwok static const struct netcp_ethtool_stat xgbe10_et_stats[] = { 154990cff9e2SWingman Kwok /* GBE module 0 */ 1550da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_good_frames), 1551da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_broadcast_frames), 1552da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_multicast_frames), 1553da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_oversized_frames), 1554da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_undersized_frames), 1555da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(overrun_type4), 1556da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(overrun_type5), 1557da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_bytes), 1558da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_good_frames), 1559da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_broadcast_frames), 1560da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_multicast_frames), 1561da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_bytes), 1562da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_64byte_frames), 1563da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_65_to_127byte_frames), 1564da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_128_to_255byte_frames), 1565da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_256_to_511byte_frames), 1566da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_512_to_1023byte_frames), 1567da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_1024byte_frames), 1568da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(net_bytes), 1569da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_sof_overruns), 1570da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_mof_overruns), 1571da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_dma_overruns), 157290cff9e2SWingman Kwok /* XGBE module 1 */ 1573da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_good_frames), 1574da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_broadcast_frames), 1575da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_multicast_frames), 1576da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_pause_frames), 1577da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_crc_errors), 1578da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_align_code_errors), 1579da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_oversized_frames), 1580da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_jabber_frames), 1581da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_undersized_frames), 1582da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_fragments), 1583da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(overrun_type4), 1584da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(overrun_type5), 1585da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_bytes), 1586da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_good_frames), 1587da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_broadcast_frames), 1588da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_multicast_frames), 1589da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_pause_frames), 1590da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_deferred_frames), 1591da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_collision_frames), 1592da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_single_coll_frames), 1593da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_mult_coll_frames), 1594da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_excessive_collisions), 1595da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_late_collisions), 1596da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_underrun), 1597da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_carrier_sense_errors), 1598da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_bytes), 1599da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_64byte_frames), 1600da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_65_to_127byte_frames), 1601da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_128_to_255byte_frames), 1602da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_256_to_511byte_frames), 1603da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_512_to_1023byte_frames), 1604da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_1024byte_frames), 1605da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(net_bytes), 1606da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_sof_overruns), 1607da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_mof_overruns), 1608da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_dma_overruns), 160990cff9e2SWingman Kwok /* XGBE module 2 */ 1610da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_good_frames), 1611da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_broadcast_frames), 1612da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_multicast_frames), 1613da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_pause_frames), 1614da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_crc_errors), 1615da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_align_code_errors), 1616da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_oversized_frames), 1617da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_jabber_frames), 1618da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_undersized_frames), 1619da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_fragments), 1620da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(overrun_type4), 1621da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(overrun_type5), 1622da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_bytes), 1623da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_good_frames), 1624da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_broadcast_frames), 1625da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_multicast_frames), 1626da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_pause_frames), 1627da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_deferred_frames), 1628da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_collision_frames), 1629da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_single_coll_frames), 1630da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_mult_coll_frames), 1631da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_excessive_collisions), 1632da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_late_collisions), 1633da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_underrun), 1634da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_carrier_sense_errors), 1635da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_bytes), 1636da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_64byte_frames), 1637da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_65_to_127byte_frames), 1638da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_128_to_255byte_frames), 1639da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_256_to_511byte_frames), 1640da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_512_to_1023byte_frames), 1641da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_1024byte_frames), 1642da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(net_bytes), 1643da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_sof_overruns), 1644da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_mof_overruns), 1645da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_dma_overruns), 164690cff9e2SWingman Kwok }; 164790cff9e2SWingman Kwok 16486f8d3f33SWingman Kwok #define for_each_intf(i, priv) \ 16496f8d3f33SWingman Kwok list_for_each_entry((i), &(priv)->gbe_intf_head, gbe_intf_list) 16506f8d3f33SWingman Kwok 16516f8d3f33SWingman Kwok #define for_each_sec_slave(slave, priv) \ 16526f8d3f33SWingman Kwok list_for_each_entry((slave), &(priv)->secondary_slaves, slave_list) 16536f8d3f33SWingman Kwok 16546f8d3f33SWingman Kwok #define first_sec_slave(priv) \ 16556f8d3f33SWingman Kwok list_first_entry(&priv->secondary_slaves, \ 16566f8d3f33SWingman Kwok struct gbe_slave, slave_list) 16576f8d3f33SWingman Kwok 16586f8d3f33SWingman Kwok static void keystone_get_drvinfo(struct net_device *ndev, 16596f8d3f33SWingman Kwok struct ethtool_drvinfo *info) 16606f8d3f33SWingman Kwok { 16616f8d3f33SWingman Kwok strncpy(info->driver, NETCP_DRIVER_NAME, sizeof(info->driver)); 16626f8d3f33SWingman Kwok strncpy(info->version, NETCP_DRIVER_VERSION, sizeof(info->version)); 16636f8d3f33SWingman Kwok } 16646f8d3f33SWingman Kwok 16656f8d3f33SWingman Kwok static u32 keystone_get_msglevel(struct net_device *ndev) 16666f8d3f33SWingman Kwok { 16676f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 16686f8d3f33SWingman Kwok 16696f8d3f33SWingman Kwok return netcp->msg_enable; 16706f8d3f33SWingman Kwok } 16716f8d3f33SWingman Kwok 16726f8d3f33SWingman Kwok static void keystone_set_msglevel(struct net_device *ndev, u32 value) 16736f8d3f33SWingman Kwok { 16746f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 16756f8d3f33SWingman Kwok 16766f8d3f33SWingman Kwok netcp->msg_enable = value; 16776f8d3f33SWingman Kwok } 16786f8d3f33SWingman Kwok 16796f8d3f33SWingman Kwok static void keystone_get_stat_strings(struct net_device *ndev, 16806f8d3f33SWingman Kwok uint32_t stringset, uint8_t *data) 16816f8d3f33SWingman Kwok { 16826f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 16836f8d3f33SWingman Kwok struct gbe_intf *gbe_intf; 16846f8d3f33SWingman Kwok struct gbe_priv *gbe_dev; 16856f8d3f33SWingman Kwok int i; 16866f8d3f33SWingman Kwok 16876f8d3f33SWingman Kwok gbe_intf = netcp_module_get_intf_data(&gbe_module, netcp); 16886f8d3f33SWingman Kwok if (!gbe_intf) 16896f8d3f33SWingman Kwok return; 16906f8d3f33SWingman Kwok gbe_dev = gbe_intf->gbe_dev; 16916f8d3f33SWingman Kwok 16926f8d3f33SWingman Kwok switch (stringset) { 16936f8d3f33SWingman Kwok case ETH_SS_STATS: 16946f8d3f33SWingman Kwok for (i = 0; i < gbe_dev->num_et_stats; i++) { 16956f8d3f33SWingman Kwok memcpy(data, gbe_dev->et_stats[i].desc, 16966f8d3f33SWingman Kwok ETH_GSTRING_LEN); 16976f8d3f33SWingman Kwok data += ETH_GSTRING_LEN; 16986f8d3f33SWingman Kwok } 16996f8d3f33SWingman Kwok break; 17006f8d3f33SWingman Kwok case ETH_SS_TEST: 17016f8d3f33SWingman Kwok break; 17026f8d3f33SWingman Kwok } 17036f8d3f33SWingman Kwok } 17046f8d3f33SWingman Kwok 17056f8d3f33SWingman Kwok static int keystone_get_sset_count(struct net_device *ndev, int stringset) 17066f8d3f33SWingman Kwok { 17076f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 17086f8d3f33SWingman Kwok struct gbe_intf *gbe_intf; 17096f8d3f33SWingman Kwok struct gbe_priv *gbe_dev; 17106f8d3f33SWingman Kwok 17116f8d3f33SWingman Kwok gbe_intf = netcp_module_get_intf_data(&gbe_module, netcp); 17126f8d3f33SWingman Kwok if (!gbe_intf) 17136f8d3f33SWingman Kwok return -EINVAL; 17146f8d3f33SWingman Kwok gbe_dev = gbe_intf->gbe_dev; 17156f8d3f33SWingman Kwok 17166f8d3f33SWingman Kwok switch (stringset) { 17176f8d3f33SWingman Kwok case ETH_SS_TEST: 17186f8d3f33SWingman Kwok return 0; 17196f8d3f33SWingman Kwok case ETH_SS_STATS: 17206f8d3f33SWingman Kwok return gbe_dev->num_et_stats; 17216f8d3f33SWingman Kwok default: 17226f8d3f33SWingman Kwok return -EINVAL; 17236f8d3f33SWingman Kwok } 17246f8d3f33SWingman Kwok } 17256f8d3f33SWingman Kwok 1726489e8a2fSWingMan Kwok static void gbe_reset_mod_stats(struct gbe_priv *gbe_dev, int stats_mod) 1727489e8a2fSWingMan Kwok { 1728489e8a2fSWingMan Kwok void __iomem *base = gbe_dev->hw_stats_regs[stats_mod]; 1729489e8a2fSWingMan Kwok u32 __iomem *p_stats_entry; 1730489e8a2fSWingMan Kwok int i; 1731489e8a2fSWingMan Kwok 1732489e8a2fSWingMan Kwok for (i = 0; i < gbe_dev->num_et_stats; i++) { 1733489e8a2fSWingMan Kwok if (gbe_dev->et_stats[i].type == stats_mod) { 1734489e8a2fSWingMan Kwok p_stats_entry = base + gbe_dev->et_stats[i].offset; 1735489e8a2fSWingMan Kwok gbe_dev->hw_stats[i] = 0; 1736489e8a2fSWingMan Kwok gbe_dev->hw_stats_prev[i] = readl(p_stats_entry); 1737489e8a2fSWingMan Kwok } 1738489e8a2fSWingMan Kwok } 1739489e8a2fSWingMan Kwok } 1740489e8a2fSWingMan Kwok 1741fbf64c19SWingMan Kwok static inline void gbe_update_hw_stats_entry(struct gbe_priv *gbe_dev, 1742fbf64c19SWingMan Kwok int et_stats_entry) 17436f8d3f33SWingman Kwok { 17446f8d3f33SWingman Kwok void __iomem *base = NULL; 1745489e8a2fSWingMan Kwok u32 __iomem *p_stats_entry; 1746489e8a2fSWingMan Kwok u32 curr, delta; 17476f8d3f33SWingman Kwok 1748fbf64c19SWingMan Kwok /* The hw_stats_regs pointers are already 1749fbf64c19SWingMan Kwok * properly set to point to the right base: 1750fbf64c19SWingMan Kwok */ 1751fbf64c19SWingMan Kwok base = gbe_dev->hw_stats_regs[gbe_dev->et_stats[et_stats_entry].type]; 1752489e8a2fSWingMan Kwok p_stats_entry = base + gbe_dev->et_stats[et_stats_entry].offset; 1753489e8a2fSWingMan Kwok curr = readl(p_stats_entry); 1754489e8a2fSWingMan Kwok delta = curr - gbe_dev->hw_stats_prev[et_stats_entry]; 1755489e8a2fSWingMan Kwok gbe_dev->hw_stats_prev[et_stats_entry] = curr; 1756489e8a2fSWingMan Kwok gbe_dev->hw_stats[et_stats_entry] += delta; 17576f8d3f33SWingman Kwok } 1758fbf64c19SWingMan Kwok 1759fbf64c19SWingMan Kwok static void gbe_update_stats(struct gbe_priv *gbe_dev, uint64_t *data) 1760fbf64c19SWingMan Kwok { 1761fbf64c19SWingMan Kwok int i; 1762fbf64c19SWingMan Kwok 1763fbf64c19SWingMan Kwok for (i = 0; i < gbe_dev->num_et_stats; i++) { 1764fbf64c19SWingMan Kwok gbe_update_hw_stats_entry(gbe_dev, i); 1765fbf64c19SWingMan Kwok 1766fbf64c19SWingMan Kwok if (data) 1767fbf64c19SWingMan Kwok data[i] = gbe_dev->hw_stats[i]; 1768fbf64c19SWingMan Kwok } 1769fbf64c19SWingMan Kwok } 1770fbf64c19SWingMan Kwok 1771fbf64c19SWingMan Kwok static inline void gbe_stats_mod_visible_ver14(struct gbe_priv *gbe_dev, 1772fbf64c19SWingMan Kwok int stats_mod) 1773fbf64c19SWingMan Kwok { 1774fbf64c19SWingMan Kwok u32 val; 1775fbf64c19SWingMan Kwok 1776fbf64c19SWingMan Kwok val = readl(GBE_REG_ADDR(gbe_dev, switch_regs, stat_port_en)); 1777fbf64c19SWingMan Kwok 1778fbf64c19SWingMan Kwok switch (stats_mod) { 1779fbf64c19SWingMan Kwok case GBE_STATSA_MODULE: 1780fbf64c19SWingMan Kwok case GBE_STATSB_MODULE: 1781fbf64c19SWingMan Kwok val &= ~GBE_STATS_CD_SEL; 1782fbf64c19SWingMan Kwok break; 1783fbf64c19SWingMan Kwok case GBE_STATSC_MODULE: 1784fbf64c19SWingMan Kwok case GBE_STATSD_MODULE: 1785fbf64c19SWingMan Kwok val |= GBE_STATS_CD_SEL; 1786fbf64c19SWingMan Kwok break; 1787fbf64c19SWingMan Kwok default: 1788fbf64c19SWingMan Kwok return; 1789fbf64c19SWingMan Kwok } 1790fbf64c19SWingMan Kwok 1791fbf64c19SWingMan Kwok /* make the stat module visible */ 1792fbf64c19SWingMan Kwok writel(val, GBE_REG_ADDR(gbe_dev, switch_regs, stat_port_en)); 17936f8d3f33SWingman Kwok } 17946f8d3f33SWingman Kwok 1795489e8a2fSWingMan Kwok static void gbe_reset_mod_stats_ver14(struct gbe_priv *gbe_dev, int stats_mod) 1796489e8a2fSWingMan Kwok { 1797489e8a2fSWingMan Kwok gbe_stats_mod_visible_ver14(gbe_dev, stats_mod); 1798489e8a2fSWingMan Kwok gbe_reset_mod_stats(gbe_dev, stats_mod); 1799489e8a2fSWingMan Kwok } 1800489e8a2fSWingMan Kwok 18016f8d3f33SWingman Kwok static void gbe_update_stats_ver14(struct gbe_priv *gbe_dev, uint64_t *data) 18026f8d3f33SWingman Kwok { 1803fbf64c19SWingMan Kwok u32 half_num_et_stats = (gbe_dev->num_et_stats / 2); 1804fbf64c19SWingMan Kwok int et_entry, j, pair; 18056f8d3f33SWingman Kwok 18066f8d3f33SWingman Kwok for (pair = 0; pair < 2; pair++) { 1807fbf64c19SWingMan Kwok gbe_stats_mod_visible_ver14(gbe_dev, (pair ? 1808fbf64c19SWingMan Kwok GBE_STATSC_MODULE : 1809fbf64c19SWingMan Kwok GBE_STATSA_MODULE)); 18106f8d3f33SWingman Kwok 1811fbf64c19SWingMan Kwok for (j = 0; j < half_num_et_stats; j++) { 1812fbf64c19SWingMan Kwok et_entry = pair * half_num_et_stats + j; 1813fbf64c19SWingMan Kwok gbe_update_hw_stats_entry(gbe_dev, et_entry); 18146f8d3f33SWingman Kwok 18156f8d3f33SWingman Kwok if (data) 1816fbf64c19SWingMan Kwok data[et_entry] = gbe_dev->hw_stats[et_entry]; 18176f8d3f33SWingman Kwok } 18186f8d3f33SWingman Kwok } 18196f8d3f33SWingman Kwok } 18206f8d3f33SWingman Kwok 18216f8d3f33SWingman Kwok static void keystone_get_ethtool_stats(struct net_device *ndev, 18226f8d3f33SWingman Kwok struct ethtool_stats *stats, 18236f8d3f33SWingman Kwok uint64_t *data) 18246f8d3f33SWingman Kwok { 18256f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 18266f8d3f33SWingman Kwok struct gbe_intf *gbe_intf; 18276f8d3f33SWingman Kwok struct gbe_priv *gbe_dev; 18286f8d3f33SWingman Kwok 18296f8d3f33SWingman Kwok gbe_intf = netcp_module_get_intf_data(&gbe_module, netcp); 18306f8d3f33SWingman Kwok if (!gbe_intf) 18316f8d3f33SWingman Kwok return; 18326f8d3f33SWingman Kwok 18336f8d3f33SWingman Kwok gbe_dev = gbe_intf->gbe_dev; 18346f8d3f33SWingman Kwok spin_lock_bh(&gbe_dev->hw_stats_lock); 183590cff9e2SWingman Kwok if (gbe_dev->ss_version == GBE_SS_VERSION_14) 18366f8d3f33SWingman Kwok gbe_update_stats_ver14(gbe_dev, data); 183790cff9e2SWingman Kwok else 183890cff9e2SWingman Kwok gbe_update_stats(gbe_dev, data); 18396f8d3f33SWingman Kwok spin_unlock_bh(&gbe_dev->hw_stats_lock); 18406f8d3f33SWingman Kwok } 18416f8d3f33SWingman Kwok 18426f8d3f33SWingman Kwok static int keystone_get_settings(struct net_device *ndev, 18436f8d3f33SWingman Kwok struct ethtool_cmd *cmd) 18446f8d3f33SWingman Kwok { 18456f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 18466f8d3f33SWingman Kwok struct phy_device *phy = ndev->phydev; 18476f8d3f33SWingman Kwok struct gbe_intf *gbe_intf; 18486f8d3f33SWingman Kwok int ret; 18496f8d3f33SWingman Kwok 18506f8d3f33SWingman Kwok if (!phy) 18516f8d3f33SWingman Kwok return -EINVAL; 18526f8d3f33SWingman Kwok 18536f8d3f33SWingman Kwok gbe_intf = netcp_module_get_intf_data(&gbe_module, netcp); 18546f8d3f33SWingman Kwok if (!gbe_intf) 18556f8d3f33SWingman Kwok return -EINVAL; 18566f8d3f33SWingman Kwok 18576f8d3f33SWingman Kwok if (!gbe_intf->slave) 18586f8d3f33SWingman Kwok return -EINVAL; 18596f8d3f33SWingman Kwok 18606f8d3f33SWingman Kwok ret = phy_ethtool_gset(phy, cmd); 18616f8d3f33SWingman Kwok if (!ret) 18626f8d3f33SWingman Kwok cmd->port = gbe_intf->slave->phy_port_t; 18636f8d3f33SWingman Kwok 18646f8d3f33SWingman Kwok return ret; 18656f8d3f33SWingman Kwok } 18666f8d3f33SWingman Kwok 18676f8d3f33SWingman Kwok static int keystone_set_settings(struct net_device *ndev, 18686f8d3f33SWingman Kwok struct ethtool_cmd *cmd) 18696f8d3f33SWingman Kwok { 18706f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 18716f8d3f33SWingman Kwok struct phy_device *phy = ndev->phydev; 18726f8d3f33SWingman Kwok struct gbe_intf *gbe_intf; 18736f8d3f33SWingman Kwok u32 features = cmd->advertising & cmd->supported; 18746f8d3f33SWingman Kwok 18756f8d3f33SWingman Kwok if (!phy) 18766f8d3f33SWingman Kwok return -EINVAL; 18776f8d3f33SWingman Kwok 18786f8d3f33SWingman Kwok gbe_intf = netcp_module_get_intf_data(&gbe_module, netcp); 18796f8d3f33SWingman Kwok if (!gbe_intf) 18806f8d3f33SWingman Kwok return -EINVAL; 18816f8d3f33SWingman Kwok 18826f8d3f33SWingman Kwok if (!gbe_intf->slave) 18836f8d3f33SWingman Kwok return -EINVAL; 18846f8d3f33SWingman Kwok 18856f8d3f33SWingman Kwok if (cmd->port != gbe_intf->slave->phy_port_t) { 18866f8d3f33SWingman Kwok if ((cmd->port == PORT_TP) && !(features & ADVERTISED_TP)) 18876f8d3f33SWingman Kwok return -EINVAL; 18886f8d3f33SWingman Kwok 18896f8d3f33SWingman Kwok if ((cmd->port == PORT_AUI) && !(features & ADVERTISED_AUI)) 18906f8d3f33SWingman Kwok return -EINVAL; 18916f8d3f33SWingman Kwok 18926f8d3f33SWingman Kwok if ((cmd->port == PORT_BNC) && !(features & ADVERTISED_BNC)) 18936f8d3f33SWingman Kwok return -EINVAL; 18946f8d3f33SWingman Kwok 18956f8d3f33SWingman Kwok if ((cmd->port == PORT_MII) && !(features & ADVERTISED_MII)) 18966f8d3f33SWingman Kwok return -EINVAL; 18976f8d3f33SWingman Kwok 18986f8d3f33SWingman Kwok if ((cmd->port == PORT_FIBRE) && !(features & ADVERTISED_FIBRE)) 18996f8d3f33SWingman Kwok return -EINVAL; 19006f8d3f33SWingman Kwok } 19016f8d3f33SWingman Kwok 19026f8d3f33SWingman Kwok gbe_intf->slave->phy_port_t = cmd->port; 19036f8d3f33SWingman Kwok return phy_ethtool_sset(phy, cmd); 19046f8d3f33SWingman Kwok } 19056f8d3f33SWingman Kwok 19066f8d3f33SWingman Kwok static const struct ethtool_ops keystone_ethtool_ops = { 19076f8d3f33SWingman Kwok .get_drvinfo = keystone_get_drvinfo, 19086f8d3f33SWingman Kwok .get_link = ethtool_op_get_link, 19096f8d3f33SWingman Kwok .get_msglevel = keystone_get_msglevel, 19106f8d3f33SWingman Kwok .set_msglevel = keystone_set_msglevel, 19116f8d3f33SWingman Kwok .get_strings = keystone_get_stat_strings, 19126f8d3f33SWingman Kwok .get_sset_count = keystone_get_sset_count, 19136f8d3f33SWingman Kwok .get_ethtool_stats = keystone_get_ethtool_stats, 19146f8d3f33SWingman Kwok .get_settings = keystone_get_settings, 19156f8d3f33SWingman Kwok .set_settings = keystone_set_settings, 19166f8d3f33SWingman Kwok }; 19176f8d3f33SWingman Kwok 19186f8d3f33SWingman Kwok #define mac_hi(mac) (((mac)[0] << 0) | ((mac)[1] << 8) | \ 19196f8d3f33SWingman Kwok ((mac)[2] << 16) | ((mac)[3] << 24)) 19206f8d3f33SWingman Kwok #define mac_lo(mac) (((mac)[4] << 0) | ((mac)[5] << 8)) 19216f8d3f33SWingman Kwok 19226f8d3f33SWingman Kwok static void gbe_set_slave_mac(struct gbe_slave *slave, 19236f8d3f33SWingman Kwok struct gbe_intf *gbe_intf) 19246f8d3f33SWingman Kwok { 19256f8d3f33SWingman Kwok struct net_device *ndev = gbe_intf->ndev; 19266f8d3f33SWingman Kwok 19276f8d3f33SWingman Kwok writel(mac_hi(ndev->dev_addr), GBE_REG_ADDR(slave, port_regs, sa_hi)); 19286f8d3f33SWingman Kwok writel(mac_lo(ndev->dev_addr), GBE_REG_ADDR(slave, port_regs, sa_lo)); 19296f8d3f33SWingman Kwok } 19306f8d3f33SWingman Kwok 19316f8d3f33SWingman Kwok static int gbe_get_slave_port(struct gbe_priv *priv, u32 slave_num) 19326f8d3f33SWingman Kwok { 19336f8d3f33SWingman Kwok if (priv->host_port == 0) 19346f8d3f33SWingman Kwok return slave_num + 1; 19356f8d3f33SWingman Kwok 19366f8d3f33SWingman Kwok return slave_num; 19376f8d3f33SWingman Kwok } 19386f8d3f33SWingman Kwok 19396f8d3f33SWingman Kwok static void netcp_ethss_link_state_action(struct gbe_priv *gbe_dev, 19406f8d3f33SWingman Kwok struct net_device *ndev, 19416f8d3f33SWingman Kwok struct gbe_slave *slave, 19426f8d3f33SWingman Kwok int up) 19436f8d3f33SWingman Kwok { 19446f8d3f33SWingman Kwok struct phy_device *phy = slave->phy; 19456f8d3f33SWingman Kwok u32 mac_control = 0; 19466f8d3f33SWingman Kwok 19476f8d3f33SWingman Kwok if (up) { 19486f8d3f33SWingman Kwok mac_control = slave->mac_control; 194990cff9e2SWingman Kwok if (phy && (phy->speed == SPEED_1000)) { 19506f8d3f33SWingman Kwok mac_control |= MACSL_GIG_MODE; 195190cff9e2SWingman Kwok mac_control &= ~MACSL_XGIG_MODE; 195290cff9e2SWingman Kwok } else if (phy && (phy->speed == SPEED_10000)) { 195390cff9e2SWingman Kwok mac_control |= MACSL_XGIG_MODE; 195490cff9e2SWingman Kwok mac_control &= ~MACSL_GIG_MODE; 195590cff9e2SWingman Kwok } 19566f8d3f33SWingman Kwok 19576f8d3f33SWingman Kwok writel(mac_control, GBE_REG_ADDR(slave, emac_regs, 19586f8d3f33SWingman Kwok mac_control)); 19596f8d3f33SWingman Kwok 19606f8d3f33SWingman Kwok cpsw_ale_control_set(gbe_dev->ale, slave->port_num, 19616f8d3f33SWingman Kwok ALE_PORT_STATE, 19626f8d3f33SWingman Kwok ALE_PORT_STATE_FORWARD); 19636f8d3f33SWingman Kwok 19648e046d68SKaricheri, Muralidharan if (ndev && slave->open && 19658e046d68SKaricheri, Muralidharan slave->link_interface != SGMII_LINK_MAC_PHY && 19668e046d68SKaricheri, Muralidharan slave->link_interface != XGMII_LINK_MAC_PHY) 19676f8d3f33SWingman Kwok netif_carrier_on(ndev); 19686f8d3f33SWingman Kwok } else { 19696f8d3f33SWingman Kwok writel(mac_control, GBE_REG_ADDR(slave, emac_regs, 19706f8d3f33SWingman Kwok mac_control)); 19716f8d3f33SWingman Kwok cpsw_ale_control_set(gbe_dev->ale, slave->port_num, 19726f8d3f33SWingman Kwok ALE_PORT_STATE, 19736f8d3f33SWingman Kwok ALE_PORT_STATE_DISABLE); 19748e046d68SKaricheri, Muralidharan if (ndev && 19758e046d68SKaricheri, Muralidharan slave->link_interface != SGMII_LINK_MAC_PHY && 19768e046d68SKaricheri, Muralidharan slave->link_interface != XGMII_LINK_MAC_PHY) 19776f8d3f33SWingman Kwok netif_carrier_off(ndev); 19786f8d3f33SWingman Kwok } 19796f8d3f33SWingman Kwok 19806f8d3f33SWingman Kwok if (phy) 19816f8d3f33SWingman Kwok phy_print_status(phy); 19826f8d3f33SWingman Kwok } 19836f8d3f33SWingman Kwok 19846f8d3f33SWingman Kwok static bool gbe_phy_link_status(struct gbe_slave *slave) 19856f8d3f33SWingman Kwok { 19866f8d3f33SWingman Kwok return !slave->phy || slave->phy->link; 19876f8d3f33SWingman Kwok } 19886f8d3f33SWingman Kwok 19896f8d3f33SWingman Kwok static void netcp_ethss_update_link_state(struct gbe_priv *gbe_dev, 19906f8d3f33SWingman Kwok struct gbe_slave *slave, 19916f8d3f33SWingman Kwok struct net_device *ndev) 19926f8d3f33SWingman Kwok { 19936f8d3f33SWingman Kwok int sp = slave->slave_num; 19946f8d3f33SWingman Kwok int phy_link_state, sgmii_link_state = 1, link_state; 19956f8d3f33SWingman Kwok 19966f8d3f33SWingman Kwok if (!slave->open) 19976f8d3f33SWingman Kwok return; 19986f8d3f33SWingman Kwok 19999a391c7bSWingMan Kwok if (!SLAVE_LINK_IS_XGMII(slave)) { 20009a391c7bSWingMan Kwok if (gbe_dev->ss_version == GBE_SS_VERSION_14) 20019a391c7bSWingMan Kwok sgmii_link_state = 20029a391c7bSWingMan Kwok netcp_sgmii_get_port_link(SGMII_BASE(sp), sp); 20039a391c7bSWingMan Kwok else 20049a391c7bSWingMan Kwok sgmii_link_state = 20059a391c7bSWingMan Kwok netcp_sgmii_get_port_link( 20069a391c7bSWingMan Kwok gbe_dev->sgmii_port_regs, sp); 20079a391c7bSWingMan Kwok } 20089a391c7bSWingMan Kwok 20096f8d3f33SWingman Kwok phy_link_state = gbe_phy_link_status(slave); 20106f8d3f33SWingman Kwok link_state = phy_link_state & sgmii_link_state; 20116f8d3f33SWingman Kwok 20126f8d3f33SWingman Kwok if (atomic_xchg(&slave->link_state, link_state) != link_state) 20136f8d3f33SWingman Kwok netcp_ethss_link_state_action(gbe_dev, ndev, slave, 20146f8d3f33SWingman Kwok link_state); 20156f8d3f33SWingman Kwok } 20166f8d3f33SWingman Kwok 201790cff9e2SWingman Kwok static void xgbe_adjust_link(struct net_device *ndev) 201890cff9e2SWingman Kwok { 201990cff9e2SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 202090cff9e2SWingman Kwok struct gbe_intf *gbe_intf; 202190cff9e2SWingman Kwok 202290cff9e2SWingman Kwok gbe_intf = netcp_module_get_intf_data(&xgbe_module, netcp); 202390cff9e2SWingman Kwok if (!gbe_intf) 202490cff9e2SWingman Kwok return; 202590cff9e2SWingman Kwok 202690cff9e2SWingman Kwok netcp_ethss_update_link_state(gbe_intf->gbe_dev, gbe_intf->slave, 202790cff9e2SWingman Kwok ndev); 202890cff9e2SWingman Kwok } 202990cff9e2SWingman Kwok 20306f8d3f33SWingman Kwok static void gbe_adjust_link(struct net_device *ndev) 20316f8d3f33SWingman Kwok { 20326f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 20336f8d3f33SWingman Kwok struct gbe_intf *gbe_intf; 20346f8d3f33SWingman Kwok 20356f8d3f33SWingman Kwok gbe_intf = netcp_module_get_intf_data(&gbe_module, netcp); 20366f8d3f33SWingman Kwok if (!gbe_intf) 20376f8d3f33SWingman Kwok return; 20386f8d3f33SWingman Kwok 20396f8d3f33SWingman Kwok netcp_ethss_update_link_state(gbe_intf->gbe_dev, gbe_intf->slave, 20406f8d3f33SWingman Kwok ndev); 20416f8d3f33SWingman Kwok } 20426f8d3f33SWingman Kwok 20436f8d3f33SWingman Kwok static void gbe_adjust_link_sec_slaves(struct net_device *ndev) 20446f8d3f33SWingman Kwok { 20456f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = netdev_priv(ndev); 20466f8d3f33SWingman Kwok struct gbe_slave *slave; 20476f8d3f33SWingman Kwok 20486f8d3f33SWingman Kwok for_each_sec_slave(slave, gbe_dev) 20496f8d3f33SWingman Kwok netcp_ethss_update_link_state(gbe_dev, slave, NULL); 20506f8d3f33SWingman Kwok } 20516f8d3f33SWingman Kwok 20526f8d3f33SWingman Kwok /* Reset EMAC 20536f8d3f33SWingman Kwok * Soft reset is set and polled until clear, or until a timeout occurs 20546f8d3f33SWingman Kwok */ 20556f8d3f33SWingman Kwok static int gbe_port_reset(struct gbe_slave *slave) 20566f8d3f33SWingman Kwok { 20576f8d3f33SWingman Kwok u32 i, v; 20586f8d3f33SWingman Kwok 20596f8d3f33SWingman Kwok /* Set the soft reset bit */ 20606f8d3f33SWingman Kwok writel(SOFT_RESET, GBE_REG_ADDR(slave, emac_regs, soft_reset)); 20616f8d3f33SWingman Kwok 20626f8d3f33SWingman Kwok /* Wait for the bit to clear */ 20636f8d3f33SWingman Kwok for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) { 20646f8d3f33SWingman Kwok v = readl(GBE_REG_ADDR(slave, emac_regs, soft_reset)); 20656f8d3f33SWingman Kwok if ((v & SOFT_RESET_MASK) != SOFT_RESET) 20666f8d3f33SWingman Kwok return 0; 20676f8d3f33SWingman Kwok } 20686f8d3f33SWingman Kwok 20696f8d3f33SWingman Kwok /* Timeout on the reset */ 20706f8d3f33SWingman Kwok return GMACSL_RET_WARN_RESET_INCOMPLETE; 20716f8d3f33SWingman Kwok } 20726f8d3f33SWingman Kwok 20736f8d3f33SWingman Kwok /* Configure EMAC */ 20746f8d3f33SWingman Kwok static void gbe_port_config(struct gbe_priv *gbe_dev, struct gbe_slave *slave, 20756f8d3f33SWingman Kwok int max_rx_len) 20766f8d3f33SWingman Kwok { 20779a391c7bSWingMan Kwok void __iomem *rx_maxlen_reg; 207890cff9e2SWingman Kwok u32 xgmii_mode; 207990cff9e2SWingman Kwok 20806f8d3f33SWingman Kwok if (max_rx_len > NETCP_MAX_FRAME_SIZE) 20816f8d3f33SWingman Kwok max_rx_len = NETCP_MAX_FRAME_SIZE; 20826f8d3f33SWingman Kwok 208390cff9e2SWingman Kwok /* Enable correct MII mode at SS level */ 208490cff9e2SWingman Kwok if ((gbe_dev->ss_version == XGBE_SS_VERSION_10) && 208590cff9e2SWingman Kwok (slave->link_interface >= XGMII_LINK_MAC_PHY)) { 208690cff9e2SWingman Kwok xgmii_mode = readl(GBE_REG_ADDR(gbe_dev, ss_regs, control)); 208790cff9e2SWingman Kwok xgmii_mode |= (1 << slave->slave_num); 208890cff9e2SWingman Kwok writel(xgmii_mode, GBE_REG_ADDR(gbe_dev, ss_regs, control)); 208990cff9e2SWingman Kwok } 209090cff9e2SWingman Kwok 20919a391c7bSWingMan Kwok if (IS_SS_ID_MU(gbe_dev)) 20929a391c7bSWingMan Kwok rx_maxlen_reg = GBE_REG_ADDR(slave, port_regs, rx_maxlen); 20939a391c7bSWingMan Kwok else 20949a391c7bSWingMan Kwok rx_maxlen_reg = GBE_REG_ADDR(slave, emac_regs, rx_maxlen); 20959a391c7bSWingMan Kwok 20969a391c7bSWingMan Kwok writel(max_rx_len, rx_maxlen_reg); 20976f8d3f33SWingman Kwok writel(slave->mac_control, GBE_REG_ADDR(slave, emac_regs, mac_control)); 20986f8d3f33SWingman Kwok } 20996f8d3f33SWingman Kwok 21006f8d3f33SWingman Kwok static void gbe_slave_stop(struct gbe_intf *intf) 21016f8d3f33SWingman Kwok { 21026f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = intf->gbe_dev; 21036f8d3f33SWingman Kwok struct gbe_slave *slave = intf->slave; 21046f8d3f33SWingman Kwok 21056f8d3f33SWingman Kwok gbe_port_reset(slave); 21066f8d3f33SWingman Kwok /* Disable forwarding */ 21076f8d3f33SWingman Kwok cpsw_ale_control_set(gbe_dev->ale, slave->port_num, 21086f8d3f33SWingman Kwok ALE_PORT_STATE, ALE_PORT_STATE_DISABLE); 21096f8d3f33SWingman Kwok cpsw_ale_del_mcast(gbe_dev->ale, intf->ndev->broadcast, 21106f8d3f33SWingman Kwok 1 << slave->port_num, 0, 0); 21116f8d3f33SWingman Kwok 21126f8d3f33SWingman Kwok if (!slave->phy) 21136f8d3f33SWingman Kwok return; 21146f8d3f33SWingman Kwok 21156f8d3f33SWingman Kwok phy_stop(slave->phy); 21166f8d3f33SWingman Kwok phy_disconnect(slave->phy); 21176f8d3f33SWingman Kwok slave->phy = NULL; 21186f8d3f33SWingman Kwok } 21196f8d3f33SWingman Kwok 21206f8d3f33SWingman Kwok static void gbe_sgmii_config(struct gbe_priv *priv, struct gbe_slave *slave) 21216f8d3f33SWingman Kwok { 21226f8d3f33SWingman Kwok void __iomem *sgmii_port_regs; 21236f8d3f33SWingman Kwok 21246f8d3f33SWingman Kwok sgmii_port_regs = priv->sgmii_port_regs; 21256f8d3f33SWingman Kwok if ((priv->ss_version == GBE_SS_VERSION_14) && (slave->slave_num >= 2)) 21266f8d3f33SWingman Kwok sgmii_port_regs = priv->sgmii_port34_regs; 21276f8d3f33SWingman Kwok 212890cff9e2SWingman Kwok if (!SLAVE_LINK_IS_XGMII(slave)) { 21296f8d3f33SWingman Kwok netcp_sgmii_reset(sgmii_port_regs, slave->slave_num); 21306f8d3f33SWingman Kwok netcp_sgmii_config(sgmii_port_regs, slave->slave_num, 21316f8d3f33SWingman Kwok slave->link_interface); 21326f8d3f33SWingman Kwok } 213390cff9e2SWingman Kwok } 21346f8d3f33SWingman Kwok 21356f8d3f33SWingman Kwok static int gbe_slave_open(struct gbe_intf *gbe_intf) 21366f8d3f33SWingman Kwok { 21376f8d3f33SWingman Kwok struct gbe_priv *priv = gbe_intf->gbe_dev; 21386f8d3f33SWingman Kwok struct gbe_slave *slave = gbe_intf->slave; 21396f8d3f33SWingman Kwok phy_interface_t phy_mode; 21406f8d3f33SWingman Kwok bool has_phy = false; 21416f8d3f33SWingman Kwok 21426f8d3f33SWingman Kwok void (*hndlr)(struct net_device *) = gbe_adjust_link; 21436f8d3f33SWingman Kwok 21446f8d3f33SWingman Kwok gbe_sgmii_config(priv, slave); 21456f8d3f33SWingman Kwok gbe_port_reset(slave); 21466f8d3f33SWingman Kwok gbe_port_config(priv, slave, priv->rx_packet_max); 21476f8d3f33SWingman Kwok gbe_set_slave_mac(slave, gbe_intf); 21486f8d3f33SWingman Kwok /* enable forwarding */ 21496f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, slave->port_num, 21506f8d3f33SWingman Kwok ALE_PORT_STATE, ALE_PORT_STATE_FORWARD); 21516f8d3f33SWingman Kwok cpsw_ale_add_mcast(priv->ale, gbe_intf->ndev->broadcast, 21526f8d3f33SWingman Kwok 1 << slave->port_num, 0, 0, ALE_MCAST_FWD_2); 21536f8d3f33SWingman Kwok 21546f8d3f33SWingman Kwok if (slave->link_interface == SGMII_LINK_MAC_PHY) { 21556f8d3f33SWingman Kwok has_phy = true; 21566f8d3f33SWingman Kwok phy_mode = PHY_INTERFACE_MODE_SGMII; 21576f8d3f33SWingman Kwok slave->phy_port_t = PORT_MII; 21586f8d3f33SWingman Kwok } else if (slave->link_interface == XGMII_LINK_MAC_PHY) { 21596f8d3f33SWingman Kwok has_phy = true; 21606f8d3f33SWingman Kwok phy_mode = PHY_INTERFACE_MODE_NA; 21616f8d3f33SWingman Kwok slave->phy_port_t = PORT_FIBRE; 21626f8d3f33SWingman Kwok } 21636f8d3f33SWingman Kwok 21646f8d3f33SWingman Kwok if (has_phy) { 216590cff9e2SWingman Kwok if (priv->ss_version == XGBE_SS_VERSION_10) 216690cff9e2SWingman Kwok hndlr = xgbe_adjust_link; 216790cff9e2SWingman Kwok 21686f8d3f33SWingman Kwok slave->phy = of_phy_connect(gbe_intf->ndev, 21696f8d3f33SWingman Kwok slave->phy_node, 21706f8d3f33SWingman Kwok hndlr, 0, 21716f8d3f33SWingman Kwok phy_mode); 21726f8d3f33SWingman Kwok if (!slave->phy) { 21736f8d3f33SWingman Kwok dev_err(priv->dev, "phy not found on slave %d\n", 21746f8d3f33SWingman Kwok slave->slave_num); 21756f8d3f33SWingman Kwok return -ENODEV; 21766f8d3f33SWingman Kwok } 21776f8d3f33SWingman Kwok dev_dbg(priv->dev, "phy found: id is: 0x%s\n", 21786f8d3f33SWingman Kwok dev_name(&slave->phy->dev)); 21796f8d3f33SWingman Kwok phy_start(slave->phy); 21806f8d3f33SWingman Kwok phy_read_status(slave->phy); 21816f8d3f33SWingman Kwok } 21826f8d3f33SWingman Kwok return 0; 21836f8d3f33SWingman Kwok } 21846f8d3f33SWingman Kwok 21856f8d3f33SWingman Kwok static void gbe_init_host_port(struct gbe_priv *priv) 21866f8d3f33SWingman Kwok { 21876f8d3f33SWingman Kwok int bypass_en = 1; 21889a391c7bSWingMan Kwok 21899a391c7bSWingMan Kwok /* Host Tx Pri */ 21909a391c7bSWingMan Kwok if (IS_SS_ID_NU(priv)) 21919a391c7bSWingMan Kwok writel(HOST_TX_PRI_MAP_DEFAULT, 21929a391c7bSWingMan Kwok GBE_REG_ADDR(priv, host_port_regs, tx_pri_map)); 21939a391c7bSWingMan Kwok 21946f8d3f33SWingman Kwok /* Max length register */ 21956f8d3f33SWingman Kwok writel(NETCP_MAX_FRAME_SIZE, GBE_REG_ADDR(priv, host_port_regs, 21966f8d3f33SWingman Kwok rx_maxlen)); 21976f8d3f33SWingman Kwok 21986f8d3f33SWingman Kwok cpsw_ale_start(priv->ale); 21996f8d3f33SWingman Kwok 22006f8d3f33SWingman Kwok if (priv->enable_ale) 22016f8d3f33SWingman Kwok bypass_en = 0; 22026f8d3f33SWingman Kwok 22036f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, 0, ALE_BYPASS, bypass_en); 22046f8d3f33SWingman Kwok 22056f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, 0, ALE_NO_PORT_VLAN, 1); 22066f8d3f33SWingman Kwok 22076f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, priv->host_port, 22086f8d3f33SWingman Kwok ALE_PORT_STATE, ALE_PORT_STATE_FORWARD); 22096f8d3f33SWingman Kwok 22106f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, 0, 22116f8d3f33SWingman Kwok ALE_PORT_UNKNOWN_VLAN_MEMBER, 22126f8d3f33SWingman Kwok GBE_PORT_MASK(priv->ale_ports)); 22136f8d3f33SWingman Kwok 22146f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, 0, 22156f8d3f33SWingman Kwok ALE_PORT_UNKNOWN_MCAST_FLOOD, 22166f8d3f33SWingman Kwok GBE_PORT_MASK(priv->ale_ports - 1)); 22176f8d3f33SWingman Kwok 22186f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, 0, 22196f8d3f33SWingman Kwok ALE_PORT_UNKNOWN_REG_MCAST_FLOOD, 22206f8d3f33SWingman Kwok GBE_PORT_MASK(priv->ale_ports)); 22216f8d3f33SWingman Kwok 22226f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, 0, 22236f8d3f33SWingman Kwok ALE_PORT_UNTAGGED_EGRESS, 22246f8d3f33SWingman Kwok GBE_PORT_MASK(priv->ale_ports)); 22256f8d3f33SWingman Kwok } 22266f8d3f33SWingman Kwok 22276f8d3f33SWingman Kwok static void gbe_add_mcast_addr(struct gbe_intf *gbe_intf, u8 *addr) 22286f8d3f33SWingman Kwok { 22296f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 22306f8d3f33SWingman Kwok u16 vlan_id; 22316f8d3f33SWingman Kwok 22326f8d3f33SWingman Kwok cpsw_ale_add_mcast(gbe_dev->ale, addr, 22336f8d3f33SWingman Kwok GBE_PORT_MASK(gbe_dev->ale_ports), 0, 0, 22346f8d3f33SWingman Kwok ALE_MCAST_FWD_2); 22356f8d3f33SWingman Kwok for_each_set_bit(vlan_id, gbe_intf->active_vlans, VLAN_N_VID) { 22366f8d3f33SWingman Kwok cpsw_ale_add_mcast(gbe_dev->ale, addr, 22376f8d3f33SWingman Kwok GBE_PORT_MASK(gbe_dev->ale_ports), 22386f8d3f33SWingman Kwok ALE_VLAN, vlan_id, ALE_MCAST_FWD_2); 22396f8d3f33SWingman Kwok } 22406f8d3f33SWingman Kwok } 22416f8d3f33SWingman Kwok 22426f8d3f33SWingman Kwok static void gbe_add_ucast_addr(struct gbe_intf *gbe_intf, u8 *addr) 22436f8d3f33SWingman Kwok { 22446f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 22456f8d3f33SWingman Kwok u16 vlan_id; 22466f8d3f33SWingman Kwok 22476f8d3f33SWingman Kwok cpsw_ale_add_ucast(gbe_dev->ale, addr, gbe_dev->host_port, 0, 0); 22486f8d3f33SWingman Kwok 22496f8d3f33SWingman Kwok for_each_set_bit(vlan_id, gbe_intf->active_vlans, VLAN_N_VID) 22506f8d3f33SWingman Kwok cpsw_ale_add_ucast(gbe_dev->ale, addr, gbe_dev->host_port, 22516f8d3f33SWingman Kwok ALE_VLAN, vlan_id); 22526f8d3f33SWingman Kwok } 22536f8d3f33SWingman Kwok 22546f8d3f33SWingman Kwok static void gbe_del_mcast_addr(struct gbe_intf *gbe_intf, u8 *addr) 22556f8d3f33SWingman Kwok { 22566f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 22576f8d3f33SWingman Kwok u16 vlan_id; 22586f8d3f33SWingman Kwok 22596f8d3f33SWingman Kwok cpsw_ale_del_mcast(gbe_dev->ale, addr, 0, 0, 0); 22606f8d3f33SWingman Kwok 22616f8d3f33SWingman Kwok for_each_set_bit(vlan_id, gbe_intf->active_vlans, VLAN_N_VID) { 22626f8d3f33SWingman Kwok cpsw_ale_del_mcast(gbe_dev->ale, addr, 0, ALE_VLAN, vlan_id); 22636f8d3f33SWingman Kwok } 22646f8d3f33SWingman Kwok } 22656f8d3f33SWingman Kwok 22666f8d3f33SWingman Kwok static void gbe_del_ucast_addr(struct gbe_intf *gbe_intf, u8 *addr) 22676f8d3f33SWingman Kwok { 22686f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 22696f8d3f33SWingman Kwok u16 vlan_id; 22706f8d3f33SWingman Kwok 22716f8d3f33SWingman Kwok cpsw_ale_del_ucast(gbe_dev->ale, addr, gbe_dev->host_port, 0, 0); 22726f8d3f33SWingman Kwok 22736f8d3f33SWingman Kwok for_each_set_bit(vlan_id, gbe_intf->active_vlans, VLAN_N_VID) { 22746f8d3f33SWingman Kwok cpsw_ale_del_ucast(gbe_dev->ale, addr, gbe_dev->host_port, 22756f8d3f33SWingman Kwok ALE_VLAN, vlan_id); 22766f8d3f33SWingman Kwok } 22776f8d3f33SWingman Kwok } 22786f8d3f33SWingman Kwok 22796f8d3f33SWingman Kwok static int gbe_add_addr(void *intf_priv, struct netcp_addr *naddr) 22806f8d3f33SWingman Kwok { 22816f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv; 22826f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 22836f8d3f33SWingman Kwok 22846f8d3f33SWingman Kwok dev_dbg(gbe_dev->dev, "ethss adding address %pM, type %d\n", 22856f8d3f33SWingman Kwok naddr->addr, naddr->type); 22866f8d3f33SWingman Kwok 22876f8d3f33SWingman Kwok switch (naddr->type) { 22886f8d3f33SWingman Kwok case ADDR_MCAST: 22896f8d3f33SWingman Kwok case ADDR_BCAST: 22906f8d3f33SWingman Kwok gbe_add_mcast_addr(gbe_intf, naddr->addr); 22916f8d3f33SWingman Kwok break; 22926f8d3f33SWingman Kwok case ADDR_UCAST: 22936f8d3f33SWingman Kwok case ADDR_DEV: 22946f8d3f33SWingman Kwok gbe_add_ucast_addr(gbe_intf, naddr->addr); 22956f8d3f33SWingman Kwok break; 22966f8d3f33SWingman Kwok case ADDR_ANY: 22976f8d3f33SWingman Kwok /* nothing to do for promiscuous */ 22986f8d3f33SWingman Kwok default: 22996f8d3f33SWingman Kwok break; 23006f8d3f33SWingman Kwok } 23016f8d3f33SWingman Kwok 23026f8d3f33SWingman Kwok return 0; 23036f8d3f33SWingman Kwok } 23046f8d3f33SWingman Kwok 23056f8d3f33SWingman Kwok static int gbe_del_addr(void *intf_priv, struct netcp_addr *naddr) 23066f8d3f33SWingman Kwok { 23076f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv; 23086f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 23096f8d3f33SWingman Kwok 23106f8d3f33SWingman Kwok dev_dbg(gbe_dev->dev, "ethss deleting address %pM, type %d\n", 23116f8d3f33SWingman Kwok naddr->addr, naddr->type); 23126f8d3f33SWingman Kwok 23136f8d3f33SWingman Kwok switch (naddr->type) { 23146f8d3f33SWingman Kwok case ADDR_MCAST: 23156f8d3f33SWingman Kwok case ADDR_BCAST: 23166f8d3f33SWingman Kwok gbe_del_mcast_addr(gbe_intf, naddr->addr); 23176f8d3f33SWingman Kwok break; 23186f8d3f33SWingman Kwok case ADDR_UCAST: 23196f8d3f33SWingman Kwok case ADDR_DEV: 23206f8d3f33SWingman Kwok gbe_del_ucast_addr(gbe_intf, naddr->addr); 23216f8d3f33SWingman Kwok break; 23226f8d3f33SWingman Kwok case ADDR_ANY: 23236f8d3f33SWingman Kwok /* nothing to do for promiscuous */ 23246f8d3f33SWingman Kwok default: 23256f8d3f33SWingman Kwok break; 23266f8d3f33SWingman Kwok } 23276f8d3f33SWingman Kwok 23286f8d3f33SWingman Kwok return 0; 23296f8d3f33SWingman Kwok } 23306f8d3f33SWingman Kwok 23316f8d3f33SWingman Kwok static int gbe_add_vid(void *intf_priv, int vid) 23326f8d3f33SWingman Kwok { 23336f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv; 23346f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 23356f8d3f33SWingman Kwok 23366f8d3f33SWingman Kwok set_bit(vid, gbe_intf->active_vlans); 23376f8d3f33SWingman Kwok 23386f8d3f33SWingman Kwok cpsw_ale_add_vlan(gbe_dev->ale, vid, 23396f8d3f33SWingman Kwok GBE_PORT_MASK(gbe_dev->ale_ports), 23406f8d3f33SWingman Kwok GBE_MASK_NO_PORTS, 23416f8d3f33SWingman Kwok GBE_PORT_MASK(gbe_dev->ale_ports), 23426f8d3f33SWingman Kwok GBE_PORT_MASK(gbe_dev->ale_ports - 1)); 23436f8d3f33SWingman Kwok 23446f8d3f33SWingman Kwok return 0; 23456f8d3f33SWingman Kwok } 23466f8d3f33SWingman Kwok 23476f8d3f33SWingman Kwok static int gbe_del_vid(void *intf_priv, int vid) 23486f8d3f33SWingman Kwok { 23496f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv; 23506f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 23516f8d3f33SWingman Kwok 23526f8d3f33SWingman Kwok cpsw_ale_del_vlan(gbe_dev->ale, vid, 0); 23536f8d3f33SWingman Kwok clear_bit(vid, gbe_intf->active_vlans); 23546f8d3f33SWingman Kwok return 0; 23556f8d3f33SWingman Kwok } 23566f8d3f33SWingman Kwok 23576f8d3f33SWingman Kwok static int gbe_ioctl(void *intf_priv, struct ifreq *req, int cmd) 23586f8d3f33SWingman Kwok { 23596f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv; 23606f8d3f33SWingman Kwok struct phy_device *phy = gbe_intf->slave->phy; 23616f8d3f33SWingman Kwok int ret = -EOPNOTSUPP; 23626f8d3f33SWingman Kwok 23636f8d3f33SWingman Kwok if (phy) 23646f8d3f33SWingman Kwok ret = phy_mii_ioctl(phy, req, cmd); 23656f8d3f33SWingman Kwok 23666f8d3f33SWingman Kwok return ret; 23676f8d3f33SWingman Kwok } 23686f8d3f33SWingman Kwok 23696f8d3f33SWingman Kwok static void netcp_ethss_timer(unsigned long arg) 23706f8d3f33SWingman Kwok { 23716f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = (struct gbe_priv *)arg; 23726f8d3f33SWingman Kwok struct gbe_intf *gbe_intf; 23736f8d3f33SWingman Kwok struct gbe_slave *slave; 23746f8d3f33SWingman Kwok 23756f8d3f33SWingman Kwok /* Check & update SGMII link state of interfaces */ 23766f8d3f33SWingman Kwok for_each_intf(gbe_intf, gbe_dev) { 23776f8d3f33SWingman Kwok if (!gbe_intf->slave->open) 23786f8d3f33SWingman Kwok continue; 23796f8d3f33SWingman Kwok netcp_ethss_update_link_state(gbe_dev, gbe_intf->slave, 23806f8d3f33SWingman Kwok gbe_intf->ndev); 23816f8d3f33SWingman Kwok } 23826f8d3f33SWingman Kwok 23836f8d3f33SWingman Kwok /* Check & update SGMII link state of secondary ports */ 23846f8d3f33SWingman Kwok for_each_sec_slave(slave, gbe_dev) { 23856f8d3f33SWingman Kwok netcp_ethss_update_link_state(gbe_dev, slave, NULL); 23866f8d3f33SWingman Kwok } 23876f8d3f33SWingman Kwok 2388c0f54edbSWingMan Kwok /* A timer runs as a BH, no need to block them */ 2389c0f54edbSWingMan Kwok spin_lock(&gbe_dev->hw_stats_lock); 23906f8d3f33SWingman Kwok 23916f8d3f33SWingman Kwok if (gbe_dev->ss_version == GBE_SS_VERSION_14) 23926f8d3f33SWingman Kwok gbe_update_stats_ver14(gbe_dev, NULL); 23936f8d3f33SWingman Kwok else 23946f8d3f33SWingman Kwok gbe_update_stats(gbe_dev, NULL); 23956f8d3f33SWingman Kwok 2396c0f54edbSWingMan Kwok spin_unlock(&gbe_dev->hw_stats_lock); 23976f8d3f33SWingman Kwok 23986f8d3f33SWingman Kwok gbe_dev->timer.expires = jiffies + GBE_TIMER_INTERVAL; 23996f8d3f33SWingman Kwok add_timer(&gbe_dev->timer); 24006f8d3f33SWingman Kwok } 24016f8d3f33SWingman Kwok 24026f8d3f33SWingman Kwok static int gbe_tx_hook(int order, void *data, struct netcp_packet *p_info) 24036f8d3f33SWingman Kwok { 24046f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = data; 24056f8d3f33SWingman Kwok 24066f8d3f33SWingman Kwok p_info->tx_pipe = &gbe_intf->tx_pipe; 24076f8d3f33SWingman Kwok return 0; 24086f8d3f33SWingman Kwok } 24096f8d3f33SWingman Kwok 24106f8d3f33SWingman Kwok static int gbe_open(void *intf_priv, struct net_device *ndev) 24116f8d3f33SWingman Kwok { 24126f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv; 24136f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 24146f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 24156f8d3f33SWingman Kwok struct gbe_slave *slave = gbe_intf->slave; 24166f8d3f33SWingman Kwok int port_num = slave->port_num; 24176f8d3f33SWingman Kwok u32 reg; 24186f8d3f33SWingman Kwok int ret; 24196f8d3f33SWingman Kwok 24206f8d3f33SWingman Kwok reg = readl(GBE_REG_ADDR(gbe_dev, switch_regs, id_ver)); 24216f8d3f33SWingman Kwok dev_dbg(gbe_dev->dev, "initializing gbe version %d.%d (%d) GBE identification value 0x%x\n", 24226f8d3f33SWingman Kwok GBE_MAJOR_VERSION(reg), GBE_MINOR_VERSION(reg), 24236f8d3f33SWingman Kwok GBE_RTL_VERSION(reg), GBE_IDENT(reg)); 24246f8d3f33SWingman Kwok 24259a391c7bSWingMan Kwok /* For 10G and on NetCP 1.5, use directed to port */ 24269a391c7bSWingMan Kwok if ((gbe_dev->ss_version == XGBE_SS_VERSION_10) || IS_SS_ID_MU(gbe_dev)) 2427e170f409SKaricheri, Muralidharan gbe_intf->tx_pipe.flags = SWITCH_TO_PORT_IN_TAGINFO; 24286f8d3f33SWingman Kwok 2429e170f409SKaricheri, Muralidharan if (gbe_dev->enable_ale) 2430e170f409SKaricheri, Muralidharan gbe_intf->tx_pipe.switch_to_port = 0; 2431e170f409SKaricheri, Muralidharan else 2432e170f409SKaricheri, Muralidharan gbe_intf->tx_pipe.switch_to_port = port_num; 2433e170f409SKaricheri, Muralidharan 2434e170f409SKaricheri, Muralidharan dev_dbg(gbe_dev->dev, 2435e170f409SKaricheri, Muralidharan "opened TX channel %s: %p with to port %d, flags %d\n", 24366f8d3f33SWingman Kwok gbe_intf->tx_pipe.dma_chan_name, 24376f8d3f33SWingman Kwok gbe_intf->tx_pipe.dma_channel, 2438e170f409SKaricheri, Muralidharan gbe_intf->tx_pipe.switch_to_port, 2439e170f409SKaricheri, Muralidharan gbe_intf->tx_pipe.flags); 24406f8d3f33SWingman Kwok 24416f8d3f33SWingman Kwok gbe_slave_stop(gbe_intf); 24426f8d3f33SWingman Kwok 24436f8d3f33SWingman Kwok /* disable priority elevation and enable statistics on all ports */ 24446f8d3f33SWingman Kwok writel(0, GBE_REG_ADDR(gbe_dev, switch_regs, ptype)); 24456f8d3f33SWingman Kwok 24466f8d3f33SWingman Kwok /* Control register */ 24476f8d3f33SWingman Kwok writel(GBE_CTL_P0_ENABLE, GBE_REG_ADDR(gbe_dev, switch_regs, control)); 24486f8d3f33SWingman Kwok 24496f8d3f33SWingman Kwok /* All statistics enabled and STAT AB visible by default */ 24509a391c7bSWingMan Kwok writel(gbe_dev->stats_en_mask, GBE_REG_ADDR(gbe_dev, switch_regs, 24516f8d3f33SWingman Kwok stat_port_en)); 24526f8d3f33SWingman Kwok 24536f8d3f33SWingman Kwok ret = gbe_slave_open(gbe_intf); 24546f8d3f33SWingman Kwok if (ret) 24556f8d3f33SWingman Kwok goto fail; 24566f8d3f33SWingman Kwok 24576f8d3f33SWingman Kwok netcp_register_txhook(netcp, GBE_TXHOOK_ORDER, gbe_tx_hook, 24586f8d3f33SWingman Kwok gbe_intf); 24596f8d3f33SWingman Kwok 24606f8d3f33SWingman Kwok slave->open = true; 24616f8d3f33SWingman Kwok netcp_ethss_update_link_state(gbe_dev, slave, ndev); 24626f8d3f33SWingman Kwok return 0; 24636f8d3f33SWingman Kwok 24646f8d3f33SWingman Kwok fail: 24656f8d3f33SWingman Kwok gbe_slave_stop(gbe_intf); 24666f8d3f33SWingman Kwok return ret; 24676f8d3f33SWingman Kwok } 24686f8d3f33SWingman Kwok 24696f8d3f33SWingman Kwok static int gbe_close(void *intf_priv, struct net_device *ndev) 24706f8d3f33SWingman Kwok { 24716f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv; 24726f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 24736f8d3f33SWingman Kwok 24746f8d3f33SWingman Kwok gbe_slave_stop(gbe_intf); 24756f8d3f33SWingman Kwok netcp_unregister_txhook(netcp, GBE_TXHOOK_ORDER, gbe_tx_hook, 24766f8d3f33SWingman Kwok gbe_intf); 24776f8d3f33SWingman Kwok 24786f8d3f33SWingman Kwok gbe_intf->slave->open = false; 24796f8d3f33SWingman Kwok atomic_set(&gbe_intf->slave->link_state, NETCP_LINK_STATE_INVALID); 24806f8d3f33SWingman Kwok return 0; 24816f8d3f33SWingman Kwok } 24826f8d3f33SWingman Kwok 24836f8d3f33SWingman Kwok static int init_slave(struct gbe_priv *gbe_dev, struct gbe_slave *slave, 24846f8d3f33SWingman Kwok struct device_node *node) 24856f8d3f33SWingman Kwok { 24866f8d3f33SWingman Kwok int port_reg_num; 24876f8d3f33SWingman Kwok u32 port_reg_ofs, emac_reg_ofs; 24889a391c7bSWingMan Kwok u32 port_reg_blk_sz, emac_reg_blk_sz; 24896f8d3f33SWingman Kwok 24906f8d3f33SWingman Kwok if (of_property_read_u32(node, "slave-port", &slave->slave_num)) { 24916f8d3f33SWingman Kwok dev_err(gbe_dev->dev, "missing slave-port parameter\n"); 24926f8d3f33SWingman Kwok return -EINVAL; 24936f8d3f33SWingman Kwok } 24946f8d3f33SWingman Kwok 24956f8d3f33SWingman Kwok if (of_property_read_u32(node, "link-interface", 24966f8d3f33SWingman Kwok &slave->link_interface)) { 24976f8d3f33SWingman Kwok dev_warn(gbe_dev->dev, 24986f8d3f33SWingman Kwok "missing link-interface value defaulting to 1G mac-phy link\n"); 24996f8d3f33SWingman Kwok slave->link_interface = SGMII_LINK_MAC_PHY; 25006f8d3f33SWingman Kwok } 25016f8d3f33SWingman Kwok 25026f8d3f33SWingman Kwok slave->open = false; 25036f8d3f33SWingman Kwok slave->phy_node = of_parse_phandle(node, "phy-handle", 0); 25046f8d3f33SWingman Kwok slave->port_num = gbe_get_slave_port(gbe_dev, slave->slave_num); 25056f8d3f33SWingman Kwok 250690cff9e2SWingman Kwok if (slave->link_interface >= XGMII_LINK_MAC_PHY) 250790cff9e2SWingman Kwok slave->mac_control = GBE_DEF_10G_MAC_CONTROL; 250890cff9e2SWingman Kwok else 25096f8d3f33SWingman Kwok slave->mac_control = GBE_DEF_1G_MAC_CONTROL; 25106f8d3f33SWingman Kwok 25116f8d3f33SWingman Kwok /* Emac regs memmap are contiguous but port regs are not */ 25126f8d3f33SWingman Kwok port_reg_num = slave->slave_num; 25136f8d3f33SWingman Kwok if (gbe_dev->ss_version == GBE_SS_VERSION_14) { 25146f8d3f33SWingman Kwok if (slave->slave_num > 1) { 25156f8d3f33SWingman Kwok port_reg_ofs = GBE13_SLAVE_PORT2_OFFSET; 25166f8d3f33SWingman Kwok port_reg_num -= 2; 25176f8d3f33SWingman Kwok } else { 25186f8d3f33SWingman Kwok port_reg_ofs = GBE13_SLAVE_PORT_OFFSET; 25196f8d3f33SWingman Kwok } 25209a391c7bSWingMan Kwok emac_reg_ofs = GBE13_EMAC_OFFSET; 25219a391c7bSWingMan Kwok port_reg_blk_sz = 0x30; 25229a391c7bSWingMan Kwok emac_reg_blk_sz = 0x40; 25239a391c7bSWingMan Kwok } else if (IS_SS_ID_MU(gbe_dev)) { 25249a391c7bSWingMan Kwok port_reg_ofs = GBENU_SLAVE_PORT_OFFSET; 25259a391c7bSWingMan Kwok emac_reg_ofs = GBENU_EMAC_OFFSET; 25269a391c7bSWingMan Kwok port_reg_blk_sz = 0x1000; 25279a391c7bSWingMan Kwok emac_reg_blk_sz = 0x1000; 252890cff9e2SWingman Kwok } else if (gbe_dev->ss_version == XGBE_SS_VERSION_10) { 252990cff9e2SWingman Kwok port_reg_ofs = XGBE10_SLAVE_PORT_OFFSET; 25309a391c7bSWingMan Kwok emac_reg_ofs = XGBE10_EMAC_OFFSET; 25319a391c7bSWingMan Kwok port_reg_blk_sz = 0x30; 25329a391c7bSWingMan Kwok emac_reg_blk_sz = 0x40; 25336f8d3f33SWingman Kwok } else { 25346f8d3f33SWingman Kwok dev_err(gbe_dev->dev, "unknown ethss(0x%x)\n", 25356f8d3f33SWingman Kwok gbe_dev->ss_version); 25366f8d3f33SWingman Kwok return -EINVAL; 25376f8d3f33SWingman Kwok } 25386f8d3f33SWingman Kwok 253921e0e0ddSKaricheri, Muralidharan slave->port_regs = gbe_dev->switch_regs + port_reg_ofs + 25409a391c7bSWingMan Kwok (port_reg_blk_sz * port_reg_num); 254121e0e0ddSKaricheri, Muralidharan slave->emac_regs = gbe_dev->switch_regs + emac_reg_ofs + 25429a391c7bSWingMan Kwok (emac_reg_blk_sz * slave->slave_num); 25436f8d3f33SWingman Kwok 25446f8d3f33SWingman Kwok if (gbe_dev->ss_version == GBE_SS_VERSION_14) { 25456f8d3f33SWingman Kwok /* Initialize slave port register offsets */ 25466f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, port_vlan); 25476f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, tx_pri_map); 25486f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, sa_lo); 25496f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, sa_hi); 25506f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, ts_ctl); 25516f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, ts_seq_ltype); 25526f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, ts_vlan); 25536f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, ts_ctl_ltype2); 25546f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, ts_ctl2); 25556f8d3f33SWingman Kwok 25566f8d3f33SWingman Kwok /* Initialize EMAC register offsets */ 25576f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, emac_regs, mac_control); 25586f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, emac_regs, soft_reset); 25596f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, emac_regs, rx_maxlen); 25606f8d3f33SWingman Kwok 25619a391c7bSWingMan Kwok } else if (IS_SS_ID_MU(gbe_dev)) { 25629a391c7bSWingMan Kwok /* Initialize slave port register offsets */ 25639a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, port_vlan); 25649a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, tx_pri_map); 25659a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, sa_lo); 25669a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, sa_hi); 25679a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, ts_ctl); 25689a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, ts_seq_ltype); 25699a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, ts_vlan); 25709a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, ts_ctl_ltype2); 25719a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, ts_ctl2); 25729a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, rx_maxlen); 25739a391c7bSWingMan Kwok 25749a391c7bSWingMan Kwok /* Initialize EMAC register offsets */ 25759a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, emac_regs, mac_control); 25769a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, emac_regs, soft_reset); 25779a391c7bSWingMan Kwok 257890cff9e2SWingman Kwok } else if (gbe_dev->ss_version == XGBE_SS_VERSION_10) { 257990cff9e2SWingman Kwok /* Initialize slave port register offsets */ 258090cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, port_vlan); 258190cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, tx_pri_map); 258290cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, sa_lo); 258390cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, sa_hi); 258490cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, ts_ctl); 258590cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, ts_seq_ltype); 258690cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, ts_vlan); 258790cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, ts_ctl_ltype2); 258890cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, ts_ctl2); 258990cff9e2SWingman Kwok 259090cff9e2SWingman Kwok /* Initialize EMAC register offsets */ 259190cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, emac_regs, mac_control); 259290cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, emac_regs, soft_reset); 259390cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, emac_regs, rx_maxlen); 25946f8d3f33SWingman Kwok } 25956f8d3f33SWingman Kwok 25966f8d3f33SWingman Kwok atomic_set(&slave->link_state, NETCP_LINK_STATE_INVALID); 25976f8d3f33SWingman Kwok return 0; 25986f8d3f33SWingman Kwok } 25996f8d3f33SWingman Kwok 26006f8d3f33SWingman Kwok static void init_secondary_ports(struct gbe_priv *gbe_dev, 26016f8d3f33SWingman Kwok struct device_node *node) 26026f8d3f33SWingman Kwok { 26036f8d3f33SWingman Kwok struct device *dev = gbe_dev->dev; 26046f8d3f33SWingman Kwok phy_interface_t phy_mode; 26056f8d3f33SWingman Kwok struct gbe_priv **priv; 26066f8d3f33SWingman Kwok struct device_node *port; 26076f8d3f33SWingman Kwok struct gbe_slave *slave; 26086f8d3f33SWingman Kwok bool mac_phy_link = false; 26096f8d3f33SWingman Kwok 26106f8d3f33SWingman Kwok for_each_child_of_node(node, port) { 26116f8d3f33SWingman Kwok slave = devm_kzalloc(dev, sizeof(*slave), GFP_KERNEL); 26126f8d3f33SWingman Kwok if (!slave) { 26136f8d3f33SWingman Kwok dev_err(dev, 26146f8d3f33SWingman Kwok "memomry alloc failed for secondary port(%s), skipping...\n", 26156f8d3f33SWingman Kwok port->name); 26166f8d3f33SWingman Kwok continue; 26176f8d3f33SWingman Kwok } 26186f8d3f33SWingman Kwok 26196f8d3f33SWingman Kwok if (init_slave(gbe_dev, slave, port)) { 26206f8d3f33SWingman Kwok dev_err(dev, 26216f8d3f33SWingman Kwok "Failed to initialize secondary port(%s), skipping...\n", 26226f8d3f33SWingman Kwok port->name); 26236f8d3f33SWingman Kwok devm_kfree(dev, slave); 26246f8d3f33SWingman Kwok continue; 26256f8d3f33SWingman Kwok } 26266f8d3f33SWingman Kwok 26276f8d3f33SWingman Kwok gbe_sgmii_config(gbe_dev, slave); 26286f8d3f33SWingman Kwok gbe_port_reset(slave); 26296f8d3f33SWingman Kwok gbe_port_config(gbe_dev, slave, gbe_dev->rx_packet_max); 26306f8d3f33SWingman Kwok list_add_tail(&slave->slave_list, &gbe_dev->secondary_slaves); 26316f8d3f33SWingman Kwok gbe_dev->num_slaves++; 263290cff9e2SWingman Kwok if ((slave->link_interface == SGMII_LINK_MAC_PHY) || 263390cff9e2SWingman Kwok (slave->link_interface == XGMII_LINK_MAC_PHY)) 26346f8d3f33SWingman Kwok mac_phy_link = true; 26356f8d3f33SWingman Kwok 26366f8d3f33SWingman Kwok slave->open = true; 26379a391c7bSWingMan Kwok if (gbe_dev->num_slaves >= gbe_dev->max_num_slaves) 26389a391c7bSWingMan Kwok break; 26396f8d3f33SWingman Kwok } 26406f8d3f33SWingman Kwok 26416f8d3f33SWingman Kwok /* of_phy_connect() is needed only for MAC-PHY interface */ 26426f8d3f33SWingman Kwok if (!mac_phy_link) 26436f8d3f33SWingman Kwok return; 26446f8d3f33SWingman Kwok 26456f8d3f33SWingman Kwok /* Allocate dummy netdev device for attaching to phy device */ 26466f8d3f33SWingman Kwok gbe_dev->dummy_ndev = alloc_netdev(sizeof(gbe_dev), "dummy", 26476f8d3f33SWingman Kwok NET_NAME_UNKNOWN, ether_setup); 26486f8d3f33SWingman Kwok if (!gbe_dev->dummy_ndev) { 26496f8d3f33SWingman Kwok dev_err(dev, 26506f8d3f33SWingman Kwok "Failed to allocate dummy netdev for secondary ports, skipping phy_connect()...\n"); 26516f8d3f33SWingman Kwok return; 26526f8d3f33SWingman Kwok } 26536f8d3f33SWingman Kwok priv = netdev_priv(gbe_dev->dummy_ndev); 26546f8d3f33SWingman Kwok *priv = gbe_dev; 26556f8d3f33SWingman Kwok 26566f8d3f33SWingman Kwok if (slave->link_interface == SGMII_LINK_MAC_PHY) { 26576f8d3f33SWingman Kwok phy_mode = PHY_INTERFACE_MODE_SGMII; 26586f8d3f33SWingman Kwok slave->phy_port_t = PORT_MII; 26596f8d3f33SWingman Kwok } else { 26606f8d3f33SWingman Kwok phy_mode = PHY_INTERFACE_MODE_NA; 26616f8d3f33SWingman Kwok slave->phy_port_t = PORT_FIBRE; 26626f8d3f33SWingman Kwok } 26636f8d3f33SWingman Kwok 26646f8d3f33SWingman Kwok for_each_sec_slave(slave, gbe_dev) { 266590cff9e2SWingman Kwok if ((slave->link_interface != SGMII_LINK_MAC_PHY) && 266690cff9e2SWingman Kwok (slave->link_interface != XGMII_LINK_MAC_PHY)) 26676f8d3f33SWingman Kwok continue; 26686f8d3f33SWingman Kwok slave->phy = 26696f8d3f33SWingman Kwok of_phy_connect(gbe_dev->dummy_ndev, 26706f8d3f33SWingman Kwok slave->phy_node, 26716f8d3f33SWingman Kwok gbe_adjust_link_sec_slaves, 26726f8d3f33SWingman Kwok 0, phy_mode); 26736f8d3f33SWingman Kwok if (!slave->phy) { 26746f8d3f33SWingman Kwok dev_err(dev, "phy not found for slave %d\n", 26756f8d3f33SWingman Kwok slave->slave_num); 26766f8d3f33SWingman Kwok slave->phy = NULL; 26776f8d3f33SWingman Kwok } else { 26786f8d3f33SWingman Kwok dev_dbg(dev, "phy found: id is: 0x%s\n", 26796f8d3f33SWingman Kwok dev_name(&slave->phy->dev)); 26806f8d3f33SWingman Kwok phy_start(slave->phy); 26816f8d3f33SWingman Kwok phy_read_status(slave->phy); 26826f8d3f33SWingman Kwok } 26836f8d3f33SWingman Kwok } 26846f8d3f33SWingman Kwok } 26856f8d3f33SWingman Kwok 26866f8d3f33SWingman Kwok static void free_secondary_ports(struct gbe_priv *gbe_dev) 26876f8d3f33SWingman Kwok { 26886f8d3f33SWingman Kwok struct gbe_slave *slave; 26896f8d3f33SWingman Kwok 26906f8d3f33SWingman Kwok for (;;) { 26916f8d3f33SWingman Kwok slave = first_sec_slave(gbe_dev); 26926f8d3f33SWingman Kwok if (!slave) 26936f8d3f33SWingman Kwok break; 26946f8d3f33SWingman Kwok if (slave->phy) 26956f8d3f33SWingman Kwok phy_disconnect(slave->phy); 26966f8d3f33SWingman Kwok list_del(&slave->slave_list); 26976f8d3f33SWingman Kwok } 26986f8d3f33SWingman Kwok if (gbe_dev->dummy_ndev) 26996f8d3f33SWingman Kwok free_netdev(gbe_dev->dummy_ndev); 27006f8d3f33SWingman Kwok } 27016f8d3f33SWingman Kwok 270290cff9e2SWingman Kwok static int set_xgbe_ethss10_priv(struct gbe_priv *gbe_dev, 270390cff9e2SWingman Kwok struct device_node *node) 270490cff9e2SWingman Kwok { 270590cff9e2SWingman Kwok struct resource res; 270690cff9e2SWingman Kwok void __iomem *regs; 270790cff9e2SWingman Kwok int ret, i; 270890cff9e2SWingman Kwok 27099a391c7bSWingMan Kwok ret = of_address_to_resource(node, XGBE_SS_REG_INDEX, &res); 271090cff9e2SWingman Kwok if (ret) { 271121e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, 271221e0e0ddSKaricheri, Muralidharan "Can't xlate xgbe of node(%s) ss address at %d\n", 271321e0e0ddSKaricheri, Muralidharan node->name, XGBE_SS_REG_INDEX); 271490cff9e2SWingman Kwok return ret; 271590cff9e2SWingman Kwok } 271690cff9e2SWingman Kwok 271790cff9e2SWingman Kwok regs = devm_ioremap_resource(gbe_dev->dev, &res); 271890cff9e2SWingman Kwok if (IS_ERR(regs)) { 271921e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, "Failed to map xgbe ss register base\n"); 272090cff9e2SWingman Kwok return PTR_ERR(regs); 272190cff9e2SWingman Kwok } 272290cff9e2SWingman Kwok gbe_dev->ss_regs = regs; 272390cff9e2SWingman Kwok 272421e0e0ddSKaricheri, Muralidharan ret = of_address_to_resource(node, XGBE_SM_REG_INDEX, &res); 272521e0e0ddSKaricheri, Muralidharan if (ret) { 272621e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, 272721e0e0ddSKaricheri, Muralidharan "Can't xlate xgbe of node(%s) sm address at %d\n", 272821e0e0ddSKaricheri, Muralidharan node->name, XGBE_SM_REG_INDEX); 272921e0e0ddSKaricheri, Muralidharan return ret; 273021e0e0ddSKaricheri, Muralidharan } 273121e0e0ddSKaricheri, Muralidharan 273221e0e0ddSKaricheri, Muralidharan regs = devm_ioremap_resource(gbe_dev->dev, &res); 273321e0e0ddSKaricheri, Muralidharan if (IS_ERR(regs)) { 273421e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, "Failed to map xgbe sm register base\n"); 273521e0e0ddSKaricheri, Muralidharan return PTR_ERR(regs); 273621e0e0ddSKaricheri, Muralidharan } 273721e0e0ddSKaricheri, Muralidharan gbe_dev->switch_regs = regs; 273821e0e0ddSKaricheri, Muralidharan 273990cff9e2SWingman Kwok ret = of_address_to_resource(node, XGBE_SERDES_REG_INDEX, &res); 274090cff9e2SWingman Kwok if (ret) { 274121e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, 274221e0e0ddSKaricheri, Muralidharan "Can't xlate xgbe serdes of node(%s) address at %d\n", 274321e0e0ddSKaricheri, Muralidharan node->name, XGBE_SERDES_REG_INDEX); 274490cff9e2SWingman Kwok return ret; 274590cff9e2SWingman Kwok } 274690cff9e2SWingman Kwok 274790cff9e2SWingman Kwok regs = devm_ioremap_resource(gbe_dev->dev, &res); 274890cff9e2SWingman Kwok if (IS_ERR(regs)) { 274990cff9e2SWingman Kwok dev_err(gbe_dev->dev, "Failed to map xgbe serdes register base\n"); 275090cff9e2SWingman Kwok return PTR_ERR(regs); 275190cff9e2SWingman Kwok } 275290cff9e2SWingman Kwok gbe_dev->xgbe_serdes_regs = regs; 275390cff9e2SWingman Kwok 2754489e8a2fSWingMan Kwok gbe_dev->num_stats_mods = gbe_dev->max_num_ports; 2755208c6b9aSWingMan Kwok gbe_dev->et_stats = xgbe10_et_stats; 2756208c6b9aSWingMan Kwok gbe_dev->num_et_stats = ARRAY_SIZE(xgbe10_et_stats); 2757208c6b9aSWingMan Kwok 275890cff9e2SWingman Kwok gbe_dev->hw_stats = devm_kzalloc(gbe_dev->dev, 2759208c6b9aSWingMan Kwok gbe_dev->num_et_stats * sizeof(u64), 276090cff9e2SWingman Kwok GFP_KERNEL); 276190cff9e2SWingman Kwok if (!gbe_dev->hw_stats) { 276290cff9e2SWingman Kwok dev_err(gbe_dev->dev, "hw_stats memory allocation failed\n"); 276390cff9e2SWingman Kwok return -ENOMEM; 276490cff9e2SWingman Kwok } 276590cff9e2SWingman Kwok 2766489e8a2fSWingMan Kwok gbe_dev->hw_stats_prev = 2767489e8a2fSWingMan Kwok devm_kzalloc(gbe_dev->dev, 2768489e8a2fSWingMan Kwok gbe_dev->num_et_stats * sizeof(u32), 2769489e8a2fSWingMan Kwok GFP_KERNEL); 2770489e8a2fSWingMan Kwok if (!gbe_dev->hw_stats_prev) { 2771489e8a2fSWingMan Kwok dev_err(gbe_dev->dev, 2772489e8a2fSWingMan Kwok "hw_stats_prev memory allocation failed\n"); 2773489e8a2fSWingMan Kwok return -ENOMEM; 2774489e8a2fSWingMan Kwok } 2775489e8a2fSWingMan Kwok 277690cff9e2SWingman Kwok gbe_dev->ss_version = XGBE_SS_VERSION_10; 277790cff9e2SWingman Kwok gbe_dev->sgmii_port_regs = gbe_dev->ss_regs + 277890cff9e2SWingman Kwok XGBE10_SGMII_MODULE_OFFSET; 277990cff9e2SWingman Kwok gbe_dev->host_port_regs = gbe_dev->ss_regs + XGBE10_HOST_PORT_OFFSET; 278090cff9e2SWingman Kwok 27819a391c7bSWingMan Kwok for (i = 0; i < gbe_dev->max_num_ports; i++) 278221e0e0ddSKaricheri, Muralidharan gbe_dev->hw_stats_regs[i] = gbe_dev->switch_regs + 278390cff9e2SWingman Kwok XGBE10_HW_STATS_OFFSET + (GBE_HW_STATS_REG_MAP_SZ * i); 278490cff9e2SWingman Kwok 27859a391c7bSWingMan Kwok gbe_dev->ale_reg = gbe_dev->switch_regs + XGBE10_ALE_OFFSET; 27869a391c7bSWingMan Kwok gbe_dev->ale_ports = gbe_dev->max_num_ports; 278790cff9e2SWingman Kwok gbe_dev->host_port = XGBE10_HOST_PORT_NUM; 278890cff9e2SWingman Kwok gbe_dev->ale_entries = XGBE10_NUM_ALE_ENTRIES; 27899a391c7bSWingMan Kwok gbe_dev->stats_en_mask = (1 << (gbe_dev->max_num_ports)) - 1; 279090cff9e2SWingman Kwok 279190cff9e2SWingman Kwok /* Subsystem registers */ 279290cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, ss_regs, id_ver); 279390cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, ss_regs, control); 279490cff9e2SWingman Kwok 279590cff9e2SWingman Kwok /* Switch module registers */ 279690cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, switch_regs, id_ver); 279790cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, switch_regs, control); 279890cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, switch_regs, ptype); 279990cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, switch_regs, stat_port_en); 280090cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, switch_regs, flow_control); 280190cff9e2SWingman Kwok 280290cff9e2SWingman Kwok /* Host port registers */ 280390cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, host_port_regs, port_vlan); 280490cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, host_port_regs, tx_pri_map); 280590cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, host_port_regs, rx_maxlen); 280690cff9e2SWingman Kwok return 0; 280790cff9e2SWingman Kwok } 280890cff9e2SWingman Kwok 28096f8d3f33SWingman Kwok static int get_gbe_resource_version(struct gbe_priv *gbe_dev, 28106f8d3f33SWingman Kwok struct device_node *node) 28116f8d3f33SWingman Kwok { 28126f8d3f33SWingman Kwok struct resource res; 28136f8d3f33SWingman Kwok void __iomem *regs; 28146f8d3f33SWingman Kwok int ret; 28156f8d3f33SWingman Kwok 281621e0e0ddSKaricheri, Muralidharan ret = of_address_to_resource(node, GBE_SS_REG_INDEX, &res); 28176f8d3f33SWingman Kwok if (ret) { 281821e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, 281921e0e0ddSKaricheri, Muralidharan "Can't translate of node(%s) of gbe ss address at %d\n", 282021e0e0ddSKaricheri, Muralidharan node->name, GBE_SS_REG_INDEX); 28216f8d3f33SWingman Kwok return ret; 28226f8d3f33SWingman Kwok } 28236f8d3f33SWingman Kwok 28246f8d3f33SWingman Kwok regs = devm_ioremap_resource(gbe_dev->dev, &res); 28256f8d3f33SWingman Kwok if (IS_ERR(regs)) { 28266f8d3f33SWingman Kwok dev_err(gbe_dev->dev, "Failed to map gbe register base\n"); 28276f8d3f33SWingman Kwok return PTR_ERR(regs); 28286f8d3f33SWingman Kwok } 28296f8d3f33SWingman Kwok gbe_dev->ss_regs = regs; 28306f8d3f33SWingman Kwok gbe_dev->ss_version = readl(gbe_dev->ss_regs); 28316f8d3f33SWingman Kwok return 0; 28326f8d3f33SWingman Kwok } 28336f8d3f33SWingman Kwok 28346f8d3f33SWingman Kwok static int set_gbe_ethss14_priv(struct gbe_priv *gbe_dev, 28356f8d3f33SWingman Kwok struct device_node *node) 28366f8d3f33SWingman Kwok { 283721e0e0ddSKaricheri, Muralidharan struct resource res; 28386f8d3f33SWingman Kwok void __iomem *regs; 283921e0e0ddSKaricheri, Muralidharan int i, ret; 284021e0e0ddSKaricheri, Muralidharan 284121e0e0ddSKaricheri, Muralidharan ret = of_address_to_resource(node, GBE_SGMII34_REG_INDEX, &res); 284221e0e0ddSKaricheri, Muralidharan if (ret) { 284321e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, 284421e0e0ddSKaricheri, Muralidharan "Can't translate of gbe node(%s) address at index %d\n", 284521e0e0ddSKaricheri, Muralidharan node->name, GBE_SGMII34_REG_INDEX); 284621e0e0ddSKaricheri, Muralidharan return ret; 284721e0e0ddSKaricheri, Muralidharan } 284821e0e0ddSKaricheri, Muralidharan 284921e0e0ddSKaricheri, Muralidharan regs = devm_ioremap_resource(gbe_dev->dev, &res); 285021e0e0ddSKaricheri, Muralidharan if (IS_ERR(regs)) { 285121e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, 285221e0e0ddSKaricheri, Muralidharan "Failed to map gbe sgmii port34 register base\n"); 285321e0e0ddSKaricheri, Muralidharan return PTR_ERR(regs); 285421e0e0ddSKaricheri, Muralidharan } 285521e0e0ddSKaricheri, Muralidharan gbe_dev->sgmii_port34_regs = regs; 285621e0e0ddSKaricheri, Muralidharan 285721e0e0ddSKaricheri, Muralidharan ret = of_address_to_resource(node, GBE_SM_REG_INDEX, &res); 285821e0e0ddSKaricheri, Muralidharan if (ret) { 285921e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, 286021e0e0ddSKaricheri, Muralidharan "Can't translate of gbe node(%s) address at index %d\n", 286121e0e0ddSKaricheri, Muralidharan node->name, GBE_SM_REG_INDEX); 286221e0e0ddSKaricheri, Muralidharan return ret; 286321e0e0ddSKaricheri, Muralidharan } 286421e0e0ddSKaricheri, Muralidharan 286521e0e0ddSKaricheri, Muralidharan regs = devm_ioremap_resource(gbe_dev->dev, &res); 286621e0e0ddSKaricheri, Muralidharan if (IS_ERR(regs)) { 286721e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, 286821e0e0ddSKaricheri, Muralidharan "Failed to map gbe switch module register base\n"); 286921e0e0ddSKaricheri, Muralidharan return PTR_ERR(regs); 287021e0e0ddSKaricheri, Muralidharan } 287121e0e0ddSKaricheri, Muralidharan gbe_dev->switch_regs = regs; 28726f8d3f33SWingman Kwok 2873489e8a2fSWingMan Kwok gbe_dev->num_stats_mods = gbe_dev->max_num_slaves; 2874208c6b9aSWingMan Kwok gbe_dev->et_stats = gbe13_et_stats; 2875208c6b9aSWingMan Kwok gbe_dev->num_et_stats = ARRAY_SIZE(gbe13_et_stats); 2876208c6b9aSWingMan Kwok 28776f8d3f33SWingman Kwok gbe_dev->hw_stats = devm_kzalloc(gbe_dev->dev, 2878208c6b9aSWingMan Kwok gbe_dev->num_et_stats * sizeof(u64), 28796f8d3f33SWingman Kwok GFP_KERNEL); 28806f8d3f33SWingman Kwok if (!gbe_dev->hw_stats) { 28816f8d3f33SWingman Kwok dev_err(gbe_dev->dev, "hw_stats memory allocation failed\n"); 28826f8d3f33SWingman Kwok return -ENOMEM; 28836f8d3f33SWingman Kwok } 28846f8d3f33SWingman Kwok 2885489e8a2fSWingMan Kwok gbe_dev->hw_stats_prev = 2886489e8a2fSWingMan Kwok devm_kzalloc(gbe_dev->dev, 2887489e8a2fSWingMan Kwok gbe_dev->num_et_stats * sizeof(u32), 2888489e8a2fSWingMan Kwok GFP_KERNEL); 2889489e8a2fSWingMan Kwok if (!gbe_dev->hw_stats_prev) { 2890489e8a2fSWingMan Kwok dev_err(gbe_dev->dev, 2891489e8a2fSWingMan Kwok "hw_stats_prev memory allocation failed\n"); 2892489e8a2fSWingMan Kwok return -ENOMEM; 2893489e8a2fSWingMan Kwok } 2894489e8a2fSWingMan Kwok 289521e0e0ddSKaricheri, Muralidharan gbe_dev->sgmii_port_regs = gbe_dev->ss_regs + GBE13_SGMII_MODULE_OFFSET; 289621e0e0ddSKaricheri, Muralidharan gbe_dev->host_port_regs = gbe_dev->switch_regs + GBE13_HOST_PORT_OFFSET; 28976f8d3f33SWingman Kwok 2898a94bcd09SWingMan Kwok /* K2HK has only 2 hw stats modules visible at a time, so 2899a94bcd09SWingMan Kwok * module 0 & 2 points to one base and 2900a94bcd09SWingMan Kwok * module 1 & 3 points to the other base 2901a94bcd09SWingMan Kwok */ 29029a391c7bSWingMan Kwok for (i = 0; i < gbe_dev->max_num_slaves; i++) { 290321e0e0ddSKaricheri, Muralidharan gbe_dev->hw_stats_regs[i] = 290421e0e0ddSKaricheri, Muralidharan gbe_dev->switch_regs + GBE13_HW_STATS_OFFSET + 2905a94bcd09SWingMan Kwok (GBE_HW_STATS_REG_MAP_SZ * (i & 0x1)); 290621e0e0ddSKaricheri, Muralidharan } 29076f8d3f33SWingman Kwok 290821e0e0ddSKaricheri, Muralidharan gbe_dev->ale_reg = gbe_dev->switch_regs + GBE13_ALE_OFFSET; 29099a391c7bSWingMan Kwok gbe_dev->ale_ports = gbe_dev->max_num_ports; 29106f8d3f33SWingman Kwok gbe_dev->host_port = GBE13_HOST_PORT_NUM; 29116f8d3f33SWingman Kwok gbe_dev->ale_entries = GBE13_NUM_ALE_ENTRIES; 29129a391c7bSWingMan Kwok gbe_dev->stats_en_mask = GBE13_REG_VAL_STAT_ENABLE_ALL; 29136f8d3f33SWingman Kwok 29146f8d3f33SWingman Kwok /* Subsystem registers */ 29156f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, ss_regs, id_ver); 29166f8d3f33SWingman Kwok 29176f8d3f33SWingman Kwok /* Switch module registers */ 29186f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, switch_regs, id_ver); 29196f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, switch_regs, control); 29206f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, switch_regs, soft_reset); 29216f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, switch_regs, stat_port_en); 29226f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, switch_regs, ptype); 29236f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, switch_regs, flow_control); 29246f8d3f33SWingman Kwok 29256f8d3f33SWingman Kwok /* Host port registers */ 29266f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, host_port_regs, port_vlan); 29276f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, host_port_regs, rx_maxlen); 29286f8d3f33SWingman Kwok return 0; 29296f8d3f33SWingman Kwok } 29306f8d3f33SWingman Kwok 29319a391c7bSWingMan Kwok static int set_gbenu_ethss_priv(struct gbe_priv *gbe_dev, 29329a391c7bSWingMan Kwok struct device_node *node) 29339a391c7bSWingMan Kwok { 29349a391c7bSWingMan Kwok struct resource res; 29359a391c7bSWingMan Kwok void __iomem *regs; 29369a391c7bSWingMan Kwok int i, ret; 29379a391c7bSWingMan Kwok 2938489e8a2fSWingMan Kwok gbe_dev->num_stats_mods = gbe_dev->max_num_ports; 2939208c6b9aSWingMan Kwok gbe_dev->et_stats = gbenu_et_stats; 2940208c6b9aSWingMan Kwok 2941208c6b9aSWingMan Kwok if (IS_SS_ID_NU(gbe_dev)) 2942208c6b9aSWingMan Kwok gbe_dev->num_et_stats = GBENU_ET_STATS_HOST_SIZE + 2943208c6b9aSWingMan Kwok (gbe_dev->max_num_slaves * GBENU_ET_STATS_PORT_SIZE); 2944208c6b9aSWingMan Kwok else 2945208c6b9aSWingMan Kwok gbe_dev->num_et_stats = GBENU_ET_STATS_HOST_SIZE + 2946208c6b9aSWingMan Kwok GBENU_ET_STATS_PORT_SIZE; 2947208c6b9aSWingMan Kwok 29489a391c7bSWingMan Kwok gbe_dev->hw_stats = devm_kzalloc(gbe_dev->dev, 2949208c6b9aSWingMan Kwok gbe_dev->num_et_stats * sizeof(u64), 29509a391c7bSWingMan Kwok GFP_KERNEL); 29519a391c7bSWingMan Kwok if (!gbe_dev->hw_stats) { 29529a391c7bSWingMan Kwok dev_err(gbe_dev->dev, "hw_stats memory allocation failed\n"); 29539a391c7bSWingMan Kwok return -ENOMEM; 29549a391c7bSWingMan Kwok } 29559a391c7bSWingMan Kwok 2956489e8a2fSWingMan Kwok gbe_dev->hw_stats_prev = 2957489e8a2fSWingMan Kwok devm_kzalloc(gbe_dev->dev, 2958489e8a2fSWingMan Kwok gbe_dev->num_et_stats * sizeof(u32), 2959489e8a2fSWingMan Kwok GFP_KERNEL); 2960489e8a2fSWingMan Kwok if (!gbe_dev->hw_stats_prev) { 2961489e8a2fSWingMan Kwok dev_err(gbe_dev->dev, 2962489e8a2fSWingMan Kwok "hw_stats_prev memory allocation failed\n"); 2963489e8a2fSWingMan Kwok return -ENOMEM; 2964489e8a2fSWingMan Kwok } 2965489e8a2fSWingMan Kwok 29669a391c7bSWingMan Kwok ret = of_address_to_resource(node, GBENU_SM_REG_INDEX, &res); 29679a391c7bSWingMan Kwok if (ret) { 29689a391c7bSWingMan Kwok dev_err(gbe_dev->dev, 29699a391c7bSWingMan Kwok "Can't translate of gbenu node(%s) addr at index %d\n", 29709a391c7bSWingMan Kwok node->name, GBENU_SM_REG_INDEX); 29719a391c7bSWingMan Kwok return ret; 29729a391c7bSWingMan Kwok } 29739a391c7bSWingMan Kwok 29749a391c7bSWingMan Kwok regs = devm_ioremap_resource(gbe_dev->dev, &res); 29759a391c7bSWingMan Kwok if (IS_ERR(regs)) { 29769a391c7bSWingMan Kwok dev_err(gbe_dev->dev, 29779a391c7bSWingMan Kwok "Failed to map gbenu switch module register base\n"); 29789a391c7bSWingMan Kwok return PTR_ERR(regs); 29799a391c7bSWingMan Kwok } 29809a391c7bSWingMan Kwok gbe_dev->switch_regs = regs; 29819a391c7bSWingMan Kwok 29829a391c7bSWingMan Kwok gbe_dev->sgmii_port_regs = gbe_dev->ss_regs + GBENU_SGMII_MODULE_OFFSET; 29839a391c7bSWingMan Kwok gbe_dev->host_port_regs = gbe_dev->switch_regs + GBENU_HOST_PORT_OFFSET; 29849a391c7bSWingMan Kwok 29859a391c7bSWingMan Kwok for (i = 0; i < (gbe_dev->max_num_ports); i++) 29869a391c7bSWingMan Kwok gbe_dev->hw_stats_regs[i] = gbe_dev->switch_regs + 29879a391c7bSWingMan Kwok GBENU_HW_STATS_OFFSET + (GBENU_HW_STATS_REG_MAP_SZ * i); 29889a391c7bSWingMan Kwok 29899a391c7bSWingMan Kwok gbe_dev->ale_reg = gbe_dev->switch_regs + GBENU_ALE_OFFSET; 29909a391c7bSWingMan Kwok gbe_dev->ale_ports = gbe_dev->max_num_ports; 29919a391c7bSWingMan Kwok gbe_dev->host_port = GBENU_HOST_PORT_NUM; 29929a391c7bSWingMan Kwok gbe_dev->ale_entries = GBE13_NUM_ALE_ENTRIES; 29939a391c7bSWingMan Kwok gbe_dev->stats_en_mask = (1 << (gbe_dev->max_num_ports)) - 1; 29949a391c7bSWingMan Kwok 29959a391c7bSWingMan Kwok /* Subsystem registers */ 29969a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, ss_regs, id_ver); 29979a391c7bSWingMan Kwok 29989a391c7bSWingMan Kwok /* Switch module registers */ 29999a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, switch_regs, id_ver); 30009a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, switch_regs, control); 30019a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, switch_regs, stat_port_en); 30029a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, switch_regs, ptype); 30039a391c7bSWingMan Kwok 30049a391c7bSWingMan Kwok /* Host port registers */ 30059a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, host_port_regs, port_vlan); 30069a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, host_port_regs, rx_maxlen); 30079a391c7bSWingMan Kwok 30089a391c7bSWingMan Kwok /* For NU only. 2U does not need tx_pri_map. 30099a391c7bSWingMan Kwok * NU cppi port 0 tx pkt streaming interface has (n-1)*8 egress threads 30109a391c7bSWingMan Kwok * while 2U has only 1 such thread 30119a391c7bSWingMan Kwok */ 30129a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, host_port_regs, tx_pri_map); 30139a391c7bSWingMan Kwok return 0; 30149a391c7bSWingMan Kwok } 30159a391c7bSWingMan Kwok 30166f8d3f33SWingman Kwok static int gbe_probe(struct netcp_device *netcp_device, struct device *dev, 30176f8d3f33SWingman Kwok struct device_node *node, void **inst_priv) 30186f8d3f33SWingman Kwok { 30196f8d3f33SWingman Kwok struct device_node *interfaces, *interface; 30206f8d3f33SWingman Kwok struct device_node *secondary_ports; 30216f8d3f33SWingman Kwok struct cpsw_ale_params ale_params; 30226f8d3f33SWingman Kwok struct gbe_priv *gbe_dev; 30236f8d3f33SWingman Kwok u32 slave_num; 3024489e8a2fSWingMan Kwok int i, ret = 0; 30256f8d3f33SWingman Kwok 30266f8d3f33SWingman Kwok if (!node) { 30276f8d3f33SWingman Kwok dev_err(dev, "device tree info unavailable\n"); 30286f8d3f33SWingman Kwok return -ENODEV; 30296f8d3f33SWingman Kwok } 30306f8d3f33SWingman Kwok 30316f8d3f33SWingman Kwok gbe_dev = devm_kzalloc(dev, sizeof(struct gbe_priv), GFP_KERNEL); 30326f8d3f33SWingman Kwok if (!gbe_dev) 30336f8d3f33SWingman Kwok return -ENOMEM; 30346f8d3f33SWingman Kwok 30359a391c7bSWingMan Kwok if (of_device_is_compatible(node, "ti,netcp-gbe-5") || 30369a391c7bSWingMan Kwok of_device_is_compatible(node, "ti,netcp-gbe")) { 30379a391c7bSWingMan Kwok gbe_dev->max_num_slaves = 4; 30389a391c7bSWingMan Kwok } else if (of_device_is_compatible(node, "ti,netcp-gbe-9")) { 30399a391c7bSWingMan Kwok gbe_dev->max_num_slaves = 8; 30409a391c7bSWingMan Kwok } else if (of_device_is_compatible(node, "ti,netcp-gbe-2")) { 30419a391c7bSWingMan Kwok gbe_dev->max_num_slaves = 1; 30429a391c7bSWingMan Kwok } else if (of_device_is_compatible(node, "ti,netcp-xgbe")) { 30439a391c7bSWingMan Kwok gbe_dev->max_num_slaves = 2; 30449a391c7bSWingMan Kwok } else { 30459a391c7bSWingMan Kwok dev_err(dev, "device tree node for unknown device\n"); 30469a391c7bSWingMan Kwok return -EINVAL; 30479a391c7bSWingMan Kwok } 30489a391c7bSWingMan Kwok gbe_dev->max_num_ports = gbe_dev->max_num_slaves + 1; 30499a391c7bSWingMan Kwok 30506f8d3f33SWingman Kwok gbe_dev->dev = dev; 30516f8d3f33SWingman Kwok gbe_dev->netcp_device = netcp_device; 30526f8d3f33SWingman Kwok gbe_dev->rx_packet_max = NETCP_MAX_FRAME_SIZE; 30536f8d3f33SWingman Kwok 30546f8d3f33SWingman Kwok /* init the hw stats lock */ 30556f8d3f33SWingman Kwok spin_lock_init(&gbe_dev->hw_stats_lock); 30566f8d3f33SWingman Kwok 30576f8d3f33SWingman Kwok if (of_find_property(node, "enable-ale", NULL)) { 30586f8d3f33SWingman Kwok gbe_dev->enable_ale = true; 30596f8d3f33SWingman Kwok dev_info(dev, "ALE enabled\n"); 30606f8d3f33SWingman Kwok } else { 30616f8d3f33SWingman Kwok gbe_dev->enable_ale = false; 30626f8d3f33SWingman Kwok dev_dbg(dev, "ALE bypass enabled*\n"); 30636f8d3f33SWingman Kwok } 30646f8d3f33SWingman Kwok 30656f8d3f33SWingman Kwok ret = of_property_read_u32(node, "tx-queue", 30666f8d3f33SWingman Kwok &gbe_dev->tx_queue_id); 30676f8d3f33SWingman Kwok if (ret < 0) { 30686f8d3f33SWingman Kwok dev_err(dev, "missing tx_queue parameter\n"); 30696f8d3f33SWingman Kwok gbe_dev->tx_queue_id = GBE_TX_QUEUE; 30706f8d3f33SWingman Kwok } 30716f8d3f33SWingman Kwok 30726f8d3f33SWingman Kwok ret = of_property_read_string(node, "tx-channel", 30736f8d3f33SWingman Kwok &gbe_dev->dma_chan_name); 30746f8d3f33SWingman Kwok if (ret < 0) { 30756f8d3f33SWingman Kwok dev_err(dev, "missing \"tx-channel\" parameter\n"); 30766f8d3f33SWingman Kwok ret = -ENODEV; 30776f8d3f33SWingman Kwok goto quit; 30786f8d3f33SWingman Kwok } 30796f8d3f33SWingman Kwok 30806f8d3f33SWingman Kwok if (!strcmp(node->name, "gbe")) { 30816f8d3f33SWingman Kwok ret = get_gbe_resource_version(gbe_dev, node); 30826f8d3f33SWingman Kwok if (ret) 30836f8d3f33SWingman Kwok goto quit; 30846f8d3f33SWingman Kwok 30859a391c7bSWingMan Kwok dev_dbg(dev, "ss_version: 0x%08x\n", gbe_dev->ss_version); 30869a391c7bSWingMan Kwok 30879a391c7bSWingMan Kwok if (gbe_dev->ss_version == GBE_SS_VERSION_14) 30886f8d3f33SWingman Kwok ret = set_gbe_ethss14_priv(gbe_dev, node); 30899a391c7bSWingMan Kwok else if (IS_SS_ID_MU(gbe_dev)) 30909a391c7bSWingMan Kwok ret = set_gbenu_ethss_priv(gbe_dev, node); 30919a391c7bSWingMan Kwok else 30929a391c7bSWingMan Kwok ret = -ENODEV; 30939a391c7bSWingMan Kwok 30946f8d3f33SWingman Kwok if (ret) 30956f8d3f33SWingman Kwok goto quit; 309690cff9e2SWingman Kwok } else if (!strcmp(node->name, "xgbe")) { 309790cff9e2SWingman Kwok ret = set_xgbe_ethss10_priv(gbe_dev, node); 309890cff9e2SWingman Kwok if (ret) 309990cff9e2SWingman Kwok goto quit; 310090cff9e2SWingman Kwok ret = netcp_xgbe_serdes_init(gbe_dev->xgbe_serdes_regs, 310190cff9e2SWingman Kwok gbe_dev->ss_regs); 310290cff9e2SWingman Kwok if (ret) 310390cff9e2SWingman Kwok goto quit; 31046f8d3f33SWingman Kwok } else { 31056f8d3f33SWingman Kwok dev_err(dev, "unknown GBE node(%s)\n", node->name); 31066f8d3f33SWingman Kwok ret = -ENODEV; 31076f8d3f33SWingman Kwok goto quit; 31086f8d3f33SWingman Kwok } 31096f8d3f33SWingman Kwok 31106f8d3f33SWingman Kwok interfaces = of_get_child_by_name(node, "interfaces"); 31116f8d3f33SWingman Kwok if (!interfaces) 31126f8d3f33SWingman Kwok dev_err(dev, "could not find interfaces\n"); 31136f8d3f33SWingman Kwok 31146f8d3f33SWingman Kwok ret = netcp_txpipe_init(&gbe_dev->tx_pipe, netcp_device, 31156f8d3f33SWingman Kwok gbe_dev->dma_chan_name, gbe_dev->tx_queue_id); 31166f8d3f33SWingman Kwok if (ret) 31176f8d3f33SWingman Kwok goto quit; 31186f8d3f33SWingman Kwok 31196f8d3f33SWingman Kwok ret = netcp_txpipe_open(&gbe_dev->tx_pipe); 31206f8d3f33SWingman Kwok if (ret) 31216f8d3f33SWingman Kwok goto quit; 31226f8d3f33SWingman Kwok 31236f8d3f33SWingman Kwok /* Create network interfaces */ 31246f8d3f33SWingman Kwok INIT_LIST_HEAD(&gbe_dev->gbe_intf_head); 31256f8d3f33SWingman Kwok for_each_child_of_node(interfaces, interface) { 31266f8d3f33SWingman Kwok ret = of_property_read_u32(interface, "slave-port", &slave_num); 31276f8d3f33SWingman Kwok if (ret) { 31286f8d3f33SWingman Kwok dev_err(dev, "missing slave-port parameter, skipping interface configuration for %s\n", 31296f8d3f33SWingman Kwok interface->name); 31306f8d3f33SWingman Kwok continue; 31316f8d3f33SWingman Kwok } 31326f8d3f33SWingman Kwok gbe_dev->num_slaves++; 31339a391c7bSWingMan Kwok if (gbe_dev->num_slaves >= gbe_dev->max_num_slaves) 31349a391c7bSWingMan Kwok break; 31356f8d3f33SWingman Kwok } 31366f8d3f33SWingman Kwok 31376f8d3f33SWingman Kwok if (!gbe_dev->num_slaves) 31386f8d3f33SWingman Kwok dev_warn(dev, "No network interface configured\n"); 31396f8d3f33SWingman Kwok 31406f8d3f33SWingman Kwok /* Initialize Secondary slave ports */ 31416f8d3f33SWingman Kwok secondary_ports = of_get_child_by_name(node, "secondary-slave-ports"); 31426f8d3f33SWingman Kwok INIT_LIST_HEAD(&gbe_dev->secondary_slaves); 31439a391c7bSWingMan Kwok if (secondary_ports && (gbe_dev->num_slaves < gbe_dev->max_num_slaves)) 31446f8d3f33SWingman Kwok init_secondary_ports(gbe_dev, secondary_ports); 31456f8d3f33SWingman Kwok of_node_put(secondary_ports); 31466f8d3f33SWingman Kwok 31476f8d3f33SWingman Kwok if (!gbe_dev->num_slaves) { 31486f8d3f33SWingman Kwok dev_err(dev, "No network interface or secondary ports configured\n"); 31496f8d3f33SWingman Kwok ret = -ENODEV; 31506f8d3f33SWingman Kwok goto quit; 31516f8d3f33SWingman Kwok } 31526f8d3f33SWingman Kwok 31536f8d3f33SWingman Kwok memset(&ale_params, 0, sizeof(ale_params)); 31546f8d3f33SWingman Kwok ale_params.dev = gbe_dev->dev; 31556f8d3f33SWingman Kwok ale_params.ale_regs = gbe_dev->ale_reg; 31566f8d3f33SWingman Kwok ale_params.ale_ageout = GBE_DEFAULT_ALE_AGEOUT; 31576f8d3f33SWingman Kwok ale_params.ale_entries = gbe_dev->ale_entries; 31586f8d3f33SWingman Kwok ale_params.ale_ports = gbe_dev->ale_ports; 31596f8d3f33SWingman Kwok 31606f8d3f33SWingman Kwok gbe_dev->ale = cpsw_ale_create(&ale_params); 31616f8d3f33SWingman Kwok if (!gbe_dev->ale) { 31626f8d3f33SWingman Kwok dev_err(gbe_dev->dev, "error initializing ale engine\n"); 31636f8d3f33SWingman Kwok ret = -ENODEV; 31646f8d3f33SWingman Kwok goto quit; 31656f8d3f33SWingman Kwok } else { 31666f8d3f33SWingman Kwok dev_dbg(gbe_dev->dev, "Created a gbe ale engine\n"); 31676f8d3f33SWingman Kwok } 31686f8d3f33SWingman Kwok 31696f8d3f33SWingman Kwok /* initialize host port */ 31706f8d3f33SWingman Kwok gbe_init_host_port(gbe_dev); 31716f8d3f33SWingman Kwok 3172489e8a2fSWingMan Kwok spin_lock_bh(&gbe_dev->hw_stats_lock); 3173489e8a2fSWingMan Kwok for (i = 0; i < gbe_dev->num_stats_mods; i++) { 3174489e8a2fSWingMan Kwok if (gbe_dev->ss_version == GBE_SS_VERSION_14) 3175489e8a2fSWingMan Kwok gbe_reset_mod_stats_ver14(gbe_dev, i); 3176489e8a2fSWingMan Kwok else 3177489e8a2fSWingMan Kwok gbe_reset_mod_stats(gbe_dev, i); 3178489e8a2fSWingMan Kwok } 3179489e8a2fSWingMan Kwok spin_unlock_bh(&gbe_dev->hw_stats_lock); 3180489e8a2fSWingMan Kwok 31816f8d3f33SWingman Kwok init_timer(&gbe_dev->timer); 31826f8d3f33SWingman Kwok gbe_dev->timer.data = (unsigned long)gbe_dev; 31836f8d3f33SWingman Kwok gbe_dev->timer.function = netcp_ethss_timer; 31846f8d3f33SWingman Kwok gbe_dev->timer.expires = jiffies + GBE_TIMER_INTERVAL; 31856f8d3f33SWingman Kwok add_timer(&gbe_dev->timer); 31866f8d3f33SWingman Kwok *inst_priv = gbe_dev; 31876f8d3f33SWingman Kwok return 0; 31886f8d3f33SWingman Kwok 31896f8d3f33SWingman Kwok quit: 31906f8d3f33SWingman Kwok if (gbe_dev->hw_stats) 31916f8d3f33SWingman Kwok devm_kfree(dev, gbe_dev->hw_stats); 3192489e8a2fSWingMan Kwok if (gbe_dev->hw_stats_prev) 3193489e8a2fSWingMan Kwok devm_kfree(dev, gbe_dev->hw_stats_prev); 31946f8d3f33SWingman Kwok cpsw_ale_destroy(gbe_dev->ale); 31956f8d3f33SWingman Kwok if (gbe_dev->ss_regs) 31966f8d3f33SWingman Kwok devm_iounmap(dev, gbe_dev->ss_regs); 31976f8d3f33SWingman Kwok of_node_put(interfaces); 31986f8d3f33SWingman Kwok devm_kfree(dev, gbe_dev); 31996f8d3f33SWingman Kwok return ret; 32006f8d3f33SWingman Kwok } 32016f8d3f33SWingman Kwok 32026f8d3f33SWingman Kwok static int gbe_attach(void *inst_priv, struct net_device *ndev, 32036f8d3f33SWingman Kwok struct device_node *node, void **intf_priv) 32046f8d3f33SWingman Kwok { 32056f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = inst_priv; 32066f8d3f33SWingman Kwok struct gbe_intf *gbe_intf; 32076f8d3f33SWingman Kwok int ret; 32086f8d3f33SWingman Kwok 32096f8d3f33SWingman Kwok if (!node) { 32106f8d3f33SWingman Kwok dev_err(gbe_dev->dev, "interface node not available\n"); 32116f8d3f33SWingman Kwok return -ENODEV; 32126f8d3f33SWingman Kwok } 32136f8d3f33SWingman Kwok 32146f8d3f33SWingman Kwok gbe_intf = devm_kzalloc(gbe_dev->dev, sizeof(*gbe_intf), GFP_KERNEL); 32156f8d3f33SWingman Kwok if (!gbe_intf) 32166f8d3f33SWingman Kwok return -ENOMEM; 32176f8d3f33SWingman Kwok 32186f8d3f33SWingman Kwok gbe_intf->ndev = ndev; 32196f8d3f33SWingman Kwok gbe_intf->dev = gbe_dev->dev; 32206f8d3f33SWingman Kwok gbe_intf->gbe_dev = gbe_dev; 32216f8d3f33SWingman Kwok 32226f8d3f33SWingman Kwok gbe_intf->slave = devm_kzalloc(gbe_dev->dev, 32236f8d3f33SWingman Kwok sizeof(*gbe_intf->slave), 32246f8d3f33SWingman Kwok GFP_KERNEL); 32256f8d3f33SWingman Kwok if (!gbe_intf->slave) { 32266f8d3f33SWingman Kwok ret = -ENOMEM; 32276f8d3f33SWingman Kwok goto fail; 32286f8d3f33SWingman Kwok } 32296f8d3f33SWingman Kwok 32306f8d3f33SWingman Kwok if (init_slave(gbe_dev, gbe_intf->slave, node)) { 32316f8d3f33SWingman Kwok ret = -ENODEV; 32326f8d3f33SWingman Kwok goto fail; 32336f8d3f33SWingman Kwok } 32346f8d3f33SWingman Kwok 32356f8d3f33SWingman Kwok gbe_intf->tx_pipe = gbe_dev->tx_pipe; 32366f8d3f33SWingman Kwok ndev->ethtool_ops = &keystone_ethtool_ops; 32376f8d3f33SWingman Kwok list_add_tail(&gbe_intf->gbe_intf_list, &gbe_dev->gbe_intf_head); 32386f8d3f33SWingman Kwok *intf_priv = gbe_intf; 32396f8d3f33SWingman Kwok return 0; 32406f8d3f33SWingman Kwok 32416f8d3f33SWingman Kwok fail: 32426f8d3f33SWingman Kwok if (gbe_intf->slave) 32436f8d3f33SWingman Kwok devm_kfree(gbe_dev->dev, gbe_intf->slave); 32446f8d3f33SWingman Kwok if (gbe_intf) 32456f8d3f33SWingman Kwok devm_kfree(gbe_dev->dev, gbe_intf); 32466f8d3f33SWingman Kwok return ret; 32476f8d3f33SWingman Kwok } 32486f8d3f33SWingman Kwok 32496f8d3f33SWingman Kwok static int gbe_release(void *intf_priv) 32506f8d3f33SWingman Kwok { 32516f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv; 32526f8d3f33SWingman Kwok 32536f8d3f33SWingman Kwok gbe_intf->ndev->ethtool_ops = NULL; 32546f8d3f33SWingman Kwok list_del(&gbe_intf->gbe_intf_list); 32556f8d3f33SWingman Kwok devm_kfree(gbe_intf->dev, gbe_intf->slave); 32566f8d3f33SWingman Kwok devm_kfree(gbe_intf->dev, gbe_intf); 32576f8d3f33SWingman Kwok return 0; 32586f8d3f33SWingman Kwok } 32596f8d3f33SWingman Kwok 32606f8d3f33SWingman Kwok static int gbe_remove(struct netcp_device *netcp_device, void *inst_priv) 32616f8d3f33SWingman Kwok { 32626f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = inst_priv; 32636f8d3f33SWingman Kwok 32646f8d3f33SWingman Kwok del_timer_sync(&gbe_dev->timer); 32656f8d3f33SWingman Kwok cpsw_ale_stop(gbe_dev->ale); 32666f8d3f33SWingman Kwok cpsw_ale_destroy(gbe_dev->ale); 32676f8d3f33SWingman Kwok netcp_txpipe_close(&gbe_dev->tx_pipe); 32686f8d3f33SWingman Kwok free_secondary_ports(gbe_dev); 32696f8d3f33SWingman Kwok 32706f8d3f33SWingman Kwok if (!list_empty(&gbe_dev->gbe_intf_head)) 32716f8d3f33SWingman Kwok dev_alert(gbe_dev->dev, "unreleased ethss interfaces present\n"); 32726f8d3f33SWingman Kwok 32736f8d3f33SWingman Kwok devm_kfree(gbe_dev->dev, gbe_dev->hw_stats); 32746f8d3f33SWingman Kwok devm_iounmap(gbe_dev->dev, gbe_dev->ss_regs); 32756f8d3f33SWingman Kwok memset(gbe_dev, 0x00, sizeof(*gbe_dev)); 32766f8d3f33SWingman Kwok devm_kfree(gbe_dev->dev, gbe_dev); 32776f8d3f33SWingman Kwok return 0; 32786f8d3f33SWingman Kwok } 32796f8d3f33SWingman Kwok 32806f8d3f33SWingman Kwok static struct netcp_module gbe_module = { 32816f8d3f33SWingman Kwok .name = GBE_MODULE_NAME, 32826f8d3f33SWingman Kwok .owner = THIS_MODULE, 32836f8d3f33SWingman Kwok .primary = true, 32846f8d3f33SWingman Kwok .probe = gbe_probe, 32856f8d3f33SWingman Kwok .open = gbe_open, 32866f8d3f33SWingman Kwok .close = gbe_close, 32876f8d3f33SWingman Kwok .remove = gbe_remove, 32886f8d3f33SWingman Kwok .attach = gbe_attach, 32896f8d3f33SWingman Kwok .release = gbe_release, 32906f8d3f33SWingman Kwok .add_addr = gbe_add_addr, 32916f8d3f33SWingman Kwok .del_addr = gbe_del_addr, 32926f8d3f33SWingman Kwok .add_vid = gbe_add_vid, 32936f8d3f33SWingman Kwok .del_vid = gbe_del_vid, 32946f8d3f33SWingman Kwok .ioctl = gbe_ioctl, 32956f8d3f33SWingman Kwok }; 32966f8d3f33SWingman Kwok 329790cff9e2SWingman Kwok static struct netcp_module xgbe_module = { 329890cff9e2SWingman Kwok .name = XGBE_MODULE_NAME, 329990cff9e2SWingman Kwok .owner = THIS_MODULE, 330090cff9e2SWingman Kwok .primary = true, 330190cff9e2SWingman Kwok .probe = gbe_probe, 330290cff9e2SWingman Kwok .open = gbe_open, 330390cff9e2SWingman Kwok .close = gbe_close, 330490cff9e2SWingman Kwok .remove = gbe_remove, 330590cff9e2SWingman Kwok .attach = gbe_attach, 330690cff9e2SWingman Kwok .release = gbe_release, 330790cff9e2SWingman Kwok .add_addr = gbe_add_addr, 330890cff9e2SWingman Kwok .del_addr = gbe_del_addr, 330990cff9e2SWingman Kwok .add_vid = gbe_add_vid, 331090cff9e2SWingman Kwok .del_vid = gbe_del_vid, 331190cff9e2SWingman Kwok .ioctl = gbe_ioctl, 331290cff9e2SWingman Kwok }; 331390cff9e2SWingman Kwok 33146f8d3f33SWingman Kwok static int __init keystone_gbe_init(void) 33156f8d3f33SWingman Kwok { 33166f8d3f33SWingman Kwok int ret; 33176f8d3f33SWingman Kwok 33186f8d3f33SWingman Kwok ret = netcp_register_module(&gbe_module); 33196f8d3f33SWingman Kwok if (ret) 33206f8d3f33SWingman Kwok return ret; 33216f8d3f33SWingman Kwok 332290cff9e2SWingman Kwok ret = netcp_register_module(&xgbe_module); 332390cff9e2SWingman Kwok if (ret) 332490cff9e2SWingman Kwok return ret; 332590cff9e2SWingman Kwok 33266f8d3f33SWingman Kwok return 0; 33276f8d3f33SWingman Kwok } 33286f8d3f33SWingman Kwok module_init(keystone_gbe_init); 33296f8d3f33SWingman Kwok 33306f8d3f33SWingman Kwok static void __exit keystone_gbe_exit(void) 33316f8d3f33SWingman Kwok { 33326f8d3f33SWingman Kwok netcp_unregister_module(&gbe_module); 333390cff9e2SWingman Kwok netcp_unregister_module(&xgbe_module); 33346f8d3f33SWingman Kwok } 33356f8d3f33SWingman Kwok module_exit(keystone_gbe_exit); 333658c11b5fSKaricheri, Muralidharan 333758c11b5fSKaricheri, Muralidharan MODULE_LICENSE("GPL v2"); 333858c11b5fSKaricheri, Muralidharan MODULE_DESCRIPTION("TI NETCP ETHSS driver for Keystone SOCs"); 333958c11b5fSKaricheri, Muralidharan MODULE_AUTHOR("Sandeep Nair <sandeep_n@ti.com"); 3340