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 29890cff9e2SWingman Kwok #define XGBE10_NUM_STAT_ENTRIES (sizeof(struct xgbe_hw_stats)/sizeof(u32)) 29990cff9e2SWingman Kwok 3009a391c7bSWingMan Kwok struct gbenu_ss_regs { 3019a391c7bSWingMan Kwok u32 id_ver; 3029a391c7bSWingMan Kwok u32 synce_count; /* NU */ 3039a391c7bSWingMan Kwok u32 synce_mux; /* NU */ 3049a391c7bSWingMan Kwok u32 control; /* 2U */ 3059a391c7bSWingMan Kwok u32 __rsvd_0[2]; /* 2U */ 3069a391c7bSWingMan Kwok u32 rgmii_status; /* 2U */ 3079a391c7bSWingMan Kwok u32 ss_status; /* 2U */ 3089a391c7bSWingMan Kwok }; 3099a391c7bSWingMan Kwok 3109a391c7bSWingMan Kwok struct gbenu_switch_regs { 3119a391c7bSWingMan Kwok u32 id_ver; 3129a391c7bSWingMan Kwok u32 control; 3139a391c7bSWingMan Kwok u32 __rsvd_0[2]; 3149a391c7bSWingMan Kwok u32 emcontrol; 3159a391c7bSWingMan Kwok u32 stat_port_en; 3169a391c7bSWingMan Kwok u32 ptype; /* NU */ 3179a391c7bSWingMan Kwok u32 soft_idle; 3189a391c7bSWingMan Kwok u32 thru_rate; /* NU */ 3199a391c7bSWingMan Kwok u32 gap_thresh; /* NU */ 3209a391c7bSWingMan Kwok u32 tx_start_wds; /* NU */ 3219a391c7bSWingMan Kwok u32 eee_prescale; /* 2U */ 3229a391c7bSWingMan Kwok u32 tx_g_oflow_thresh_set; /* NU */ 3239a391c7bSWingMan Kwok u32 tx_g_oflow_thresh_clr; /* NU */ 3249a391c7bSWingMan Kwok u32 tx_g_buf_thresh_set_l; /* NU */ 3259a391c7bSWingMan Kwok u32 tx_g_buf_thresh_set_h; /* NU */ 3269a391c7bSWingMan Kwok u32 tx_g_buf_thresh_clr_l; /* NU */ 3279a391c7bSWingMan Kwok u32 tx_g_buf_thresh_clr_h; /* NU */ 3289a391c7bSWingMan Kwok }; 3299a391c7bSWingMan Kwok 3309a391c7bSWingMan Kwok struct gbenu_port_regs { 3319a391c7bSWingMan Kwok u32 __rsvd_0; 3329a391c7bSWingMan Kwok u32 control; 3339a391c7bSWingMan Kwok u32 max_blks; /* 2U */ 3349a391c7bSWingMan Kwok u32 mem_align1; 3359a391c7bSWingMan Kwok u32 blk_cnt; 3369a391c7bSWingMan Kwok u32 port_vlan; 3379a391c7bSWingMan Kwok u32 tx_pri_map; /* NU */ 3389a391c7bSWingMan Kwok u32 pri_ctl; /* 2U */ 3399a391c7bSWingMan Kwok u32 rx_pri_map; 3409a391c7bSWingMan Kwok u32 rx_maxlen; 3419a391c7bSWingMan Kwok u32 tx_blks_pri; /* NU */ 3429a391c7bSWingMan Kwok u32 __rsvd_1; 3439a391c7bSWingMan Kwok u32 idle2lpi; /* 2U */ 3449a391c7bSWingMan Kwok u32 lpi2idle; /* 2U */ 3459a391c7bSWingMan Kwok u32 eee_status; /* 2U */ 3469a391c7bSWingMan Kwok u32 __rsvd_2; 3479a391c7bSWingMan Kwok u32 __rsvd_3[176]; /* NU: more to add */ 3489a391c7bSWingMan Kwok u32 __rsvd_4[2]; 3499a391c7bSWingMan Kwok u32 sa_lo; 3509a391c7bSWingMan Kwok u32 sa_hi; 3519a391c7bSWingMan Kwok u32 ts_ctl; 3529a391c7bSWingMan Kwok u32 ts_seq_ltype; 3539a391c7bSWingMan Kwok u32 ts_vlan; 3549a391c7bSWingMan Kwok u32 ts_ctl_ltype2; 3559a391c7bSWingMan Kwok u32 ts_ctl2; 3569a391c7bSWingMan Kwok }; 3579a391c7bSWingMan Kwok 3589a391c7bSWingMan Kwok struct gbenu_host_port_regs { 3599a391c7bSWingMan Kwok u32 __rsvd_0; 3609a391c7bSWingMan Kwok u32 control; 3619a391c7bSWingMan Kwok u32 flow_id_offset; /* 2U */ 3629a391c7bSWingMan Kwok u32 __rsvd_1; 3639a391c7bSWingMan Kwok u32 blk_cnt; 3649a391c7bSWingMan Kwok u32 port_vlan; 3659a391c7bSWingMan Kwok u32 tx_pri_map; /* NU */ 3669a391c7bSWingMan Kwok u32 pri_ctl; 3679a391c7bSWingMan Kwok u32 rx_pri_map; 3689a391c7bSWingMan Kwok u32 rx_maxlen; 3699a391c7bSWingMan Kwok u32 tx_blks_pri; /* NU */ 3709a391c7bSWingMan Kwok u32 __rsvd_2; 3719a391c7bSWingMan Kwok u32 idle2lpi; /* 2U */ 3729a391c7bSWingMan Kwok u32 lpi2wake; /* 2U */ 3739a391c7bSWingMan Kwok u32 eee_status; /* 2U */ 3749a391c7bSWingMan Kwok u32 __rsvd_3; 3759a391c7bSWingMan Kwok u32 __rsvd_4[184]; /* NU */ 3769a391c7bSWingMan Kwok u32 host_blks_pri; /* NU */ 3779a391c7bSWingMan Kwok }; 3789a391c7bSWingMan Kwok 3799a391c7bSWingMan Kwok struct gbenu_emac_regs { 3809a391c7bSWingMan Kwok u32 mac_control; 3819a391c7bSWingMan Kwok u32 mac_status; 3829a391c7bSWingMan Kwok u32 soft_reset; 3839a391c7bSWingMan Kwok u32 boff_test; 3849a391c7bSWingMan Kwok u32 rx_pause; 3859a391c7bSWingMan Kwok u32 __rsvd_0[11]; /* NU */ 3869a391c7bSWingMan Kwok u32 tx_pause; 3879a391c7bSWingMan Kwok u32 __rsvd_1[11]; /* NU */ 3889a391c7bSWingMan Kwok u32 em_control; 3899a391c7bSWingMan Kwok u32 tx_gap; 3909a391c7bSWingMan Kwok }; 3919a391c7bSWingMan Kwok 3929a391c7bSWingMan Kwok /* Some hw stat regs are applicable to slave port only. 3939a391c7bSWingMan Kwok * This is handled by gbenu_et_stats struct. Also some 3949a391c7bSWingMan Kwok * are for SS version NU and some are for 2U. 3959a391c7bSWingMan Kwok */ 3969a391c7bSWingMan Kwok struct gbenu_hw_stats { 3979a391c7bSWingMan Kwok u32 rx_good_frames; 3989a391c7bSWingMan Kwok u32 rx_broadcast_frames; 3999a391c7bSWingMan Kwok u32 rx_multicast_frames; 4009a391c7bSWingMan Kwok u32 rx_pause_frames; /* slave */ 4019a391c7bSWingMan Kwok u32 rx_crc_errors; 4029a391c7bSWingMan Kwok u32 rx_align_code_errors; /* slave */ 4039a391c7bSWingMan Kwok u32 rx_oversized_frames; 4049a391c7bSWingMan Kwok u32 rx_jabber_frames; /* slave */ 4059a391c7bSWingMan Kwok u32 rx_undersized_frames; 4069a391c7bSWingMan Kwok u32 rx_fragments; /* slave */ 4079a391c7bSWingMan Kwok u32 ale_drop; 4089a391c7bSWingMan Kwok u32 ale_overrun_drop; 4099a391c7bSWingMan Kwok u32 rx_bytes; 4109a391c7bSWingMan Kwok u32 tx_good_frames; 4119a391c7bSWingMan Kwok u32 tx_broadcast_frames; 4129a391c7bSWingMan Kwok u32 tx_multicast_frames; 4139a391c7bSWingMan Kwok u32 tx_pause_frames; /* slave */ 4149a391c7bSWingMan Kwok u32 tx_deferred_frames; /* slave */ 4159a391c7bSWingMan Kwok u32 tx_collision_frames; /* slave */ 4169a391c7bSWingMan Kwok u32 tx_single_coll_frames; /* slave */ 4179a391c7bSWingMan Kwok u32 tx_mult_coll_frames; /* slave */ 4189a391c7bSWingMan Kwok u32 tx_excessive_collisions; /* slave */ 4199a391c7bSWingMan Kwok u32 tx_late_collisions; /* slave */ 4209a391c7bSWingMan Kwok u32 rx_ipg_error; /* slave 10G only */ 4219a391c7bSWingMan Kwok u32 tx_carrier_sense_errors; /* slave */ 4229a391c7bSWingMan Kwok u32 tx_bytes; 4239a391c7bSWingMan Kwok u32 tx_64B_frames; 4249a391c7bSWingMan Kwok u32 tx_65_to_127B_frames; 4259a391c7bSWingMan Kwok u32 tx_128_to_255B_frames; 4269a391c7bSWingMan Kwok u32 tx_256_to_511B_frames; 4279a391c7bSWingMan Kwok u32 tx_512_to_1023B_frames; 4289a391c7bSWingMan Kwok u32 tx_1024B_frames; 4299a391c7bSWingMan Kwok u32 net_bytes; 4309a391c7bSWingMan Kwok u32 rx_bottom_fifo_drop; 4319a391c7bSWingMan Kwok u32 rx_port_mask_drop; 4329a391c7bSWingMan Kwok u32 rx_top_fifo_drop; 4339a391c7bSWingMan Kwok u32 ale_rate_limit_drop; 4349a391c7bSWingMan Kwok u32 ale_vid_ingress_drop; 4359a391c7bSWingMan Kwok u32 ale_da_eq_sa_drop; 4369a391c7bSWingMan Kwok u32 __rsvd_0[3]; 4379a391c7bSWingMan Kwok u32 ale_unknown_ucast; 4389a391c7bSWingMan Kwok u32 ale_unknown_ucast_bytes; 4399a391c7bSWingMan Kwok u32 ale_unknown_mcast; 4409a391c7bSWingMan Kwok u32 ale_unknown_mcast_bytes; 4419a391c7bSWingMan Kwok u32 ale_unknown_bcast; 4429a391c7bSWingMan Kwok u32 ale_unknown_bcast_bytes; 4439a391c7bSWingMan Kwok u32 ale_pol_match; 4449a391c7bSWingMan Kwok u32 ale_pol_match_red; /* NU */ 4459a391c7bSWingMan Kwok u32 ale_pol_match_yellow; /* NU */ 4469a391c7bSWingMan Kwok u32 __rsvd_1[44]; 4479a391c7bSWingMan Kwok u32 tx_mem_protect_err; 4489a391c7bSWingMan Kwok /* following NU only */ 4499a391c7bSWingMan Kwok u32 tx_pri0; 4509a391c7bSWingMan Kwok u32 tx_pri1; 4519a391c7bSWingMan Kwok u32 tx_pri2; 4529a391c7bSWingMan Kwok u32 tx_pri3; 4539a391c7bSWingMan Kwok u32 tx_pri4; 4549a391c7bSWingMan Kwok u32 tx_pri5; 4559a391c7bSWingMan Kwok u32 tx_pri6; 4569a391c7bSWingMan Kwok u32 tx_pri7; 4579a391c7bSWingMan Kwok u32 tx_pri0_bcnt; 4589a391c7bSWingMan Kwok u32 tx_pri1_bcnt; 4599a391c7bSWingMan Kwok u32 tx_pri2_bcnt; 4609a391c7bSWingMan Kwok u32 tx_pri3_bcnt; 4619a391c7bSWingMan Kwok u32 tx_pri4_bcnt; 4629a391c7bSWingMan Kwok u32 tx_pri5_bcnt; 4639a391c7bSWingMan Kwok u32 tx_pri6_bcnt; 4649a391c7bSWingMan Kwok u32 tx_pri7_bcnt; 4659a391c7bSWingMan Kwok u32 tx_pri0_drop; 4669a391c7bSWingMan Kwok u32 tx_pri1_drop; 4679a391c7bSWingMan Kwok u32 tx_pri2_drop; 4689a391c7bSWingMan Kwok u32 tx_pri3_drop; 4699a391c7bSWingMan Kwok u32 tx_pri4_drop; 4709a391c7bSWingMan Kwok u32 tx_pri5_drop; 4719a391c7bSWingMan Kwok u32 tx_pri6_drop; 4729a391c7bSWingMan Kwok u32 tx_pri7_drop; 4739a391c7bSWingMan Kwok u32 tx_pri0_drop_bcnt; 4749a391c7bSWingMan Kwok u32 tx_pri1_drop_bcnt; 4759a391c7bSWingMan Kwok u32 tx_pri2_drop_bcnt; 4769a391c7bSWingMan Kwok u32 tx_pri3_drop_bcnt; 4779a391c7bSWingMan Kwok u32 tx_pri4_drop_bcnt; 4789a391c7bSWingMan Kwok u32 tx_pri5_drop_bcnt; 4799a391c7bSWingMan Kwok u32 tx_pri6_drop_bcnt; 4809a391c7bSWingMan Kwok u32 tx_pri7_drop_bcnt; 4819a391c7bSWingMan Kwok }; 4829a391c7bSWingMan Kwok 4839a391c7bSWingMan Kwok #define GBENU_NUM_HW_STAT_ENTRIES (sizeof(struct gbenu_hw_stats) / sizeof(u32)) 4849a391c7bSWingMan Kwok #define GBENU_HW_STATS_REG_MAP_SZ 0x200 4859a391c7bSWingMan Kwok 4866f8d3f33SWingman Kwok struct gbe_ss_regs { 4876f8d3f33SWingman Kwok u32 id_ver; 4886f8d3f33SWingman Kwok u32 synce_count; 4896f8d3f33SWingman Kwok u32 synce_mux; 4906f8d3f33SWingman Kwok }; 4916f8d3f33SWingman Kwok 4926f8d3f33SWingman Kwok struct gbe_ss_regs_ofs { 4936f8d3f33SWingman Kwok u16 id_ver; 4946f8d3f33SWingman Kwok u16 control; 4956f8d3f33SWingman Kwok }; 4966f8d3f33SWingman Kwok 4976f8d3f33SWingman Kwok struct gbe_switch_regs { 4986f8d3f33SWingman Kwok u32 id_ver; 4996f8d3f33SWingman Kwok u32 control; 5006f8d3f33SWingman Kwok u32 soft_reset; 5016f8d3f33SWingman Kwok u32 stat_port_en; 5026f8d3f33SWingman Kwok u32 ptype; 5036f8d3f33SWingman Kwok u32 soft_idle; 5046f8d3f33SWingman Kwok u32 thru_rate; 5056f8d3f33SWingman Kwok u32 gap_thresh; 5066f8d3f33SWingman Kwok u32 tx_start_wds; 5076f8d3f33SWingman Kwok u32 flow_control; 5086f8d3f33SWingman Kwok }; 5096f8d3f33SWingman Kwok 5106f8d3f33SWingman Kwok struct gbe_switch_regs_ofs { 5116f8d3f33SWingman Kwok u16 id_ver; 5126f8d3f33SWingman Kwok u16 control; 5136f8d3f33SWingman Kwok u16 soft_reset; 5146f8d3f33SWingman Kwok u16 emcontrol; 5156f8d3f33SWingman Kwok u16 stat_port_en; 5166f8d3f33SWingman Kwok u16 ptype; 5176f8d3f33SWingman Kwok u16 flow_control; 5186f8d3f33SWingman Kwok }; 5196f8d3f33SWingman Kwok 5206f8d3f33SWingman Kwok struct gbe_port_regs { 5216f8d3f33SWingman Kwok u32 max_blks; 5226f8d3f33SWingman Kwok u32 blk_cnt; 5236f8d3f33SWingman Kwok u32 port_vlan; 5246f8d3f33SWingman Kwok u32 tx_pri_map; 5256f8d3f33SWingman Kwok u32 sa_lo; 5266f8d3f33SWingman Kwok u32 sa_hi; 5276f8d3f33SWingman Kwok u32 ts_ctl; 5286f8d3f33SWingman Kwok u32 ts_seq_ltype; 5296f8d3f33SWingman Kwok u32 ts_vlan; 5306f8d3f33SWingman Kwok u32 ts_ctl_ltype2; 5316f8d3f33SWingman Kwok u32 ts_ctl2; 5326f8d3f33SWingman Kwok }; 5336f8d3f33SWingman Kwok 5346f8d3f33SWingman Kwok struct gbe_port_regs_ofs { 5356f8d3f33SWingman Kwok u16 port_vlan; 5366f8d3f33SWingman Kwok u16 tx_pri_map; 5376f8d3f33SWingman Kwok u16 sa_lo; 5386f8d3f33SWingman Kwok u16 sa_hi; 5396f8d3f33SWingman Kwok u16 ts_ctl; 5406f8d3f33SWingman Kwok u16 ts_seq_ltype; 5416f8d3f33SWingman Kwok u16 ts_vlan; 5426f8d3f33SWingman Kwok u16 ts_ctl_ltype2; 5436f8d3f33SWingman Kwok u16 ts_ctl2; 5449a391c7bSWingMan Kwok u16 rx_maxlen; /* 2U, NU */ 5456f8d3f33SWingman Kwok }; 5466f8d3f33SWingman Kwok 5476f8d3f33SWingman Kwok struct gbe_host_port_regs { 5486f8d3f33SWingman Kwok u32 src_id; 5496f8d3f33SWingman Kwok u32 port_vlan; 5506f8d3f33SWingman Kwok u32 rx_pri_map; 5516f8d3f33SWingman Kwok u32 rx_maxlen; 5526f8d3f33SWingman Kwok }; 5536f8d3f33SWingman Kwok 5546f8d3f33SWingman Kwok struct gbe_host_port_regs_ofs { 5556f8d3f33SWingman Kwok u16 port_vlan; 5566f8d3f33SWingman Kwok u16 tx_pri_map; 5576f8d3f33SWingman Kwok u16 rx_maxlen; 5586f8d3f33SWingman Kwok }; 5596f8d3f33SWingman Kwok 5606f8d3f33SWingman Kwok struct gbe_emac_regs { 5616f8d3f33SWingman Kwok u32 id_ver; 5626f8d3f33SWingman Kwok u32 mac_control; 5636f8d3f33SWingman Kwok u32 mac_status; 5646f8d3f33SWingman Kwok u32 soft_reset; 5656f8d3f33SWingman Kwok u32 rx_maxlen; 5666f8d3f33SWingman Kwok u32 __reserved_0; 5676f8d3f33SWingman Kwok u32 rx_pause; 5686f8d3f33SWingman Kwok u32 tx_pause; 5696f8d3f33SWingman Kwok u32 __reserved_1; 5706f8d3f33SWingman Kwok u32 rx_pri_map; 5716f8d3f33SWingman Kwok u32 rsvd[6]; 5726f8d3f33SWingman Kwok }; 5736f8d3f33SWingman Kwok 5746f8d3f33SWingman Kwok struct gbe_emac_regs_ofs { 5756f8d3f33SWingman Kwok u16 mac_control; 5766f8d3f33SWingman Kwok u16 soft_reset; 5776f8d3f33SWingman Kwok u16 rx_maxlen; 5786f8d3f33SWingman Kwok }; 5796f8d3f33SWingman Kwok 5806f8d3f33SWingman Kwok struct gbe_hw_stats { 5816f8d3f33SWingman Kwok u32 rx_good_frames; 5826f8d3f33SWingman Kwok u32 rx_broadcast_frames; 5836f8d3f33SWingman Kwok u32 rx_multicast_frames; 5846f8d3f33SWingman Kwok u32 rx_pause_frames; 5856f8d3f33SWingman Kwok u32 rx_crc_errors; 5866f8d3f33SWingman Kwok u32 rx_align_code_errors; 5876f8d3f33SWingman Kwok u32 rx_oversized_frames; 5886f8d3f33SWingman Kwok u32 rx_jabber_frames; 5896f8d3f33SWingman Kwok u32 rx_undersized_frames; 5906f8d3f33SWingman Kwok u32 rx_fragments; 5916f8d3f33SWingman Kwok u32 __pad_0[2]; 5926f8d3f33SWingman Kwok u32 rx_bytes; 5936f8d3f33SWingman Kwok u32 tx_good_frames; 5946f8d3f33SWingman Kwok u32 tx_broadcast_frames; 5956f8d3f33SWingman Kwok u32 tx_multicast_frames; 5966f8d3f33SWingman Kwok u32 tx_pause_frames; 5976f8d3f33SWingman Kwok u32 tx_deferred_frames; 5986f8d3f33SWingman Kwok u32 tx_collision_frames; 5996f8d3f33SWingman Kwok u32 tx_single_coll_frames; 6006f8d3f33SWingman Kwok u32 tx_mult_coll_frames; 6016f8d3f33SWingman Kwok u32 tx_excessive_collisions; 6026f8d3f33SWingman Kwok u32 tx_late_collisions; 6036f8d3f33SWingman Kwok u32 tx_underrun; 6046f8d3f33SWingman Kwok u32 tx_carrier_sense_errors; 6056f8d3f33SWingman Kwok u32 tx_bytes; 6066f8d3f33SWingman Kwok u32 tx_64byte_frames; 6076f8d3f33SWingman Kwok u32 tx_65_to_127byte_frames; 6086f8d3f33SWingman Kwok u32 tx_128_to_255byte_frames; 6096f8d3f33SWingman Kwok u32 tx_256_to_511byte_frames; 6106f8d3f33SWingman Kwok u32 tx_512_to_1023byte_frames; 6116f8d3f33SWingman Kwok u32 tx_1024byte_frames; 6126f8d3f33SWingman Kwok u32 net_bytes; 6136f8d3f33SWingman Kwok u32 rx_sof_overruns; 6146f8d3f33SWingman Kwok u32 rx_mof_overruns; 6156f8d3f33SWingman Kwok u32 rx_dma_overruns; 6166f8d3f33SWingman Kwok }; 6176f8d3f33SWingman Kwok 6186f8d3f33SWingman Kwok #define GBE13_NUM_HW_STAT_ENTRIES (sizeof(struct gbe_hw_stats)/sizeof(u32)) 6199a391c7bSWingMan Kwok #define GBE_MAX_HW_STAT_MODS 9 6206f8d3f33SWingman Kwok #define GBE_HW_STATS_REG_MAP_SZ 0x100 6216f8d3f33SWingman Kwok 6226f8d3f33SWingman Kwok struct gbe_slave { 6236f8d3f33SWingman Kwok void __iomem *port_regs; 6246f8d3f33SWingman Kwok void __iomem *emac_regs; 6256f8d3f33SWingman Kwok struct gbe_port_regs_ofs port_regs_ofs; 6266f8d3f33SWingman Kwok struct gbe_emac_regs_ofs emac_regs_ofs; 6276f8d3f33SWingman Kwok int slave_num; /* 0 based logical number */ 6286f8d3f33SWingman Kwok int port_num; /* actual port number */ 6296f8d3f33SWingman Kwok atomic_t link_state; 6306f8d3f33SWingman Kwok bool open; 6316f8d3f33SWingman Kwok struct phy_device *phy; 6326f8d3f33SWingman Kwok u32 link_interface; 6336f8d3f33SWingman Kwok u32 mac_control; 6346f8d3f33SWingman Kwok u8 phy_port_t; 6356f8d3f33SWingman Kwok struct device_node *phy_node; 6366f8d3f33SWingman Kwok struct list_head slave_list; 6376f8d3f33SWingman Kwok }; 6386f8d3f33SWingman Kwok 6396f8d3f33SWingman Kwok struct gbe_priv { 6406f8d3f33SWingman Kwok struct device *dev; 6416f8d3f33SWingman Kwok struct netcp_device *netcp_device; 6426f8d3f33SWingman Kwok struct timer_list timer; 6436f8d3f33SWingman Kwok u32 num_slaves; 6446f8d3f33SWingman Kwok u32 ale_entries; 6456f8d3f33SWingman Kwok u32 ale_ports; 6466f8d3f33SWingman Kwok bool enable_ale; 6479a391c7bSWingMan Kwok u8 max_num_slaves; 6489a391c7bSWingMan Kwok u8 max_num_ports; /* max_num_slaves + 1 */ 6496f8d3f33SWingman Kwok struct netcp_tx_pipe tx_pipe; 6506f8d3f33SWingman Kwok 6516f8d3f33SWingman Kwok int host_port; 6526f8d3f33SWingman Kwok u32 rx_packet_max; 6536f8d3f33SWingman Kwok u32 ss_version; 6549a391c7bSWingMan Kwok u32 stats_en_mask; 6556f8d3f33SWingman Kwok 6566f8d3f33SWingman Kwok void __iomem *ss_regs; 6576f8d3f33SWingman Kwok void __iomem *switch_regs; 6586f8d3f33SWingman Kwok void __iomem *host_port_regs; 6596f8d3f33SWingman Kwok void __iomem *ale_reg; 6606f8d3f33SWingman Kwok void __iomem *sgmii_port_regs; 6616f8d3f33SWingman Kwok void __iomem *sgmii_port34_regs; 6626f8d3f33SWingman Kwok void __iomem *xgbe_serdes_regs; 6636f8d3f33SWingman Kwok void __iomem *hw_stats_regs[GBE_MAX_HW_STAT_MODS]; 6646f8d3f33SWingman Kwok 6656f8d3f33SWingman Kwok struct gbe_ss_regs_ofs ss_regs_ofs; 6666f8d3f33SWingman Kwok struct gbe_switch_regs_ofs switch_regs_ofs; 6676f8d3f33SWingman Kwok struct gbe_host_port_regs_ofs host_port_regs_ofs; 6686f8d3f33SWingman Kwok 6696f8d3f33SWingman Kwok struct cpsw_ale *ale; 6706f8d3f33SWingman Kwok unsigned int tx_queue_id; 6716f8d3f33SWingman Kwok const char *dma_chan_name; 6726f8d3f33SWingman Kwok 6736f8d3f33SWingman Kwok struct list_head gbe_intf_head; 6746f8d3f33SWingman Kwok struct list_head secondary_slaves; 6756f8d3f33SWingman Kwok struct net_device *dummy_ndev; 6766f8d3f33SWingman Kwok 6776f8d3f33SWingman Kwok u64 *hw_stats; 6786f8d3f33SWingman Kwok const struct netcp_ethtool_stat *et_stats; 6796f8d3f33SWingman Kwok int num_et_stats; 6806f8d3f33SWingman Kwok /* Lock for updating the hwstats */ 6816f8d3f33SWingman Kwok spinlock_t hw_stats_lock; 6826f8d3f33SWingman Kwok }; 6836f8d3f33SWingman Kwok 6846f8d3f33SWingman Kwok struct gbe_intf { 6856f8d3f33SWingman Kwok struct net_device *ndev; 6866f8d3f33SWingman Kwok struct device *dev; 6876f8d3f33SWingman Kwok struct gbe_priv *gbe_dev; 6886f8d3f33SWingman Kwok struct netcp_tx_pipe tx_pipe; 6896f8d3f33SWingman Kwok struct gbe_slave *slave; 6906f8d3f33SWingman Kwok struct list_head gbe_intf_list; 6916f8d3f33SWingman Kwok unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; 6926f8d3f33SWingman Kwok }; 6936f8d3f33SWingman Kwok 6946f8d3f33SWingman Kwok static struct netcp_module gbe_module; 69590cff9e2SWingman Kwok static struct netcp_module xgbe_module; 6966f8d3f33SWingman Kwok 6976f8d3f33SWingman Kwok /* Statistic management */ 6986f8d3f33SWingman Kwok struct netcp_ethtool_stat { 6996f8d3f33SWingman Kwok char desc[ETH_GSTRING_LEN]; 7006f8d3f33SWingman Kwok int type; 7016f8d3f33SWingman Kwok u32 size; 7026f8d3f33SWingman Kwok int offset; 7036f8d3f33SWingman Kwok }; 7046f8d3f33SWingman Kwok 705da866ba0SKaricheri, Muralidharan #define GBE_STATSA_INFO(field) \ 706da866ba0SKaricheri, Muralidharan { \ 707da866ba0SKaricheri, Muralidharan "GBE_A:"#field, GBE_STATSA_MODULE, \ 7086f8d3f33SWingman Kwok FIELD_SIZEOF(struct gbe_hw_stats, field), \ 709da866ba0SKaricheri, Muralidharan offsetof(struct gbe_hw_stats, field) \ 710da866ba0SKaricheri, Muralidharan } 7116f8d3f33SWingman Kwok 712da866ba0SKaricheri, Muralidharan #define GBE_STATSB_INFO(field) \ 713da866ba0SKaricheri, Muralidharan { \ 714da866ba0SKaricheri, Muralidharan "GBE_B:"#field, GBE_STATSB_MODULE, \ 7156f8d3f33SWingman Kwok FIELD_SIZEOF(struct gbe_hw_stats, field), \ 716da866ba0SKaricheri, Muralidharan offsetof(struct gbe_hw_stats, field) \ 717da866ba0SKaricheri, Muralidharan } 7186f8d3f33SWingman Kwok 719da866ba0SKaricheri, Muralidharan #define GBE_STATSC_INFO(field) \ 720da866ba0SKaricheri, Muralidharan { \ 721da866ba0SKaricheri, Muralidharan "GBE_C:"#field, GBE_STATSC_MODULE, \ 7226f8d3f33SWingman Kwok FIELD_SIZEOF(struct gbe_hw_stats, field), \ 723da866ba0SKaricheri, Muralidharan offsetof(struct gbe_hw_stats, field) \ 724da866ba0SKaricheri, Muralidharan } 7256f8d3f33SWingman Kwok 726da866ba0SKaricheri, Muralidharan #define GBE_STATSD_INFO(field) \ 727da866ba0SKaricheri, Muralidharan { \ 728da866ba0SKaricheri, Muralidharan "GBE_D:"#field, GBE_STATSD_MODULE, \ 7296f8d3f33SWingman Kwok FIELD_SIZEOF(struct gbe_hw_stats, field), \ 730da866ba0SKaricheri, Muralidharan offsetof(struct gbe_hw_stats, field) \ 731da866ba0SKaricheri, Muralidharan } 7326f8d3f33SWingman Kwok 7336f8d3f33SWingman Kwok static const struct netcp_ethtool_stat gbe13_et_stats[] = { 7346f8d3f33SWingman Kwok /* GBE module A */ 735da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_good_frames), 736da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_broadcast_frames), 737da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_multicast_frames), 738da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_pause_frames), 739da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_crc_errors), 740da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_align_code_errors), 741da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_oversized_frames), 742da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_jabber_frames), 743da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_undersized_frames), 744da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_fragments), 745da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_bytes), 746da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_good_frames), 747da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_broadcast_frames), 748da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_multicast_frames), 749da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_pause_frames), 750da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_deferred_frames), 751da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_collision_frames), 752da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_single_coll_frames), 753da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_mult_coll_frames), 754da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_excessive_collisions), 755da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_late_collisions), 756da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_underrun), 757da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_carrier_sense_errors), 758da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_bytes), 759da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_64byte_frames), 760da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_65_to_127byte_frames), 761da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_128_to_255byte_frames), 762da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_256_to_511byte_frames), 763da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_512_to_1023byte_frames), 764da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_1024byte_frames), 765da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(net_bytes), 766da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_sof_overruns), 767da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_mof_overruns), 768da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_dma_overruns), 7696f8d3f33SWingman Kwok /* GBE module B */ 770da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_good_frames), 771da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_broadcast_frames), 772da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_multicast_frames), 773da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_pause_frames), 774da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_crc_errors), 775da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_align_code_errors), 776da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_oversized_frames), 777da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_jabber_frames), 778da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_undersized_frames), 779da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_fragments), 780da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_bytes), 781da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_good_frames), 782da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_broadcast_frames), 783da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_multicast_frames), 784da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_pause_frames), 785da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_deferred_frames), 786da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_collision_frames), 787da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_single_coll_frames), 788da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_mult_coll_frames), 789da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_excessive_collisions), 790da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_late_collisions), 791da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_underrun), 792da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_carrier_sense_errors), 793da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_bytes), 794da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_64byte_frames), 795da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_65_to_127byte_frames), 796da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_128_to_255byte_frames), 797da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_256_to_511byte_frames), 798da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_512_to_1023byte_frames), 799da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_1024byte_frames), 800da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(net_bytes), 801da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_sof_overruns), 802da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_mof_overruns), 803da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_dma_overruns), 8046f8d3f33SWingman Kwok /* GBE module C */ 805da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_good_frames), 806da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_broadcast_frames), 807da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_multicast_frames), 808da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_pause_frames), 809da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_crc_errors), 810da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_align_code_errors), 811da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_oversized_frames), 812da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_jabber_frames), 813da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_undersized_frames), 814da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_fragments), 815da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_bytes), 816da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_good_frames), 817da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_broadcast_frames), 818da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_multicast_frames), 819da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_pause_frames), 820da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_deferred_frames), 821da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_collision_frames), 822da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_single_coll_frames), 823da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_mult_coll_frames), 824da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_excessive_collisions), 825da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_late_collisions), 826da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_underrun), 827da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_carrier_sense_errors), 828da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_bytes), 829da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_64byte_frames), 830da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_65_to_127byte_frames), 831da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_128_to_255byte_frames), 832da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_256_to_511byte_frames), 833da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_512_to_1023byte_frames), 834da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_1024byte_frames), 835da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(net_bytes), 836da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_sof_overruns), 837da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_mof_overruns), 838da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_dma_overruns), 8396f8d3f33SWingman Kwok /* GBE module D */ 840da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_good_frames), 841da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_broadcast_frames), 842da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_multicast_frames), 843da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_pause_frames), 844da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_crc_errors), 845da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_align_code_errors), 846da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_oversized_frames), 847da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_jabber_frames), 848da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_undersized_frames), 849da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_fragments), 850da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_bytes), 851da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_good_frames), 852da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_broadcast_frames), 853da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_multicast_frames), 854da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_pause_frames), 855da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_deferred_frames), 856da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_collision_frames), 857da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_single_coll_frames), 858da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_mult_coll_frames), 859da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_excessive_collisions), 860da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_late_collisions), 861da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_underrun), 862da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_carrier_sense_errors), 863da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_bytes), 864da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_64byte_frames), 865da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_65_to_127byte_frames), 866da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_128_to_255byte_frames), 867da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_256_to_511byte_frames), 868da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_512_to_1023byte_frames), 869da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_1024byte_frames), 870da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(net_bytes), 871da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_sof_overruns), 872da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_mof_overruns), 873da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_dma_overruns), 8746f8d3f33SWingman Kwok }; 8756f8d3f33SWingman Kwok 8769a391c7bSWingMan Kwok /* This is the size of entries in GBENU_STATS_HOST */ 8779a391c7bSWingMan Kwok #define GBENU_ET_STATS_HOST_SIZE 33 8789a391c7bSWingMan Kwok 8799a391c7bSWingMan Kwok #define GBENU_STATS_HOST(field) \ 8809a391c7bSWingMan Kwok { \ 8819a391c7bSWingMan Kwok "GBE_HOST:"#field, GBENU_STATS0_MODULE, \ 8829a391c7bSWingMan Kwok FIELD_SIZEOF(struct gbenu_hw_stats, field), \ 8839a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \ 8849a391c7bSWingMan Kwok } 8859a391c7bSWingMan Kwok 8869a391c7bSWingMan Kwok /* This is the size of entries in GBENU_STATS_HOST */ 8879a391c7bSWingMan Kwok #define GBENU_ET_STATS_PORT_SIZE 46 8889a391c7bSWingMan Kwok 8899a391c7bSWingMan Kwok #define GBENU_STATS_P1(field) \ 8909a391c7bSWingMan Kwok { \ 8919a391c7bSWingMan Kwok "GBE_P1:"#field, GBENU_STATS1_MODULE, \ 8929a391c7bSWingMan Kwok FIELD_SIZEOF(struct gbenu_hw_stats, field), \ 8939a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \ 8949a391c7bSWingMan Kwok } 8959a391c7bSWingMan Kwok 8969a391c7bSWingMan Kwok #define GBENU_STATS_P2(field) \ 8979a391c7bSWingMan Kwok { \ 8989a391c7bSWingMan Kwok "GBE_P2:"#field, GBENU_STATS2_MODULE, \ 8999a391c7bSWingMan Kwok FIELD_SIZEOF(struct gbenu_hw_stats, field), \ 9009a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \ 9019a391c7bSWingMan Kwok } 9029a391c7bSWingMan Kwok 9039a391c7bSWingMan Kwok #define GBENU_STATS_P3(field) \ 9049a391c7bSWingMan Kwok { \ 9059a391c7bSWingMan Kwok "GBE_P3:"#field, GBENU_STATS3_MODULE, \ 9069a391c7bSWingMan Kwok FIELD_SIZEOF(struct gbenu_hw_stats, field), \ 9079a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \ 9089a391c7bSWingMan Kwok } 9099a391c7bSWingMan Kwok 9109a391c7bSWingMan Kwok #define GBENU_STATS_P4(field) \ 9119a391c7bSWingMan Kwok { \ 9129a391c7bSWingMan Kwok "GBE_P4:"#field, GBENU_STATS4_MODULE, \ 9139a391c7bSWingMan Kwok FIELD_SIZEOF(struct gbenu_hw_stats, field), \ 9149a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \ 9159a391c7bSWingMan Kwok } 9169a391c7bSWingMan Kwok 9179a391c7bSWingMan Kwok #define GBENU_STATS_P5(field) \ 9189a391c7bSWingMan Kwok { \ 9199a391c7bSWingMan Kwok "GBE_P5:"#field, GBENU_STATS5_MODULE, \ 9209a391c7bSWingMan Kwok FIELD_SIZEOF(struct gbenu_hw_stats, field), \ 9219a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \ 9229a391c7bSWingMan Kwok } 9239a391c7bSWingMan Kwok 9249a391c7bSWingMan Kwok #define GBENU_STATS_P6(field) \ 9259a391c7bSWingMan Kwok { \ 9269a391c7bSWingMan Kwok "GBE_P6:"#field, GBENU_STATS6_MODULE, \ 9279a391c7bSWingMan Kwok FIELD_SIZEOF(struct gbenu_hw_stats, field), \ 9289a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \ 9299a391c7bSWingMan Kwok } 9309a391c7bSWingMan Kwok 9319a391c7bSWingMan Kwok #define GBENU_STATS_P7(field) \ 9329a391c7bSWingMan Kwok { \ 9339a391c7bSWingMan Kwok "GBE_P7:"#field, GBENU_STATS7_MODULE, \ 9349a391c7bSWingMan Kwok FIELD_SIZEOF(struct gbenu_hw_stats, field), \ 9359a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \ 9369a391c7bSWingMan Kwok } 9379a391c7bSWingMan Kwok 9389a391c7bSWingMan Kwok #define GBENU_STATS_P8(field) \ 9399a391c7bSWingMan Kwok { \ 9409a391c7bSWingMan Kwok "GBE_P8:"#field, GBENU_STATS8_MODULE, \ 9419a391c7bSWingMan Kwok FIELD_SIZEOF(struct gbenu_hw_stats, field), \ 9429a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \ 9439a391c7bSWingMan Kwok } 9449a391c7bSWingMan Kwok 9459a391c7bSWingMan Kwok static const struct netcp_ethtool_stat gbenu_et_stats[] = { 9469a391c7bSWingMan Kwok /* GBENU Host Module */ 9479a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_good_frames), 9489a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_broadcast_frames), 9499a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_multicast_frames), 9509a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_crc_errors), 9519a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_oversized_frames), 9529a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_undersized_frames), 9539a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_drop), 9549a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_overrun_drop), 9559a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_bytes), 9569a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_good_frames), 9579a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_broadcast_frames), 9589a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_multicast_frames), 9599a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_bytes), 9609a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_64B_frames), 9619a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_65_to_127B_frames), 9629a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_128_to_255B_frames), 9639a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_256_to_511B_frames), 9649a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_512_to_1023B_frames), 9659a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_1024B_frames), 9669a391c7bSWingMan Kwok GBENU_STATS_HOST(net_bytes), 9679a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_bottom_fifo_drop), 9689a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_port_mask_drop), 9699a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_top_fifo_drop), 9709a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_rate_limit_drop), 9719a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_vid_ingress_drop), 9729a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_da_eq_sa_drop), 9739a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_unknown_ucast), 9749a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_unknown_ucast_bytes), 9759a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_unknown_mcast), 9769a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_unknown_mcast_bytes), 9779a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_unknown_bcast), 9789a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_unknown_bcast_bytes), 9799a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_mem_protect_err), 9809a391c7bSWingMan Kwok /* GBENU Module 1 */ 9819a391c7bSWingMan Kwok GBENU_STATS_P1(rx_good_frames), 9829a391c7bSWingMan Kwok GBENU_STATS_P1(rx_broadcast_frames), 9839a391c7bSWingMan Kwok GBENU_STATS_P1(rx_multicast_frames), 9849a391c7bSWingMan Kwok GBENU_STATS_P1(rx_pause_frames), 9859a391c7bSWingMan Kwok GBENU_STATS_P1(rx_crc_errors), 9869a391c7bSWingMan Kwok GBENU_STATS_P1(rx_align_code_errors), 9879a391c7bSWingMan Kwok GBENU_STATS_P1(rx_oversized_frames), 9889a391c7bSWingMan Kwok GBENU_STATS_P1(rx_jabber_frames), 9899a391c7bSWingMan Kwok GBENU_STATS_P1(rx_undersized_frames), 9909a391c7bSWingMan Kwok GBENU_STATS_P1(rx_fragments), 9919a391c7bSWingMan Kwok GBENU_STATS_P1(ale_drop), 9929a391c7bSWingMan Kwok GBENU_STATS_P1(ale_overrun_drop), 9939a391c7bSWingMan Kwok GBENU_STATS_P1(rx_bytes), 9949a391c7bSWingMan Kwok GBENU_STATS_P1(tx_good_frames), 9959a391c7bSWingMan Kwok GBENU_STATS_P1(tx_broadcast_frames), 9969a391c7bSWingMan Kwok GBENU_STATS_P1(tx_multicast_frames), 9979a391c7bSWingMan Kwok GBENU_STATS_P1(tx_pause_frames), 9989a391c7bSWingMan Kwok GBENU_STATS_P1(tx_deferred_frames), 9999a391c7bSWingMan Kwok GBENU_STATS_P1(tx_collision_frames), 10009a391c7bSWingMan Kwok GBENU_STATS_P1(tx_single_coll_frames), 10019a391c7bSWingMan Kwok GBENU_STATS_P1(tx_mult_coll_frames), 10029a391c7bSWingMan Kwok GBENU_STATS_P1(tx_excessive_collisions), 10039a391c7bSWingMan Kwok GBENU_STATS_P1(tx_late_collisions), 10049a391c7bSWingMan Kwok GBENU_STATS_P1(rx_ipg_error), 10059a391c7bSWingMan Kwok GBENU_STATS_P1(tx_carrier_sense_errors), 10069a391c7bSWingMan Kwok GBENU_STATS_P1(tx_bytes), 10079a391c7bSWingMan Kwok GBENU_STATS_P1(tx_64B_frames), 10089a391c7bSWingMan Kwok GBENU_STATS_P1(tx_65_to_127B_frames), 10099a391c7bSWingMan Kwok GBENU_STATS_P1(tx_128_to_255B_frames), 10109a391c7bSWingMan Kwok GBENU_STATS_P1(tx_256_to_511B_frames), 10119a391c7bSWingMan Kwok GBENU_STATS_P1(tx_512_to_1023B_frames), 10129a391c7bSWingMan Kwok GBENU_STATS_P1(tx_1024B_frames), 10139a391c7bSWingMan Kwok GBENU_STATS_P1(net_bytes), 10149a391c7bSWingMan Kwok GBENU_STATS_P1(rx_bottom_fifo_drop), 10159a391c7bSWingMan Kwok GBENU_STATS_P1(rx_port_mask_drop), 10169a391c7bSWingMan Kwok GBENU_STATS_P1(rx_top_fifo_drop), 10179a391c7bSWingMan Kwok GBENU_STATS_P1(ale_rate_limit_drop), 10189a391c7bSWingMan Kwok GBENU_STATS_P1(ale_vid_ingress_drop), 10199a391c7bSWingMan Kwok GBENU_STATS_P1(ale_da_eq_sa_drop), 10209a391c7bSWingMan Kwok GBENU_STATS_P1(ale_unknown_ucast), 10219a391c7bSWingMan Kwok GBENU_STATS_P1(ale_unknown_ucast_bytes), 10229a391c7bSWingMan Kwok GBENU_STATS_P1(ale_unknown_mcast), 10239a391c7bSWingMan Kwok GBENU_STATS_P1(ale_unknown_mcast_bytes), 10249a391c7bSWingMan Kwok GBENU_STATS_P1(ale_unknown_bcast), 10259a391c7bSWingMan Kwok GBENU_STATS_P1(ale_unknown_bcast_bytes), 10269a391c7bSWingMan Kwok GBENU_STATS_P1(tx_mem_protect_err), 10279a391c7bSWingMan Kwok /* GBENU Module 2 */ 10289a391c7bSWingMan Kwok GBENU_STATS_P2(rx_good_frames), 10299a391c7bSWingMan Kwok GBENU_STATS_P2(rx_broadcast_frames), 10309a391c7bSWingMan Kwok GBENU_STATS_P2(rx_multicast_frames), 10319a391c7bSWingMan Kwok GBENU_STATS_P2(rx_pause_frames), 10329a391c7bSWingMan Kwok GBENU_STATS_P2(rx_crc_errors), 10339a391c7bSWingMan Kwok GBENU_STATS_P2(rx_align_code_errors), 10349a391c7bSWingMan Kwok GBENU_STATS_P2(rx_oversized_frames), 10359a391c7bSWingMan Kwok GBENU_STATS_P2(rx_jabber_frames), 10369a391c7bSWingMan Kwok GBENU_STATS_P2(rx_undersized_frames), 10379a391c7bSWingMan Kwok GBENU_STATS_P2(rx_fragments), 10389a391c7bSWingMan Kwok GBENU_STATS_P2(ale_drop), 10399a391c7bSWingMan Kwok GBENU_STATS_P2(ale_overrun_drop), 10409a391c7bSWingMan Kwok GBENU_STATS_P2(rx_bytes), 10419a391c7bSWingMan Kwok GBENU_STATS_P2(tx_good_frames), 10429a391c7bSWingMan Kwok GBENU_STATS_P2(tx_broadcast_frames), 10439a391c7bSWingMan Kwok GBENU_STATS_P2(tx_multicast_frames), 10449a391c7bSWingMan Kwok GBENU_STATS_P2(tx_pause_frames), 10459a391c7bSWingMan Kwok GBENU_STATS_P2(tx_deferred_frames), 10469a391c7bSWingMan Kwok GBENU_STATS_P2(tx_collision_frames), 10479a391c7bSWingMan Kwok GBENU_STATS_P2(tx_single_coll_frames), 10489a391c7bSWingMan Kwok GBENU_STATS_P2(tx_mult_coll_frames), 10499a391c7bSWingMan Kwok GBENU_STATS_P2(tx_excessive_collisions), 10509a391c7bSWingMan Kwok GBENU_STATS_P2(tx_late_collisions), 10519a391c7bSWingMan Kwok GBENU_STATS_P2(rx_ipg_error), 10529a391c7bSWingMan Kwok GBENU_STATS_P2(tx_carrier_sense_errors), 10539a391c7bSWingMan Kwok GBENU_STATS_P2(tx_bytes), 10549a391c7bSWingMan Kwok GBENU_STATS_P2(tx_64B_frames), 10559a391c7bSWingMan Kwok GBENU_STATS_P2(tx_65_to_127B_frames), 10569a391c7bSWingMan Kwok GBENU_STATS_P2(tx_128_to_255B_frames), 10579a391c7bSWingMan Kwok GBENU_STATS_P2(tx_256_to_511B_frames), 10589a391c7bSWingMan Kwok GBENU_STATS_P2(tx_512_to_1023B_frames), 10599a391c7bSWingMan Kwok GBENU_STATS_P2(tx_1024B_frames), 10609a391c7bSWingMan Kwok GBENU_STATS_P2(net_bytes), 10619a391c7bSWingMan Kwok GBENU_STATS_P2(rx_bottom_fifo_drop), 10629a391c7bSWingMan Kwok GBENU_STATS_P2(rx_port_mask_drop), 10639a391c7bSWingMan Kwok GBENU_STATS_P2(rx_top_fifo_drop), 10649a391c7bSWingMan Kwok GBENU_STATS_P2(ale_rate_limit_drop), 10659a391c7bSWingMan Kwok GBENU_STATS_P2(ale_vid_ingress_drop), 10669a391c7bSWingMan Kwok GBENU_STATS_P2(ale_da_eq_sa_drop), 10679a391c7bSWingMan Kwok GBENU_STATS_P2(ale_unknown_ucast), 10689a391c7bSWingMan Kwok GBENU_STATS_P2(ale_unknown_ucast_bytes), 10699a391c7bSWingMan Kwok GBENU_STATS_P2(ale_unknown_mcast), 10709a391c7bSWingMan Kwok GBENU_STATS_P2(ale_unknown_mcast_bytes), 10719a391c7bSWingMan Kwok GBENU_STATS_P2(ale_unknown_bcast), 10729a391c7bSWingMan Kwok GBENU_STATS_P2(ale_unknown_bcast_bytes), 10739a391c7bSWingMan Kwok GBENU_STATS_P2(tx_mem_protect_err), 10749a391c7bSWingMan Kwok /* GBENU Module 3 */ 10759a391c7bSWingMan Kwok GBENU_STATS_P3(rx_good_frames), 10769a391c7bSWingMan Kwok GBENU_STATS_P3(rx_broadcast_frames), 10779a391c7bSWingMan Kwok GBENU_STATS_P3(rx_multicast_frames), 10789a391c7bSWingMan Kwok GBENU_STATS_P3(rx_pause_frames), 10799a391c7bSWingMan Kwok GBENU_STATS_P3(rx_crc_errors), 10809a391c7bSWingMan Kwok GBENU_STATS_P3(rx_align_code_errors), 10819a391c7bSWingMan Kwok GBENU_STATS_P3(rx_oversized_frames), 10829a391c7bSWingMan Kwok GBENU_STATS_P3(rx_jabber_frames), 10839a391c7bSWingMan Kwok GBENU_STATS_P3(rx_undersized_frames), 10849a391c7bSWingMan Kwok GBENU_STATS_P3(rx_fragments), 10859a391c7bSWingMan Kwok GBENU_STATS_P3(ale_drop), 10869a391c7bSWingMan Kwok GBENU_STATS_P3(ale_overrun_drop), 10879a391c7bSWingMan Kwok GBENU_STATS_P3(rx_bytes), 10889a391c7bSWingMan Kwok GBENU_STATS_P3(tx_good_frames), 10899a391c7bSWingMan Kwok GBENU_STATS_P3(tx_broadcast_frames), 10909a391c7bSWingMan Kwok GBENU_STATS_P3(tx_multicast_frames), 10919a391c7bSWingMan Kwok GBENU_STATS_P3(tx_pause_frames), 10929a391c7bSWingMan Kwok GBENU_STATS_P3(tx_deferred_frames), 10939a391c7bSWingMan Kwok GBENU_STATS_P3(tx_collision_frames), 10949a391c7bSWingMan Kwok GBENU_STATS_P3(tx_single_coll_frames), 10959a391c7bSWingMan Kwok GBENU_STATS_P3(tx_mult_coll_frames), 10969a391c7bSWingMan Kwok GBENU_STATS_P3(tx_excessive_collisions), 10979a391c7bSWingMan Kwok GBENU_STATS_P3(tx_late_collisions), 10989a391c7bSWingMan Kwok GBENU_STATS_P3(rx_ipg_error), 10999a391c7bSWingMan Kwok GBENU_STATS_P3(tx_carrier_sense_errors), 11009a391c7bSWingMan Kwok GBENU_STATS_P3(tx_bytes), 11019a391c7bSWingMan Kwok GBENU_STATS_P3(tx_64B_frames), 11029a391c7bSWingMan Kwok GBENU_STATS_P3(tx_65_to_127B_frames), 11039a391c7bSWingMan Kwok GBENU_STATS_P3(tx_128_to_255B_frames), 11049a391c7bSWingMan Kwok GBENU_STATS_P3(tx_256_to_511B_frames), 11059a391c7bSWingMan Kwok GBENU_STATS_P3(tx_512_to_1023B_frames), 11069a391c7bSWingMan Kwok GBENU_STATS_P3(tx_1024B_frames), 11079a391c7bSWingMan Kwok GBENU_STATS_P3(net_bytes), 11089a391c7bSWingMan Kwok GBENU_STATS_P3(rx_bottom_fifo_drop), 11099a391c7bSWingMan Kwok GBENU_STATS_P3(rx_port_mask_drop), 11109a391c7bSWingMan Kwok GBENU_STATS_P3(rx_top_fifo_drop), 11119a391c7bSWingMan Kwok GBENU_STATS_P3(ale_rate_limit_drop), 11129a391c7bSWingMan Kwok GBENU_STATS_P3(ale_vid_ingress_drop), 11139a391c7bSWingMan Kwok GBENU_STATS_P3(ale_da_eq_sa_drop), 11149a391c7bSWingMan Kwok GBENU_STATS_P3(ale_unknown_ucast), 11159a391c7bSWingMan Kwok GBENU_STATS_P3(ale_unknown_ucast_bytes), 11169a391c7bSWingMan Kwok GBENU_STATS_P3(ale_unknown_mcast), 11179a391c7bSWingMan Kwok GBENU_STATS_P3(ale_unknown_mcast_bytes), 11189a391c7bSWingMan Kwok GBENU_STATS_P3(ale_unknown_bcast), 11199a391c7bSWingMan Kwok GBENU_STATS_P3(ale_unknown_bcast_bytes), 11209a391c7bSWingMan Kwok GBENU_STATS_P3(tx_mem_protect_err), 11219a391c7bSWingMan Kwok /* GBENU Module 4 */ 11229a391c7bSWingMan Kwok GBENU_STATS_P4(rx_good_frames), 11239a391c7bSWingMan Kwok GBENU_STATS_P4(rx_broadcast_frames), 11249a391c7bSWingMan Kwok GBENU_STATS_P4(rx_multicast_frames), 11259a391c7bSWingMan Kwok GBENU_STATS_P4(rx_pause_frames), 11269a391c7bSWingMan Kwok GBENU_STATS_P4(rx_crc_errors), 11279a391c7bSWingMan Kwok GBENU_STATS_P4(rx_align_code_errors), 11289a391c7bSWingMan Kwok GBENU_STATS_P4(rx_oversized_frames), 11299a391c7bSWingMan Kwok GBENU_STATS_P4(rx_jabber_frames), 11309a391c7bSWingMan Kwok GBENU_STATS_P4(rx_undersized_frames), 11319a391c7bSWingMan Kwok GBENU_STATS_P4(rx_fragments), 11329a391c7bSWingMan Kwok GBENU_STATS_P4(ale_drop), 11339a391c7bSWingMan Kwok GBENU_STATS_P4(ale_overrun_drop), 11349a391c7bSWingMan Kwok GBENU_STATS_P4(rx_bytes), 11359a391c7bSWingMan Kwok GBENU_STATS_P4(tx_good_frames), 11369a391c7bSWingMan Kwok GBENU_STATS_P4(tx_broadcast_frames), 11379a391c7bSWingMan Kwok GBENU_STATS_P4(tx_multicast_frames), 11389a391c7bSWingMan Kwok GBENU_STATS_P4(tx_pause_frames), 11399a391c7bSWingMan Kwok GBENU_STATS_P4(tx_deferred_frames), 11409a391c7bSWingMan Kwok GBENU_STATS_P4(tx_collision_frames), 11419a391c7bSWingMan Kwok GBENU_STATS_P4(tx_single_coll_frames), 11429a391c7bSWingMan Kwok GBENU_STATS_P4(tx_mult_coll_frames), 11439a391c7bSWingMan Kwok GBENU_STATS_P4(tx_excessive_collisions), 11449a391c7bSWingMan Kwok GBENU_STATS_P4(tx_late_collisions), 11459a391c7bSWingMan Kwok GBENU_STATS_P4(rx_ipg_error), 11469a391c7bSWingMan Kwok GBENU_STATS_P4(tx_carrier_sense_errors), 11479a391c7bSWingMan Kwok GBENU_STATS_P4(tx_bytes), 11489a391c7bSWingMan Kwok GBENU_STATS_P4(tx_64B_frames), 11499a391c7bSWingMan Kwok GBENU_STATS_P4(tx_65_to_127B_frames), 11509a391c7bSWingMan Kwok GBENU_STATS_P4(tx_128_to_255B_frames), 11519a391c7bSWingMan Kwok GBENU_STATS_P4(tx_256_to_511B_frames), 11529a391c7bSWingMan Kwok GBENU_STATS_P4(tx_512_to_1023B_frames), 11539a391c7bSWingMan Kwok GBENU_STATS_P4(tx_1024B_frames), 11549a391c7bSWingMan Kwok GBENU_STATS_P4(net_bytes), 11559a391c7bSWingMan Kwok GBENU_STATS_P4(rx_bottom_fifo_drop), 11569a391c7bSWingMan Kwok GBENU_STATS_P4(rx_port_mask_drop), 11579a391c7bSWingMan Kwok GBENU_STATS_P4(rx_top_fifo_drop), 11589a391c7bSWingMan Kwok GBENU_STATS_P4(ale_rate_limit_drop), 11599a391c7bSWingMan Kwok GBENU_STATS_P4(ale_vid_ingress_drop), 11609a391c7bSWingMan Kwok GBENU_STATS_P4(ale_da_eq_sa_drop), 11619a391c7bSWingMan Kwok GBENU_STATS_P4(ale_unknown_ucast), 11629a391c7bSWingMan Kwok GBENU_STATS_P4(ale_unknown_ucast_bytes), 11639a391c7bSWingMan Kwok GBENU_STATS_P4(ale_unknown_mcast), 11649a391c7bSWingMan Kwok GBENU_STATS_P4(ale_unknown_mcast_bytes), 11659a391c7bSWingMan Kwok GBENU_STATS_P4(ale_unknown_bcast), 11669a391c7bSWingMan Kwok GBENU_STATS_P4(ale_unknown_bcast_bytes), 11679a391c7bSWingMan Kwok GBENU_STATS_P4(tx_mem_protect_err), 11689a391c7bSWingMan Kwok /* GBENU Module 5 */ 11699a391c7bSWingMan Kwok GBENU_STATS_P5(rx_good_frames), 11709a391c7bSWingMan Kwok GBENU_STATS_P5(rx_broadcast_frames), 11719a391c7bSWingMan Kwok GBENU_STATS_P5(rx_multicast_frames), 11729a391c7bSWingMan Kwok GBENU_STATS_P5(rx_pause_frames), 11739a391c7bSWingMan Kwok GBENU_STATS_P5(rx_crc_errors), 11749a391c7bSWingMan Kwok GBENU_STATS_P5(rx_align_code_errors), 11759a391c7bSWingMan Kwok GBENU_STATS_P5(rx_oversized_frames), 11769a391c7bSWingMan Kwok GBENU_STATS_P5(rx_jabber_frames), 11779a391c7bSWingMan Kwok GBENU_STATS_P5(rx_undersized_frames), 11789a391c7bSWingMan Kwok GBENU_STATS_P5(rx_fragments), 11799a391c7bSWingMan Kwok GBENU_STATS_P5(ale_drop), 11809a391c7bSWingMan Kwok GBENU_STATS_P5(ale_overrun_drop), 11819a391c7bSWingMan Kwok GBENU_STATS_P5(rx_bytes), 11829a391c7bSWingMan Kwok GBENU_STATS_P5(tx_good_frames), 11839a391c7bSWingMan Kwok GBENU_STATS_P5(tx_broadcast_frames), 11849a391c7bSWingMan Kwok GBENU_STATS_P5(tx_multicast_frames), 11859a391c7bSWingMan Kwok GBENU_STATS_P5(tx_pause_frames), 11869a391c7bSWingMan Kwok GBENU_STATS_P5(tx_deferred_frames), 11879a391c7bSWingMan Kwok GBENU_STATS_P5(tx_collision_frames), 11889a391c7bSWingMan Kwok GBENU_STATS_P5(tx_single_coll_frames), 11899a391c7bSWingMan Kwok GBENU_STATS_P5(tx_mult_coll_frames), 11909a391c7bSWingMan Kwok GBENU_STATS_P5(tx_excessive_collisions), 11919a391c7bSWingMan Kwok GBENU_STATS_P5(tx_late_collisions), 11929a391c7bSWingMan Kwok GBENU_STATS_P5(rx_ipg_error), 11939a391c7bSWingMan Kwok GBENU_STATS_P5(tx_carrier_sense_errors), 11949a391c7bSWingMan Kwok GBENU_STATS_P5(tx_bytes), 11959a391c7bSWingMan Kwok GBENU_STATS_P5(tx_64B_frames), 11969a391c7bSWingMan Kwok GBENU_STATS_P5(tx_65_to_127B_frames), 11979a391c7bSWingMan Kwok GBENU_STATS_P5(tx_128_to_255B_frames), 11989a391c7bSWingMan Kwok GBENU_STATS_P5(tx_256_to_511B_frames), 11999a391c7bSWingMan Kwok GBENU_STATS_P5(tx_512_to_1023B_frames), 12009a391c7bSWingMan Kwok GBENU_STATS_P5(tx_1024B_frames), 12019a391c7bSWingMan Kwok GBENU_STATS_P5(net_bytes), 12029a391c7bSWingMan Kwok GBENU_STATS_P5(rx_bottom_fifo_drop), 12039a391c7bSWingMan Kwok GBENU_STATS_P5(rx_port_mask_drop), 12049a391c7bSWingMan Kwok GBENU_STATS_P5(rx_top_fifo_drop), 12059a391c7bSWingMan Kwok GBENU_STATS_P5(ale_rate_limit_drop), 12069a391c7bSWingMan Kwok GBENU_STATS_P5(ale_vid_ingress_drop), 12079a391c7bSWingMan Kwok GBENU_STATS_P5(ale_da_eq_sa_drop), 12089a391c7bSWingMan Kwok GBENU_STATS_P5(ale_unknown_ucast), 12099a391c7bSWingMan Kwok GBENU_STATS_P5(ale_unknown_ucast_bytes), 12109a391c7bSWingMan Kwok GBENU_STATS_P5(ale_unknown_mcast), 12119a391c7bSWingMan Kwok GBENU_STATS_P5(ale_unknown_mcast_bytes), 12129a391c7bSWingMan Kwok GBENU_STATS_P5(ale_unknown_bcast), 12139a391c7bSWingMan Kwok GBENU_STATS_P5(ale_unknown_bcast_bytes), 12149a391c7bSWingMan Kwok GBENU_STATS_P5(tx_mem_protect_err), 12159a391c7bSWingMan Kwok /* GBENU Module 6 */ 12169a391c7bSWingMan Kwok GBENU_STATS_P6(rx_good_frames), 12179a391c7bSWingMan Kwok GBENU_STATS_P6(rx_broadcast_frames), 12189a391c7bSWingMan Kwok GBENU_STATS_P6(rx_multicast_frames), 12199a391c7bSWingMan Kwok GBENU_STATS_P6(rx_pause_frames), 12209a391c7bSWingMan Kwok GBENU_STATS_P6(rx_crc_errors), 12219a391c7bSWingMan Kwok GBENU_STATS_P6(rx_align_code_errors), 12229a391c7bSWingMan Kwok GBENU_STATS_P6(rx_oversized_frames), 12239a391c7bSWingMan Kwok GBENU_STATS_P6(rx_jabber_frames), 12249a391c7bSWingMan Kwok GBENU_STATS_P6(rx_undersized_frames), 12259a391c7bSWingMan Kwok GBENU_STATS_P6(rx_fragments), 12269a391c7bSWingMan Kwok GBENU_STATS_P6(ale_drop), 12279a391c7bSWingMan Kwok GBENU_STATS_P6(ale_overrun_drop), 12289a391c7bSWingMan Kwok GBENU_STATS_P6(rx_bytes), 12299a391c7bSWingMan Kwok GBENU_STATS_P6(tx_good_frames), 12309a391c7bSWingMan Kwok GBENU_STATS_P6(tx_broadcast_frames), 12319a391c7bSWingMan Kwok GBENU_STATS_P6(tx_multicast_frames), 12329a391c7bSWingMan Kwok GBENU_STATS_P6(tx_pause_frames), 12339a391c7bSWingMan Kwok GBENU_STATS_P6(tx_deferred_frames), 12349a391c7bSWingMan Kwok GBENU_STATS_P6(tx_collision_frames), 12359a391c7bSWingMan Kwok GBENU_STATS_P6(tx_single_coll_frames), 12369a391c7bSWingMan Kwok GBENU_STATS_P6(tx_mult_coll_frames), 12379a391c7bSWingMan Kwok GBENU_STATS_P6(tx_excessive_collisions), 12389a391c7bSWingMan Kwok GBENU_STATS_P6(tx_late_collisions), 12399a391c7bSWingMan Kwok GBENU_STATS_P6(rx_ipg_error), 12409a391c7bSWingMan Kwok GBENU_STATS_P6(tx_carrier_sense_errors), 12419a391c7bSWingMan Kwok GBENU_STATS_P6(tx_bytes), 12429a391c7bSWingMan Kwok GBENU_STATS_P6(tx_64B_frames), 12439a391c7bSWingMan Kwok GBENU_STATS_P6(tx_65_to_127B_frames), 12449a391c7bSWingMan Kwok GBENU_STATS_P6(tx_128_to_255B_frames), 12459a391c7bSWingMan Kwok GBENU_STATS_P6(tx_256_to_511B_frames), 12469a391c7bSWingMan Kwok GBENU_STATS_P6(tx_512_to_1023B_frames), 12479a391c7bSWingMan Kwok GBENU_STATS_P6(tx_1024B_frames), 12489a391c7bSWingMan Kwok GBENU_STATS_P6(net_bytes), 12499a391c7bSWingMan Kwok GBENU_STATS_P6(rx_bottom_fifo_drop), 12509a391c7bSWingMan Kwok GBENU_STATS_P6(rx_port_mask_drop), 12519a391c7bSWingMan Kwok GBENU_STATS_P6(rx_top_fifo_drop), 12529a391c7bSWingMan Kwok GBENU_STATS_P6(ale_rate_limit_drop), 12539a391c7bSWingMan Kwok GBENU_STATS_P6(ale_vid_ingress_drop), 12549a391c7bSWingMan Kwok GBENU_STATS_P6(ale_da_eq_sa_drop), 12559a391c7bSWingMan Kwok GBENU_STATS_P6(ale_unknown_ucast), 12569a391c7bSWingMan Kwok GBENU_STATS_P6(ale_unknown_ucast_bytes), 12579a391c7bSWingMan Kwok GBENU_STATS_P6(ale_unknown_mcast), 12589a391c7bSWingMan Kwok GBENU_STATS_P6(ale_unknown_mcast_bytes), 12599a391c7bSWingMan Kwok GBENU_STATS_P6(ale_unknown_bcast), 12609a391c7bSWingMan Kwok GBENU_STATS_P6(ale_unknown_bcast_bytes), 12619a391c7bSWingMan Kwok GBENU_STATS_P6(tx_mem_protect_err), 12629a391c7bSWingMan Kwok /* GBENU Module 7 */ 12639a391c7bSWingMan Kwok GBENU_STATS_P7(rx_good_frames), 12649a391c7bSWingMan Kwok GBENU_STATS_P7(rx_broadcast_frames), 12659a391c7bSWingMan Kwok GBENU_STATS_P7(rx_multicast_frames), 12669a391c7bSWingMan Kwok GBENU_STATS_P7(rx_pause_frames), 12679a391c7bSWingMan Kwok GBENU_STATS_P7(rx_crc_errors), 12689a391c7bSWingMan Kwok GBENU_STATS_P7(rx_align_code_errors), 12699a391c7bSWingMan Kwok GBENU_STATS_P7(rx_oversized_frames), 12709a391c7bSWingMan Kwok GBENU_STATS_P7(rx_jabber_frames), 12719a391c7bSWingMan Kwok GBENU_STATS_P7(rx_undersized_frames), 12729a391c7bSWingMan Kwok GBENU_STATS_P7(rx_fragments), 12739a391c7bSWingMan Kwok GBENU_STATS_P7(ale_drop), 12749a391c7bSWingMan Kwok GBENU_STATS_P7(ale_overrun_drop), 12759a391c7bSWingMan Kwok GBENU_STATS_P7(rx_bytes), 12769a391c7bSWingMan Kwok GBENU_STATS_P7(tx_good_frames), 12779a391c7bSWingMan Kwok GBENU_STATS_P7(tx_broadcast_frames), 12789a391c7bSWingMan Kwok GBENU_STATS_P7(tx_multicast_frames), 12799a391c7bSWingMan Kwok GBENU_STATS_P7(tx_pause_frames), 12809a391c7bSWingMan Kwok GBENU_STATS_P7(tx_deferred_frames), 12819a391c7bSWingMan Kwok GBENU_STATS_P7(tx_collision_frames), 12829a391c7bSWingMan Kwok GBENU_STATS_P7(tx_single_coll_frames), 12839a391c7bSWingMan Kwok GBENU_STATS_P7(tx_mult_coll_frames), 12849a391c7bSWingMan Kwok GBENU_STATS_P7(tx_excessive_collisions), 12859a391c7bSWingMan Kwok GBENU_STATS_P7(tx_late_collisions), 12869a391c7bSWingMan Kwok GBENU_STATS_P7(rx_ipg_error), 12879a391c7bSWingMan Kwok GBENU_STATS_P7(tx_carrier_sense_errors), 12889a391c7bSWingMan Kwok GBENU_STATS_P7(tx_bytes), 12899a391c7bSWingMan Kwok GBENU_STATS_P7(tx_64B_frames), 12909a391c7bSWingMan Kwok GBENU_STATS_P7(tx_65_to_127B_frames), 12919a391c7bSWingMan Kwok GBENU_STATS_P7(tx_128_to_255B_frames), 12929a391c7bSWingMan Kwok GBENU_STATS_P7(tx_256_to_511B_frames), 12939a391c7bSWingMan Kwok GBENU_STATS_P7(tx_512_to_1023B_frames), 12949a391c7bSWingMan Kwok GBENU_STATS_P7(tx_1024B_frames), 12959a391c7bSWingMan Kwok GBENU_STATS_P7(net_bytes), 12969a391c7bSWingMan Kwok GBENU_STATS_P7(rx_bottom_fifo_drop), 12979a391c7bSWingMan Kwok GBENU_STATS_P7(rx_port_mask_drop), 12989a391c7bSWingMan Kwok GBENU_STATS_P7(rx_top_fifo_drop), 12999a391c7bSWingMan Kwok GBENU_STATS_P7(ale_rate_limit_drop), 13009a391c7bSWingMan Kwok GBENU_STATS_P7(ale_vid_ingress_drop), 13019a391c7bSWingMan Kwok GBENU_STATS_P7(ale_da_eq_sa_drop), 13029a391c7bSWingMan Kwok GBENU_STATS_P7(ale_unknown_ucast), 13039a391c7bSWingMan Kwok GBENU_STATS_P7(ale_unknown_ucast_bytes), 13049a391c7bSWingMan Kwok GBENU_STATS_P7(ale_unknown_mcast), 13059a391c7bSWingMan Kwok GBENU_STATS_P7(ale_unknown_mcast_bytes), 13069a391c7bSWingMan Kwok GBENU_STATS_P7(ale_unknown_bcast), 13079a391c7bSWingMan Kwok GBENU_STATS_P7(ale_unknown_bcast_bytes), 13089a391c7bSWingMan Kwok GBENU_STATS_P7(tx_mem_protect_err), 13099a391c7bSWingMan Kwok /* GBENU Module 8 */ 13109a391c7bSWingMan Kwok GBENU_STATS_P8(rx_good_frames), 13119a391c7bSWingMan Kwok GBENU_STATS_P8(rx_broadcast_frames), 13129a391c7bSWingMan Kwok GBENU_STATS_P8(rx_multicast_frames), 13139a391c7bSWingMan Kwok GBENU_STATS_P8(rx_pause_frames), 13149a391c7bSWingMan Kwok GBENU_STATS_P8(rx_crc_errors), 13159a391c7bSWingMan Kwok GBENU_STATS_P8(rx_align_code_errors), 13169a391c7bSWingMan Kwok GBENU_STATS_P8(rx_oversized_frames), 13179a391c7bSWingMan Kwok GBENU_STATS_P8(rx_jabber_frames), 13189a391c7bSWingMan Kwok GBENU_STATS_P8(rx_undersized_frames), 13199a391c7bSWingMan Kwok GBENU_STATS_P8(rx_fragments), 13209a391c7bSWingMan Kwok GBENU_STATS_P8(ale_drop), 13219a391c7bSWingMan Kwok GBENU_STATS_P8(ale_overrun_drop), 13229a391c7bSWingMan Kwok GBENU_STATS_P8(rx_bytes), 13239a391c7bSWingMan Kwok GBENU_STATS_P8(tx_good_frames), 13249a391c7bSWingMan Kwok GBENU_STATS_P8(tx_broadcast_frames), 13259a391c7bSWingMan Kwok GBENU_STATS_P8(tx_multicast_frames), 13269a391c7bSWingMan Kwok GBENU_STATS_P8(tx_pause_frames), 13279a391c7bSWingMan Kwok GBENU_STATS_P8(tx_deferred_frames), 13289a391c7bSWingMan Kwok GBENU_STATS_P8(tx_collision_frames), 13299a391c7bSWingMan Kwok GBENU_STATS_P8(tx_single_coll_frames), 13309a391c7bSWingMan Kwok GBENU_STATS_P8(tx_mult_coll_frames), 13319a391c7bSWingMan Kwok GBENU_STATS_P8(tx_excessive_collisions), 13329a391c7bSWingMan Kwok GBENU_STATS_P8(tx_late_collisions), 13339a391c7bSWingMan Kwok GBENU_STATS_P8(rx_ipg_error), 13349a391c7bSWingMan Kwok GBENU_STATS_P8(tx_carrier_sense_errors), 13359a391c7bSWingMan Kwok GBENU_STATS_P8(tx_bytes), 13369a391c7bSWingMan Kwok GBENU_STATS_P8(tx_64B_frames), 13379a391c7bSWingMan Kwok GBENU_STATS_P8(tx_65_to_127B_frames), 13389a391c7bSWingMan Kwok GBENU_STATS_P8(tx_128_to_255B_frames), 13399a391c7bSWingMan Kwok GBENU_STATS_P8(tx_256_to_511B_frames), 13409a391c7bSWingMan Kwok GBENU_STATS_P8(tx_512_to_1023B_frames), 13419a391c7bSWingMan Kwok GBENU_STATS_P8(tx_1024B_frames), 13429a391c7bSWingMan Kwok GBENU_STATS_P8(net_bytes), 13439a391c7bSWingMan Kwok GBENU_STATS_P8(rx_bottom_fifo_drop), 13449a391c7bSWingMan Kwok GBENU_STATS_P8(rx_port_mask_drop), 13459a391c7bSWingMan Kwok GBENU_STATS_P8(rx_top_fifo_drop), 13469a391c7bSWingMan Kwok GBENU_STATS_P8(ale_rate_limit_drop), 13479a391c7bSWingMan Kwok GBENU_STATS_P8(ale_vid_ingress_drop), 13489a391c7bSWingMan Kwok GBENU_STATS_P8(ale_da_eq_sa_drop), 13499a391c7bSWingMan Kwok GBENU_STATS_P8(ale_unknown_ucast), 13509a391c7bSWingMan Kwok GBENU_STATS_P8(ale_unknown_ucast_bytes), 13519a391c7bSWingMan Kwok GBENU_STATS_P8(ale_unknown_mcast), 13529a391c7bSWingMan Kwok GBENU_STATS_P8(ale_unknown_mcast_bytes), 13539a391c7bSWingMan Kwok GBENU_STATS_P8(ale_unknown_bcast), 13549a391c7bSWingMan Kwok GBENU_STATS_P8(ale_unknown_bcast_bytes), 13559a391c7bSWingMan Kwok GBENU_STATS_P8(tx_mem_protect_err), 13569a391c7bSWingMan Kwok }; 13579a391c7bSWingMan Kwok 1358da866ba0SKaricheri, Muralidharan #define XGBE_STATS0_INFO(field) \ 1359da866ba0SKaricheri, Muralidharan { \ 1360da866ba0SKaricheri, Muralidharan "GBE_0:"#field, XGBE_STATS0_MODULE, \ 136190cff9e2SWingman Kwok FIELD_SIZEOF(struct xgbe_hw_stats, field), \ 1362da866ba0SKaricheri, Muralidharan offsetof(struct xgbe_hw_stats, field) \ 1363da866ba0SKaricheri, Muralidharan } 136490cff9e2SWingman Kwok 1365da866ba0SKaricheri, Muralidharan #define XGBE_STATS1_INFO(field) \ 1366da866ba0SKaricheri, Muralidharan { \ 1367da866ba0SKaricheri, Muralidharan "GBE_1:"#field, XGBE_STATS1_MODULE, \ 136890cff9e2SWingman Kwok FIELD_SIZEOF(struct xgbe_hw_stats, field), \ 1369da866ba0SKaricheri, Muralidharan offsetof(struct xgbe_hw_stats, field) \ 1370da866ba0SKaricheri, Muralidharan } 137190cff9e2SWingman Kwok 1372da866ba0SKaricheri, Muralidharan #define XGBE_STATS2_INFO(field) \ 1373da866ba0SKaricheri, Muralidharan { \ 1374da866ba0SKaricheri, Muralidharan "GBE_2:"#field, XGBE_STATS2_MODULE, \ 137590cff9e2SWingman Kwok FIELD_SIZEOF(struct xgbe_hw_stats, field), \ 1376da866ba0SKaricheri, Muralidharan offsetof(struct xgbe_hw_stats, field) \ 1377da866ba0SKaricheri, Muralidharan } 137890cff9e2SWingman Kwok 137990cff9e2SWingman Kwok static const struct netcp_ethtool_stat xgbe10_et_stats[] = { 138090cff9e2SWingman Kwok /* GBE module 0 */ 1381da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_good_frames), 1382da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_broadcast_frames), 1383da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_multicast_frames), 1384da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_oversized_frames), 1385da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_undersized_frames), 1386da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(overrun_type4), 1387da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(overrun_type5), 1388da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_bytes), 1389da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_good_frames), 1390da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_broadcast_frames), 1391da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_multicast_frames), 1392da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_bytes), 1393da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_64byte_frames), 1394da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_65_to_127byte_frames), 1395da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_128_to_255byte_frames), 1396da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_256_to_511byte_frames), 1397da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_512_to_1023byte_frames), 1398da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_1024byte_frames), 1399da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(net_bytes), 1400da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_sof_overruns), 1401da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_mof_overruns), 1402da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_dma_overruns), 140390cff9e2SWingman Kwok /* XGBE module 1 */ 1404da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_good_frames), 1405da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_broadcast_frames), 1406da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_multicast_frames), 1407da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_pause_frames), 1408da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_crc_errors), 1409da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_align_code_errors), 1410da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_oversized_frames), 1411da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_jabber_frames), 1412da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_undersized_frames), 1413da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_fragments), 1414da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(overrun_type4), 1415da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(overrun_type5), 1416da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_bytes), 1417da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_good_frames), 1418da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_broadcast_frames), 1419da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_multicast_frames), 1420da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_pause_frames), 1421da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_deferred_frames), 1422da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_collision_frames), 1423da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_single_coll_frames), 1424da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_mult_coll_frames), 1425da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_excessive_collisions), 1426da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_late_collisions), 1427da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_underrun), 1428da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_carrier_sense_errors), 1429da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_bytes), 1430da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_64byte_frames), 1431da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_65_to_127byte_frames), 1432da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_128_to_255byte_frames), 1433da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_256_to_511byte_frames), 1434da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_512_to_1023byte_frames), 1435da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_1024byte_frames), 1436da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(net_bytes), 1437da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_sof_overruns), 1438da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_mof_overruns), 1439da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_dma_overruns), 144090cff9e2SWingman Kwok /* XGBE module 2 */ 1441da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_good_frames), 1442da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_broadcast_frames), 1443da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_multicast_frames), 1444da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_pause_frames), 1445da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_crc_errors), 1446da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_align_code_errors), 1447da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_oversized_frames), 1448da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_jabber_frames), 1449da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_undersized_frames), 1450da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_fragments), 1451da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(overrun_type4), 1452da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(overrun_type5), 1453da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_bytes), 1454da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_good_frames), 1455da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_broadcast_frames), 1456da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_multicast_frames), 1457da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_pause_frames), 1458da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_deferred_frames), 1459da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_collision_frames), 1460da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_single_coll_frames), 1461da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_mult_coll_frames), 1462da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_excessive_collisions), 1463da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_late_collisions), 1464da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_underrun), 1465da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_carrier_sense_errors), 1466da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_bytes), 1467da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_64byte_frames), 1468da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_65_to_127byte_frames), 1469da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_128_to_255byte_frames), 1470da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_256_to_511byte_frames), 1471da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_512_to_1023byte_frames), 1472da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_1024byte_frames), 1473da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(net_bytes), 1474da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_sof_overruns), 1475da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_mof_overruns), 1476da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_dma_overruns), 147790cff9e2SWingman Kwok }; 147890cff9e2SWingman Kwok 14796f8d3f33SWingman Kwok #define for_each_intf(i, priv) \ 14806f8d3f33SWingman Kwok list_for_each_entry((i), &(priv)->gbe_intf_head, gbe_intf_list) 14816f8d3f33SWingman Kwok 14826f8d3f33SWingman Kwok #define for_each_sec_slave(slave, priv) \ 14836f8d3f33SWingman Kwok list_for_each_entry((slave), &(priv)->secondary_slaves, slave_list) 14846f8d3f33SWingman Kwok 14856f8d3f33SWingman Kwok #define first_sec_slave(priv) \ 14866f8d3f33SWingman Kwok list_first_entry(&priv->secondary_slaves, \ 14876f8d3f33SWingman Kwok struct gbe_slave, slave_list) 14886f8d3f33SWingman Kwok 14896f8d3f33SWingman Kwok static void keystone_get_drvinfo(struct net_device *ndev, 14906f8d3f33SWingman Kwok struct ethtool_drvinfo *info) 14916f8d3f33SWingman Kwok { 14926f8d3f33SWingman Kwok strncpy(info->driver, NETCP_DRIVER_NAME, sizeof(info->driver)); 14936f8d3f33SWingman Kwok strncpy(info->version, NETCP_DRIVER_VERSION, sizeof(info->version)); 14946f8d3f33SWingman Kwok } 14956f8d3f33SWingman Kwok 14966f8d3f33SWingman Kwok static u32 keystone_get_msglevel(struct net_device *ndev) 14976f8d3f33SWingman Kwok { 14986f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 14996f8d3f33SWingman Kwok 15006f8d3f33SWingman Kwok return netcp->msg_enable; 15016f8d3f33SWingman Kwok } 15026f8d3f33SWingman Kwok 15036f8d3f33SWingman Kwok static void keystone_set_msglevel(struct net_device *ndev, u32 value) 15046f8d3f33SWingman Kwok { 15056f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 15066f8d3f33SWingman Kwok 15076f8d3f33SWingman Kwok netcp->msg_enable = value; 15086f8d3f33SWingman Kwok } 15096f8d3f33SWingman Kwok 15106f8d3f33SWingman Kwok static void keystone_get_stat_strings(struct net_device *ndev, 15116f8d3f33SWingman Kwok uint32_t stringset, uint8_t *data) 15126f8d3f33SWingman Kwok { 15136f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 15146f8d3f33SWingman Kwok struct gbe_intf *gbe_intf; 15156f8d3f33SWingman Kwok struct gbe_priv *gbe_dev; 15166f8d3f33SWingman Kwok int i; 15176f8d3f33SWingman Kwok 15186f8d3f33SWingman Kwok gbe_intf = netcp_module_get_intf_data(&gbe_module, netcp); 15196f8d3f33SWingman Kwok if (!gbe_intf) 15206f8d3f33SWingman Kwok return; 15216f8d3f33SWingman Kwok gbe_dev = gbe_intf->gbe_dev; 15226f8d3f33SWingman Kwok 15236f8d3f33SWingman Kwok switch (stringset) { 15246f8d3f33SWingman Kwok case ETH_SS_STATS: 15256f8d3f33SWingman Kwok for (i = 0; i < gbe_dev->num_et_stats; i++) { 15266f8d3f33SWingman Kwok memcpy(data, gbe_dev->et_stats[i].desc, 15276f8d3f33SWingman Kwok ETH_GSTRING_LEN); 15286f8d3f33SWingman Kwok data += ETH_GSTRING_LEN; 15296f8d3f33SWingman Kwok } 15306f8d3f33SWingman Kwok break; 15316f8d3f33SWingman Kwok case ETH_SS_TEST: 15326f8d3f33SWingman Kwok break; 15336f8d3f33SWingman Kwok } 15346f8d3f33SWingman Kwok } 15356f8d3f33SWingman Kwok 15366f8d3f33SWingman Kwok static int keystone_get_sset_count(struct net_device *ndev, int stringset) 15376f8d3f33SWingman Kwok { 15386f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 15396f8d3f33SWingman Kwok struct gbe_intf *gbe_intf; 15406f8d3f33SWingman Kwok struct gbe_priv *gbe_dev; 15416f8d3f33SWingman Kwok 15426f8d3f33SWingman Kwok gbe_intf = netcp_module_get_intf_data(&gbe_module, netcp); 15436f8d3f33SWingman Kwok if (!gbe_intf) 15446f8d3f33SWingman Kwok return -EINVAL; 15456f8d3f33SWingman Kwok gbe_dev = gbe_intf->gbe_dev; 15466f8d3f33SWingman Kwok 15476f8d3f33SWingman Kwok switch (stringset) { 15486f8d3f33SWingman Kwok case ETH_SS_TEST: 15496f8d3f33SWingman Kwok return 0; 15506f8d3f33SWingman Kwok case ETH_SS_STATS: 15516f8d3f33SWingman Kwok return gbe_dev->num_et_stats; 15526f8d3f33SWingman Kwok default: 15536f8d3f33SWingman Kwok return -EINVAL; 15546f8d3f33SWingman Kwok } 15556f8d3f33SWingman Kwok } 15566f8d3f33SWingman Kwok 15576f8d3f33SWingman Kwok static void gbe_update_stats(struct gbe_priv *gbe_dev, uint64_t *data) 15586f8d3f33SWingman Kwok { 15596f8d3f33SWingman Kwok void __iomem *base = NULL; 15606f8d3f33SWingman Kwok u32 __iomem *p; 15616f8d3f33SWingman Kwok u32 tmp = 0; 15626f8d3f33SWingman Kwok int i; 15636f8d3f33SWingman Kwok 15646f8d3f33SWingman Kwok for (i = 0; i < gbe_dev->num_et_stats; i++) { 15656f8d3f33SWingman Kwok base = gbe_dev->hw_stats_regs[gbe_dev->et_stats[i].type]; 15666f8d3f33SWingman Kwok p = base + gbe_dev->et_stats[i].offset; 15676f8d3f33SWingman Kwok tmp = readl(p); 15686f8d3f33SWingman Kwok gbe_dev->hw_stats[i] = gbe_dev->hw_stats[i] + tmp; 15696f8d3f33SWingman Kwok if (data) 15706f8d3f33SWingman Kwok data[i] = gbe_dev->hw_stats[i]; 15716f8d3f33SWingman Kwok /* write-to-decrement: 15726f8d3f33SWingman Kwok * new register value = old register value - write value 15736f8d3f33SWingman Kwok */ 15746f8d3f33SWingman Kwok writel(tmp, p); 15756f8d3f33SWingman Kwok } 15766f8d3f33SWingman Kwok } 15776f8d3f33SWingman Kwok 15786f8d3f33SWingman Kwok static void gbe_update_stats_ver14(struct gbe_priv *gbe_dev, uint64_t *data) 15796f8d3f33SWingman Kwok { 15806f8d3f33SWingman Kwok void __iomem *gbe_statsa = gbe_dev->hw_stats_regs[0]; 15816f8d3f33SWingman Kwok void __iomem *gbe_statsb = gbe_dev->hw_stats_regs[1]; 15826f8d3f33SWingman Kwok u64 *hw_stats = &gbe_dev->hw_stats[0]; 15836f8d3f33SWingman Kwok void __iomem *base = NULL; 15846f8d3f33SWingman Kwok u32 __iomem *p; 15856f8d3f33SWingman Kwok u32 tmp = 0, val, pair_size = (gbe_dev->num_et_stats / 2); 15866f8d3f33SWingman Kwok int i, j, pair; 15876f8d3f33SWingman Kwok 15886f8d3f33SWingman Kwok for (pair = 0; pair < 2; pair++) { 15896f8d3f33SWingman Kwok val = readl(GBE_REG_ADDR(gbe_dev, switch_regs, stat_port_en)); 15906f8d3f33SWingman Kwok 15916f8d3f33SWingman Kwok if (pair == 0) 15926f8d3f33SWingman Kwok val &= ~GBE_STATS_CD_SEL; 15936f8d3f33SWingman Kwok else 15946f8d3f33SWingman Kwok val |= GBE_STATS_CD_SEL; 15956f8d3f33SWingman Kwok 15966f8d3f33SWingman Kwok /* make the stat modules visible */ 15976f8d3f33SWingman Kwok writel(val, GBE_REG_ADDR(gbe_dev, switch_regs, stat_port_en)); 15986f8d3f33SWingman Kwok 15996f8d3f33SWingman Kwok for (i = 0; i < pair_size; i++) { 16006f8d3f33SWingman Kwok j = pair * pair_size + i; 16016f8d3f33SWingman Kwok switch (gbe_dev->et_stats[j].type) { 16026f8d3f33SWingman Kwok case GBE_STATSA_MODULE: 16036f8d3f33SWingman Kwok case GBE_STATSC_MODULE: 16046f8d3f33SWingman Kwok base = gbe_statsa; 16056f8d3f33SWingman Kwok break; 16066f8d3f33SWingman Kwok case GBE_STATSB_MODULE: 16076f8d3f33SWingman Kwok case GBE_STATSD_MODULE: 16086f8d3f33SWingman Kwok base = gbe_statsb; 16096f8d3f33SWingman Kwok break; 16106f8d3f33SWingman Kwok } 16116f8d3f33SWingman Kwok 16126f8d3f33SWingman Kwok p = base + gbe_dev->et_stats[j].offset; 16136f8d3f33SWingman Kwok tmp = readl(p); 16146f8d3f33SWingman Kwok hw_stats[j] += tmp; 16156f8d3f33SWingman Kwok if (data) 16166f8d3f33SWingman Kwok data[j] = hw_stats[j]; 16176f8d3f33SWingman Kwok /* write-to-decrement: 16186f8d3f33SWingman Kwok * new register value = old register value - write value 16196f8d3f33SWingman Kwok */ 16206f8d3f33SWingman Kwok writel(tmp, p); 16216f8d3f33SWingman Kwok } 16226f8d3f33SWingman Kwok } 16236f8d3f33SWingman Kwok } 16246f8d3f33SWingman Kwok 16256f8d3f33SWingman Kwok static void keystone_get_ethtool_stats(struct net_device *ndev, 16266f8d3f33SWingman Kwok struct ethtool_stats *stats, 16276f8d3f33SWingman Kwok uint64_t *data) 16286f8d3f33SWingman Kwok { 16296f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 16306f8d3f33SWingman Kwok struct gbe_intf *gbe_intf; 16316f8d3f33SWingman Kwok struct gbe_priv *gbe_dev; 16326f8d3f33SWingman Kwok 16336f8d3f33SWingman Kwok gbe_intf = netcp_module_get_intf_data(&gbe_module, netcp); 16346f8d3f33SWingman Kwok if (!gbe_intf) 16356f8d3f33SWingman Kwok return; 16366f8d3f33SWingman Kwok 16376f8d3f33SWingman Kwok gbe_dev = gbe_intf->gbe_dev; 16386f8d3f33SWingman Kwok spin_lock_bh(&gbe_dev->hw_stats_lock); 163990cff9e2SWingman Kwok if (gbe_dev->ss_version == GBE_SS_VERSION_14) 16406f8d3f33SWingman Kwok gbe_update_stats_ver14(gbe_dev, data); 164190cff9e2SWingman Kwok else 164290cff9e2SWingman Kwok gbe_update_stats(gbe_dev, data); 16436f8d3f33SWingman Kwok spin_unlock_bh(&gbe_dev->hw_stats_lock); 16446f8d3f33SWingman Kwok } 16456f8d3f33SWingman Kwok 16466f8d3f33SWingman Kwok static int keystone_get_settings(struct net_device *ndev, 16476f8d3f33SWingman Kwok struct ethtool_cmd *cmd) 16486f8d3f33SWingman Kwok { 16496f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 16506f8d3f33SWingman Kwok struct phy_device *phy = ndev->phydev; 16516f8d3f33SWingman Kwok struct gbe_intf *gbe_intf; 16526f8d3f33SWingman Kwok int ret; 16536f8d3f33SWingman Kwok 16546f8d3f33SWingman Kwok if (!phy) 16556f8d3f33SWingman Kwok return -EINVAL; 16566f8d3f33SWingman Kwok 16576f8d3f33SWingman Kwok gbe_intf = netcp_module_get_intf_data(&gbe_module, netcp); 16586f8d3f33SWingman Kwok if (!gbe_intf) 16596f8d3f33SWingman Kwok return -EINVAL; 16606f8d3f33SWingman Kwok 16616f8d3f33SWingman Kwok if (!gbe_intf->slave) 16626f8d3f33SWingman Kwok return -EINVAL; 16636f8d3f33SWingman Kwok 16646f8d3f33SWingman Kwok ret = phy_ethtool_gset(phy, cmd); 16656f8d3f33SWingman Kwok if (!ret) 16666f8d3f33SWingman Kwok cmd->port = gbe_intf->slave->phy_port_t; 16676f8d3f33SWingman Kwok 16686f8d3f33SWingman Kwok return ret; 16696f8d3f33SWingman Kwok } 16706f8d3f33SWingman Kwok 16716f8d3f33SWingman Kwok static int keystone_set_settings(struct net_device *ndev, 16726f8d3f33SWingman Kwok struct ethtool_cmd *cmd) 16736f8d3f33SWingman Kwok { 16746f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 16756f8d3f33SWingman Kwok struct phy_device *phy = ndev->phydev; 16766f8d3f33SWingman Kwok struct gbe_intf *gbe_intf; 16776f8d3f33SWingman Kwok u32 features = cmd->advertising & cmd->supported; 16786f8d3f33SWingman Kwok 16796f8d3f33SWingman Kwok if (!phy) 16806f8d3f33SWingman Kwok return -EINVAL; 16816f8d3f33SWingman Kwok 16826f8d3f33SWingman Kwok gbe_intf = netcp_module_get_intf_data(&gbe_module, netcp); 16836f8d3f33SWingman Kwok if (!gbe_intf) 16846f8d3f33SWingman Kwok return -EINVAL; 16856f8d3f33SWingman Kwok 16866f8d3f33SWingman Kwok if (!gbe_intf->slave) 16876f8d3f33SWingman Kwok return -EINVAL; 16886f8d3f33SWingman Kwok 16896f8d3f33SWingman Kwok if (cmd->port != gbe_intf->slave->phy_port_t) { 16906f8d3f33SWingman Kwok if ((cmd->port == PORT_TP) && !(features & ADVERTISED_TP)) 16916f8d3f33SWingman Kwok return -EINVAL; 16926f8d3f33SWingman Kwok 16936f8d3f33SWingman Kwok if ((cmd->port == PORT_AUI) && !(features & ADVERTISED_AUI)) 16946f8d3f33SWingman Kwok return -EINVAL; 16956f8d3f33SWingman Kwok 16966f8d3f33SWingman Kwok if ((cmd->port == PORT_BNC) && !(features & ADVERTISED_BNC)) 16976f8d3f33SWingman Kwok return -EINVAL; 16986f8d3f33SWingman Kwok 16996f8d3f33SWingman Kwok if ((cmd->port == PORT_MII) && !(features & ADVERTISED_MII)) 17006f8d3f33SWingman Kwok return -EINVAL; 17016f8d3f33SWingman Kwok 17026f8d3f33SWingman Kwok if ((cmd->port == PORT_FIBRE) && !(features & ADVERTISED_FIBRE)) 17036f8d3f33SWingman Kwok return -EINVAL; 17046f8d3f33SWingman Kwok } 17056f8d3f33SWingman Kwok 17066f8d3f33SWingman Kwok gbe_intf->slave->phy_port_t = cmd->port; 17076f8d3f33SWingman Kwok return phy_ethtool_sset(phy, cmd); 17086f8d3f33SWingman Kwok } 17096f8d3f33SWingman Kwok 17106f8d3f33SWingman Kwok static const struct ethtool_ops keystone_ethtool_ops = { 17116f8d3f33SWingman Kwok .get_drvinfo = keystone_get_drvinfo, 17126f8d3f33SWingman Kwok .get_link = ethtool_op_get_link, 17136f8d3f33SWingman Kwok .get_msglevel = keystone_get_msglevel, 17146f8d3f33SWingman Kwok .set_msglevel = keystone_set_msglevel, 17156f8d3f33SWingman Kwok .get_strings = keystone_get_stat_strings, 17166f8d3f33SWingman Kwok .get_sset_count = keystone_get_sset_count, 17176f8d3f33SWingman Kwok .get_ethtool_stats = keystone_get_ethtool_stats, 17186f8d3f33SWingman Kwok .get_settings = keystone_get_settings, 17196f8d3f33SWingman Kwok .set_settings = keystone_set_settings, 17206f8d3f33SWingman Kwok }; 17216f8d3f33SWingman Kwok 17226f8d3f33SWingman Kwok #define mac_hi(mac) (((mac)[0] << 0) | ((mac)[1] << 8) | \ 17236f8d3f33SWingman Kwok ((mac)[2] << 16) | ((mac)[3] << 24)) 17246f8d3f33SWingman Kwok #define mac_lo(mac) (((mac)[4] << 0) | ((mac)[5] << 8)) 17256f8d3f33SWingman Kwok 17266f8d3f33SWingman Kwok static void gbe_set_slave_mac(struct gbe_slave *slave, 17276f8d3f33SWingman Kwok struct gbe_intf *gbe_intf) 17286f8d3f33SWingman Kwok { 17296f8d3f33SWingman Kwok struct net_device *ndev = gbe_intf->ndev; 17306f8d3f33SWingman Kwok 17316f8d3f33SWingman Kwok writel(mac_hi(ndev->dev_addr), GBE_REG_ADDR(slave, port_regs, sa_hi)); 17326f8d3f33SWingman Kwok writel(mac_lo(ndev->dev_addr), GBE_REG_ADDR(slave, port_regs, sa_lo)); 17336f8d3f33SWingman Kwok } 17346f8d3f33SWingman Kwok 17356f8d3f33SWingman Kwok static int gbe_get_slave_port(struct gbe_priv *priv, u32 slave_num) 17366f8d3f33SWingman Kwok { 17376f8d3f33SWingman Kwok if (priv->host_port == 0) 17386f8d3f33SWingman Kwok return slave_num + 1; 17396f8d3f33SWingman Kwok 17406f8d3f33SWingman Kwok return slave_num; 17416f8d3f33SWingman Kwok } 17426f8d3f33SWingman Kwok 17436f8d3f33SWingman Kwok static void netcp_ethss_link_state_action(struct gbe_priv *gbe_dev, 17446f8d3f33SWingman Kwok struct net_device *ndev, 17456f8d3f33SWingman Kwok struct gbe_slave *slave, 17466f8d3f33SWingman Kwok int up) 17476f8d3f33SWingman Kwok { 17486f8d3f33SWingman Kwok struct phy_device *phy = slave->phy; 17496f8d3f33SWingman Kwok u32 mac_control = 0; 17506f8d3f33SWingman Kwok 17516f8d3f33SWingman Kwok if (up) { 17526f8d3f33SWingman Kwok mac_control = slave->mac_control; 175390cff9e2SWingman Kwok if (phy && (phy->speed == SPEED_1000)) { 17546f8d3f33SWingman Kwok mac_control |= MACSL_GIG_MODE; 175590cff9e2SWingman Kwok mac_control &= ~MACSL_XGIG_MODE; 175690cff9e2SWingman Kwok } else if (phy && (phy->speed == SPEED_10000)) { 175790cff9e2SWingman Kwok mac_control |= MACSL_XGIG_MODE; 175890cff9e2SWingman Kwok mac_control &= ~MACSL_GIG_MODE; 175990cff9e2SWingman Kwok } 17606f8d3f33SWingman Kwok 17616f8d3f33SWingman Kwok writel(mac_control, GBE_REG_ADDR(slave, emac_regs, 17626f8d3f33SWingman Kwok mac_control)); 17636f8d3f33SWingman Kwok 17646f8d3f33SWingman Kwok cpsw_ale_control_set(gbe_dev->ale, slave->port_num, 17656f8d3f33SWingman Kwok ALE_PORT_STATE, 17666f8d3f33SWingman Kwok ALE_PORT_STATE_FORWARD); 17676f8d3f33SWingman Kwok 17688e046d68SKaricheri, Muralidharan if (ndev && slave->open && 17698e046d68SKaricheri, Muralidharan slave->link_interface != SGMII_LINK_MAC_PHY && 17708e046d68SKaricheri, Muralidharan slave->link_interface != XGMII_LINK_MAC_PHY) 17716f8d3f33SWingman Kwok netif_carrier_on(ndev); 17726f8d3f33SWingman Kwok } else { 17736f8d3f33SWingman Kwok writel(mac_control, GBE_REG_ADDR(slave, emac_regs, 17746f8d3f33SWingman Kwok mac_control)); 17756f8d3f33SWingman Kwok cpsw_ale_control_set(gbe_dev->ale, slave->port_num, 17766f8d3f33SWingman Kwok ALE_PORT_STATE, 17776f8d3f33SWingman Kwok ALE_PORT_STATE_DISABLE); 17788e046d68SKaricheri, Muralidharan if (ndev && 17798e046d68SKaricheri, Muralidharan slave->link_interface != SGMII_LINK_MAC_PHY && 17808e046d68SKaricheri, Muralidharan slave->link_interface != XGMII_LINK_MAC_PHY) 17816f8d3f33SWingman Kwok netif_carrier_off(ndev); 17826f8d3f33SWingman Kwok } 17836f8d3f33SWingman Kwok 17846f8d3f33SWingman Kwok if (phy) 17856f8d3f33SWingman Kwok phy_print_status(phy); 17866f8d3f33SWingman Kwok } 17876f8d3f33SWingman Kwok 17886f8d3f33SWingman Kwok static bool gbe_phy_link_status(struct gbe_slave *slave) 17896f8d3f33SWingman Kwok { 17906f8d3f33SWingman Kwok return !slave->phy || slave->phy->link; 17916f8d3f33SWingman Kwok } 17926f8d3f33SWingman Kwok 17936f8d3f33SWingman Kwok static void netcp_ethss_update_link_state(struct gbe_priv *gbe_dev, 17946f8d3f33SWingman Kwok struct gbe_slave *slave, 17956f8d3f33SWingman Kwok struct net_device *ndev) 17966f8d3f33SWingman Kwok { 17976f8d3f33SWingman Kwok int sp = slave->slave_num; 17986f8d3f33SWingman Kwok int phy_link_state, sgmii_link_state = 1, link_state; 17996f8d3f33SWingman Kwok 18006f8d3f33SWingman Kwok if (!slave->open) 18016f8d3f33SWingman Kwok return; 18026f8d3f33SWingman Kwok 18039a391c7bSWingMan Kwok if (!SLAVE_LINK_IS_XGMII(slave)) { 18049a391c7bSWingMan Kwok if (gbe_dev->ss_version == GBE_SS_VERSION_14) 18059a391c7bSWingMan Kwok sgmii_link_state = 18069a391c7bSWingMan Kwok netcp_sgmii_get_port_link(SGMII_BASE(sp), sp); 18079a391c7bSWingMan Kwok else 18089a391c7bSWingMan Kwok sgmii_link_state = 18099a391c7bSWingMan Kwok netcp_sgmii_get_port_link( 18109a391c7bSWingMan Kwok gbe_dev->sgmii_port_regs, sp); 18119a391c7bSWingMan Kwok } 18129a391c7bSWingMan Kwok 18136f8d3f33SWingman Kwok phy_link_state = gbe_phy_link_status(slave); 18146f8d3f33SWingman Kwok link_state = phy_link_state & sgmii_link_state; 18156f8d3f33SWingman Kwok 18166f8d3f33SWingman Kwok if (atomic_xchg(&slave->link_state, link_state) != link_state) 18176f8d3f33SWingman Kwok netcp_ethss_link_state_action(gbe_dev, ndev, slave, 18186f8d3f33SWingman Kwok link_state); 18196f8d3f33SWingman Kwok } 18206f8d3f33SWingman Kwok 182190cff9e2SWingman Kwok static void xgbe_adjust_link(struct net_device *ndev) 182290cff9e2SWingman Kwok { 182390cff9e2SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 182490cff9e2SWingman Kwok struct gbe_intf *gbe_intf; 182590cff9e2SWingman Kwok 182690cff9e2SWingman Kwok gbe_intf = netcp_module_get_intf_data(&xgbe_module, netcp); 182790cff9e2SWingman Kwok if (!gbe_intf) 182890cff9e2SWingman Kwok return; 182990cff9e2SWingman Kwok 183090cff9e2SWingman Kwok netcp_ethss_update_link_state(gbe_intf->gbe_dev, gbe_intf->slave, 183190cff9e2SWingman Kwok ndev); 183290cff9e2SWingman Kwok } 183390cff9e2SWingman Kwok 18346f8d3f33SWingman Kwok static void gbe_adjust_link(struct net_device *ndev) 18356f8d3f33SWingman Kwok { 18366f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 18376f8d3f33SWingman Kwok struct gbe_intf *gbe_intf; 18386f8d3f33SWingman Kwok 18396f8d3f33SWingman Kwok gbe_intf = netcp_module_get_intf_data(&gbe_module, netcp); 18406f8d3f33SWingman Kwok if (!gbe_intf) 18416f8d3f33SWingman Kwok return; 18426f8d3f33SWingman Kwok 18436f8d3f33SWingman Kwok netcp_ethss_update_link_state(gbe_intf->gbe_dev, gbe_intf->slave, 18446f8d3f33SWingman Kwok ndev); 18456f8d3f33SWingman Kwok } 18466f8d3f33SWingman Kwok 18476f8d3f33SWingman Kwok static void gbe_adjust_link_sec_slaves(struct net_device *ndev) 18486f8d3f33SWingman Kwok { 18496f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = netdev_priv(ndev); 18506f8d3f33SWingman Kwok struct gbe_slave *slave; 18516f8d3f33SWingman Kwok 18526f8d3f33SWingman Kwok for_each_sec_slave(slave, gbe_dev) 18536f8d3f33SWingman Kwok netcp_ethss_update_link_state(gbe_dev, slave, NULL); 18546f8d3f33SWingman Kwok } 18556f8d3f33SWingman Kwok 18566f8d3f33SWingman Kwok /* Reset EMAC 18576f8d3f33SWingman Kwok * Soft reset is set and polled until clear, or until a timeout occurs 18586f8d3f33SWingman Kwok */ 18596f8d3f33SWingman Kwok static int gbe_port_reset(struct gbe_slave *slave) 18606f8d3f33SWingman Kwok { 18616f8d3f33SWingman Kwok u32 i, v; 18626f8d3f33SWingman Kwok 18636f8d3f33SWingman Kwok /* Set the soft reset bit */ 18646f8d3f33SWingman Kwok writel(SOFT_RESET, GBE_REG_ADDR(slave, emac_regs, soft_reset)); 18656f8d3f33SWingman Kwok 18666f8d3f33SWingman Kwok /* Wait for the bit to clear */ 18676f8d3f33SWingman Kwok for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) { 18686f8d3f33SWingman Kwok v = readl(GBE_REG_ADDR(slave, emac_regs, soft_reset)); 18696f8d3f33SWingman Kwok if ((v & SOFT_RESET_MASK) != SOFT_RESET) 18706f8d3f33SWingman Kwok return 0; 18716f8d3f33SWingman Kwok } 18726f8d3f33SWingman Kwok 18736f8d3f33SWingman Kwok /* Timeout on the reset */ 18746f8d3f33SWingman Kwok return GMACSL_RET_WARN_RESET_INCOMPLETE; 18756f8d3f33SWingman Kwok } 18766f8d3f33SWingman Kwok 18776f8d3f33SWingman Kwok /* Configure EMAC */ 18786f8d3f33SWingman Kwok static void gbe_port_config(struct gbe_priv *gbe_dev, struct gbe_slave *slave, 18796f8d3f33SWingman Kwok int max_rx_len) 18806f8d3f33SWingman Kwok { 18819a391c7bSWingMan Kwok void __iomem *rx_maxlen_reg; 188290cff9e2SWingman Kwok u32 xgmii_mode; 188390cff9e2SWingman Kwok 18846f8d3f33SWingman Kwok if (max_rx_len > NETCP_MAX_FRAME_SIZE) 18856f8d3f33SWingman Kwok max_rx_len = NETCP_MAX_FRAME_SIZE; 18866f8d3f33SWingman Kwok 188790cff9e2SWingman Kwok /* Enable correct MII mode at SS level */ 188890cff9e2SWingman Kwok if ((gbe_dev->ss_version == XGBE_SS_VERSION_10) && 188990cff9e2SWingman Kwok (slave->link_interface >= XGMII_LINK_MAC_PHY)) { 189090cff9e2SWingman Kwok xgmii_mode = readl(GBE_REG_ADDR(gbe_dev, ss_regs, control)); 189190cff9e2SWingman Kwok xgmii_mode |= (1 << slave->slave_num); 189290cff9e2SWingman Kwok writel(xgmii_mode, GBE_REG_ADDR(gbe_dev, ss_regs, control)); 189390cff9e2SWingman Kwok } 189490cff9e2SWingman Kwok 18959a391c7bSWingMan Kwok if (IS_SS_ID_MU(gbe_dev)) 18969a391c7bSWingMan Kwok rx_maxlen_reg = GBE_REG_ADDR(slave, port_regs, rx_maxlen); 18979a391c7bSWingMan Kwok else 18989a391c7bSWingMan Kwok rx_maxlen_reg = GBE_REG_ADDR(slave, emac_regs, rx_maxlen); 18999a391c7bSWingMan Kwok 19009a391c7bSWingMan Kwok writel(max_rx_len, rx_maxlen_reg); 19016f8d3f33SWingman Kwok writel(slave->mac_control, GBE_REG_ADDR(slave, emac_regs, mac_control)); 19026f8d3f33SWingman Kwok } 19036f8d3f33SWingman Kwok 19047025e88aSWingMan Kwok static void gbe_sgmii_rtreset(struct gbe_priv *priv, 19057025e88aSWingMan Kwok struct gbe_slave *slave, bool set) 19067025e88aSWingMan Kwok { 19077025e88aSWingMan Kwok void __iomem *sgmii_port_regs; 19087025e88aSWingMan Kwok 19097025e88aSWingMan Kwok if (SLAVE_LINK_IS_XGMII(slave)) 19107025e88aSWingMan Kwok return; 19117025e88aSWingMan Kwok 19127025e88aSWingMan Kwok if ((priv->ss_version == GBE_SS_VERSION_14) && (slave->slave_num >= 2)) 19137025e88aSWingMan Kwok sgmii_port_regs = priv->sgmii_port34_regs; 19147025e88aSWingMan Kwok else 19157025e88aSWingMan Kwok sgmii_port_regs = priv->sgmii_port_regs; 19167025e88aSWingMan Kwok 19177025e88aSWingMan Kwok netcp_sgmii_rtreset(sgmii_port_regs, slave->slave_num, set); 19187025e88aSWingMan Kwok } 19197025e88aSWingMan Kwok 19206f8d3f33SWingman Kwok static void gbe_slave_stop(struct gbe_intf *intf) 19216f8d3f33SWingman Kwok { 19226f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = intf->gbe_dev; 19236f8d3f33SWingman Kwok struct gbe_slave *slave = intf->slave; 19246f8d3f33SWingman Kwok 19257025e88aSWingMan Kwok gbe_sgmii_rtreset(gbe_dev, slave, true); 19266f8d3f33SWingman Kwok gbe_port_reset(slave); 19276f8d3f33SWingman Kwok /* Disable forwarding */ 19286f8d3f33SWingman Kwok cpsw_ale_control_set(gbe_dev->ale, slave->port_num, 19296f8d3f33SWingman Kwok ALE_PORT_STATE, ALE_PORT_STATE_DISABLE); 19306f8d3f33SWingman Kwok cpsw_ale_del_mcast(gbe_dev->ale, intf->ndev->broadcast, 19316f8d3f33SWingman Kwok 1 << slave->port_num, 0, 0); 19326f8d3f33SWingman Kwok 19336f8d3f33SWingman Kwok if (!slave->phy) 19346f8d3f33SWingman Kwok return; 19356f8d3f33SWingman Kwok 19366f8d3f33SWingman Kwok phy_stop(slave->phy); 19376f8d3f33SWingman Kwok phy_disconnect(slave->phy); 19386f8d3f33SWingman Kwok slave->phy = NULL; 19396f8d3f33SWingman Kwok } 19406f8d3f33SWingman Kwok 19416f8d3f33SWingman Kwok static void gbe_sgmii_config(struct gbe_priv *priv, struct gbe_slave *slave) 19426f8d3f33SWingman Kwok { 19436f8d3f33SWingman Kwok void __iomem *sgmii_port_regs; 19446f8d3f33SWingman Kwok 19456f8d3f33SWingman Kwok sgmii_port_regs = priv->sgmii_port_regs; 19466f8d3f33SWingman Kwok if ((priv->ss_version == GBE_SS_VERSION_14) && (slave->slave_num >= 2)) 19476f8d3f33SWingman Kwok sgmii_port_regs = priv->sgmii_port34_regs; 19486f8d3f33SWingman Kwok 194990cff9e2SWingman Kwok if (!SLAVE_LINK_IS_XGMII(slave)) { 19506f8d3f33SWingman Kwok netcp_sgmii_reset(sgmii_port_regs, slave->slave_num); 19516f8d3f33SWingman Kwok netcp_sgmii_config(sgmii_port_regs, slave->slave_num, 19526f8d3f33SWingman Kwok slave->link_interface); 19536f8d3f33SWingman Kwok } 195490cff9e2SWingman Kwok } 19556f8d3f33SWingman Kwok 19566f8d3f33SWingman Kwok static int gbe_slave_open(struct gbe_intf *gbe_intf) 19576f8d3f33SWingman Kwok { 19586f8d3f33SWingman Kwok struct gbe_priv *priv = gbe_intf->gbe_dev; 19596f8d3f33SWingman Kwok struct gbe_slave *slave = gbe_intf->slave; 19606f8d3f33SWingman Kwok phy_interface_t phy_mode; 19616f8d3f33SWingman Kwok bool has_phy = false; 19626f8d3f33SWingman Kwok 19636f8d3f33SWingman Kwok void (*hndlr)(struct net_device *) = gbe_adjust_link; 19646f8d3f33SWingman Kwok 19656f8d3f33SWingman Kwok gbe_sgmii_config(priv, slave); 19666f8d3f33SWingman Kwok gbe_port_reset(slave); 19677025e88aSWingMan Kwok gbe_sgmii_rtreset(priv, slave, false); 19686f8d3f33SWingman Kwok gbe_port_config(priv, slave, priv->rx_packet_max); 19696f8d3f33SWingman Kwok gbe_set_slave_mac(slave, gbe_intf); 19706f8d3f33SWingman Kwok /* enable forwarding */ 19716f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, slave->port_num, 19726f8d3f33SWingman Kwok ALE_PORT_STATE, ALE_PORT_STATE_FORWARD); 19736f8d3f33SWingman Kwok cpsw_ale_add_mcast(priv->ale, gbe_intf->ndev->broadcast, 19746f8d3f33SWingman Kwok 1 << slave->port_num, 0, 0, ALE_MCAST_FWD_2); 19756f8d3f33SWingman Kwok 19766f8d3f33SWingman Kwok if (slave->link_interface == SGMII_LINK_MAC_PHY) { 19776f8d3f33SWingman Kwok has_phy = true; 19786f8d3f33SWingman Kwok phy_mode = PHY_INTERFACE_MODE_SGMII; 19796f8d3f33SWingman Kwok slave->phy_port_t = PORT_MII; 19806f8d3f33SWingman Kwok } else if (slave->link_interface == XGMII_LINK_MAC_PHY) { 19816f8d3f33SWingman Kwok has_phy = true; 19826f8d3f33SWingman Kwok phy_mode = PHY_INTERFACE_MODE_NA; 19836f8d3f33SWingman Kwok slave->phy_port_t = PORT_FIBRE; 19846f8d3f33SWingman Kwok } 19856f8d3f33SWingman Kwok 19866f8d3f33SWingman Kwok if (has_phy) { 198790cff9e2SWingman Kwok if (priv->ss_version == XGBE_SS_VERSION_10) 198890cff9e2SWingman Kwok hndlr = xgbe_adjust_link; 198990cff9e2SWingman Kwok 19906f8d3f33SWingman Kwok slave->phy = of_phy_connect(gbe_intf->ndev, 19916f8d3f33SWingman Kwok slave->phy_node, 19926f8d3f33SWingman Kwok hndlr, 0, 19936f8d3f33SWingman Kwok phy_mode); 19946f8d3f33SWingman Kwok if (!slave->phy) { 19956f8d3f33SWingman Kwok dev_err(priv->dev, "phy not found on slave %d\n", 19966f8d3f33SWingman Kwok slave->slave_num); 19976f8d3f33SWingman Kwok return -ENODEV; 19986f8d3f33SWingman Kwok } 19996f8d3f33SWingman Kwok dev_dbg(priv->dev, "phy found: id is: 0x%s\n", 20006f8d3f33SWingman Kwok dev_name(&slave->phy->dev)); 20016f8d3f33SWingman Kwok phy_start(slave->phy); 20026f8d3f33SWingman Kwok phy_read_status(slave->phy); 20036f8d3f33SWingman Kwok } 20046f8d3f33SWingman Kwok return 0; 20056f8d3f33SWingman Kwok } 20066f8d3f33SWingman Kwok 20076f8d3f33SWingman Kwok static void gbe_init_host_port(struct gbe_priv *priv) 20086f8d3f33SWingman Kwok { 20096f8d3f33SWingman Kwok int bypass_en = 1; 20109a391c7bSWingMan Kwok 20119a391c7bSWingMan Kwok /* Host Tx Pri */ 20129a391c7bSWingMan Kwok if (IS_SS_ID_NU(priv)) 20139a391c7bSWingMan Kwok writel(HOST_TX_PRI_MAP_DEFAULT, 20149a391c7bSWingMan Kwok GBE_REG_ADDR(priv, host_port_regs, tx_pri_map)); 20159a391c7bSWingMan Kwok 20166f8d3f33SWingman Kwok /* Max length register */ 20176f8d3f33SWingman Kwok writel(NETCP_MAX_FRAME_SIZE, GBE_REG_ADDR(priv, host_port_regs, 20186f8d3f33SWingman Kwok rx_maxlen)); 20196f8d3f33SWingman Kwok 20206f8d3f33SWingman Kwok cpsw_ale_start(priv->ale); 20216f8d3f33SWingman Kwok 20226f8d3f33SWingman Kwok if (priv->enable_ale) 20236f8d3f33SWingman Kwok bypass_en = 0; 20246f8d3f33SWingman Kwok 20256f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, 0, ALE_BYPASS, bypass_en); 20266f8d3f33SWingman Kwok 20276f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, 0, ALE_NO_PORT_VLAN, 1); 20286f8d3f33SWingman Kwok 20296f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, priv->host_port, 20306f8d3f33SWingman Kwok ALE_PORT_STATE, ALE_PORT_STATE_FORWARD); 20316f8d3f33SWingman Kwok 20326f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, 0, 20336f8d3f33SWingman Kwok ALE_PORT_UNKNOWN_VLAN_MEMBER, 20346f8d3f33SWingman Kwok GBE_PORT_MASK(priv->ale_ports)); 20356f8d3f33SWingman Kwok 20366f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, 0, 20376f8d3f33SWingman Kwok ALE_PORT_UNKNOWN_MCAST_FLOOD, 20386f8d3f33SWingman Kwok GBE_PORT_MASK(priv->ale_ports - 1)); 20396f8d3f33SWingman Kwok 20406f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, 0, 20416f8d3f33SWingman Kwok ALE_PORT_UNKNOWN_REG_MCAST_FLOOD, 20426f8d3f33SWingman Kwok GBE_PORT_MASK(priv->ale_ports)); 20436f8d3f33SWingman Kwok 20446f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, 0, 20456f8d3f33SWingman Kwok ALE_PORT_UNTAGGED_EGRESS, 20466f8d3f33SWingman Kwok GBE_PORT_MASK(priv->ale_ports)); 20476f8d3f33SWingman Kwok } 20486f8d3f33SWingman Kwok 20496f8d3f33SWingman Kwok static void gbe_add_mcast_addr(struct gbe_intf *gbe_intf, u8 *addr) 20506f8d3f33SWingman Kwok { 20516f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 20526f8d3f33SWingman Kwok u16 vlan_id; 20536f8d3f33SWingman Kwok 20546f8d3f33SWingman Kwok cpsw_ale_add_mcast(gbe_dev->ale, addr, 20556f8d3f33SWingman Kwok GBE_PORT_MASK(gbe_dev->ale_ports), 0, 0, 20566f8d3f33SWingman Kwok ALE_MCAST_FWD_2); 20576f8d3f33SWingman Kwok for_each_set_bit(vlan_id, gbe_intf->active_vlans, VLAN_N_VID) { 20586f8d3f33SWingman Kwok cpsw_ale_add_mcast(gbe_dev->ale, addr, 20596f8d3f33SWingman Kwok GBE_PORT_MASK(gbe_dev->ale_ports), 20606f8d3f33SWingman Kwok ALE_VLAN, vlan_id, ALE_MCAST_FWD_2); 20616f8d3f33SWingman Kwok } 20626f8d3f33SWingman Kwok } 20636f8d3f33SWingman Kwok 20646f8d3f33SWingman Kwok static void gbe_add_ucast_addr(struct gbe_intf *gbe_intf, u8 *addr) 20656f8d3f33SWingman Kwok { 20666f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 20676f8d3f33SWingman Kwok u16 vlan_id; 20686f8d3f33SWingman Kwok 20696f8d3f33SWingman Kwok cpsw_ale_add_ucast(gbe_dev->ale, addr, gbe_dev->host_port, 0, 0); 20706f8d3f33SWingman Kwok 20716f8d3f33SWingman Kwok for_each_set_bit(vlan_id, gbe_intf->active_vlans, VLAN_N_VID) 20726f8d3f33SWingman Kwok cpsw_ale_add_ucast(gbe_dev->ale, addr, gbe_dev->host_port, 20736f8d3f33SWingman Kwok ALE_VLAN, vlan_id); 20746f8d3f33SWingman Kwok } 20756f8d3f33SWingman Kwok 20766f8d3f33SWingman Kwok static void gbe_del_mcast_addr(struct gbe_intf *gbe_intf, u8 *addr) 20776f8d3f33SWingman Kwok { 20786f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 20796f8d3f33SWingman Kwok u16 vlan_id; 20806f8d3f33SWingman Kwok 20816f8d3f33SWingman Kwok cpsw_ale_del_mcast(gbe_dev->ale, addr, 0, 0, 0); 20826f8d3f33SWingman Kwok 20836f8d3f33SWingman Kwok for_each_set_bit(vlan_id, gbe_intf->active_vlans, VLAN_N_VID) { 20846f8d3f33SWingman Kwok cpsw_ale_del_mcast(gbe_dev->ale, addr, 0, ALE_VLAN, vlan_id); 20856f8d3f33SWingman Kwok } 20866f8d3f33SWingman Kwok } 20876f8d3f33SWingman Kwok 20886f8d3f33SWingman Kwok static void gbe_del_ucast_addr(struct gbe_intf *gbe_intf, u8 *addr) 20896f8d3f33SWingman Kwok { 20906f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 20916f8d3f33SWingman Kwok u16 vlan_id; 20926f8d3f33SWingman Kwok 20936f8d3f33SWingman Kwok cpsw_ale_del_ucast(gbe_dev->ale, addr, gbe_dev->host_port, 0, 0); 20946f8d3f33SWingman Kwok 20956f8d3f33SWingman Kwok for_each_set_bit(vlan_id, gbe_intf->active_vlans, VLAN_N_VID) { 20966f8d3f33SWingman Kwok cpsw_ale_del_ucast(gbe_dev->ale, addr, gbe_dev->host_port, 20976f8d3f33SWingman Kwok ALE_VLAN, vlan_id); 20986f8d3f33SWingman Kwok } 20996f8d3f33SWingman Kwok } 21006f8d3f33SWingman Kwok 21016f8d3f33SWingman Kwok static int gbe_add_addr(void *intf_priv, struct netcp_addr *naddr) 21026f8d3f33SWingman Kwok { 21036f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv; 21046f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 21056f8d3f33SWingman Kwok 21066f8d3f33SWingman Kwok dev_dbg(gbe_dev->dev, "ethss adding address %pM, type %d\n", 21076f8d3f33SWingman Kwok naddr->addr, naddr->type); 21086f8d3f33SWingman Kwok 21096f8d3f33SWingman Kwok switch (naddr->type) { 21106f8d3f33SWingman Kwok case ADDR_MCAST: 21116f8d3f33SWingman Kwok case ADDR_BCAST: 21126f8d3f33SWingman Kwok gbe_add_mcast_addr(gbe_intf, naddr->addr); 21136f8d3f33SWingman Kwok break; 21146f8d3f33SWingman Kwok case ADDR_UCAST: 21156f8d3f33SWingman Kwok case ADDR_DEV: 21166f8d3f33SWingman Kwok gbe_add_ucast_addr(gbe_intf, naddr->addr); 21176f8d3f33SWingman Kwok break; 21186f8d3f33SWingman Kwok case ADDR_ANY: 21196f8d3f33SWingman Kwok /* nothing to do for promiscuous */ 21206f8d3f33SWingman Kwok default: 21216f8d3f33SWingman Kwok break; 21226f8d3f33SWingman Kwok } 21236f8d3f33SWingman Kwok 21246f8d3f33SWingman Kwok return 0; 21256f8d3f33SWingman Kwok } 21266f8d3f33SWingman Kwok 21276f8d3f33SWingman Kwok static int gbe_del_addr(void *intf_priv, struct netcp_addr *naddr) 21286f8d3f33SWingman Kwok { 21296f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv; 21306f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 21316f8d3f33SWingman Kwok 21326f8d3f33SWingman Kwok dev_dbg(gbe_dev->dev, "ethss deleting address %pM, type %d\n", 21336f8d3f33SWingman Kwok naddr->addr, naddr->type); 21346f8d3f33SWingman Kwok 21356f8d3f33SWingman Kwok switch (naddr->type) { 21366f8d3f33SWingman Kwok case ADDR_MCAST: 21376f8d3f33SWingman Kwok case ADDR_BCAST: 21386f8d3f33SWingman Kwok gbe_del_mcast_addr(gbe_intf, naddr->addr); 21396f8d3f33SWingman Kwok break; 21406f8d3f33SWingman Kwok case ADDR_UCAST: 21416f8d3f33SWingman Kwok case ADDR_DEV: 21426f8d3f33SWingman Kwok gbe_del_ucast_addr(gbe_intf, naddr->addr); 21436f8d3f33SWingman Kwok break; 21446f8d3f33SWingman Kwok case ADDR_ANY: 21456f8d3f33SWingman Kwok /* nothing to do for promiscuous */ 21466f8d3f33SWingman Kwok default: 21476f8d3f33SWingman Kwok break; 21486f8d3f33SWingman Kwok } 21496f8d3f33SWingman Kwok 21506f8d3f33SWingman Kwok return 0; 21516f8d3f33SWingman Kwok } 21526f8d3f33SWingman Kwok 21536f8d3f33SWingman Kwok static int gbe_add_vid(void *intf_priv, int vid) 21546f8d3f33SWingman Kwok { 21556f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv; 21566f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 21576f8d3f33SWingman Kwok 21586f8d3f33SWingman Kwok set_bit(vid, gbe_intf->active_vlans); 21596f8d3f33SWingman Kwok 21606f8d3f33SWingman Kwok cpsw_ale_add_vlan(gbe_dev->ale, vid, 21616f8d3f33SWingman Kwok GBE_PORT_MASK(gbe_dev->ale_ports), 21626f8d3f33SWingman Kwok GBE_MASK_NO_PORTS, 21636f8d3f33SWingman Kwok GBE_PORT_MASK(gbe_dev->ale_ports), 21646f8d3f33SWingman Kwok GBE_PORT_MASK(gbe_dev->ale_ports - 1)); 21656f8d3f33SWingman Kwok 21666f8d3f33SWingman Kwok return 0; 21676f8d3f33SWingman Kwok } 21686f8d3f33SWingman Kwok 21696f8d3f33SWingman Kwok static int gbe_del_vid(void *intf_priv, int vid) 21706f8d3f33SWingman Kwok { 21716f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv; 21726f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 21736f8d3f33SWingman Kwok 21746f8d3f33SWingman Kwok cpsw_ale_del_vlan(gbe_dev->ale, vid, 0); 21756f8d3f33SWingman Kwok clear_bit(vid, gbe_intf->active_vlans); 21766f8d3f33SWingman Kwok return 0; 21776f8d3f33SWingman Kwok } 21786f8d3f33SWingman Kwok 21796f8d3f33SWingman Kwok static int gbe_ioctl(void *intf_priv, struct ifreq *req, int cmd) 21806f8d3f33SWingman Kwok { 21816f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv; 21826f8d3f33SWingman Kwok struct phy_device *phy = gbe_intf->slave->phy; 21836f8d3f33SWingman Kwok int ret = -EOPNOTSUPP; 21846f8d3f33SWingman Kwok 21856f8d3f33SWingman Kwok if (phy) 21866f8d3f33SWingman Kwok ret = phy_mii_ioctl(phy, req, cmd); 21876f8d3f33SWingman Kwok 21886f8d3f33SWingman Kwok return ret; 21896f8d3f33SWingman Kwok } 21906f8d3f33SWingman Kwok 21916f8d3f33SWingman Kwok static void netcp_ethss_timer(unsigned long arg) 21926f8d3f33SWingman Kwok { 21936f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = (struct gbe_priv *)arg; 21946f8d3f33SWingman Kwok struct gbe_intf *gbe_intf; 21956f8d3f33SWingman Kwok struct gbe_slave *slave; 21966f8d3f33SWingman Kwok 21976f8d3f33SWingman Kwok /* Check & update SGMII link state of interfaces */ 21986f8d3f33SWingman Kwok for_each_intf(gbe_intf, gbe_dev) { 21996f8d3f33SWingman Kwok if (!gbe_intf->slave->open) 22006f8d3f33SWingman Kwok continue; 22016f8d3f33SWingman Kwok netcp_ethss_update_link_state(gbe_dev, gbe_intf->slave, 22026f8d3f33SWingman Kwok gbe_intf->ndev); 22036f8d3f33SWingman Kwok } 22046f8d3f33SWingman Kwok 22056f8d3f33SWingman Kwok /* Check & update SGMII link state of secondary ports */ 22066f8d3f33SWingman Kwok for_each_sec_slave(slave, gbe_dev) { 22076f8d3f33SWingman Kwok netcp_ethss_update_link_state(gbe_dev, slave, NULL); 22086f8d3f33SWingman Kwok } 22096f8d3f33SWingman Kwok 22106f8d3f33SWingman Kwok spin_lock_bh(&gbe_dev->hw_stats_lock); 22116f8d3f33SWingman Kwok 22126f8d3f33SWingman Kwok if (gbe_dev->ss_version == GBE_SS_VERSION_14) 22136f8d3f33SWingman Kwok gbe_update_stats_ver14(gbe_dev, NULL); 22146f8d3f33SWingman Kwok else 22156f8d3f33SWingman Kwok gbe_update_stats(gbe_dev, NULL); 22166f8d3f33SWingman Kwok 22176f8d3f33SWingman Kwok spin_unlock_bh(&gbe_dev->hw_stats_lock); 22186f8d3f33SWingman Kwok 22196f8d3f33SWingman Kwok gbe_dev->timer.expires = jiffies + GBE_TIMER_INTERVAL; 22206f8d3f33SWingman Kwok add_timer(&gbe_dev->timer); 22216f8d3f33SWingman Kwok } 22226f8d3f33SWingman Kwok 22236f8d3f33SWingman Kwok static int gbe_tx_hook(int order, void *data, struct netcp_packet *p_info) 22246f8d3f33SWingman Kwok { 22256f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = data; 22266f8d3f33SWingman Kwok 22276f8d3f33SWingman Kwok p_info->tx_pipe = &gbe_intf->tx_pipe; 22286f8d3f33SWingman Kwok return 0; 22296f8d3f33SWingman Kwok } 22306f8d3f33SWingman Kwok 22316f8d3f33SWingman Kwok static int gbe_open(void *intf_priv, struct net_device *ndev) 22326f8d3f33SWingman Kwok { 22336f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv; 22346f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev; 22356f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 22366f8d3f33SWingman Kwok struct gbe_slave *slave = gbe_intf->slave; 22376f8d3f33SWingman Kwok int port_num = slave->port_num; 22386f8d3f33SWingman Kwok u32 reg; 22396f8d3f33SWingman Kwok int ret; 22406f8d3f33SWingman Kwok 22416f8d3f33SWingman Kwok reg = readl(GBE_REG_ADDR(gbe_dev, switch_regs, id_ver)); 22426f8d3f33SWingman Kwok dev_dbg(gbe_dev->dev, "initializing gbe version %d.%d (%d) GBE identification value 0x%x\n", 22436f8d3f33SWingman Kwok GBE_MAJOR_VERSION(reg), GBE_MINOR_VERSION(reg), 22446f8d3f33SWingman Kwok GBE_RTL_VERSION(reg), GBE_IDENT(reg)); 22456f8d3f33SWingman Kwok 22469a391c7bSWingMan Kwok /* For 10G and on NetCP 1.5, use directed to port */ 22479a391c7bSWingMan Kwok if ((gbe_dev->ss_version == XGBE_SS_VERSION_10) || IS_SS_ID_MU(gbe_dev)) 2248e170f409SKaricheri, Muralidharan gbe_intf->tx_pipe.flags = SWITCH_TO_PORT_IN_TAGINFO; 22496f8d3f33SWingman Kwok 2250e170f409SKaricheri, Muralidharan if (gbe_dev->enable_ale) 2251e170f409SKaricheri, Muralidharan gbe_intf->tx_pipe.switch_to_port = 0; 2252e170f409SKaricheri, Muralidharan else 2253e170f409SKaricheri, Muralidharan gbe_intf->tx_pipe.switch_to_port = port_num; 2254e170f409SKaricheri, Muralidharan 2255e170f409SKaricheri, Muralidharan dev_dbg(gbe_dev->dev, 2256e170f409SKaricheri, Muralidharan "opened TX channel %s: %p with to port %d, flags %d\n", 22576f8d3f33SWingman Kwok gbe_intf->tx_pipe.dma_chan_name, 22586f8d3f33SWingman Kwok gbe_intf->tx_pipe.dma_channel, 2259e170f409SKaricheri, Muralidharan gbe_intf->tx_pipe.switch_to_port, 2260e170f409SKaricheri, Muralidharan gbe_intf->tx_pipe.flags); 22616f8d3f33SWingman Kwok 22626f8d3f33SWingman Kwok gbe_slave_stop(gbe_intf); 22636f8d3f33SWingman Kwok 22646f8d3f33SWingman Kwok /* disable priority elevation and enable statistics on all ports */ 22656f8d3f33SWingman Kwok writel(0, GBE_REG_ADDR(gbe_dev, switch_regs, ptype)); 22666f8d3f33SWingman Kwok 22676f8d3f33SWingman Kwok /* Control register */ 22686f8d3f33SWingman Kwok writel(GBE_CTL_P0_ENABLE, GBE_REG_ADDR(gbe_dev, switch_regs, control)); 22696f8d3f33SWingman Kwok 22706f8d3f33SWingman Kwok /* All statistics enabled and STAT AB visible by default */ 22719a391c7bSWingMan Kwok writel(gbe_dev->stats_en_mask, GBE_REG_ADDR(gbe_dev, switch_regs, 22726f8d3f33SWingman Kwok stat_port_en)); 22736f8d3f33SWingman Kwok 22746f8d3f33SWingman Kwok ret = gbe_slave_open(gbe_intf); 22756f8d3f33SWingman Kwok if (ret) 22766f8d3f33SWingman Kwok goto fail; 22776f8d3f33SWingman Kwok 22786f8d3f33SWingman Kwok netcp_register_txhook(netcp, GBE_TXHOOK_ORDER, gbe_tx_hook, 22796f8d3f33SWingman Kwok gbe_intf); 22806f8d3f33SWingman Kwok 22816f8d3f33SWingman Kwok slave->open = true; 22826f8d3f33SWingman Kwok netcp_ethss_update_link_state(gbe_dev, slave, ndev); 22836f8d3f33SWingman Kwok return 0; 22846f8d3f33SWingman Kwok 22856f8d3f33SWingman Kwok fail: 22866f8d3f33SWingman Kwok gbe_slave_stop(gbe_intf); 22876f8d3f33SWingman Kwok return ret; 22886f8d3f33SWingman Kwok } 22896f8d3f33SWingman Kwok 22906f8d3f33SWingman Kwok static int gbe_close(void *intf_priv, struct net_device *ndev) 22916f8d3f33SWingman Kwok { 22926f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv; 22936f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev); 22946f8d3f33SWingman Kwok 22956f8d3f33SWingman Kwok gbe_slave_stop(gbe_intf); 22966f8d3f33SWingman Kwok netcp_unregister_txhook(netcp, GBE_TXHOOK_ORDER, gbe_tx_hook, 22976f8d3f33SWingman Kwok gbe_intf); 22986f8d3f33SWingman Kwok 22996f8d3f33SWingman Kwok gbe_intf->slave->open = false; 23006f8d3f33SWingman Kwok atomic_set(&gbe_intf->slave->link_state, NETCP_LINK_STATE_INVALID); 23016f8d3f33SWingman Kwok return 0; 23026f8d3f33SWingman Kwok } 23036f8d3f33SWingman Kwok 23046f8d3f33SWingman Kwok static int init_slave(struct gbe_priv *gbe_dev, struct gbe_slave *slave, 23056f8d3f33SWingman Kwok struct device_node *node) 23066f8d3f33SWingman Kwok { 23076f8d3f33SWingman Kwok int port_reg_num; 23086f8d3f33SWingman Kwok u32 port_reg_ofs, emac_reg_ofs; 23099a391c7bSWingMan Kwok u32 port_reg_blk_sz, emac_reg_blk_sz; 23106f8d3f33SWingman Kwok 23116f8d3f33SWingman Kwok if (of_property_read_u32(node, "slave-port", &slave->slave_num)) { 23126f8d3f33SWingman Kwok dev_err(gbe_dev->dev, "missing slave-port parameter\n"); 23136f8d3f33SWingman Kwok return -EINVAL; 23146f8d3f33SWingman Kwok } 23156f8d3f33SWingman Kwok 23166f8d3f33SWingman Kwok if (of_property_read_u32(node, "link-interface", 23176f8d3f33SWingman Kwok &slave->link_interface)) { 23186f8d3f33SWingman Kwok dev_warn(gbe_dev->dev, 23196f8d3f33SWingman Kwok "missing link-interface value defaulting to 1G mac-phy link\n"); 23206f8d3f33SWingman Kwok slave->link_interface = SGMII_LINK_MAC_PHY; 23216f8d3f33SWingman Kwok } 23226f8d3f33SWingman Kwok 23236f8d3f33SWingman Kwok slave->open = false; 23246f8d3f33SWingman Kwok slave->phy_node = of_parse_phandle(node, "phy-handle", 0); 23256f8d3f33SWingman Kwok slave->port_num = gbe_get_slave_port(gbe_dev, slave->slave_num); 23266f8d3f33SWingman Kwok 232790cff9e2SWingman Kwok if (slave->link_interface >= XGMII_LINK_MAC_PHY) 232890cff9e2SWingman Kwok slave->mac_control = GBE_DEF_10G_MAC_CONTROL; 232990cff9e2SWingman Kwok else 23306f8d3f33SWingman Kwok slave->mac_control = GBE_DEF_1G_MAC_CONTROL; 23316f8d3f33SWingman Kwok 23326f8d3f33SWingman Kwok /* Emac regs memmap are contiguous but port regs are not */ 23336f8d3f33SWingman Kwok port_reg_num = slave->slave_num; 23346f8d3f33SWingman Kwok if (gbe_dev->ss_version == GBE_SS_VERSION_14) { 23356f8d3f33SWingman Kwok if (slave->slave_num > 1) { 23366f8d3f33SWingman Kwok port_reg_ofs = GBE13_SLAVE_PORT2_OFFSET; 23376f8d3f33SWingman Kwok port_reg_num -= 2; 23386f8d3f33SWingman Kwok } else { 23396f8d3f33SWingman Kwok port_reg_ofs = GBE13_SLAVE_PORT_OFFSET; 23406f8d3f33SWingman Kwok } 23419a391c7bSWingMan Kwok emac_reg_ofs = GBE13_EMAC_OFFSET; 23429a391c7bSWingMan Kwok port_reg_blk_sz = 0x30; 23439a391c7bSWingMan Kwok emac_reg_blk_sz = 0x40; 23449a391c7bSWingMan Kwok } else if (IS_SS_ID_MU(gbe_dev)) { 23459a391c7bSWingMan Kwok port_reg_ofs = GBENU_SLAVE_PORT_OFFSET; 23469a391c7bSWingMan Kwok emac_reg_ofs = GBENU_EMAC_OFFSET; 23479a391c7bSWingMan Kwok port_reg_blk_sz = 0x1000; 23489a391c7bSWingMan Kwok emac_reg_blk_sz = 0x1000; 234990cff9e2SWingman Kwok } else if (gbe_dev->ss_version == XGBE_SS_VERSION_10) { 235090cff9e2SWingman Kwok port_reg_ofs = XGBE10_SLAVE_PORT_OFFSET; 23519a391c7bSWingMan Kwok emac_reg_ofs = XGBE10_EMAC_OFFSET; 23529a391c7bSWingMan Kwok port_reg_blk_sz = 0x30; 23539a391c7bSWingMan Kwok emac_reg_blk_sz = 0x40; 23546f8d3f33SWingman Kwok } else { 23556f8d3f33SWingman Kwok dev_err(gbe_dev->dev, "unknown ethss(0x%x)\n", 23566f8d3f33SWingman Kwok gbe_dev->ss_version); 23576f8d3f33SWingman Kwok return -EINVAL; 23586f8d3f33SWingman Kwok } 23596f8d3f33SWingman Kwok 236021e0e0ddSKaricheri, Muralidharan slave->port_regs = gbe_dev->switch_regs + port_reg_ofs + 23619a391c7bSWingMan Kwok (port_reg_blk_sz * port_reg_num); 236221e0e0ddSKaricheri, Muralidharan slave->emac_regs = gbe_dev->switch_regs + emac_reg_ofs + 23639a391c7bSWingMan Kwok (emac_reg_blk_sz * slave->slave_num); 23646f8d3f33SWingman Kwok 23656f8d3f33SWingman Kwok if (gbe_dev->ss_version == GBE_SS_VERSION_14) { 23666f8d3f33SWingman Kwok /* Initialize slave port register offsets */ 23676f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, port_vlan); 23686f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, tx_pri_map); 23696f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, sa_lo); 23706f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, sa_hi); 23716f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, ts_ctl); 23726f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, ts_seq_ltype); 23736f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, ts_vlan); 23746f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, ts_ctl_ltype2); 23756f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, ts_ctl2); 23766f8d3f33SWingman Kwok 23776f8d3f33SWingman Kwok /* Initialize EMAC register offsets */ 23786f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, emac_regs, mac_control); 23796f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, emac_regs, soft_reset); 23806f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, emac_regs, rx_maxlen); 23816f8d3f33SWingman Kwok 23829a391c7bSWingMan Kwok } else if (IS_SS_ID_MU(gbe_dev)) { 23839a391c7bSWingMan Kwok /* Initialize slave port register offsets */ 23849a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, port_vlan); 23859a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, tx_pri_map); 23869a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, sa_lo); 23879a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, sa_hi); 23889a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, ts_ctl); 23899a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, ts_seq_ltype); 23909a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, ts_vlan); 23919a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, ts_ctl_ltype2); 23929a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, ts_ctl2); 23939a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, rx_maxlen); 23949a391c7bSWingMan Kwok 23959a391c7bSWingMan Kwok /* Initialize EMAC register offsets */ 23969a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, emac_regs, mac_control); 23979a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, emac_regs, soft_reset); 23989a391c7bSWingMan Kwok 239990cff9e2SWingman Kwok } else if (gbe_dev->ss_version == XGBE_SS_VERSION_10) { 240090cff9e2SWingman Kwok /* Initialize slave port register offsets */ 240190cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, port_vlan); 240290cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, tx_pri_map); 240390cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, sa_lo); 240490cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, sa_hi); 240590cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, ts_ctl); 240690cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, ts_seq_ltype); 240790cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, ts_vlan); 240890cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, ts_ctl_ltype2); 240990cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, ts_ctl2); 241090cff9e2SWingman Kwok 241190cff9e2SWingman Kwok /* Initialize EMAC register offsets */ 241290cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, emac_regs, mac_control); 241390cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, emac_regs, soft_reset); 241490cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, emac_regs, rx_maxlen); 24156f8d3f33SWingman Kwok } 24166f8d3f33SWingman Kwok 24176f8d3f33SWingman Kwok atomic_set(&slave->link_state, NETCP_LINK_STATE_INVALID); 24186f8d3f33SWingman Kwok return 0; 24196f8d3f33SWingman Kwok } 24206f8d3f33SWingman Kwok 24216f8d3f33SWingman Kwok static void init_secondary_ports(struct gbe_priv *gbe_dev, 24226f8d3f33SWingman Kwok struct device_node *node) 24236f8d3f33SWingman Kwok { 24246f8d3f33SWingman Kwok struct device *dev = gbe_dev->dev; 24256f8d3f33SWingman Kwok phy_interface_t phy_mode; 24266f8d3f33SWingman Kwok struct gbe_priv **priv; 24276f8d3f33SWingman Kwok struct device_node *port; 24286f8d3f33SWingman Kwok struct gbe_slave *slave; 24296f8d3f33SWingman Kwok bool mac_phy_link = false; 24306f8d3f33SWingman Kwok 24316f8d3f33SWingman Kwok for_each_child_of_node(node, port) { 24326f8d3f33SWingman Kwok slave = devm_kzalloc(dev, sizeof(*slave), GFP_KERNEL); 24336f8d3f33SWingman Kwok if (!slave) { 24346f8d3f33SWingman Kwok dev_err(dev, 24356f8d3f33SWingman Kwok "memomry alloc failed for secondary port(%s), skipping...\n", 24366f8d3f33SWingman Kwok port->name); 24376f8d3f33SWingman Kwok continue; 24386f8d3f33SWingman Kwok } 24396f8d3f33SWingman Kwok 24406f8d3f33SWingman Kwok if (init_slave(gbe_dev, slave, port)) { 24416f8d3f33SWingman Kwok dev_err(dev, 24426f8d3f33SWingman Kwok "Failed to initialize secondary port(%s), skipping...\n", 24436f8d3f33SWingman Kwok port->name); 24446f8d3f33SWingman Kwok devm_kfree(dev, slave); 24456f8d3f33SWingman Kwok continue; 24466f8d3f33SWingman Kwok } 24476f8d3f33SWingman Kwok 24486f8d3f33SWingman Kwok gbe_sgmii_config(gbe_dev, slave); 24496f8d3f33SWingman Kwok gbe_port_reset(slave); 24506f8d3f33SWingman Kwok gbe_port_config(gbe_dev, slave, gbe_dev->rx_packet_max); 24516f8d3f33SWingman Kwok list_add_tail(&slave->slave_list, &gbe_dev->secondary_slaves); 24526f8d3f33SWingman Kwok gbe_dev->num_slaves++; 245390cff9e2SWingman Kwok if ((slave->link_interface == SGMII_LINK_MAC_PHY) || 245490cff9e2SWingman Kwok (slave->link_interface == XGMII_LINK_MAC_PHY)) 24556f8d3f33SWingman Kwok mac_phy_link = true; 24566f8d3f33SWingman Kwok 24576f8d3f33SWingman Kwok slave->open = true; 24589a391c7bSWingMan Kwok if (gbe_dev->num_slaves >= gbe_dev->max_num_slaves) 24599a391c7bSWingMan Kwok break; 24606f8d3f33SWingman Kwok } 24616f8d3f33SWingman Kwok 24626f8d3f33SWingman Kwok /* of_phy_connect() is needed only for MAC-PHY interface */ 24636f8d3f33SWingman Kwok if (!mac_phy_link) 24646f8d3f33SWingman Kwok return; 24656f8d3f33SWingman Kwok 24666f8d3f33SWingman Kwok /* Allocate dummy netdev device for attaching to phy device */ 24676f8d3f33SWingman Kwok gbe_dev->dummy_ndev = alloc_netdev(sizeof(gbe_dev), "dummy", 24686f8d3f33SWingman Kwok NET_NAME_UNKNOWN, ether_setup); 24696f8d3f33SWingman Kwok if (!gbe_dev->dummy_ndev) { 24706f8d3f33SWingman Kwok dev_err(dev, 24716f8d3f33SWingman Kwok "Failed to allocate dummy netdev for secondary ports, skipping phy_connect()...\n"); 24726f8d3f33SWingman Kwok return; 24736f8d3f33SWingman Kwok } 24746f8d3f33SWingman Kwok priv = netdev_priv(gbe_dev->dummy_ndev); 24756f8d3f33SWingman Kwok *priv = gbe_dev; 24766f8d3f33SWingman Kwok 24776f8d3f33SWingman Kwok if (slave->link_interface == SGMII_LINK_MAC_PHY) { 24786f8d3f33SWingman Kwok phy_mode = PHY_INTERFACE_MODE_SGMII; 24796f8d3f33SWingman Kwok slave->phy_port_t = PORT_MII; 24806f8d3f33SWingman Kwok } else { 24816f8d3f33SWingman Kwok phy_mode = PHY_INTERFACE_MODE_NA; 24826f8d3f33SWingman Kwok slave->phy_port_t = PORT_FIBRE; 24836f8d3f33SWingman Kwok } 24846f8d3f33SWingman Kwok 24856f8d3f33SWingman Kwok for_each_sec_slave(slave, gbe_dev) { 248690cff9e2SWingman Kwok if ((slave->link_interface != SGMII_LINK_MAC_PHY) && 248790cff9e2SWingman Kwok (slave->link_interface != XGMII_LINK_MAC_PHY)) 24886f8d3f33SWingman Kwok continue; 24896f8d3f33SWingman Kwok slave->phy = 24906f8d3f33SWingman Kwok of_phy_connect(gbe_dev->dummy_ndev, 24916f8d3f33SWingman Kwok slave->phy_node, 24926f8d3f33SWingman Kwok gbe_adjust_link_sec_slaves, 24936f8d3f33SWingman Kwok 0, phy_mode); 24946f8d3f33SWingman Kwok if (!slave->phy) { 24956f8d3f33SWingman Kwok dev_err(dev, "phy not found for slave %d\n", 24966f8d3f33SWingman Kwok slave->slave_num); 24976f8d3f33SWingman Kwok slave->phy = NULL; 24986f8d3f33SWingman Kwok } else { 24996f8d3f33SWingman Kwok dev_dbg(dev, "phy found: id is: 0x%s\n", 25006f8d3f33SWingman Kwok dev_name(&slave->phy->dev)); 25016f8d3f33SWingman Kwok phy_start(slave->phy); 25026f8d3f33SWingman Kwok phy_read_status(slave->phy); 25036f8d3f33SWingman Kwok } 25046f8d3f33SWingman Kwok } 25056f8d3f33SWingman Kwok } 25066f8d3f33SWingman Kwok 25076f8d3f33SWingman Kwok static void free_secondary_ports(struct gbe_priv *gbe_dev) 25086f8d3f33SWingman Kwok { 25096f8d3f33SWingman Kwok struct gbe_slave *slave; 25106f8d3f33SWingman Kwok 2511c20afae7SKaricheri, Muralidharan while (!list_empty(&gbe_dev->secondary_slaves)) { 25126f8d3f33SWingman Kwok slave = first_sec_slave(gbe_dev); 2513c20afae7SKaricheri, Muralidharan 25146f8d3f33SWingman Kwok if (slave->phy) 25156f8d3f33SWingman Kwok phy_disconnect(slave->phy); 25166f8d3f33SWingman Kwok list_del(&slave->slave_list); 25176f8d3f33SWingman Kwok } 25186f8d3f33SWingman Kwok if (gbe_dev->dummy_ndev) 25196f8d3f33SWingman Kwok free_netdev(gbe_dev->dummy_ndev); 25206f8d3f33SWingman Kwok } 25216f8d3f33SWingman Kwok 252290cff9e2SWingman Kwok static int set_xgbe_ethss10_priv(struct gbe_priv *gbe_dev, 252390cff9e2SWingman Kwok struct device_node *node) 252490cff9e2SWingman Kwok { 252590cff9e2SWingman Kwok struct resource res; 252690cff9e2SWingman Kwok void __iomem *regs; 252790cff9e2SWingman Kwok int ret, i; 252890cff9e2SWingman Kwok 25299a391c7bSWingMan Kwok ret = of_address_to_resource(node, XGBE_SS_REG_INDEX, &res); 253090cff9e2SWingman Kwok if (ret) { 253121e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, 253221e0e0ddSKaricheri, Muralidharan "Can't xlate xgbe of node(%s) ss address at %d\n", 253321e0e0ddSKaricheri, Muralidharan node->name, XGBE_SS_REG_INDEX); 253490cff9e2SWingman Kwok return ret; 253590cff9e2SWingman Kwok } 253690cff9e2SWingman Kwok 253790cff9e2SWingman Kwok regs = devm_ioremap_resource(gbe_dev->dev, &res); 253890cff9e2SWingman Kwok if (IS_ERR(regs)) { 253921e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, "Failed to map xgbe ss register base\n"); 254090cff9e2SWingman Kwok return PTR_ERR(regs); 254190cff9e2SWingman Kwok } 254290cff9e2SWingman Kwok gbe_dev->ss_regs = regs; 254390cff9e2SWingman Kwok 254421e0e0ddSKaricheri, Muralidharan ret = of_address_to_resource(node, XGBE_SM_REG_INDEX, &res); 254521e0e0ddSKaricheri, Muralidharan if (ret) { 254621e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, 254721e0e0ddSKaricheri, Muralidharan "Can't xlate xgbe of node(%s) sm address at %d\n", 254821e0e0ddSKaricheri, Muralidharan node->name, XGBE_SM_REG_INDEX); 254921e0e0ddSKaricheri, Muralidharan return ret; 255021e0e0ddSKaricheri, Muralidharan } 255121e0e0ddSKaricheri, Muralidharan 255221e0e0ddSKaricheri, Muralidharan regs = devm_ioremap_resource(gbe_dev->dev, &res); 255321e0e0ddSKaricheri, Muralidharan if (IS_ERR(regs)) { 255421e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, "Failed to map xgbe sm register base\n"); 255521e0e0ddSKaricheri, Muralidharan return PTR_ERR(regs); 255621e0e0ddSKaricheri, Muralidharan } 255721e0e0ddSKaricheri, Muralidharan gbe_dev->switch_regs = regs; 255821e0e0ddSKaricheri, Muralidharan 255990cff9e2SWingman Kwok ret = of_address_to_resource(node, XGBE_SERDES_REG_INDEX, &res); 256090cff9e2SWingman Kwok if (ret) { 256121e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, 256221e0e0ddSKaricheri, Muralidharan "Can't xlate xgbe serdes of node(%s) address at %d\n", 256321e0e0ddSKaricheri, Muralidharan node->name, XGBE_SERDES_REG_INDEX); 256490cff9e2SWingman Kwok return ret; 256590cff9e2SWingman Kwok } 256690cff9e2SWingman Kwok 256790cff9e2SWingman Kwok regs = devm_ioremap_resource(gbe_dev->dev, &res); 256890cff9e2SWingman Kwok if (IS_ERR(regs)) { 256990cff9e2SWingman Kwok dev_err(gbe_dev->dev, "Failed to map xgbe serdes register base\n"); 257090cff9e2SWingman Kwok return PTR_ERR(regs); 257190cff9e2SWingman Kwok } 257290cff9e2SWingman Kwok gbe_dev->xgbe_serdes_regs = regs; 257390cff9e2SWingman Kwok 257490cff9e2SWingman Kwok gbe_dev->hw_stats = devm_kzalloc(gbe_dev->dev, 257590cff9e2SWingman Kwok XGBE10_NUM_STAT_ENTRIES * 25769a391c7bSWingMan Kwok (gbe_dev->max_num_ports) * sizeof(u64), 257790cff9e2SWingman Kwok GFP_KERNEL); 257890cff9e2SWingman Kwok if (!gbe_dev->hw_stats) { 257990cff9e2SWingman Kwok dev_err(gbe_dev->dev, "hw_stats memory allocation failed\n"); 258090cff9e2SWingman Kwok return -ENOMEM; 258190cff9e2SWingman Kwok } 258290cff9e2SWingman Kwok 258390cff9e2SWingman Kwok gbe_dev->ss_version = XGBE_SS_VERSION_10; 258490cff9e2SWingman Kwok gbe_dev->sgmii_port_regs = gbe_dev->ss_regs + 258590cff9e2SWingman Kwok XGBE10_SGMII_MODULE_OFFSET; 258690cff9e2SWingman Kwok gbe_dev->host_port_regs = gbe_dev->ss_regs + XGBE10_HOST_PORT_OFFSET; 258790cff9e2SWingman Kwok 25889a391c7bSWingMan Kwok for (i = 0; i < gbe_dev->max_num_ports; i++) 258921e0e0ddSKaricheri, Muralidharan gbe_dev->hw_stats_regs[i] = gbe_dev->switch_regs + 259090cff9e2SWingman Kwok XGBE10_HW_STATS_OFFSET + (GBE_HW_STATS_REG_MAP_SZ * i); 259190cff9e2SWingman Kwok 25929a391c7bSWingMan Kwok gbe_dev->ale_reg = gbe_dev->switch_regs + XGBE10_ALE_OFFSET; 25939a391c7bSWingMan Kwok gbe_dev->ale_ports = gbe_dev->max_num_ports; 259490cff9e2SWingman Kwok gbe_dev->host_port = XGBE10_HOST_PORT_NUM; 259590cff9e2SWingman Kwok gbe_dev->ale_entries = XGBE10_NUM_ALE_ENTRIES; 259690cff9e2SWingman Kwok gbe_dev->et_stats = xgbe10_et_stats; 259790cff9e2SWingman Kwok gbe_dev->num_et_stats = ARRAY_SIZE(xgbe10_et_stats); 25989a391c7bSWingMan Kwok gbe_dev->stats_en_mask = (1 << (gbe_dev->max_num_ports)) - 1; 259990cff9e2SWingman Kwok 260090cff9e2SWingman Kwok /* Subsystem registers */ 260190cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, ss_regs, id_ver); 260290cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, ss_regs, control); 260390cff9e2SWingman Kwok 260490cff9e2SWingman Kwok /* Switch module registers */ 260590cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, switch_regs, id_ver); 260690cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, switch_regs, control); 260790cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, switch_regs, ptype); 260890cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, switch_regs, stat_port_en); 260990cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, switch_regs, flow_control); 261090cff9e2SWingman Kwok 261190cff9e2SWingman Kwok /* Host port registers */ 261290cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, host_port_regs, port_vlan); 261390cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, host_port_regs, tx_pri_map); 261490cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, host_port_regs, rx_maxlen); 261590cff9e2SWingman Kwok return 0; 261690cff9e2SWingman Kwok } 261790cff9e2SWingman Kwok 26186f8d3f33SWingman Kwok static int get_gbe_resource_version(struct gbe_priv *gbe_dev, 26196f8d3f33SWingman Kwok struct device_node *node) 26206f8d3f33SWingman Kwok { 26216f8d3f33SWingman Kwok struct resource res; 26226f8d3f33SWingman Kwok void __iomem *regs; 26236f8d3f33SWingman Kwok int ret; 26246f8d3f33SWingman Kwok 262521e0e0ddSKaricheri, Muralidharan ret = of_address_to_resource(node, GBE_SS_REG_INDEX, &res); 26266f8d3f33SWingman Kwok if (ret) { 262721e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, 262821e0e0ddSKaricheri, Muralidharan "Can't translate of node(%s) of gbe ss address at %d\n", 262921e0e0ddSKaricheri, Muralidharan node->name, GBE_SS_REG_INDEX); 26306f8d3f33SWingman Kwok return ret; 26316f8d3f33SWingman Kwok } 26326f8d3f33SWingman Kwok 26336f8d3f33SWingman Kwok regs = devm_ioremap_resource(gbe_dev->dev, &res); 26346f8d3f33SWingman Kwok if (IS_ERR(regs)) { 26356f8d3f33SWingman Kwok dev_err(gbe_dev->dev, "Failed to map gbe register base\n"); 26366f8d3f33SWingman Kwok return PTR_ERR(regs); 26376f8d3f33SWingman Kwok } 26386f8d3f33SWingman Kwok gbe_dev->ss_regs = regs; 26396f8d3f33SWingman Kwok gbe_dev->ss_version = readl(gbe_dev->ss_regs); 26406f8d3f33SWingman Kwok return 0; 26416f8d3f33SWingman Kwok } 26426f8d3f33SWingman Kwok 26436f8d3f33SWingman Kwok static int set_gbe_ethss14_priv(struct gbe_priv *gbe_dev, 26446f8d3f33SWingman Kwok struct device_node *node) 26456f8d3f33SWingman Kwok { 264621e0e0ddSKaricheri, Muralidharan struct resource res; 26476f8d3f33SWingman Kwok void __iomem *regs; 264821e0e0ddSKaricheri, Muralidharan int i, ret; 264921e0e0ddSKaricheri, Muralidharan 265021e0e0ddSKaricheri, Muralidharan ret = of_address_to_resource(node, GBE_SGMII34_REG_INDEX, &res); 265121e0e0ddSKaricheri, Muralidharan if (ret) { 265221e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, 265321e0e0ddSKaricheri, Muralidharan "Can't translate of gbe node(%s) address at index %d\n", 265421e0e0ddSKaricheri, Muralidharan node->name, GBE_SGMII34_REG_INDEX); 265521e0e0ddSKaricheri, Muralidharan return ret; 265621e0e0ddSKaricheri, Muralidharan } 265721e0e0ddSKaricheri, Muralidharan 265821e0e0ddSKaricheri, Muralidharan regs = devm_ioremap_resource(gbe_dev->dev, &res); 265921e0e0ddSKaricheri, Muralidharan if (IS_ERR(regs)) { 266021e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, 266121e0e0ddSKaricheri, Muralidharan "Failed to map gbe sgmii port34 register base\n"); 266221e0e0ddSKaricheri, Muralidharan return PTR_ERR(regs); 266321e0e0ddSKaricheri, Muralidharan } 266421e0e0ddSKaricheri, Muralidharan gbe_dev->sgmii_port34_regs = regs; 266521e0e0ddSKaricheri, Muralidharan 266621e0e0ddSKaricheri, Muralidharan ret = of_address_to_resource(node, GBE_SM_REG_INDEX, &res); 266721e0e0ddSKaricheri, Muralidharan if (ret) { 266821e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, 266921e0e0ddSKaricheri, Muralidharan "Can't translate of gbe node(%s) address at index %d\n", 267021e0e0ddSKaricheri, Muralidharan node->name, GBE_SM_REG_INDEX); 267121e0e0ddSKaricheri, Muralidharan return ret; 267221e0e0ddSKaricheri, Muralidharan } 267321e0e0ddSKaricheri, Muralidharan 267421e0e0ddSKaricheri, Muralidharan regs = devm_ioremap_resource(gbe_dev->dev, &res); 267521e0e0ddSKaricheri, Muralidharan if (IS_ERR(regs)) { 267621e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, 267721e0e0ddSKaricheri, Muralidharan "Failed to map gbe switch module register base\n"); 267821e0e0ddSKaricheri, Muralidharan return PTR_ERR(regs); 267921e0e0ddSKaricheri, Muralidharan } 268021e0e0ddSKaricheri, Muralidharan gbe_dev->switch_regs = regs; 26816f8d3f33SWingman Kwok 26826f8d3f33SWingman Kwok gbe_dev->hw_stats = devm_kzalloc(gbe_dev->dev, 26836f8d3f33SWingman Kwok GBE13_NUM_HW_STAT_ENTRIES * 26849a391c7bSWingMan Kwok gbe_dev->max_num_slaves * sizeof(u64), 26856f8d3f33SWingman Kwok GFP_KERNEL); 26866f8d3f33SWingman Kwok if (!gbe_dev->hw_stats) { 26876f8d3f33SWingman Kwok dev_err(gbe_dev->dev, "hw_stats memory allocation failed\n"); 26886f8d3f33SWingman Kwok return -ENOMEM; 26896f8d3f33SWingman Kwok } 26906f8d3f33SWingman Kwok 269121e0e0ddSKaricheri, Muralidharan gbe_dev->sgmii_port_regs = gbe_dev->ss_regs + GBE13_SGMII_MODULE_OFFSET; 269221e0e0ddSKaricheri, Muralidharan gbe_dev->host_port_regs = gbe_dev->switch_regs + GBE13_HOST_PORT_OFFSET; 26936f8d3f33SWingman Kwok 26949a391c7bSWingMan Kwok for (i = 0; i < gbe_dev->max_num_slaves; i++) { 269521e0e0ddSKaricheri, Muralidharan gbe_dev->hw_stats_regs[i] = 269621e0e0ddSKaricheri, Muralidharan gbe_dev->switch_regs + GBE13_HW_STATS_OFFSET + 26976f8d3f33SWingman Kwok (GBE_HW_STATS_REG_MAP_SZ * i); 269821e0e0ddSKaricheri, Muralidharan } 26996f8d3f33SWingman Kwok 270021e0e0ddSKaricheri, Muralidharan gbe_dev->ale_reg = gbe_dev->switch_regs + GBE13_ALE_OFFSET; 27019a391c7bSWingMan Kwok gbe_dev->ale_ports = gbe_dev->max_num_ports; 27026f8d3f33SWingman Kwok gbe_dev->host_port = GBE13_HOST_PORT_NUM; 27036f8d3f33SWingman Kwok gbe_dev->ale_entries = GBE13_NUM_ALE_ENTRIES; 27046f8d3f33SWingman Kwok gbe_dev->et_stats = gbe13_et_stats; 27056f8d3f33SWingman Kwok gbe_dev->num_et_stats = ARRAY_SIZE(gbe13_et_stats); 27069a391c7bSWingMan Kwok gbe_dev->stats_en_mask = GBE13_REG_VAL_STAT_ENABLE_ALL; 27076f8d3f33SWingman Kwok 27086f8d3f33SWingman Kwok /* Subsystem registers */ 27096f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, ss_regs, id_ver); 27106f8d3f33SWingman Kwok 27116f8d3f33SWingman Kwok /* Switch module registers */ 27126f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, switch_regs, id_ver); 27136f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, switch_regs, control); 27146f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, switch_regs, soft_reset); 27156f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, switch_regs, stat_port_en); 27166f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, switch_regs, ptype); 27176f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, switch_regs, flow_control); 27186f8d3f33SWingman Kwok 27196f8d3f33SWingman Kwok /* Host port registers */ 27206f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, host_port_regs, port_vlan); 27216f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, host_port_regs, rx_maxlen); 27226f8d3f33SWingman Kwok return 0; 27236f8d3f33SWingman Kwok } 27246f8d3f33SWingman Kwok 27259a391c7bSWingMan Kwok static int set_gbenu_ethss_priv(struct gbe_priv *gbe_dev, 27269a391c7bSWingMan Kwok struct device_node *node) 27279a391c7bSWingMan Kwok { 27289a391c7bSWingMan Kwok struct resource res; 27299a391c7bSWingMan Kwok void __iomem *regs; 27309a391c7bSWingMan Kwok int i, ret; 27319a391c7bSWingMan Kwok 27329a391c7bSWingMan Kwok gbe_dev->hw_stats = devm_kzalloc(gbe_dev->dev, 27339a391c7bSWingMan Kwok GBENU_NUM_HW_STAT_ENTRIES * 27349a391c7bSWingMan Kwok (gbe_dev->max_num_ports) * sizeof(u64), 27359a391c7bSWingMan Kwok GFP_KERNEL); 27369a391c7bSWingMan Kwok if (!gbe_dev->hw_stats) { 27379a391c7bSWingMan Kwok dev_err(gbe_dev->dev, "hw_stats memory allocation failed\n"); 27389a391c7bSWingMan Kwok return -ENOMEM; 27399a391c7bSWingMan Kwok } 27409a391c7bSWingMan Kwok 27419a391c7bSWingMan Kwok ret = of_address_to_resource(node, GBENU_SM_REG_INDEX, &res); 27429a391c7bSWingMan Kwok if (ret) { 27439a391c7bSWingMan Kwok dev_err(gbe_dev->dev, 27449a391c7bSWingMan Kwok "Can't translate of gbenu node(%s) addr at index %d\n", 27459a391c7bSWingMan Kwok node->name, GBENU_SM_REG_INDEX); 27469a391c7bSWingMan Kwok return ret; 27479a391c7bSWingMan Kwok } 27489a391c7bSWingMan Kwok 27499a391c7bSWingMan Kwok regs = devm_ioremap_resource(gbe_dev->dev, &res); 27509a391c7bSWingMan Kwok if (IS_ERR(regs)) { 27519a391c7bSWingMan Kwok dev_err(gbe_dev->dev, 27529a391c7bSWingMan Kwok "Failed to map gbenu switch module register base\n"); 27539a391c7bSWingMan Kwok return PTR_ERR(regs); 27549a391c7bSWingMan Kwok } 27559a391c7bSWingMan Kwok gbe_dev->switch_regs = regs; 27569a391c7bSWingMan Kwok 27579a391c7bSWingMan Kwok gbe_dev->sgmii_port_regs = gbe_dev->ss_regs + GBENU_SGMII_MODULE_OFFSET; 27589a391c7bSWingMan Kwok gbe_dev->host_port_regs = gbe_dev->switch_regs + GBENU_HOST_PORT_OFFSET; 27599a391c7bSWingMan Kwok 27609a391c7bSWingMan Kwok for (i = 0; i < (gbe_dev->max_num_ports); i++) 27619a391c7bSWingMan Kwok gbe_dev->hw_stats_regs[i] = gbe_dev->switch_regs + 27629a391c7bSWingMan Kwok GBENU_HW_STATS_OFFSET + (GBENU_HW_STATS_REG_MAP_SZ * i); 27639a391c7bSWingMan Kwok 27649a391c7bSWingMan Kwok gbe_dev->ale_reg = gbe_dev->switch_regs + GBENU_ALE_OFFSET; 27659a391c7bSWingMan Kwok gbe_dev->ale_ports = gbe_dev->max_num_ports; 27669a391c7bSWingMan Kwok gbe_dev->host_port = GBENU_HOST_PORT_NUM; 27679a391c7bSWingMan Kwok gbe_dev->ale_entries = GBE13_NUM_ALE_ENTRIES; 27689a391c7bSWingMan Kwok gbe_dev->et_stats = gbenu_et_stats; 27699a391c7bSWingMan Kwok gbe_dev->stats_en_mask = (1 << (gbe_dev->max_num_ports)) - 1; 27709a391c7bSWingMan Kwok 27719a391c7bSWingMan Kwok if (IS_SS_ID_NU(gbe_dev)) 27729a391c7bSWingMan Kwok gbe_dev->num_et_stats = GBENU_ET_STATS_HOST_SIZE + 27739a391c7bSWingMan Kwok (gbe_dev->max_num_slaves * GBENU_ET_STATS_PORT_SIZE); 27749a391c7bSWingMan Kwok else 27759a391c7bSWingMan Kwok gbe_dev->num_et_stats = GBENU_ET_STATS_HOST_SIZE + 27769a391c7bSWingMan Kwok GBENU_ET_STATS_PORT_SIZE; 27779a391c7bSWingMan Kwok 27789a391c7bSWingMan Kwok /* Subsystem registers */ 27799a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, ss_regs, id_ver); 27809a391c7bSWingMan Kwok 27819a391c7bSWingMan Kwok /* Switch module registers */ 27829a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, switch_regs, id_ver); 27839a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, switch_regs, control); 27849a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, switch_regs, stat_port_en); 27859a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, switch_regs, ptype); 27869a391c7bSWingMan Kwok 27879a391c7bSWingMan Kwok /* Host port registers */ 27889a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, host_port_regs, port_vlan); 27899a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, host_port_regs, rx_maxlen); 27909a391c7bSWingMan Kwok 27919a391c7bSWingMan Kwok /* For NU only. 2U does not need tx_pri_map. 27929a391c7bSWingMan Kwok * NU cppi port 0 tx pkt streaming interface has (n-1)*8 egress threads 27939a391c7bSWingMan Kwok * while 2U has only 1 such thread 27949a391c7bSWingMan Kwok */ 27959a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, host_port_regs, tx_pri_map); 27969a391c7bSWingMan Kwok return 0; 27979a391c7bSWingMan Kwok } 27989a391c7bSWingMan Kwok 27996f8d3f33SWingman Kwok static int gbe_probe(struct netcp_device *netcp_device, struct device *dev, 28006f8d3f33SWingman Kwok struct device_node *node, void **inst_priv) 28016f8d3f33SWingman Kwok { 28026f8d3f33SWingman Kwok struct device_node *interfaces, *interface; 28036f8d3f33SWingman Kwok struct device_node *secondary_ports; 28046f8d3f33SWingman Kwok struct cpsw_ale_params ale_params; 28056f8d3f33SWingman Kwok struct gbe_priv *gbe_dev; 28066f8d3f33SWingman Kwok u32 slave_num; 28076f8d3f33SWingman Kwok int ret = 0; 28086f8d3f33SWingman Kwok 28096f8d3f33SWingman Kwok if (!node) { 28106f8d3f33SWingman Kwok dev_err(dev, "device tree info unavailable\n"); 28116f8d3f33SWingman Kwok return -ENODEV; 28126f8d3f33SWingman Kwok } 28136f8d3f33SWingman Kwok 28146f8d3f33SWingman Kwok gbe_dev = devm_kzalloc(dev, sizeof(struct gbe_priv), GFP_KERNEL); 28156f8d3f33SWingman Kwok if (!gbe_dev) 28166f8d3f33SWingman Kwok return -ENOMEM; 28176f8d3f33SWingman Kwok 28189a391c7bSWingMan Kwok if (of_device_is_compatible(node, "ti,netcp-gbe-5") || 28199a391c7bSWingMan Kwok of_device_is_compatible(node, "ti,netcp-gbe")) { 28209a391c7bSWingMan Kwok gbe_dev->max_num_slaves = 4; 28219a391c7bSWingMan Kwok } else if (of_device_is_compatible(node, "ti,netcp-gbe-9")) { 28229a391c7bSWingMan Kwok gbe_dev->max_num_slaves = 8; 28239a391c7bSWingMan Kwok } else if (of_device_is_compatible(node, "ti,netcp-gbe-2")) { 28249a391c7bSWingMan Kwok gbe_dev->max_num_slaves = 1; 28259a391c7bSWingMan Kwok } else if (of_device_is_compatible(node, "ti,netcp-xgbe")) { 28269a391c7bSWingMan Kwok gbe_dev->max_num_slaves = 2; 28279a391c7bSWingMan Kwok } else { 28289a391c7bSWingMan Kwok dev_err(dev, "device tree node for unknown device\n"); 28299a391c7bSWingMan Kwok return -EINVAL; 28309a391c7bSWingMan Kwok } 28319a391c7bSWingMan Kwok gbe_dev->max_num_ports = gbe_dev->max_num_slaves + 1; 28329a391c7bSWingMan Kwok 28336f8d3f33SWingman Kwok gbe_dev->dev = dev; 28346f8d3f33SWingman Kwok gbe_dev->netcp_device = netcp_device; 28356f8d3f33SWingman Kwok gbe_dev->rx_packet_max = NETCP_MAX_FRAME_SIZE; 28366f8d3f33SWingman Kwok 28376f8d3f33SWingman Kwok /* init the hw stats lock */ 28386f8d3f33SWingman Kwok spin_lock_init(&gbe_dev->hw_stats_lock); 28396f8d3f33SWingman Kwok 28406f8d3f33SWingman Kwok if (of_find_property(node, "enable-ale", NULL)) { 28416f8d3f33SWingman Kwok gbe_dev->enable_ale = true; 28426f8d3f33SWingman Kwok dev_info(dev, "ALE enabled\n"); 28436f8d3f33SWingman Kwok } else { 28446f8d3f33SWingman Kwok gbe_dev->enable_ale = false; 28456f8d3f33SWingman Kwok dev_dbg(dev, "ALE bypass enabled*\n"); 28466f8d3f33SWingman Kwok } 28476f8d3f33SWingman Kwok 28486f8d3f33SWingman Kwok ret = of_property_read_u32(node, "tx-queue", 28496f8d3f33SWingman Kwok &gbe_dev->tx_queue_id); 28506f8d3f33SWingman Kwok if (ret < 0) { 28516f8d3f33SWingman Kwok dev_err(dev, "missing tx_queue parameter\n"); 28526f8d3f33SWingman Kwok gbe_dev->tx_queue_id = GBE_TX_QUEUE; 28536f8d3f33SWingman Kwok } 28546f8d3f33SWingman Kwok 28556f8d3f33SWingman Kwok ret = of_property_read_string(node, "tx-channel", 28566f8d3f33SWingman Kwok &gbe_dev->dma_chan_name); 28576f8d3f33SWingman Kwok if (ret < 0) { 28586f8d3f33SWingman Kwok dev_err(dev, "missing \"tx-channel\" parameter\n"); 28596f8d3f33SWingman Kwok ret = -ENODEV; 28606f8d3f33SWingman Kwok goto quit; 28616f8d3f33SWingman Kwok } 28626f8d3f33SWingman Kwok 28636f8d3f33SWingman Kwok if (!strcmp(node->name, "gbe")) { 28646f8d3f33SWingman Kwok ret = get_gbe_resource_version(gbe_dev, node); 28656f8d3f33SWingman Kwok if (ret) 28666f8d3f33SWingman Kwok goto quit; 28676f8d3f33SWingman Kwok 28689a391c7bSWingMan Kwok dev_dbg(dev, "ss_version: 0x%08x\n", gbe_dev->ss_version); 28699a391c7bSWingMan Kwok 28709a391c7bSWingMan Kwok if (gbe_dev->ss_version == GBE_SS_VERSION_14) 28716f8d3f33SWingman Kwok ret = set_gbe_ethss14_priv(gbe_dev, node); 28729a391c7bSWingMan Kwok else if (IS_SS_ID_MU(gbe_dev)) 28739a391c7bSWingMan Kwok ret = set_gbenu_ethss_priv(gbe_dev, node); 28749a391c7bSWingMan Kwok else 28759a391c7bSWingMan Kwok ret = -ENODEV; 28769a391c7bSWingMan Kwok 28776f8d3f33SWingman Kwok if (ret) 28786f8d3f33SWingman Kwok goto quit; 287990cff9e2SWingman Kwok } else if (!strcmp(node->name, "xgbe")) { 288090cff9e2SWingman Kwok ret = set_xgbe_ethss10_priv(gbe_dev, node); 288190cff9e2SWingman Kwok if (ret) 288290cff9e2SWingman Kwok goto quit; 288390cff9e2SWingman Kwok ret = netcp_xgbe_serdes_init(gbe_dev->xgbe_serdes_regs, 288490cff9e2SWingman Kwok gbe_dev->ss_regs); 288590cff9e2SWingman Kwok if (ret) 288690cff9e2SWingman Kwok goto quit; 28876f8d3f33SWingman Kwok } else { 28886f8d3f33SWingman Kwok dev_err(dev, "unknown GBE node(%s)\n", node->name); 28896f8d3f33SWingman Kwok ret = -ENODEV; 28906f8d3f33SWingman Kwok goto quit; 28916f8d3f33SWingman Kwok } 28926f8d3f33SWingman Kwok 28936f8d3f33SWingman Kwok interfaces = of_get_child_by_name(node, "interfaces"); 28946f8d3f33SWingman Kwok if (!interfaces) 28956f8d3f33SWingman Kwok dev_err(dev, "could not find interfaces\n"); 28966f8d3f33SWingman Kwok 28976f8d3f33SWingman Kwok ret = netcp_txpipe_init(&gbe_dev->tx_pipe, netcp_device, 28986f8d3f33SWingman Kwok gbe_dev->dma_chan_name, gbe_dev->tx_queue_id); 28996f8d3f33SWingman Kwok if (ret) 29006f8d3f33SWingman Kwok goto quit; 29016f8d3f33SWingman Kwok 29026f8d3f33SWingman Kwok ret = netcp_txpipe_open(&gbe_dev->tx_pipe); 29036f8d3f33SWingman Kwok if (ret) 29046f8d3f33SWingman Kwok goto quit; 29056f8d3f33SWingman Kwok 29066f8d3f33SWingman Kwok /* Create network interfaces */ 29076f8d3f33SWingman Kwok INIT_LIST_HEAD(&gbe_dev->gbe_intf_head); 29086f8d3f33SWingman Kwok for_each_child_of_node(interfaces, interface) { 29096f8d3f33SWingman Kwok ret = of_property_read_u32(interface, "slave-port", &slave_num); 29106f8d3f33SWingman Kwok if (ret) { 29116f8d3f33SWingman Kwok dev_err(dev, "missing slave-port parameter, skipping interface configuration for %s\n", 29126f8d3f33SWingman Kwok interface->name); 29136f8d3f33SWingman Kwok continue; 29146f8d3f33SWingman Kwok } 29156f8d3f33SWingman Kwok gbe_dev->num_slaves++; 29169a391c7bSWingMan Kwok if (gbe_dev->num_slaves >= gbe_dev->max_num_slaves) 29179a391c7bSWingMan Kwok break; 29186f8d3f33SWingman Kwok } 29196f8d3f33SWingman Kwok 29206f8d3f33SWingman Kwok if (!gbe_dev->num_slaves) 29216f8d3f33SWingman Kwok dev_warn(dev, "No network interface configured\n"); 29226f8d3f33SWingman Kwok 29236f8d3f33SWingman Kwok /* Initialize Secondary slave ports */ 29246f8d3f33SWingman Kwok secondary_ports = of_get_child_by_name(node, "secondary-slave-ports"); 29256f8d3f33SWingman Kwok INIT_LIST_HEAD(&gbe_dev->secondary_slaves); 29269a391c7bSWingMan Kwok if (secondary_ports && (gbe_dev->num_slaves < gbe_dev->max_num_slaves)) 29276f8d3f33SWingman Kwok init_secondary_ports(gbe_dev, secondary_ports); 29286f8d3f33SWingman Kwok of_node_put(secondary_ports); 29296f8d3f33SWingman Kwok 29306f8d3f33SWingman Kwok if (!gbe_dev->num_slaves) { 29316f8d3f33SWingman Kwok dev_err(dev, "No network interface or secondary ports configured\n"); 29326f8d3f33SWingman Kwok ret = -ENODEV; 29336f8d3f33SWingman Kwok goto quit; 29346f8d3f33SWingman Kwok } 29356f8d3f33SWingman Kwok 29366f8d3f33SWingman Kwok memset(&ale_params, 0, sizeof(ale_params)); 29376f8d3f33SWingman Kwok ale_params.dev = gbe_dev->dev; 29386f8d3f33SWingman Kwok ale_params.ale_regs = gbe_dev->ale_reg; 29396f8d3f33SWingman Kwok ale_params.ale_ageout = GBE_DEFAULT_ALE_AGEOUT; 29406f8d3f33SWingman Kwok ale_params.ale_entries = gbe_dev->ale_entries; 29416f8d3f33SWingman Kwok ale_params.ale_ports = gbe_dev->ale_ports; 29426f8d3f33SWingman Kwok 29436f8d3f33SWingman Kwok gbe_dev->ale = cpsw_ale_create(&ale_params); 29446f8d3f33SWingman Kwok if (!gbe_dev->ale) { 29456f8d3f33SWingman Kwok dev_err(gbe_dev->dev, "error initializing ale engine\n"); 29466f8d3f33SWingman Kwok ret = -ENODEV; 29476f8d3f33SWingman Kwok goto quit; 29486f8d3f33SWingman Kwok } else { 29496f8d3f33SWingman Kwok dev_dbg(gbe_dev->dev, "Created a gbe ale engine\n"); 29506f8d3f33SWingman Kwok } 29516f8d3f33SWingman Kwok 29526f8d3f33SWingman Kwok /* initialize host port */ 29536f8d3f33SWingman Kwok gbe_init_host_port(gbe_dev); 29546f8d3f33SWingman Kwok 29556f8d3f33SWingman Kwok init_timer(&gbe_dev->timer); 29566f8d3f33SWingman Kwok gbe_dev->timer.data = (unsigned long)gbe_dev; 29576f8d3f33SWingman Kwok gbe_dev->timer.function = netcp_ethss_timer; 29586f8d3f33SWingman Kwok gbe_dev->timer.expires = jiffies + GBE_TIMER_INTERVAL; 29596f8d3f33SWingman Kwok add_timer(&gbe_dev->timer); 29606f8d3f33SWingman Kwok *inst_priv = gbe_dev; 29616f8d3f33SWingman Kwok return 0; 29626f8d3f33SWingman Kwok 29636f8d3f33SWingman Kwok quit: 29646f8d3f33SWingman Kwok if (gbe_dev->hw_stats) 29656f8d3f33SWingman Kwok devm_kfree(dev, gbe_dev->hw_stats); 29666f8d3f33SWingman Kwok cpsw_ale_destroy(gbe_dev->ale); 29676f8d3f33SWingman Kwok if (gbe_dev->ss_regs) 29686f8d3f33SWingman Kwok devm_iounmap(dev, gbe_dev->ss_regs); 29696f8d3f33SWingman Kwok of_node_put(interfaces); 29706f8d3f33SWingman Kwok devm_kfree(dev, gbe_dev); 29716f8d3f33SWingman Kwok return ret; 29726f8d3f33SWingman Kwok } 29736f8d3f33SWingman Kwok 29746f8d3f33SWingman Kwok static int gbe_attach(void *inst_priv, struct net_device *ndev, 29756f8d3f33SWingman Kwok struct device_node *node, void **intf_priv) 29766f8d3f33SWingman Kwok { 29776f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = inst_priv; 29786f8d3f33SWingman Kwok struct gbe_intf *gbe_intf; 29796f8d3f33SWingman Kwok int ret; 29806f8d3f33SWingman Kwok 29816f8d3f33SWingman Kwok if (!node) { 29826f8d3f33SWingman Kwok dev_err(gbe_dev->dev, "interface node not available\n"); 29836f8d3f33SWingman Kwok return -ENODEV; 29846f8d3f33SWingman Kwok } 29856f8d3f33SWingman Kwok 29866f8d3f33SWingman Kwok gbe_intf = devm_kzalloc(gbe_dev->dev, sizeof(*gbe_intf), GFP_KERNEL); 29876f8d3f33SWingman Kwok if (!gbe_intf) 29886f8d3f33SWingman Kwok return -ENOMEM; 29896f8d3f33SWingman Kwok 29906f8d3f33SWingman Kwok gbe_intf->ndev = ndev; 29916f8d3f33SWingman Kwok gbe_intf->dev = gbe_dev->dev; 29926f8d3f33SWingman Kwok gbe_intf->gbe_dev = gbe_dev; 29936f8d3f33SWingman Kwok 29946f8d3f33SWingman Kwok gbe_intf->slave = devm_kzalloc(gbe_dev->dev, 29956f8d3f33SWingman Kwok sizeof(*gbe_intf->slave), 29966f8d3f33SWingman Kwok GFP_KERNEL); 29976f8d3f33SWingman Kwok if (!gbe_intf->slave) { 29986f8d3f33SWingman Kwok ret = -ENOMEM; 29996f8d3f33SWingman Kwok goto fail; 30006f8d3f33SWingman Kwok } 30016f8d3f33SWingman Kwok 30026f8d3f33SWingman Kwok if (init_slave(gbe_dev, gbe_intf->slave, node)) { 30036f8d3f33SWingman Kwok ret = -ENODEV; 30046f8d3f33SWingman Kwok goto fail; 30056f8d3f33SWingman Kwok } 30066f8d3f33SWingman Kwok 30076f8d3f33SWingman Kwok gbe_intf->tx_pipe = gbe_dev->tx_pipe; 30086f8d3f33SWingman Kwok ndev->ethtool_ops = &keystone_ethtool_ops; 30096f8d3f33SWingman Kwok list_add_tail(&gbe_intf->gbe_intf_list, &gbe_dev->gbe_intf_head); 30106f8d3f33SWingman Kwok *intf_priv = gbe_intf; 30116f8d3f33SWingman Kwok return 0; 30126f8d3f33SWingman Kwok 30136f8d3f33SWingman Kwok fail: 30146f8d3f33SWingman Kwok if (gbe_intf->slave) 30156f8d3f33SWingman Kwok devm_kfree(gbe_dev->dev, gbe_intf->slave); 30166f8d3f33SWingman Kwok if (gbe_intf) 30176f8d3f33SWingman Kwok devm_kfree(gbe_dev->dev, gbe_intf); 30186f8d3f33SWingman Kwok return ret; 30196f8d3f33SWingman Kwok } 30206f8d3f33SWingman Kwok 30216f8d3f33SWingman Kwok static int gbe_release(void *intf_priv) 30226f8d3f33SWingman Kwok { 30236f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv; 30246f8d3f33SWingman Kwok 30256f8d3f33SWingman Kwok gbe_intf->ndev->ethtool_ops = NULL; 30266f8d3f33SWingman Kwok list_del(&gbe_intf->gbe_intf_list); 30276f8d3f33SWingman Kwok devm_kfree(gbe_intf->dev, gbe_intf->slave); 30286f8d3f33SWingman Kwok devm_kfree(gbe_intf->dev, gbe_intf); 30296f8d3f33SWingman Kwok return 0; 30306f8d3f33SWingman Kwok } 30316f8d3f33SWingman Kwok 30326f8d3f33SWingman Kwok static int gbe_remove(struct netcp_device *netcp_device, void *inst_priv) 30336f8d3f33SWingman Kwok { 30346f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = inst_priv; 30356f8d3f33SWingman Kwok 30366f8d3f33SWingman Kwok del_timer_sync(&gbe_dev->timer); 30376f8d3f33SWingman Kwok cpsw_ale_stop(gbe_dev->ale); 30386f8d3f33SWingman Kwok cpsw_ale_destroy(gbe_dev->ale); 30396f8d3f33SWingman Kwok netcp_txpipe_close(&gbe_dev->tx_pipe); 30406f8d3f33SWingman Kwok free_secondary_ports(gbe_dev); 30416f8d3f33SWingman Kwok 30426f8d3f33SWingman Kwok if (!list_empty(&gbe_dev->gbe_intf_head)) 30436f8d3f33SWingman Kwok dev_alert(gbe_dev->dev, "unreleased ethss interfaces present\n"); 30446f8d3f33SWingman Kwok 30456f8d3f33SWingman Kwok devm_kfree(gbe_dev->dev, gbe_dev->hw_stats); 30466f8d3f33SWingman Kwok devm_iounmap(gbe_dev->dev, gbe_dev->ss_regs); 30476f8d3f33SWingman Kwok memset(gbe_dev, 0x00, sizeof(*gbe_dev)); 30486f8d3f33SWingman Kwok devm_kfree(gbe_dev->dev, gbe_dev); 30496f8d3f33SWingman Kwok return 0; 30506f8d3f33SWingman Kwok } 30516f8d3f33SWingman Kwok 30526f8d3f33SWingman Kwok static struct netcp_module gbe_module = { 30536f8d3f33SWingman Kwok .name = GBE_MODULE_NAME, 30546f8d3f33SWingman Kwok .owner = THIS_MODULE, 30556f8d3f33SWingman Kwok .primary = true, 30566f8d3f33SWingman Kwok .probe = gbe_probe, 30576f8d3f33SWingman Kwok .open = gbe_open, 30586f8d3f33SWingman Kwok .close = gbe_close, 30596f8d3f33SWingman Kwok .remove = gbe_remove, 30606f8d3f33SWingman Kwok .attach = gbe_attach, 30616f8d3f33SWingman Kwok .release = gbe_release, 30626f8d3f33SWingman Kwok .add_addr = gbe_add_addr, 30636f8d3f33SWingman Kwok .del_addr = gbe_del_addr, 30646f8d3f33SWingman Kwok .add_vid = gbe_add_vid, 30656f8d3f33SWingman Kwok .del_vid = gbe_del_vid, 30666f8d3f33SWingman Kwok .ioctl = gbe_ioctl, 30676f8d3f33SWingman Kwok }; 30686f8d3f33SWingman Kwok 306990cff9e2SWingman Kwok static struct netcp_module xgbe_module = { 307090cff9e2SWingman Kwok .name = XGBE_MODULE_NAME, 307190cff9e2SWingman Kwok .owner = THIS_MODULE, 307290cff9e2SWingman Kwok .primary = true, 307390cff9e2SWingman Kwok .probe = gbe_probe, 307490cff9e2SWingman Kwok .open = gbe_open, 307590cff9e2SWingman Kwok .close = gbe_close, 307690cff9e2SWingman Kwok .remove = gbe_remove, 307790cff9e2SWingman Kwok .attach = gbe_attach, 307890cff9e2SWingman Kwok .release = gbe_release, 307990cff9e2SWingman Kwok .add_addr = gbe_add_addr, 308090cff9e2SWingman Kwok .del_addr = gbe_del_addr, 308190cff9e2SWingman Kwok .add_vid = gbe_add_vid, 308290cff9e2SWingman Kwok .del_vid = gbe_del_vid, 308390cff9e2SWingman Kwok .ioctl = gbe_ioctl, 308490cff9e2SWingman Kwok }; 308590cff9e2SWingman Kwok 30866f8d3f33SWingman Kwok static int __init keystone_gbe_init(void) 30876f8d3f33SWingman Kwok { 30886f8d3f33SWingman Kwok int ret; 30896f8d3f33SWingman Kwok 30906f8d3f33SWingman Kwok ret = netcp_register_module(&gbe_module); 30916f8d3f33SWingman Kwok if (ret) 30926f8d3f33SWingman Kwok return ret; 30936f8d3f33SWingman Kwok 309490cff9e2SWingman Kwok ret = netcp_register_module(&xgbe_module); 309590cff9e2SWingman Kwok if (ret) 309690cff9e2SWingman Kwok return ret; 309790cff9e2SWingman Kwok 30986f8d3f33SWingman Kwok return 0; 30996f8d3f33SWingman Kwok } 31006f8d3f33SWingman Kwok module_init(keystone_gbe_init); 31016f8d3f33SWingman Kwok 31026f8d3f33SWingman Kwok static void __exit keystone_gbe_exit(void) 31036f8d3f33SWingman Kwok { 31046f8d3f33SWingman Kwok netcp_unregister_module(&gbe_module); 310590cff9e2SWingman Kwok netcp_unregister_module(&xgbe_module); 31066f8d3f33SWingman Kwok } 31076f8d3f33SWingman Kwok module_exit(keystone_gbe_exit); 310858c11b5fSKaricheri, Muralidharan 310958c11b5fSKaricheri, Muralidharan MODULE_LICENSE("GPL v2"); 311058c11b5fSKaricheri, Muralidharan MODULE_DESCRIPTION("TI NETCP ETHSS driver for Keystone SOCs"); 311158c11b5fSKaricheri, Muralidharan MODULE_AUTHOR("Sandeep Nair <sandeep_n@ti.com"); 3112