168cf027fSGrygorii Strashko // SPDX-License-Identifier: GPL-2.0
26f8d3f33SWingman Kwok /*
390cff9e2SWingman Kwok * Keystone GBE and XGBE subsystem code
46f8d3f33SWingman Kwok *
56f8d3f33SWingman Kwok * Copyright (C) 2014 Texas Instruments Incorporated
66f8d3f33SWingman Kwok * Authors: Sandeep Nair <sandeep_n@ti.com>
76f8d3f33SWingman Kwok * Sandeep Paulraj <s-paulraj@ti.com>
86f8d3f33SWingman Kwok * Cyril Chemparathy <cyril@ti.com>
96f8d3f33SWingman Kwok * Santosh Shilimkar <santosh.shilimkar@ti.com>
106f8d3f33SWingman Kwok * Wingman Kwok <w-kwok2@ti.com>
116f8d3f33SWingman Kwok */
126f8d3f33SWingman Kwok
136f8d3f33SWingman Kwok #include <linux/io.h>
1458c11b5fSKaricheri, Muralidharan #include <linux/module.h>
156f8d3f33SWingman Kwok #include <linux/of_mdio.h>
167b647b93SMurali Karicheri #include <linux/of_net.h>
176f8d3f33SWingman Kwok #include <linux/of_address.h>
186f8d3f33SWingman Kwok #include <linux/if_vlan.h>
196246168bSWingMan Kwok #include <linux/ptp_classify.h>
206246168bSWingMan Kwok #include <linux/net_tstamp.h>
216f8d3f33SWingman Kwok #include <linux/ethtool.h>
226f8d3f33SWingman Kwok
232733d7b8SGrygorii Strashko #include "cpsw.h"
246f8d3f33SWingman Kwok #include "cpsw_ale.h"
256f8d3f33SWingman Kwok #include "netcp.h"
266246168bSWingMan Kwok #include "cpts.h"
276f8d3f33SWingman Kwok
286f8d3f33SWingman Kwok #define NETCP_DRIVER_NAME "TI KeyStone Ethernet Driver"
296f8d3f33SWingman Kwok #define NETCP_DRIVER_VERSION "v1.0"
306f8d3f33SWingman Kwok
316f8d3f33SWingman Kwok #define GBE_IDENT(reg) ((reg >> 16) & 0xffff)
326f8d3f33SWingman Kwok #define GBE_MAJOR_VERSION(reg) (reg >> 8 & 0x7)
336f8d3f33SWingman Kwok #define GBE_MINOR_VERSION(reg) (reg & 0xff)
346f8d3f33SWingman Kwok #define GBE_RTL_VERSION(reg) ((reg >> 11) & 0x1f)
356f8d3f33SWingman Kwok
366f8d3f33SWingman Kwok /* 1G Ethernet SS defines */
376f8d3f33SWingman Kwok #define GBE_MODULE_NAME "netcp-gbe"
382953586dSMurali Karicheri #define GBE_SS_VERSION_14 0x4ed2
396f8d3f33SWingman Kwok
4021e0e0ddSKaricheri, Muralidharan #define GBE_SS_REG_INDEX 0
4121e0e0ddSKaricheri, Muralidharan #define GBE_SGMII34_REG_INDEX 1
4221e0e0ddSKaricheri, Muralidharan #define GBE_SM_REG_INDEX 2
4321e0e0ddSKaricheri, Muralidharan /* offset relative to base of GBE_SS_REG_INDEX */
446f8d3f33SWingman Kwok #define GBE13_SGMII_MODULE_OFFSET 0x100
4521e0e0ddSKaricheri, Muralidharan /* offset relative to base of GBE_SM_REG_INDEX */
4621e0e0ddSKaricheri, Muralidharan #define GBE13_HOST_PORT_OFFSET 0x34
4721e0e0ddSKaricheri, Muralidharan #define GBE13_SLAVE_PORT_OFFSET 0x60
4821e0e0ddSKaricheri, Muralidharan #define GBE13_EMAC_OFFSET 0x100
4921e0e0ddSKaricheri, Muralidharan #define GBE13_SLAVE_PORT2_OFFSET 0x200
5021e0e0ddSKaricheri, Muralidharan #define GBE13_HW_STATS_OFFSET 0x300
516246168bSWingMan Kwok #define GBE13_CPTS_OFFSET 0x500
5221e0e0ddSKaricheri, Muralidharan #define GBE13_ALE_OFFSET 0x600
536f8d3f33SWingman Kwok #define GBE13_HOST_PORT_NUM 0
546f8d3f33SWingman Kwok
559a391c7bSWingMan Kwok /* 1G Ethernet NU SS defines */
569a391c7bSWingMan Kwok #define GBENU_MODULE_NAME "netcp-gbenu"
579a391c7bSWingMan Kwok #define GBE_SS_ID_NU 0x4ee6
589a391c7bSWingMan Kwok #define GBE_SS_ID_2U 0x4ee8
599a391c7bSWingMan Kwok
609a391c7bSWingMan Kwok #define IS_SS_ID_MU(d) \
619a391c7bSWingMan Kwok ((GBE_IDENT((d)->ss_version) == GBE_SS_ID_NU) || \
629a391c7bSWingMan Kwok (GBE_IDENT((d)->ss_version) == GBE_SS_ID_2U))
639a391c7bSWingMan Kwok
649a391c7bSWingMan Kwok #define IS_SS_ID_NU(d) \
659a391c7bSWingMan Kwok (GBE_IDENT((d)->ss_version) == GBE_SS_ID_NU)
669a391c7bSWingMan Kwok
672953586dSMurali Karicheri #define IS_SS_ID_VER_14(d) \
682953586dSMurali Karicheri (GBE_IDENT((d)->ss_version) == GBE_SS_VERSION_14)
69775f9535SMurali Karicheri #define IS_SS_ID_2U(d) \
70775f9535SMurali Karicheri (GBE_IDENT((d)->ss_version) == GBE_SS_ID_2U)
712953586dSMurali Karicheri
729a391c7bSWingMan Kwok #define GBENU_SS_REG_INDEX 0
739a391c7bSWingMan Kwok #define GBENU_SM_REG_INDEX 1
749a391c7bSWingMan Kwok #define GBENU_SGMII_MODULE_OFFSET 0x100
759a391c7bSWingMan Kwok #define GBENU_HOST_PORT_OFFSET 0x1000
769a391c7bSWingMan Kwok #define GBENU_SLAVE_PORT_OFFSET 0x2000
779a391c7bSWingMan Kwok #define GBENU_EMAC_OFFSET 0x2330
789a391c7bSWingMan Kwok #define GBENU_HW_STATS_OFFSET 0x1a000
796246168bSWingMan Kwok #define GBENU_CPTS_OFFSET 0x1d000
809a391c7bSWingMan Kwok #define GBENU_ALE_OFFSET 0x1e000
819a391c7bSWingMan Kwok #define GBENU_HOST_PORT_NUM 0
828c85151dSWingMan Kwok #define GBENU_SGMII_MODULE_SIZE 0x100
839a391c7bSWingMan Kwok
8490cff9e2SWingman Kwok /* 10G Ethernet SS defines */
8590cff9e2SWingman Kwok #define XGBE_MODULE_NAME "netcp-xgbe"
862953586dSMurali Karicheri #define XGBE_SS_VERSION_10 0x4ee4
8790cff9e2SWingman Kwok
8821e0e0ddSKaricheri, Muralidharan #define XGBE_SS_REG_INDEX 0
8921e0e0ddSKaricheri, Muralidharan #define XGBE_SM_REG_INDEX 1
9021e0e0ddSKaricheri, Muralidharan #define XGBE_SERDES_REG_INDEX 2
9121e0e0ddSKaricheri, Muralidharan
9221e0e0ddSKaricheri, Muralidharan /* offset relative to base of XGBE_SS_REG_INDEX */
9390cff9e2SWingman Kwok #define XGBE10_SGMII_MODULE_OFFSET 0x100
944c0ef231SWingMan Kwok #define IS_SS_ID_XGBE(d) ((d)->ss_version == XGBE_SS_VERSION_10)
9521e0e0ddSKaricheri, Muralidharan /* offset relative to base of XGBE_SM_REG_INDEX */
9621e0e0ddSKaricheri, Muralidharan #define XGBE10_HOST_PORT_OFFSET 0x34
9721e0e0ddSKaricheri, Muralidharan #define XGBE10_SLAVE_PORT_OFFSET 0x64
9821e0e0ddSKaricheri, Muralidharan #define XGBE10_EMAC_OFFSET 0x400
996246168bSWingMan Kwok #define XGBE10_CPTS_OFFSET 0x600
10021e0e0ddSKaricheri, Muralidharan #define XGBE10_ALE_OFFSET 0x700
10121e0e0ddSKaricheri, Muralidharan #define XGBE10_HW_STATS_OFFSET 0x800
10290cff9e2SWingman Kwok #define XGBE10_HOST_PORT_NUM 0
10390cff9e2SWingman Kwok
1046f8d3f33SWingman Kwok #define GBE_TIMER_INTERVAL (HZ / 2)
1056f8d3f33SWingman Kwok
1066f8d3f33SWingman Kwok /* Soft reset register values */
1076f8d3f33SWingman Kwok #define SOFT_RESET_MASK BIT(0)
1086f8d3f33SWingman Kwok #define SOFT_RESET BIT(0)
1096f8d3f33SWingman Kwok #define DEVICE_EMACSL_RESET_POLL_COUNT 100
1106f8d3f33SWingman Kwok #define GMACSL_RET_WARN_RESET_INCOMPLETE -2
1116f8d3f33SWingman Kwok
1126f8d3f33SWingman Kwok #define MACSL_RX_ENABLE_CSF BIT(23)
1136f8d3f33SWingman Kwok #define MACSL_ENABLE_EXT_CTL BIT(18)
11490cff9e2SWingman Kwok #define MACSL_XGMII_ENABLE BIT(13)
11590cff9e2SWingman Kwok #define MACSL_XGIG_MODE BIT(8)
1166f8d3f33SWingman Kwok #define MACSL_GIG_MODE BIT(7)
1176f8d3f33SWingman Kwok #define MACSL_GMII_ENABLE BIT(5)
1186f8d3f33SWingman Kwok #define MACSL_FULLDUPLEX BIT(0)
1196f8d3f33SWingman Kwok
1206f8d3f33SWingman Kwok #define GBE_CTL_P0_ENABLE BIT(2)
1214cd85a61SKaricheri, Muralidharan #define ETH_SW_CTL_P0_TX_CRC_REMOVE BIT(13)
1229a391c7bSWingMan Kwok #define GBE13_REG_VAL_STAT_ENABLE_ALL 0xff
12390cff9e2SWingman Kwok #define XGBE_REG_VAL_STAT_ENABLE_ALL 0xf
1246f8d3f33SWingman Kwok #define GBE_STATS_CD_SEL BIT(28)
1256f8d3f33SWingman Kwok
1266f8d3f33SWingman Kwok #define GBE_PORT_MASK(x) (BIT(x) - 1)
1276f8d3f33SWingman Kwok #define GBE_MASK_NO_PORTS 0
1286f8d3f33SWingman Kwok
1296f8d3f33SWingman Kwok #define GBE_DEF_1G_MAC_CONTROL \
1306f8d3f33SWingman Kwok (MACSL_GIG_MODE | MACSL_GMII_ENABLE | \
1316f8d3f33SWingman Kwok MACSL_ENABLE_EXT_CTL | MACSL_RX_ENABLE_CSF)
1326f8d3f33SWingman Kwok
13390cff9e2SWingman Kwok #define GBE_DEF_10G_MAC_CONTROL \
13490cff9e2SWingman Kwok (MACSL_XGIG_MODE | MACSL_XGMII_ENABLE | \
13590cff9e2SWingman Kwok MACSL_ENABLE_EXT_CTL | MACSL_RX_ENABLE_CSF)
13690cff9e2SWingman Kwok
1376f8d3f33SWingman Kwok #define GBE_STATSA_MODULE 0
1386f8d3f33SWingman Kwok #define GBE_STATSB_MODULE 1
1396f8d3f33SWingman Kwok #define GBE_STATSC_MODULE 2
1406f8d3f33SWingman Kwok #define GBE_STATSD_MODULE 3
1416f8d3f33SWingman Kwok
1429a391c7bSWingMan Kwok #define GBENU_STATS0_MODULE 0
1439a391c7bSWingMan Kwok #define GBENU_STATS1_MODULE 1
1449a391c7bSWingMan Kwok #define GBENU_STATS2_MODULE 2
1459a391c7bSWingMan Kwok #define GBENU_STATS3_MODULE 3
1469a391c7bSWingMan Kwok #define GBENU_STATS4_MODULE 4
1479a391c7bSWingMan Kwok #define GBENU_STATS5_MODULE 5
1489a391c7bSWingMan Kwok #define GBENU_STATS6_MODULE 6
1499a391c7bSWingMan Kwok #define GBENU_STATS7_MODULE 7
1509a391c7bSWingMan Kwok #define GBENU_STATS8_MODULE 8
1519a391c7bSWingMan Kwok
15290cff9e2SWingman Kwok #define XGBE_STATS0_MODULE 0
15390cff9e2SWingman Kwok #define XGBE_STATS1_MODULE 1
15490cff9e2SWingman Kwok #define XGBE_STATS2_MODULE 2
15590cff9e2SWingman Kwok
1566f8d3f33SWingman Kwok /* s: 0-based slave_port */
1578c85151dSWingMan Kwok #define SGMII_BASE(d, s) \
1588c85151dSWingMan Kwok (((s) < 2) ? (d)->sgmii_port_regs : (d)->sgmii_port34_regs)
1596f8d3f33SWingman Kwok
1606f8d3f33SWingman Kwok #define GBE_TX_QUEUE 648
1616f8d3f33SWingman Kwok #define GBE_TXHOOK_ORDER 0
1626246168bSWingMan Kwok #define GBE_RXHOOK_ORDER 0
1636f8d3f33SWingman Kwok #define GBE_DEFAULT_ALE_AGEOUT 30
16490cff9e2SWingman Kwok #define SLAVE_LINK_IS_XGMII(s) ((s)->link_interface >= XGMII_LINK_MAC_PHY)
1657771f2b4SMurali Karicheri #define SLAVE_LINK_IS_RGMII(s) \
1667771f2b4SMurali Karicheri (((s)->link_interface >= RGMII_LINK_MAC_PHY) && \
1677771f2b4SMurali Karicheri ((s)->link_interface <= RGMII_LINK_MAC_PHY_NO_MDIO))
1687771f2b4SMurali Karicheri #define SLAVE_LINK_IS_SGMII(s) \
1697771f2b4SMurali Karicheri ((s)->link_interface <= SGMII_LINK_MAC_PHY_NO_MDIO)
1706f8d3f33SWingman Kwok #define NETCP_LINK_STATE_INVALID -1
1716f8d3f33SWingman Kwok
1726f8d3f33SWingman Kwok #define GBE_SET_REG_OFS(p, rb, rn) p->rb##_ofs.rn = \
1736f8d3f33SWingman Kwok offsetof(struct gbe##_##rb, rn)
1749a391c7bSWingMan Kwok #define GBENU_SET_REG_OFS(p, rb, rn) p->rb##_ofs.rn = \
1759a391c7bSWingMan Kwok offsetof(struct gbenu##_##rb, rn)
17690cff9e2SWingman Kwok #define XGBE_SET_REG_OFS(p, rb, rn) p->rb##_ofs.rn = \
17790cff9e2SWingman Kwok offsetof(struct xgbe##_##rb, rn)
1786f8d3f33SWingman Kwok #define GBE_REG_ADDR(p, rb, rn) (p->rb + p->rb##_ofs.rn)
1796f8d3f33SWingman Kwok
1809a391c7bSWingMan Kwok #define HOST_TX_PRI_MAP_DEFAULT 0x00000000
1819a391c7bSWingMan Kwok
1826246168bSWingMan Kwok #if IS_ENABLED(CONFIG_TI_CPTS)
1836246168bSWingMan Kwok /* Px_TS_CTL register fields */
1846246168bSWingMan Kwok #define TS_RX_ANX_F_EN BIT(0)
1856246168bSWingMan Kwok #define TS_RX_VLAN_LT1_EN BIT(1)
1866246168bSWingMan Kwok #define TS_RX_VLAN_LT2_EN BIT(2)
1876246168bSWingMan Kwok #define TS_RX_ANX_D_EN BIT(3)
1886246168bSWingMan Kwok #define TS_TX_ANX_F_EN BIT(4)
1896246168bSWingMan Kwok #define TS_TX_VLAN_LT1_EN BIT(5)
1906246168bSWingMan Kwok #define TS_TX_VLAN_LT2_EN BIT(6)
1916246168bSWingMan Kwok #define TS_TX_ANX_D_EN BIT(7)
1926246168bSWingMan Kwok #define TS_LT2_EN BIT(8)
1936246168bSWingMan Kwok #define TS_RX_ANX_E_EN BIT(9)
1946246168bSWingMan Kwok #define TS_TX_ANX_E_EN BIT(10)
1956246168bSWingMan Kwok #define TS_MSG_TYPE_EN_SHIFT 16
1966246168bSWingMan Kwok #define TS_MSG_TYPE_EN_MASK 0xffff
1976246168bSWingMan Kwok
1986246168bSWingMan Kwok /* Px_TS_SEQ_LTYPE register fields */
1996246168bSWingMan Kwok #define TS_SEQ_ID_OFS_SHIFT 16
2006246168bSWingMan Kwok #define TS_SEQ_ID_OFS_MASK 0x3f
2016246168bSWingMan Kwok
2026246168bSWingMan Kwok /* Px_TS_CTL_LTYPE2 register fields */
2036246168bSWingMan Kwok #define TS_107 BIT(16)
2046246168bSWingMan Kwok #define TS_129 BIT(17)
2056246168bSWingMan Kwok #define TS_130 BIT(18)
2066246168bSWingMan Kwok #define TS_131 BIT(19)
2076246168bSWingMan Kwok #define TS_132 BIT(20)
2086246168bSWingMan Kwok #define TS_319 BIT(21)
2096246168bSWingMan Kwok #define TS_320 BIT(22)
2106246168bSWingMan Kwok #define TS_TTL_NONZERO BIT(23)
2116246168bSWingMan Kwok #define TS_UNI_EN BIT(24)
2126246168bSWingMan Kwok #define TS_UNI_EN_SHIFT 24
2136246168bSWingMan Kwok
2146246168bSWingMan Kwok #define TS_TX_ANX_ALL_EN \
2156246168bSWingMan Kwok (TS_TX_ANX_D_EN | TS_TX_ANX_E_EN | TS_TX_ANX_F_EN)
2166246168bSWingMan Kwok
2176246168bSWingMan Kwok #define TS_RX_ANX_ALL_EN \
2186246168bSWingMan Kwok (TS_RX_ANX_D_EN | TS_RX_ANX_E_EN | TS_RX_ANX_F_EN)
2196246168bSWingMan Kwok
2206246168bSWingMan Kwok #define TS_CTL_DST_PORT TS_319
2216246168bSWingMan Kwok #define TS_CTL_DST_PORT_SHIFT 21
2226246168bSWingMan Kwok
2236246168bSWingMan Kwok #define TS_CTL_MADDR_ALL \
2246246168bSWingMan Kwok (TS_107 | TS_129 | TS_130 | TS_131 | TS_132)
2256246168bSWingMan Kwok
2266246168bSWingMan Kwok #define TS_CTL_MADDR_SHIFT 16
2276246168bSWingMan Kwok
2286246168bSWingMan Kwok /* The PTP event messages - Sync, Delay_Req, Pdelay_Req, and Pdelay_Resp. */
2296246168bSWingMan Kwok #define EVENT_MSG_BITS (BIT(0) | BIT(1) | BIT(2) | BIT(3))
2306246168bSWingMan Kwok #endif /* CONFIG_TI_CPTS */
2316246168bSWingMan Kwok
23290cff9e2SWingman Kwok struct xgbe_ss_regs {
23390cff9e2SWingman Kwok u32 id_ver;
23490cff9e2SWingman Kwok u32 synce_count;
23590cff9e2SWingman Kwok u32 synce_mux;
23690cff9e2SWingman Kwok u32 control;
23790cff9e2SWingman Kwok };
23890cff9e2SWingman Kwok
23990cff9e2SWingman Kwok struct xgbe_switch_regs {
24090cff9e2SWingman Kwok u32 id_ver;
24190cff9e2SWingman Kwok u32 control;
24290cff9e2SWingman Kwok u32 emcontrol;
24390cff9e2SWingman Kwok u32 stat_port_en;
24490cff9e2SWingman Kwok u32 ptype;
24590cff9e2SWingman Kwok u32 soft_idle;
24690cff9e2SWingman Kwok u32 thru_rate;
24790cff9e2SWingman Kwok u32 gap_thresh;
24890cff9e2SWingman Kwok u32 tx_start_wds;
24990cff9e2SWingman Kwok u32 flow_control;
25090cff9e2SWingman Kwok u32 cppi_thresh;
25190cff9e2SWingman Kwok };
25290cff9e2SWingman Kwok
25390cff9e2SWingman Kwok struct xgbe_port_regs {
25490cff9e2SWingman Kwok u32 blk_cnt;
25590cff9e2SWingman Kwok u32 port_vlan;
25690cff9e2SWingman Kwok u32 tx_pri_map;
25790cff9e2SWingman Kwok u32 sa_lo;
25890cff9e2SWingman Kwok u32 sa_hi;
25990cff9e2SWingman Kwok u32 ts_ctl;
26090cff9e2SWingman Kwok u32 ts_seq_ltype;
26190cff9e2SWingman Kwok u32 ts_vlan;
26290cff9e2SWingman Kwok u32 ts_ctl_ltype2;
26390cff9e2SWingman Kwok u32 ts_ctl2;
26490cff9e2SWingman Kwok u32 control;
26590cff9e2SWingman Kwok };
26690cff9e2SWingman Kwok
26790cff9e2SWingman Kwok struct xgbe_host_port_regs {
26890cff9e2SWingman Kwok u32 blk_cnt;
26990cff9e2SWingman Kwok u32 port_vlan;
27090cff9e2SWingman Kwok u32 tx_pri_map;
27190cff9e2SWingman Kwok u32 src_id;
27290cff9e2SWingman Kwok u32 rx_pri_map;
27390cff9e2SWingman Kwok u32 rx_maxlen;
27490cff9e2SWingman Kwok };
27590cff9e2SWingman Kwok
27690cff9e2SWingman Kwok struct xgbe_emac_regs {
27790cff9e2SWingman Kwok u32 id_ver;
27890cff9e2SWingman Kwok u32 mac_control;
27990cff9e2SWingman Kwok u32 mac_status;
28090cff9e2SWingman Kwok u32 soft_reset;
28190cff9e2SWingman Kwok u32 rx_maxlen;
28290cff9e2SWingman Kwok u32 __reserved_0;
28390cff9e2SWingman Kwok u32 rx_pause;
28490cff9e2SWingman Kwok u32 tx_pause;
28590cff9e2SWingman Kwok u32 em_control;
28690cff9e2SWingman Kwok u32 __reserved_1;
28790cff9e2SWingman Kwok u32 tx_gap;
28890cff9e2SWingman Kwok u32 rsvd[4];
28990cff9e2SWingman Kwok };
29090cff9e2SWingman Kwok
29190cff9e2SWingman Kwok struct xgbe_host_hw_stats {
29290cff9e2SWingman Kwok u32 rx_good_frames;
29390cff9e2SWingman Kwok u32 rx_broadcast_frames;
29490cff9e2SWingman Kwok u32 rx_multicast_frames;
29590cff9e2SWingman Kwok u32 __rsvd_0[3];
29690cff9e2SWingman Kwok u32 rx_oversized_frames;
29790cff9e2SWingman Kwok u32 __rsvd_1;
29890cff9e2SWingman Kwok u32 rx_undersized_frames;
29990cff9e2SWingman Kwok u32 __rsvd_2;
30090cff9e2SWingman Kwok u32 overrun_type4;
30190cff9e2SWingman Kwok u32 overrun_type5;
30290cff9e2SWingman Kwok u32 rx_bytes;
30390cff9e2SWingman Kwok u32 tx_good_frames;
30490cff9e2SWingman Kwok u32 tx_broadcast_frames;
30590cff9e2SWingman Kwok u32 tx_multicast_frames;
30690cff9e2SWingman Kwok u32 __rsvd_3[9];
30790cff9e2SWingman Kwok u32 tx_bytes;
30890cff9e2SWingman Kwok u32 tx_64byte_frames;
30990cff9e2SWingman Kwok u32 tx_65_to_127byte_frames;
31090cff9e2SWingman Kwok u32 tx_128_to_255byte_frames;
31190cff9e2SWingman Kwok u32 tx_256_to_511byte_frames;
31290cff9e2SWingman Kwok u32 tx_512_to_1023byte_frames;
31390cff9e2SWingman Kwok u32 tx_1024byte_frames;
31490cff9e2SWingman Kwok u32 net_bytes;
31590cff9e2SWingman Kwok u32 rx_sof_overruns;
31690cff9e2SWingman Kwok u32 rx_mof_overruns;
31790cff9e2SWingman Kwok u32 rx_dma_overruns;
31890cff9e2SWingman Kwok };
31990cff9e2SWingman Kwok
32090cff9e2SWingman Kwok struct xgbe_hw_stats {
32190cff9e2SWingman Kwok u32 rx_good_frames;
32290cff9e2SWingman Kwok u32 rx_broadcast_frames;
32390cff9e2SWingman Kwok u32 rx_multicast_frames;
32490cff9e2SWingman Kwok u32 rx_pause_frames;
32590cff9e2SWingman Kwok u32 rx_crc_errors;
32690cff9e2SWingman Kwok u32 rx_align_code_errors;
32790cff9e2SWingman Kwok u32 rx_oversized_frames;
32890cff9e2SWingman Kwok u32 rx_jabber_frames;
32990cff9e2SWingman Kwok u32 rx_undersized_frames;
33090cff9e2SWingman Kwok u32 rx_fragments;
33190cff9e2SWingman Kwok u32 overrun_type4;
33290cff9e2SWingman Kwok u32 overrun_type5;
33390cff9e2SWingman Kwok u32 rx_bytes;
33490cff9e2SWingman Kwok u32 tx_good_frames;
33590cff9e2SWingman Kwok u32 tx_broadcast_frames;
33690cff9e2SWingman Kwok u32 tx_multicast_frames;
33790cff9e2SWingman Kwok u32 tx_pause_frames;
33890cff9e2SWingman Kwok u32 tx_deferred_frames;
33990cff9e2SWingman Kwok u32 tx_collision_frames;
34090cff9e2SWingman Kwok u32 tx_single_coll_frames;
34190cff9e2SWingman Kwok u32 tx_mult_coll_frames;
34290cff9e2SWingman Kwok u32 tx_excessive_collisions;
34390cff9e2SWingman Kwok u32 tx_late_collisions;
34490cff9e2SWingman Kwok u32 tx_underrun;
34590cff9e2SWingman Kwok u32 tx_carrier_sense_errors;
34690cff9e2SWingman Kwok u32 tx_bytes;
34790cff9e2SWingman Kwok u32 tx_64byte_frames;
34890cff9e2SWingman Kwok u32 tx_65_to_127byte_frames;
34990cff9e2SWingman Kwok u32 tx_128_to_255byte_frames;
35090cff9e2SWingman Kwok u32 tx_256_to_511byte_frames;
35190cff9e2SWingman Kwok u32 tx_512_to_1023byte_frames;
35290cff9e2SWingman Kwok u32 tx_1024byte_frames;
35390cff9e2SWingman Kwok u32 net_bytes;
35490cff9e2SWingman Kwok u32 rx_sof_overruns;
35590cff9e2SWingman Kwok u32 rx_mof_overruns;
35690cff9e2SWingman Kwok u32 rx_dma_overruns;
35790cff9e2SWingman Kwok };
35890cff9e2SWingman Kwok
3599a391c7bSWingMan Kwok struct gbenu_ss_regs {
3609a391c7bSWingMan Kwok u32 id_ver;
3619a391c7bSWingMan Kwok u32 synce_count; /* NU */
3629a391c7bSWingMan Kwok u32 synce_mux; /* NU */
3639a391c7bSWingMan Kwok u32 control; /* 2U */
3649a391c7bSWingMan Kwok u32 __rsvd_0[2]; /* 2U */
3659a391c7bSWingMan Kwok u32 rgmii_status; /* 2U */
3669a391c7bSWingMan Kwok u32 ss_status; /* 2U */
3679a391c7bSWingMan Kwok };
3689a391c7bSWingMan Kwok
3699a391c7bSWingMan Kwok struct gbenu_switch_regs {
3709a391c7bSWingMan Kwok u32 id_ver;
3719a391c7bSWingMan Kwok u32 control;
3729a391c7bSWingMan Kwok u32 __rsvd_0[2];
3739a391c7bSWingMan Kwok u32 emcontrol;
3749a391c7bSWingMan Kwok u32 stat_port_en;
3759a391c7bSWingMan Kwok u32 ptype; /* NU */
3769a391c7bSWingMan Kwok u32 soft_idle;
3779a391c7bSWingMan Kwok u32 thru_rate; /* NU */
3789a391c7bSWingMan Kwok u32 gap_thresh; /* NU */
3799a391c7bSWingMan Kwok u32 tx_start_wds; /* NU */
3809a391c7bSWingMan Kwok u32 eee_prescale; /* 2U */
3819a391c7bSWingMan Kwok u32 tx_g_oflow_thresh_set; /* NU */
3829a391c7bSWingMan Kwok u32 tx_g_oflow_thresh_clr; /* NU */
3839a391c7bSWingMan Kwok u32 tx_g_buf_thresh_set_l; /* NU */
3849a391c7bSWingMan Kwok u32 tx_g_buf_thresh_set_h; /* NU */
3859a391c7bSWingMan Kwok u32 tx_g_buf_thresh_clr_l; /* NU */
3869a391c7bSWingMan Kwok u32 tx_g_buf_thresh_clr_h; /* NU */
3879a391c7bSWingMan Kwok };
3889a391c7bSWingMan Kwok
3899a391c7bSWingMan Kwok struct gbenu_port_regs {
3909a391c7bSWingMan Kwok u32 __rsvd_0;
3919a391c7bSWingMan Kwok u32 control;
3929a391c7bSWingMan Kwok u32 max_blks; /* 2U */
3939a391c7bSWingMan Kwok u32 mem_align1;
3949a391c7bSWingMan Kwok u32 blk_cnt;
3959a391c7bSWingMan Kwok u32 port_vlan;
3969a391c7bSWingMan Kwok u32 tx_pri_map; /* NU */
3979a391c7bSWingMan Kwok u32 pri_ctl; /* 2U */
3989a391c7bSWingMan Kwok u32 rx_pri_map;
3999a391c7bSWingMan Kwok u32 rx_maxlen;
4009a391c7bSWingMan Kwok u32 tx_blks_pri; /* NU */
4019a391c7bSWingMan Kwok u32 __rsvd_1;
4029a391c7bSWingMan Kwok u32 idle2lpi; /* 2U */
4039a391c7bSWingMan Kwok u32 lpi2idle; /* 2U */
4049a391c7bSWingMan Kwok u32 eee_status; /* 2U */
4059a391c7bSWingMan Kwok u32 __rsvd_2;
4069a391c7bSWingMan Kwok u32 __rsvd_3[176]; /* NU: more to add */
4079a391c7bSWingMan Kwok u32 __rsvd_4[2];
4089a391c7bSWingMan Kwok u32 sa_lo;
4099a391c7bSWingMan Kwok u32 sa_hi;
4109a391c7bSWingMan Kwok u32 ts_ctl;
4119a391c7bSWingMan Kwok u32 ts_seq_ltype;
4129a391c7bSWingMan Kwok u32 ts_vlan;
4139a391c7bSWingMan Kwok u32 ts_ctl_ltype2;
4149a391c7bSWingMan Kwok u32 ts_ctl2;
4159a391c7bSWingMan Kwok };
4169a391c7bSWingMan Kwok
4179a391c7bSWingMan Kwok struct gbenu_host_port_regs {
4189a391c7bSWingMan Kwok u32 __rsvd_0;
4199a391c7bSWingMan Kwok u32 control;
4209a391c7bSWingMan Kwok u32 flow_id_offset; /* 2U */
4219a391c7bSWingMan Kwok u32 __rsvd_1;
4229a391c7bSWingMan Kwok u32 blk_cnt;
4239a391c7bSWingMan Kwok u32 port_vlan;
4249a391c7bSWingMan Kwok u32 tx_pri_map; /* NU */
4259a391c7bSWingMan Kwok u32 pri_ctl;
4269a391c7bSWingMan Kwok u32 rx_pri_map;
4279a391c7bSWingMan Kwok u32 rx_maxlen;
4289a391c7bSWingMan Kwok u32 tx_blks_pri; /* NU */
4299a391c7bSWingMan Kwok u32 __rsvd_2;
4309a391c7bSWingMan Kwok u32 idle2lpi; /* 2U */
4319a391c7bSWingMan Kwok u32 lpi2wake; /* 2U */
4329a391c7bSWingMan Kwok u32 eee_status; /* 2U */
4339a391c7bSWingMan Kwok u32 __rsvd_3;
4349a391c7bSWingMan Kwok u32 __rsvd_4[184]; /* NU */
4359a391c7bSWingMan Kwok u32 host_blks_pri; /* NU */
4369a391c7bSWingMan Kwok };
4379a391c7bSWingMan Kwok
4389a391c7bSWingMan Kwok struct gbenu_emac_regs {
4399a391c7bSWingMan Kwok u32 mac_control;
4409a391c7bSWingMan Kwok u32 mac_status;
4419a391c7bSWingMan Kwok u32 soft_reset;
4429a391c7bSWingMan Kwok u32 boff_test;
4439a391c7bSWingMan Kwok u32 rx_pause;
4449a391c7bSWingMan Kwok u32 __rsvd_0[11]; /* NU */
4459a391c7bSWingMan Kwok u32 tx_pause;
4469a391c7bSWingMan Kwok u32 __rsvd_1[11]; /* NU */
4479a391c7bSWingMan Kwok u32 em_control;
4489a391c7bSWingMan Kwok u32 tx_gap;
4499a391c7bSWingMan Kwok };
4509a391c7bSWingMan Kwok
4519a391c7bSWingMan Kwok /* Some hw stat regs are applicable to slave port only.
4529a391c7bSWingMan Kwok * This is handled by gbenu_et_stats struct. Also some
4539a391c7bSWingMan Kwok * are for SS version NU and some are for 2U.
4549a391c7bSWingMan Kwok */
4559a391c7bSWingMan Kwok struct gbenu_hw_stats {
4569a391c7bSWingMan Kwok u32 rx_good_frames;
4579a391c7bSWingMan Kwok u32 rx_broadcast_frames;
4589a391c7bSWingMan Kwok u32 rx_multicast_frames;
4599a391c7bSWingMan Kwok u32 rx_pause_frames; /* slave */
4609a391c7bSWingMan Kwok u32 rx_crc_errors;
4619a391c7bSWingMan Kwok u32 rx_align_code_errors; /* slave */
4629a391c7bSWingMan Kwok u32 rx_oversized_frames;
4639a391c7bSWingMan Kwok u32 rx_jabber_frames; /* slave */
4649a391c7bSWingMan Kwok u32 rx_undersized_frames;
4659a391c7bSWingMan Kwok u32 rx_fragments; /* slave */
4669a391c7bSWingMan Kwok u32 ale_drop;
4679a391c7bSWingMan Kwok u32 ale_overrun_drop;
4689a391c7bSWingMan Kwok u32 rx_bytes;
4699a391c7bSWingMan Kwok u32 tx_good_frames;
4709a391c7bSWingMan Kwok u32 tx_broadcast_frames;
4719a391c7bSWingMan Kwok u32 tx_multicast_frames;
4729a391c7bSWingMan Kwok u32 tx_pause_frames; /* slave */
4739a391c7bSWingMan Kwok u32 tx_deferred_frames; /* slave */
4749a391c7bSWingMan Kwok u32 tx_collision_frames; /* slave */
4759a391c7bSWingMan Kwok u32 tx_single_coll_frames; /* slave */
4769a391c7bSWingMan Kwok u32 tx_mult_coll_frames; /* slave */
4779a391c7bSWingMan Kwok u32 tx_excessive_collisions; /* slave */
4789a391c7bSWingMan Kwok u32 tx_late_collisions; /* slave */
4799a391c7bSWingMan Kwok u32 rx_ipg_error; /* slave 10G only */
4809a391c7bSWingMan Kwok u32 tx_carrier_sense_errors; /* slave */
4819a391c7bSWingMan Kwok u32 tx_bytes;
4829a391c7bSWingMan Kwok u32 tx_64B_frames;
4839a391c7bSWingMan Kwok u32 tx_65_to_127B_frames;
4849a391c7bSWingMan Kwok u32 tx_128_to_255B_frames;
4859a391c7bSWingMan Kwok u32 tx_256_to_511B_frames;
4869a391c7bSWingMan Kwok u32 tx_512_to_1023B_frames;
4879a391c7bSWingMan Kwok u32 tx_1024B_frames;
4889a391c7bSWingMan Kwok u32 net_bytes;
4899a391c7bSWingMan Kwok u32 rx_bottom_fifo_drop;
4909a391c7bSWingMan Kwok u32 rx_port_mask_drop;
4919a391c7bSWingMan Kwok u32 rx_top_fifo_drop;
4929a391c7bSWingMan Kwok u32 ale_rate_limit_drop;
4939a391c7bSWingMan Kwok u32 ale_vid_ingress_drop;
4949a391c7bSWingMan Kwok u32 ale_da_eq_sa_drop;
4959a391c7bSWingMan Kwok u32 __rsvd_0[3];
4969a391c7bSWingMan Kwok u32 ale_unknown_ucast;
4979a391c7bSWingMan Kwok u32 ale_unknown_ucast_bytes;
4989a391c7bSWingMan Kwok u32 ale_unknown_mcast;
4999a391c7bSWingMan Kwok u32 ale_unknown_mcast_bytes;
5009a391c7bSWingMan Kwok u32 ale_unknown_bcast;
5019a391c7bSWingMan Kwok u32 ale_unknown_bcast_bytes;
5029a391c7bSWingMan Kwok u32 ale_pol_match;
5039a391c7bSWingMan Kwok u32 ale_pol_match_red; /* NU */
5049a391c7bSWingMan Kwok u32 ale_pol_match_yellow; /* NU */
5059a391c7bSWingMan Kwok u32 __rsvd_1[44];
5069a391c7bSWingMan Kwok u32 tx_mem_protect_err;
5079a391c7bSWingMan Kwok /* following NU only */
5089a391c7bSWingMan Kwok u32 tx_pri0;
5099a391c7bSWingMan Kwok u32 tx_pri1;
5109a391c7bSWingMan Kwok u32 tx_pri2;
5119a391c7bSWingMan Kwok u32 tx_pri3;
5129a391c7bSWingMan Kwok u32 tx_pri4;
5139a391c7bSWingMan Kwok u32 tx_pri5;
5149a391c7bSWingMan Kwok u32 tx_pri6;
5159a391c7bSWingMan Kwok u32 tx_pri7;
5169a391c7bSWingMan Kwok u32 tx_pri0_bcnt;
5179a391c7bSWingMan Kwok u32 tx_pri1_bcnt;
5189a391c7bSWingMan Kwok u32 tx_pri2_bcnt;
5199a391c7bSWingMan Kwok u32 tx_pri3_bcnt;
5209a391c7bSWingMan Kwok u32 tx_pri4_bcnt;
5219a391c7bSWingMan Kwok u32 tx_pri5_bcnt;
5229a391c7bSWingMan Kwok u32 tx_pri6_bcnt;
5239a391c7bSWingMan Kwok u32 tx_pri7_bcnt;
5249a391c7bSWingMan Kwok u32 tx_pri0_drop;
5259a391c7bSWingMan Kwok u32 tx_pri1_drop;
5269a391c7bSWingMan Kwok u32 tx_pri2_drop;
5279a391c7bSWingMan Kwok u32 tx_pri3_drop;
5289a391c7bSWingMan Kwok u32 tx_pri4_drop;
5299a391c7bSWingMan Kwok u32 tx_pri5_drop;
5309a391c7bSWingMan Kwok u32 tx_pri6_drop;
5319a391c7bSWingMan Kwok u32 tx_pri7_drop;
5329a391c7bSWingMan Kwok u32 tx_pri0_drop_bcnt;
5339a391c7bSWingMan Kwok u32 tx_pri1_drop_bcnt;
5349a391c7bSWingMan Kwok u32 tx_pri2_drop_bcnt;
5359a391c7bSWingMan Kwok u32 tx_pri3_drop_bcnt;
5369a391c7bSWingMan Kwok u32 tx_pri4_drop_bcnt;
5379a391c7bSWingMan Kwok u32 tx_pri5_drop_bcnt;
5389a391c7bSWingMan Kwok u32 tx_pri6_drop_bcnt;
5399a391c7bSWingMan Kwok u32 tx_pri7_drop_bcnt;
5409a391c7bSWingMan Kwok };
5419a391c7bSWingMan Kwok
5429a391c7bSWingMan Kwok #define GBENU_HW_STATS_REG_MAP_SZ 0x200
5439a391c7bSWingMan Kwok
5446f8d3f33SWingman Kwok struct gbe_ss_regs {
5456f8d3f33SWingman Kwok u32 id_ver;
5466f8d3f33SWingman Kwok u32 synce_count;
5476f8d3f33SWingman Kwok u32 synce_mux;
5486f8d3f33SWingman Kwok };
5496f8d3f33SWingman Kwok
5506f8d3f33SWingman Kwok struct gbe_ss_regs_ofs {
5516f8d3f33SWingman Kwok u16 id_ver;
5526f8d3f33SWingman Kwok u16 control;
5537771f2b4SMurali Karicheri u16 rgmii_status; /* 2U */
5546f8d3f33SWingman Kwok };
5556f8d3f33SWingman Kwok
5566f8d3f33SWingman Kwok struct gbe_switch_regs {
5576f8d3f33SWingman Kwok u32 id_ver;
5586f8d3f33SWingman Kwok u32 control;
5596f8d3f33SWingman Kwok u32 soft_reset;
5606f8d3f33SWingman Kwok u32 stat_port_en;
5616f8d3f33SWingman Kwok u32 ptype;
5626f8d3f33SWingman Kwok u32 soft_idle;
5636f8d3f33SWingman Kwok u32 thru_rate;
5646f8d3f33SWingman Kwok u32 gap_thresh;
5656f8d3f33SWingman Kwok u32 tx_start_wds;
5666f8d3f33SWingman Kwok u32 flow_control;
5676f8d3f33SWingman Kwok };
5686f8d3f33SWingman Kwok
5696f8d3f33SWingman Kwok struct gbe_switch_regs_ofs {
5706f8d3f33SWingman Kwok u16 id_ver;
5716f8d3f33SWingman Kwok u16 control;
5726f8d3f33SWingman Kwok u16 soft_reset;
5736f8d3f33SWingman Kwok u16 emcontrol;
5746f8d3f33SWingman Kwok u16 stat_port_en;
5756f8d3f33SWingman Kwok u16 ptype;
5766f8d3f33SWingman Kwok u16 flow_control;
5776f8d3f33SWingman Kwok };
5786f8d3f33SWingman Kwok
5796f8d3f33SWingman Kwok struct gbe_port_regs {
5806f8d3f33SWingman Kwok u32 max_blks;
5816f8d3f33SWingman Kwok u32 blk_cnt;
5826f8d3f33SWingman Kwok u32 port_vlan;
5836f8d3f33SWingman Kwok u32 tx_pri_map;
5846f8d3f33SWingman Kwok u32 sa_lo;
5856f8d3f33SWingman Kwok u32 sa_hi;
5866f8d3f33SWingman Kwok u32 ts_ctl;
5876f8d3f33SWingman Kwok u32 ts_seq_ltype;
5886f8d3f33SWingman Kwok u32 ts_vlan;
5896f8d3f33SWingman Kwok u32 ts_ctl_ltype2;
5906f8d3f33SWingman Kwok u32 ts_ctl2;
5916f8d3f33SWingman Kwok };
5926f8d3f33SWingman Kwok
5936f8d3f33SWingman Kwok struct gbe_port_regs_ofs {
5946f8d3f33SWingman Kwok u16 port_vlan;
5956f8d3f33SWingman Kwok u16 tx_pri_map;
59665c45064SMurali Karicheri u16 rx_pri_map;
5976f8d3f33SWingman Kwok u16 sa_lo;
5986f8d3f33SWingman Kwok u16 sa_hi;
5996f8d3f33SWingman Kwok u16 ts_ctl;
6006f8d3f33SWingman Kwok u16 ts_seq_ltype;
6016f8d3f33SWingman Kwok u16 ts_vlan;
6026f8d3f33SWingman Kwok u16 ts_ctl_ltype2;
6036f8d3f33SWingman Kwok u16 ts_ctl2;
6049a391c7bSWingMan Kwok u16 rx_maxlen; /* 2U, NU */
6056f8d3f33SWingman Kwok };
6066f8d3f33SWingman Kwok
6076f8d3f33SWingman Kwok struct gbe_host_port_regs {
6086f8d3f33SWingman Kwok u32 src_id;
6096f8d3f33SWingman Kwok u32 port_vlan;
6106f8d3f33SWingman Kwok u32 rx_pri_map;
6116f8d3f33SWingman Kwok u32 rx_maxlen;
6126f8d3f33SWingman Kwok };
6136f8d3f33SWingman Kwok
6146f8d3f33SWingman Kwok struct gbe_host_port_regs_ofs {
6156f8d3f33SWingman Kwok u16 port_vlan;
6166f8d3f33SWingman Kwok u16 tx_pri_map;
6176f8d3f33SWingman Kwok u16 rx_maxlen;
6186f8d3f33SWingman Kwok };
6196f8d3f33SWingman Kwok
6206f8d3f33SWingman Kwok struct gbe_emac_regs {
6216f8d3f33SWingman Kwok u32 id_ver;
6226f8d3f33SWingman Kwok u32 mac_control;
6236f8d3f33SWingman Kwok u32 mac_status;
6246f8d3f33SWingman Kwok u32 soft_reset;
6256f8d3f33SWingman Kwok u32 rx_maxlen;
6266f8d3f33SWingman Kwok u32 __reserved_0;
6276f8d3f33SWingman Kwok u32 rx_pause;
6286f8d3f33SWingman Kwok u32 tx_pause;
6296f8d3f33SWingman Kwok u32 __reserved_1;
6306f8d3f33SWingman Kwok u32 rx_pri_map;
6316f8d3f33SWingman Kwok u32 rsvd[6];
6326f8d3f33SWingman Kwok };
6336f8d3f33SWingman Kwok
6346f8d3f33SWingman Kwok struct gbe_emac_regs_ofs {
6356f8d3f33SWingman Kwok u16 mac_control;
6366f8d3f33SWingman Kwok u16 soft_reset;
6376f8d3f33SWingman Kwok u16 rx_maxlen;
6386f8d3f33SWingman Kwok };
6396f8d3f33SWingman Kwok
6406f8d3f33SWingman Kwok struct gbe_hw_stats {
6416f8d3f33SWingman Kwok u32 rx_good_frames;
6426f8d3f33SWingman Kwok u32 rx_broadcast_frames;
6436f8d3f33SWingman Kwok u32 rx_multicast_frames;
6446f8d3f33SWingman Kwok u32 rx_pause_frames;
6456f8d3f33SWingman Kwok u32 rx_crc_errors;
6466f8d3f33SWingman Kwok u32 rx_align_code_errors;
6476f8d3f33SWingman Kwok u32 rx_oversized_frames;
6486f8d3f33SWingman Kwok u32 rx_jabber_frames;
6496f8d3f33SWingman Kwok u32 rx_undersized_frames;
6506f8d3f33SWingman Kwok u32 rx_fragments;
6516f8d3f33SWingman Kwok u32 __pad_0[2];
6526f8d3f33SWingman Kwok u32 rx_bytes;
6536f8d3f33SWingman Kwok u32 tx_good_frames;
6546f8d3f33SWingman Kwok u32 tx_broadcast_frames;
6556f8d3f33SWingman Kwok u32 tx_multicast_frames;
6566f8d3f33SWingman Kwok u32 tx_pause_frames;
6576f8d3f33SWingman Kwok u32 tx_deferred_frames;
6586f8d3f33SWingman Kwok u32 tx_collision_frames;
6596f8d3f33SWingman Kwok u32 tx_single_coll_frames;
6606f8d3f33SWingman Kwok u32 tx_mult_coll_frames;
6616f8d3f33SWingman Kwok u32 tx_excessive_collisions;
6626f8d3f33SWingman Kwok u32 tx_late_collisions;
6636f8d3f33SWingman Kwok u32 tx_underrun;
6646f8d3f33SWingman Kwok u32 tx_carrier_sense_errors;
6656f8d3f33SWingman Kwok u32 tx_bytes;
6666f8d3f33SWingman Kwok u32 tx_64byte_frames;
6676f8d3f33SWingman Kwok u32 tx_65_to_127byte_frames;
6686f8d3f33SWingman Kwok u32 tx_128_to_255byte_frames;
6696f8d3f33SWingman Kwok u32 tx_256_to_511byte_frames;
6706f8d3f33SWingman Kwok u32 tx_512_to_1023byte_frames;
6716f8d3f33SWingman Kwok u32 tx_1024byte_frames;
6726f8d3f33SWingman Kwok u32 net_bytes;
6736f8d3f33SWingman Kwok u32 rx_sof_overruns;
6746f8d3f33SWingman Kwok u32 rx_mof_overruns;
6756f8d3f33SWingman Kwok u32 rx_dma_overruns;
6766f8d3f33SWingman Kwok };
6776f8d3f33SWingman Kwok
6789a391c7bSWingMan Kwok #define GBE_MAX_HW_STAT_MODS 9
6796f8d3f33SWingman Kwok #define GBE_HW_STATS_REG_MAP_SZ 0x100
6806f8d3f33SWingman Kwok
6816246168bSWingMan Kwok struct ts_ctl {
6826246168bSWingMan Kwok int uni;
6836246168bSWingMan Kwok u8 dst_port_map;
6846246168bSWingMan Kwok u8 maddr_map;
6856246168bSWingMan Kwok u8 ts_mcast_type;
6866246168bSWingMan Kwok };
6876246168bSWingMan Kwok
6886f8d3f33SWingman Kwok struct gbe_slave {
6896f8d3f33SWingman Kwok void __iomem *port_regs;
6906f8d3f33SWingman Kwok void __iomem *emac_regs;
6916f8d3f33SWingman Kwok struct gbe_port_regs_ofs port_regs_ofs;
6926f8d3f33SWingman Kwok struct gbe_emac_regs_ofs emac_regs_ofs;
6936f8d3f33SWingman Kwok int slave_num; /* 0 based logical number */
6946f8d3f33SWingman Kwok int port_num; /* actual port number */
6956f8d3f33SWingman Kwok atomic_t link_state;
6966f8d3f33SWingman Kwok bool open;
6976f8d3f33SWingman Kwok struct phy_device *phy;
6986f8d3f33SWingman Kwok u32 link_interface;
6996f8d3f33SWingman Kwok u32 mac_control;
7006f8d3f33SWingman Kwok u8 phy_port_t;
7017b647b93SMurali Karicheri struct device_node *node;
7026f8d3f33SWingman Kwok struct device_node *phy_node;
7036246168bSWingMan Kwok struct ts_ctl ts_ctl;
7046f8d3f33SWingman Kwok struct list_head slave_list;
7056f8d3f33SWingman Kwok };
7066f8d3f33SWingman Kwok
7076f8d3f33SWingman Kwok struct gbe_priv {
7086f8d3f33SWingman Kwok struct device *dev;
7096f8d3f33SWingman Kwok struct netcp_device *netcp_device;
7106f8d3f33SWingman Kwok struct timer_list timer;
7116f8d3f33SWingman Kwok u32 num_slaves;
7126f8d3f33SWingman Kwok u32 ale_ports;
7136f8d3f33SWingman Kwok bool enable_ale;
7149a391c7bSWingMan Kwok u8 max_num_slaves;
7159a391c7bSWingMan Kwok u8 max_num_ports; /* max_num_slaves + 1 */
716489e8a2fSWingMan Kwok u8 num_stats_mods;
7176f8d3f33SWingman Kwok struct netcp_tx_pipe tx_pipe;
7186f8d3f33SWingman Kwok
7196f8d3f33SWingman Kwok int host_port;
7206f8d3f33SWingman Kwok u32 rx_packet_max;
7216f8d3f33SWingman Kwok u32 ss_version;
7229a391c7bSWingMan Kwok u32 stats_en_mask;
7236f8d3f33SWingman Kwok
7246f8d3f33SWingman Kwok void __iomem *ss_regs;
7256f8d3f33SWingman Kwok void __iomem *switch_regs;
7266f8d3f33SWingman Kwok void __iomem *host_port_regs;
7276f8d3f33SWingman Kwok void __iomem *ale_reg;
7286246168bSWingMan Kwok void __iomem *cpts_reg;
7296f8d3f33SWingman Kwok void __iomem *sgmii_port_regs;
7306f8d3f33SWingman Kwok void __iomem *sgmii_port34_regs;
7316f8d3f33SWingman Kwok void __iomem *xgbe_serdes_regs;
7326f8d3f33SWingman Kwok void __iomem *hw_stats_regs[GBE_MAX_HW_STAT_MODS];
7336f8d3f33SWingman Kwok
7346f8d3f33SWingman Kwok struct gbe_ss_regs_ofs ss_regs_ofs;
7356f8d3f33SWingman Kwok struct gbe_switch_regs_ofs switch_regs_ofs;
7366f8d3f33SWingman Kwok struct gbe_host_port_regs_ofs host_port_regs_ofs;
7376f8d3f33SWingman Kwok
7386f8d3f33SWingman Kwok struct cpsw_ale *ale;
7396f8d3f33SWingman Kwok unsigned int tx_queue_id;
7406f8d3f33SWingman Kwok const char *dma_chan_name;
7416f8d3f33SWingman Kwok
7426f8d3f33SWingman Kwok struct list_head gbe_intf_head;
7436f8d3f33SWingman Kwok struct list_head secondary_slaves;
7446f8d3f33SWingman Kwok struct net_device *dummy_ndev;
7456f8d3f33SWingman Kwok
7466f8d3f33SWingman Kwok u64 *hw_stats;
747489e8a2fSWingMan Kwok u32 *hw_stats_prev;
7486f8d3f33SWingman Kwok const struct netcp_ethtool_stat *et_stats;
7496f8d3f33SWingman Kwok int num_et_stats;
7506f8d3f33SWingman Kwok /* Lock for updating the hwstats */
7516f8d3f33SWingman Kwok spinlock_t hw_stats_lock;
7526246168bSWingMan Kwok
7536246168bSWingMan Kwok int cpts_registered;
7546246168bSWingMan Kwok struct cpts *cpts;
755a9423120SIvan Khoronzhuk int rx_ts_enabled;
756a9423120SIvan Khoronzhuk int tx_ts_enabled;
7576f8d3f33SWingman Kwok };
7586f8d3f33SWingman Kwok
7596f8d3f33SWingman Kwok struct gbe_intf {
7606f8d3f33SWingman Kwok struct net_device *ndev;
7616f8d3f33SWingman Kwok struct device *dev;
7626f8d3f33SWingman Kwok struct gbe_priv *gbe_dev;
7636f8d3f33SWingman Kwok struct netcp_tx_pipe tx_pipe;
7646f8d3f33SWingman Kwok struct gbe_slave *slave;
7656f8d3f33SWingman Kwok struct list_head gbe_intf_list;
7666f8d3f33SWingman Kwok unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
7676f8d3f33SWingman Kwok };
7686f8d3f33SWingman Kwok
7696f8d3f33SWingman Kwok static struct netcp_module gbe_module;
77090cff9e2SWingman Kwok static struct netcp_module xgbe_module;
7716f8d3f33SWingman Kwok
7726f8d3f33SWingman Kwok /* Statistic management */
7736f8d3f33SWingman Kwok struct netcp_ethtool_stat {
7746f8d3f33SWingman Kwok char desc[ETH_GSTRING_LEN];
7756f8d3f33SWingman Kwok int type;
7766f8d3f33SWingman Kwok u32 size;
7776f8d3f33SWingman Kwok int offset;
7786f8d3f33SWingman Kwok };
7796f8d3f33SWingman Kwok
780da866ba0SKaricheri, Muralidharan #define GBE_STATSA_INFO(field) \
781da866ba0SKaricheri, Muralidharan { \
782da866ba0SKaricheri, Muralidharan "GBE_A:"#field, GBE_STATSA_MODULE, \
783c593642cSPankaj Bharadiya sizeof_field(struct gbe_hw_stats, field), \
784da866ba0SKaricheri, Muralidharan offsetof(struct gbe_hw_stats, field) \
785da866ba0SKaricheri, Muralidharan }
7866f8d3f33SWingman Kwok
787da866ba0SKaricheri, Muralidharan #define GBE_STATSB_INFO(field) \
788da866ba0SKaricheri, Muralidharan { \
789da866ba0SKaricheri, Muralidharan "GBE_B:"#field, GBE_STATSB_MODULE, \
790c593642cSPankaj Bharadiya sizeof_field(struct gbe_hw_stats, field), \
791da866ba0SKaricheri, Muralidharan offsetof(struct gbe_hw_stats, field) \
792da866ba0SKaricheri, Muralidharan }
7936f8d3f33SWingman Kwok
794da866ba0SKaricheri, Muralidharan #define GBE_STATSC_INFO(field) \
795da866ba0SKaricheri, Muralidharan { \
796da866ba0SKaricheri, Muralidharan "GBE_C:"#field, GBE_STATSC_MODULE, \
797c593642cSPankaj Bharadiya sizeof_field(struct gbe_hw_stats, field), \
798da866ba0SKaricheri, Muralidharan offsetof(struct gbe_hw_stats, field) \
799da866ba0SKaricheri, Muralidharan }
8006f8d3f33SWingman Kwok
801da866ba0SKaricheri, Muralidharan #define GBE_STATSD_INFO(field) \
802da866ba0SKaricheri, Muralidharan { \
803da866ba0SKaricheri, Muralidharan "GBE_D:"#field, GBE_STATSD_MODULE, \
804c593642cSPankaj Bharadiya sizeof_field(struct gbe_hw_stats, field), \
805da866ba0SKaricheri, Muralidharan offsetof(struct gbe_hw_stats, field) \
806da866ba0SKaricheri, Muralidharan }
8076f8d3f33SWingman Kwok
8086f8d3f33SWingman Kwok static const struct netcp_ethtool_stat gbe13_et_stats[] = {
8096f8d3f33SWingman Kwok /* GBE module A */
810da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_good_frames),
811da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_broadcast_frames),
812da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_multicast_frames),
813da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_pause_frames),
814da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_crc_errors),
815da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_align_code_errors),
816da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_oversized_frames),
817da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_jabber_frames),
818da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_undersized_frames),
819da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_fragments),
820da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_bytes),
821da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_good_frames),
822da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_broadcast_frames),
823da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_multicast_frames),
824da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_pause_frames),
825da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_deferred_frames),
826da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_collision_frames),
827da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_single_coll_frames),
828da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_mult_coll_frames),
829da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_excessive_collisions),
830da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_late_collisions),
831da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_underrun),
832da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_carrier_sense_errors),
833da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_bytes),
834da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_64byte_frames),
835da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_65_to_127byte_frames),
836da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_128_to_255byte_frames),
837da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_256_to_511byte_frames),
838da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_512_to_1023byte_frames),
839da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(tx_1024byte_frames),
840da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(net_bytes),
841da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_sof_overruns),
842da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_mof_overruns),
843da866ba0SKaricheri, Muralidharan GBE_STATSA_INFO(rx_dma_overruns),
8446f8d3f33SWingman Kwok /* GBE module B */
845da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_good_frames),
846da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_broadcast_frames),
847da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_multicast_frames),
848da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_pause_frames),
849da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_crc_errors),
850da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_align_code_errors),
851da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_oversized_frames),
852da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_jabber_frames),
853da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_undersized_frames),
854da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_fragments),
855da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_bytes),
856da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_good_frames),
857da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_broadcast_frames),
858da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_multicast_frames),
859da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_pause_frames),
860da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_deferred_frames),
861da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_collision_frames),
862da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_single_coll_frames),
863da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_mult_coll_frames),
864da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_excessive_collisions),
865da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_late_collisions),
866da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_underrun),
867da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_carrier_sense_errors),
868da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_bytes),
869da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_64byte_frames),
870da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_65_to_127byte_frames),
871da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_128_to_255byte_frames),
872da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_256_to_511byte_frames),
873da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_512_to_1023byte_frames),
874da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(tx_1024byte_frames),
875da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(net_bytes),
876da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_sof_overruns),
877da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_mof_overruns),
878da866ba0SKaricheri, Muralidharan GBE_STATSB_INFO(rx_dma_overruns),
8796f8d3f33SWingman Kwok /* GBE module C */
880da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_good_frames),
881da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_broadcast_frames),
882da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_multicast_frames),
883da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_pause_frames),
884da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_crc_errors),
885da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_align_code_errors),
886da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_oversized_frames),
887da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_jabber_frames),
888da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_undersized_frames),
889da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_fragments),
890da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_bytes),
891da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_good_frames),
892da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_broadcast_frames),
893da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_multicast_frames),
894da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_pause_frames),
895da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_deferred_frames),
896da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_collision_frames),
897da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_single_coll_frames),
898da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_mult_coll_frames),
899da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_excessive_collisions),
900da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_late_collisions),
901da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_underrun),
902da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_carrier_sense_errors),
903da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_bytes),
904da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_64byte_frames),
905da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_65_to_127byte_frames),
906da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_128_to_255byte_frames),
907da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_256_to_511byte_frames),
908da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_512_to_1023byte_frames),
909da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(tx_1024byte_frames),
910da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(net_bytes),
911da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_sof_overruns),
912da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_mof_overruns),
913da866ba0SKaricheri, Muralidharan GBE_STATSC_INFO(rx_dma_overruns),
9146f8d3f33SWingman Kwok /* GBE module D */
915da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_good_frames),
916da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_broadcast_frames),
917da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_multicast_frames),
918da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_pause_frames),
919da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_crc_errors),
920da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_align_code_errors),
921da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_oversized_frames),
922da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_jabber_frames),
923da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_undersized_frames),
924da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_fragments),
925da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_bytes),
926da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_good_frames),
927da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_broadcast_frames),
928da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_multicast_frames),
929da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_pause_frames),
930da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_deferred_frames),
931da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_collision_frames),
932da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_single_coll_frames),
933da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_mult_coll_frames),
934da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_excessive_collisions),
935da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_late_collisions),
936da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_underrun),
937da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_carrier_sense_errors),
938da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_bytes),
939da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_64byte_frames),
940da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_65_to_127byte_frames),
941da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_128_to_255byte_frames),
942da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_256_to_511byte_frames),
943da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_512_to_1023byte_frames),
944da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(tx_1024byte_frames),
945da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(net_bytes),
946da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_sof_overruns),
947da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_mof_overruns),
948da866ba0SKaricheri, Muralidharan GBE_STATSD_INFO(rx_dma_overruns),
9496f8d3f33SWingman Kwok };
9506f8d3f33SWingman Kwok
9519a391c7bSWingMan Kwok /* This is the size of entries in GBENU_STATS_HOST */
9525be4001eSWingMan Kwok #define GBENU_ET_STATS_HOST_SIZE 52
9539a391c7bSWingMan Kwok
9549a391c7bSWingMan Kwok #define GBENU_STATS_HOST(field) \
9559a391c7bSWingMan Kwok { \
9569a391c7bSWingMan Kwok "GBE_HOST:"#field, GBENU_STATS0_MODULE, \
957c593642cSPankaj Bharadiya sizeof_field(struct gbenu_hw_stats, field), \
9589a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \
9599a391c7bSWingMan Kwok }
9609a391c7bSWingMan Kwok
9615be4001eSWingMan Kwok /* This is the size of entries in GBENU_STATS_PORT */
9625be4001eSWingMan Kwok #define GBENU_ET_STATS_PORT_SIZE 65
9639a391c7bSWingMan Kwok
9649a391c7bSWingMan Kwok #define GBENU_STATS_P1(field) \
9659a391c7bSWingMan Kwok { \
9669a391c7bSWingMan Kwok "GBE_P1:"#field, GBENU_STATS1_MODULE, \
967c593642cSPankaj Bharadiya sizeof_field(struct gbenu_hw_stats, field), \
9689a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \
9699a391c7bSWingMan Kwok }
9709a391c7bSWingMan Kwok
9719a391c7bSWingMan Kwok #define GBENU_STATS_P2(field) \
9729a391c7bSWingMan Kwok { \
9739a391c7bSWingMan Kwok "GBE_P2:"#field, GBENU_STATS2_MODULE, \
974c593642cSPankaj Bharadiya sizeof_field(struct gbenu_hw_stats, field), \
9759a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \
9769a391c7bSWingMan Kwok }
9779a391c7bSWingMan Kwok
9789a391c7bSWingMan Kwok #define GBENU_STATS_P3(field) \
9799a391c7bSWingMan Kwok { \
9809a391c7bSWingMan Kwok "GBE_P3:"#field, GBENU_STATS3_MODULE, \
981c593642cSPankaj Bharadiya sizeof_field(struct gbenu_hw_stats, field), \
9829a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \
9839a391c7bSWingMan Kwok }
9849a391c7bSWingMan Kwok
9859a391c7bSWingMan Kwok #define GBENU_STATS_P4(field) \
9869a391c7bSWingMan Kwok { \
9879a391c7bSWingMan Kwok "GBE_P4:"#field, GBENU_STATS4_MODULE, \
988c593642cSPankaj Bharadiya sizeof_field(struct gbenu_hw_stats, field), \
9899a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \
9909a391c7bSWingMan Kwok }
9919a391c7bSWingMan Kwok
9929a391c7bSWingMan Kwok #define GBENU_STATS_P5(field) \
9939a391c7bSWingMan Kwok { \
9949a391c7bSWingMan Kwok "GBE_P5:"#field, GBENU_STATS5_MODULE, \
995c593642cSPankaj Bharadiya sizeof_field(struct gbenu_hw_stats, field), \
9969a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \
9979a391c7bSWingMan Kwok }
9989a391c7bSWingMan Kwok
9999a391c7bSWingMan Kwok #define GBENU_STATS_P6(field) \
10009a391c7bSWingMan Kwok { \
10019a391c7bSWingMan Kwok "GBE_P6:"#field, GBENU_STATS6_MODULE, \
1002c593642cSPankaj Bharadiya sizeof_field(struct gbenu_hw_stats, field), \
10039a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \
10049a391c7bSWingMan Kwok }
10059a391c7bSWingMan Kwok
10069a391c7bSWingMan Kwok #define GBENU_STATS_P7(field) \
10079a391c7bSWingMan Kwok { \
10089a391c7bSWingMan Kwok "GBE_P7:"#field, GBENU_STATS7_MODULE, \
1009c593642cSPankaj Bharadiya sizeof_field(struct gbenu_hw_stats, field), \
10109a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \
10119a391c7bSWingMan Kwok }
10129a391c7bSWingMan Kwok
10139a391c7bSWingMan Kwok #define GBENU_STATS_P8(field) \
10149a391c7bSWingMan Kwok { \
10159a391c7bSWingMan Kwok "GBE_P8:"#field, GBENU_STATS8_MODULE, \
1016c593642cSPankaj Bharadiya sizeof_field(struct gbenu_hw_stats, field), \
10179a391c7bSWingMan Kwok offsetof(struct gbenu_hw_stats, field) \
10189a391c7bSWingMan Kwok }
10199a391c7bSWingMan Kwok
10209a391c7bSWingMan Kwok static const struct netcp_ethtool_stat gbenu_et_stats[] = {
10219a391c7bSWingMan Kwok /* GBENU Host Module */
10229a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_good_frames),
10239a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_broadcast_frames),
10249a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_multicast_frames),
10259a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_crc_errors),
10269a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_oversized_frames),
10279a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_undersized_frames),
10289a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_drop),
10299a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_overrun_drop),
10309a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_bytes),
10319a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_good_frames),
10329a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_broadcast_frames),
10339a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_multicast_frames),
10349a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_bytes),
10359a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_64B_frames),
10369a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_65_to_127B_frames),
10379a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_128_to_255B_frames),
10389a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_256_to_511B_frames),
10399a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_512_to_1023B_frames),
10409a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_1024B_frames),
10419a391c7bSWingMan Kwok GBENU_STATS_HOST(net_bytes),
10429a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_bottom_fifo_drop),
10439a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_port_mask_drop),
10449a391c7bSWingMan Kwok GBENU_STATS_HOST(rx_top_fifo_drop),
10459a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_rate_limit_drop),
10469a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_vid_ingress_drop),
10479a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_da_eq_sa_drop),
10489a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_unknown_ucast),
10499a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_unknown_ucast_bytes),
10509a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_unknown_mcast),
10519a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_unknown_mcast_bytes),
10529a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_unknown_bcast),
10539a391c7bSWingMan Kwok GBENU_STATS_HOST(ale_unknown_bcast_bytes),
10545be4001eSWingMan Kwok GBENU_STATS_HOST(ale_pol_match),
10555be4001eSWingMan Kwok GBENU_STATS_HOST(ale_pol_match_red),
10565be4001eSWingMan Kwok GBENU_STATS_HOST(ale_pol_match_yellow),
10579a391c7bSWingMan Kwok GBENU_STATS_HOST(tx_mem_protect_err),
10585be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri0_drop),
10595be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri1_drop),
10605be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri2_drop),
10615be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri3_drop),
10625be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri4_drop),
10635be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri5_drop),
10645be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri6_drop),
10655be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri7_drop),
10665be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri0_drop_bcnt),
10675be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri1_drop_bcnt),
10685be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri2_drop_bcnt),
10695be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri3_drop_bcnt),
10705be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri4_drop_bcnt),
10715be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri5_drop_bcnt),
10725be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri6_drop_bcnt),
10735be4001eSWingMan Kwok GBENU_STATS_HOST(tx_pri7_drop_bcnt),
10749a391c7bSWingMan Kwok /* GBENU Module 1 */
10759a391c7bSWingMan Kwok GBENU_STATS_P1(rx_good_frames),
10769a391c7bSWingMan Kwok GBENU_STATS_P1(rx_broadcast_frames),
10779a391c7bSWingMan Kwok GBENU_STATS_P1(rx_multicast_frames),
10789a391c7bSWingMan Kwok GBENU_STATS_P1(rx_pause_frames),
10799a391c7bSWingMan Kwok GBENU_STATS_P1(rx_crc_errors),
10809a391c7bSWingMan Kwok GBENU_STATS_P1(rx_align_code_errors),
10819a391c7bSWingMan Kwok GBENU_STATS_P1(rx_oversized_frames),
10829a391c7bSWingMan Kwok GBENU_STATS_P1(rx_jabber_frames),
10839a391c7bSWingMan Kwok GBENU_STATS_P1(rx_undersized_frames),
10849a391c7bSWingMan Kwok GBENU_STATS_P1(rx_fragments),
10859a391c7bSWingMan Kwok GBENU_STATS_P1(ale_drop),
10869a391c7bSWingMan Kwok GBENU_STATS_P1(ale_overrun_drop),
10879a391c7bSWingMan Kwok GBENU_STATS_P1(rx_bytes),
10889a391c7bSWingMan Kwok GBENU_STATS_P1(tx_good_frames),
10899a391c7bSWingMan Kwok GBENU_STATS_P1(tx_broadcast_frames),
10909a391c7bSWingMan Kwok GBENU_STATS_P1(tx_multicast_frames),
10919a391c7bSWingMan Kwok GBENU_STATS_P1(tx_pause_frames),
10929a391c7bSWingMan Kwok GBENU_STATS_P1(tx_deferred_frames),
10939a391c7bSWingMan Kwok GBENU_STATS_P1(tx_collision_frames),
10949a391c7bSWingMan Kwok GBENU_STATS_P1(tx_single_coll_frames),
10959a391c7bSWingMan Kwok GBENU_STATS_P1(tx_mult_coll_frames),
10969a391c7bSWingMan Kwok GBENU_STATS_P1(tx_excessive_collisions),
10979a391c7bSWingMan Kwok GBENU_STATS_P1(tx_late_collisions),
10989a391c7bSWingMan Kwok GBENU_STATS_P1(rx_ipg_error),
10999a391c7bSWingMan Kwok GBENU_STATS_P1(tx_carrier_sense_errors),
11009a391c7bSWingMan Kwok GBENU_STATS_P1(tx_bytes),
11019a391c7bSWingMan Kwok GBENU_STATS_P1(tx_64B_frames),
11029a391c7bSWingMan Kwok GBENU_STATS_P1(tx_65_to_127B_frames),
11039a391c7bSWingMan Kwok GBENU_STATS_P1(tx_128_to_255B_frames),
11049a391c7bSWingMan Kwok GBENU_STATS_P1(tx_256_to_511B_frames),
11059a391c7bSWingMan Kwok GBENU_STATS_P1(tx_512_to_1023B_frames),
11069a391c7bSWingMan Kwok GBENU_STATS_P1(tx_1024B_frames),
11079a391c7bSWingMan Kwok GBENU_STATS_P1(net_bytes),
11089a391c7bSWingMan Kwok GBENU_STATS_P1(rx_bottom_fifo_drop),
11099a391c7bSWingMan Kwok GBENU_STATS_P1(rx_port_mask_drop),
11109a391c7bSWingMan Kwok GBENU_STATS_P1(rx_top_fifo_drop),
11119a391c7bSWingMan Kwok GBENU_STATS_P1(ale_rate_limit_drop),
11129a391c7bSWingMan Kwok GBENU_STATS_P1(ale_vid_ingress_drop),
11139a391c7bSWingMan Kwok GBENU_STATS_P1(ale_da_eq_sa_drop),
11149a391c7bSWingMan Kwok GBENU_STATS_P1(ale_unknown_ucast),
11159a391c7bSWingMan Kwok GBENU_STATS_P1(ale_unknown_ucast_bytes),
11169a391c7bSWingMan Kwok GBENU_STATS_P1(ale_unknown_mcast),
11179a391c7bSWingMan Kwok GBENU_STATS_P1(ale_unknown_mcast_bytes),
11189a391c7bSWingMan Kwok GBENU_STATS_P1(ale_unknown_bcast),
11199a391c7bSWingMan Kwok GBENU_STATS_P1(ale_unknown_bcast_bytes),
11205be4001eSWingMan Kwok GBENU_STATS_P1(ale_pol_match),
11215be4001eSWingMan Kwok GBENU_STATS_P1(ale_pol_match_red),
11225be4001eSWingMan Kwok GBENU_STATS_P1(ale_pol_match_yellow),
11239a391c7bSWingMan Kwok GBENU_STATS_P1(tx_mem_protect_err),
11245be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri0_drop),
11255be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri1_drop),
11265be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri2_drop),
11275be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri3_drop),
11285be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri4_drop),
11295be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri5_drop),
11305be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri6_drop),
11315be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri7_drop),
11325be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri0_drop_bcnt),
11335be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri1_drop_bcnt),
11345be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri2_drop_bcnt),
11355be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri3_drop_bcnt),
11365be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri4_drop_bcnt),
11375be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri5_drop_bcnt),
11385be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri6_drop_bcnt),
11395be4001eSWingMan Kwok GBENU_STATS_P1(tx_pri7_drop_bcnt),
11409a391c7bSWingMan Kwok /* GBENU Module 2 */
11419a391c7bSWingMan Kwok GBENU_STATS_P2(rx_good_frames),
11429a391c7bSWingMan Kwok GBENU_STATS_P2(rx_broadcast_frames),
11439a391c7bSWingMan Kwok GBENU_STATS_P2(rx_multicast_frames),
11449a391c7bSWingMan Kwok GBENU_STATS_P2(rx_pause_frames),
11459a391c7bSWingMan Kwok GBENU_STATS_P2(rx_crc_errors),
11469a391c7bSWingMan Kwok GBENU_STATS_P2(rx_align_code_errors),
11479a391c7bSWingMan Kwok GBENU_STATS_P2(rx_oversized_frames),
11489a391c7bSWingMan Kwok GBENU_STATS_P2(rx_jabber_frames),
11499a391c7bSWingMan Kwok GBENU_STATS_P2(rx_undersized_frames),
11509a391c7bSWingMan Kwok GBENU_STATS_P2(rx_fragments),
11519a391c7bSWingMan Kwok GBENU_STATS_P2(ale_drop),
11529a391c7bSWingMan Kwok GBENU_STATS_P2(ale_overrun_drop),
11539a391c7bSWingMan Kwok GBENU_STATS_P2(rx_bytes),
11549a391c7bSWingMan Kwok GBENU_STATS_P2(tx_good_frames),
11559a391c7bSWingMan Kwok GBENU_STATS_P2(tx_broadcast_frames),
11569a391c7bSWingMan Kwok GBENU_STATS_P2(tx_multicast_frames),
11579a391c7bSWingMan Kwok GBENU_STATS_P2(tx_pause_frames),
11589a391c7bSWingMan Kwok GBENU_STATS_P2(tx_deferred_frames),
11599a391c7bSWingMan Kwok GBENU_STATS_P2(tx_collision_frames),
11609a391c7bSWingMan Kwok GBENU_STATS_P2(tx_single_coll_frames),
11619a391c7bSWingMan Kwok GBENU_STATS_P2(tx_mult_coll_frames),
11629a391c7bSWingMan Kwok GBENU_STATS_P2(tx_excessive_collisions),
11639a391c7bSWingMan Kwok GBENU_STATS_P2(tx_late_collisions),
11649a391c7bSWingMan Kwok GBENU_STATS_P2(rx_ipg_error),
11659a391c7bSWingMan Kwok GBENU_STATS_P2(tx_carrier_sense_errors),
11669a391c7bSWingMan Kwok GBENU_STATS_P2(tx_bytes),
11679a391c7bSWingMan Kwok GBENU_STATS_P2(tx_64B_frames),
11689a391c7bSWingMan Kwok GBENU_STATS_P2(tx_65_to_127B_frames),
11699a391c7bSWingMan Kwok GBENU_STATS_P2(tx_128_to_255B_frames),
11709a391c7bSWingMan Kwok GBENU_STATS_P2(tx_256_to_511B_frames),
11719a391c7bSWingMan Kwok GBENU_STATS_P2(tx_512_to_1023B_frames),
11729a391c7bSWingMan Kwok GBENU_STATS_P2(tx_1024B_frames),
11739a391c7bSWingMan Kwok GBENU_STATS_P2(net_bytes),
11749a391c7bSWingMan Kwok GBENU_STATS_P2(rx_bottom_fifo_drop),
11759a391c7bSWingMan Kwok GBENU_STATS_P2(rx_port_mask_drop),
11769a391c7bSWingMan Kwok GBENU_STATS_P2(rx_top_fifo_drop),
11779a391c7bSWingMan Kwok GBENU_STATS_P2(ale_rate_limit_drop),
11789a391c7bSWingMan Kwok GBENU_STATS_P2(ale_vid_ingress_drop),
11799a391c7bSWingMan Kwok GBENU_STATS_P2(ale_da_eq_sa_drop),
11809a391c7bSWingMan Kwok GBENU_STATS_P2(ale_unknown_ucast),
11819a391c7bSWingMan Kwok GBENU_STATS_P2(ale_unknown_ucast_bytes),
11829a391c7bSWingMan Kwok GBENU_STATS_P2(ale_unknown_mcast),
11839a391c7bSWingMan Kwok GBENU_STATS_P2(ale_unknown_mcast_bytes),
11849a391c7bSWingMan Kwok GBENU_STATS_P2(ale_unknown_bcast),
11859a391c7bSWingMan Kwok GBENU_STATS_P2(ale_unknown_bcast_bytes),
11865be4001eSWingMan Kwok GBENU_STATS_P2(ale_pol_match),
11875be4001eSWingMan Kwok GBENU_STATS_P2(ale_pol_match_red),
11885be4001eSWingMan Kwok GBENU_STATS_P2(ale_pol_match_yellow),
11899a391c7bSWingMan Kwok GBENU_STATS_P2(tx_mem_protect_err),
11905be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri0_drop),
11915be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri1_drop),
11925be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri2_drop),
11935be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri3_drop),
11945be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri4_drop),
11955be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri5_drop),
11965be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri6_drop),
11975be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri7_drop),
11985be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri0_drop_bcnt),
11995be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri1_drop_bcnt),
12005be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri2_drop_bcnt),
12015be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri3_drop_bcnt),
12025be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri4_drop_bcnt),
12035be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri5_drop_bcnt),
12045be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri6_drop_bcnt),
12055be4001eSWingMan Kwok GBENU_STATS_P2(tx_pri7_drop_bcnt),
12069a391c7bSWingMan Kwok /* GBENU Module 3 */
12079a391c7bSWingMan Kwok GBENU_STATS_P3(rx_good_frames),
12089a391c7bSWingMan Kwok GBENU_STATS_P3(rx_broadcast_frames),
12099a391c7bSWingMan Kwok GBENU_STATS_P3(rx_multicast_frames),
12109a391c7bSWingMan Kwok GBENU_STATS_P3(rx_pause_frames),
12119a391c7bSWingMan Kwok GBENU_STATS_P3(rx_crc_errors),
12129a391c7bSWingMan Kwok GBENU_STATS_P3(rx_align_code_errors),
12139a391c7bSWingMan Kwok GBENU_STATS_P3(rx_oversized_frames),
12149a391c7bSWingMan Kwok GBENU_STATS_P3(rx_jabber_frames),
12159a391c7bSWingMan Kwok GBENU_STATS_P3(rx_undersized_frames),
12169a391c7bSWingMan Kwok GBENU_STATS_P3(rx_fragments),
12179a391c7bSWingMan Kwok GBENU_STATS_P3(ale_drop),
12189a391c7bSWingMan Kwok GBENU_STATS_P3(ale_overrun_drop),
12199a391c7bSWingMan Kwok GBENU_STATS_P3(rx_bytes),
12209a391c7bSWingMan Kwok GBENU_STATS_P3(tx_good_frames),
12219a391c7bSWingMan Kwok GBENU_STATS_P3(tx_broadcast_frames),
12229a391c7bSWingMan Kwok GBENU_STATS_P3(tx_multicast_frames),
12239a391c7bSWingMan Kwok GBENU_STATS_P3(tx_pause_frames),
12249a391c7bSWingMan Kwok GBENU_STATS_P3(tx_deferred_frames),
12259a391c7bSWingMan Kwok GBENU_STATS_P3(tx_collision_frames),
12269a391c7bSWingMan Kwok GBENU_STATS_P3(tx_single_coll_frames),
12279a391c7bSWingMan Kwok GBENU_STATS_P3(tx_mult_coll_frames),
12289a391c7bSWingMan Kwok GBENU_STATS_P3(tx_excessive_collisions),
12299a391c7bSWingMan Kwok GBENU_STATS_P3(tx_late_collisions),
12309a391c7bSWingMan Kwok GBENU_STATS_P3(rx_ipg_error),
12319a391c7bSWingMan Kwok GBENU_STATS_P3(tx_carrier_sense_errors),
12329a391c7bSWingMan Kwok GBENU_STATS_P3(tx_bytes),
12339a391c7bSWingMan Kwok GBENU_STATS_P3(tx_64B_frames),
12349a391c7bSWingMan Kwok GBENU_STATS_P3(tx_65_to_127B_frames),
12359a391c7bSWingMan Kwok GBENU_STATS_P3(tx_128_to_255B_frames),
12369a391c7bSWingMan Kwok GBENU_STATS_P3(tx_256_to_511B_frames),
12379a391c7bSWingMan Kwok GBENU_STATS_P3(tx_512_to_1023B_frames),
12389a391c7bSWingMan Kwok GBENU_STATS_P3(tx_1024B_frames),
12399a391c7bSWingMan Kwok GBENU_STATS_P3(net_bytes),
12409a391c7bSWingMan Kwok GBENU_STATS_P3(rx_bottom_fifo_drop),
12419a391c7bSWingMan Kwok GBENU_STATS_P3(rx_port_mask_drop),
12429a391c7bSWingMan Kwok GBENU_STATS_P3(rx_top_fifo_drop),
12439a391c7bSWingMan Kwok GBENU_STATS_P3(ale_rate_limit_drop),
12449a391c7bSWingMan Kwok GBENU_STATS_P3(ale_vid_ingress_drop),
12459a391c7bSWingMan Kwok GBENU_STATS_P3(ale_da_eq_sa_drop),
12469a391c7bSWingMan Kwok GBENU_STATS_P3(ale_unknown_ucast),
12479a391c7bSWingMan Kwok GBENU_STATS_P3(ale_unknown_ucast_bytes),
12489a391c7bSWingMan Kwok GBENU_STATS_P3(ale_unknown_mcast),
12499a391c7bSWingMan Kwok GBENU_STATS_P3(ale_unknown_mcast_bytes),
12509a391c7bSWingMan Kwok GBENU_STATS_P3(ale_unknown_bcast),
12519a391c7bSWingMan Kwok GBENU_STATS_P3(ale_unknown_bcast_bytes),
12525be4001eSWingMan Kwok GBENU_STATS_P3(ale_pol_match),
12535be4001eSWingMan Kwok GBENU_STATS_P3(ale_pol_match_red),
12545be4001eSWingMan Kwok GBENU_STATS_P3(ale_pol_match_yellow),
12559a391c7bSWingMan Kwok GBENU_STATS_P3(tx_mem_protect_err),
12565be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri0_drop),
12575be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri1_drop),
12585be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri2_drop),
12595be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri3_drop),
12605be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri4_drop),
12615be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri5_drop),
12625be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri6_drop),
12635be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri7_drop),
12645be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri0_drop_bcnt),
12655be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri1_drop_bcnt),
12665be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri2_drop_bcnt),
12675be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri3_drop_bcnt),
12685be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri4_drop_bcnt),
12695be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri5_drop_bcnt),
12705be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri6_drop_bcnt),
12715be4001eSWingMan Kwok GBENU_STATS_P3(tx_pri7_drop_bcnt),
12729a391c7bSWingMan Kwok /* GBENU Module 4 */
12739a391c7bSWingMan Kwok GBENU_STATS_P4(rx_good_frames),
12749a391c7bSWingMan Kwok GBENU_STATS_P4(rx_broadcast_frames),
12759a391c7bSWingMan Kwok GBENU_STATS_P4(rx_multicast_frames),
12769a391c7bSWingMan Kwok GBENU_STATS_P4(rx_pause_frames),
12779a391c7bSWingMan Kwok GBENU_STATS_P4(rx_crc_errors),
12789a391c7bSWingMan Kwok GBENU_STATS_P4(rx_align_code_errors),
12799a391c7bSWingMan Kwok GBENU_STATS_P4(rx_oversized_frames),
12809a391c7bSWingMan Kwok GBENU_STATS_P4(rx_jabber_frames),
12819a391c7bSWingMan Kwok GBENU_STATS_P4(rx_undersized_frames),
12829a391c7bSWingMan Kwok GBENU_STATS_P4(rx_fragments),
12839a391c7bSWingMan Kwok GBENU_STATS_P4(ale_drop),
12849a391c7bSWingMan Kwok GBENU_STATS_P4(ale_overrun_drop),
12859a391c7bSWingMan Kwok GBENU_STATS_P4(rx_bytes),
12869a391c7bSWingMan Kwok GBENU_STATS_P4(tx_good_frames),
12879a391c7bSWingMan Kwok GBENU_STATS_P4(tx_broadcast_frames),
12889a391c7bSWingMan Kwok GBENU_STATS_P4(tx_multicast_frames),
12899a391c7bSWingMan Kwok GBENU_STATS_P4(tx_pause_frames),
12909a391c7bSWingMan Kwok GBENU_STATS_P4(tx_deferred_frames),
12919a391c7bSWingMan Kwok GBENU_STATS_P4(tx_collision_frames),
12929a391c7bSWingMan Kwok GBENU_STATS_P4(tx_single_coll_frames),
12939a391c7bSWingMan Kwok GBENU_STATS_P4(tx_mult_coll_frames),
12949a391c7bSWingMan Kwok GBENU_STATS_P4(tx_excessive_collisions),
12959a391c7bSWingMan Kwok GBENU_STATS_P4(tx_late_collisions),
12969a391c7bSWingMan Kwok GBENU_STATS_P4(rx_ipg_error),
12979a391c7bSWingMan Kwok GBENU_STATS_P4(tx_carrier_sense_errors),
12989a391c7bSWingMan Kwok GBENU_STATS_P4(tx_bytes),
12999a391c7bSWingMan Kwok GBENU_STATS_P4(tx_64B_frames),
13009a391c7bSWingMan Kwok GBENU_STATS_P4(tx_65_to_127B_frames),
13019a391c7bSWingMan Kwok GBENU_STATS_P4(tx_128_to_255B_frames),
13029a391c7bSWingMan Kwok GBENU_STATS_P4(tx_256_to_511B_frames),
13039a391c7bSWingMan Kwok GBENU_STATS_P4(tx_512_to_1023B_frames),
13049a391c7bSWingMan Kwok GBENU_STATS_P4(tx_1024B_frames),
13059a391c7bSWingMan Kwok GBENU_STATS_P4(net_bytes),
13069a391c7bSWingMan Kwok GBENU_STATS_P4(rx_bottom_fifo_drop),
13079a391c7bSWingMan Kwok GBENU_STATS_P4(rx_port_mask_drop),
13089a391c7bSWingMan Kwok GBENU_STATS_P4(rx_top_fifo_drop),
13099a391c7bSWingMan Kwok GBENU_STATS_P4(ale_rate_limit_drop),
13109a391c7bSWingMan Kwok GBENU_STATS_P4(ale_vid_ingress_drop),
13119a391c7bSWingMan Kwok GBENU_STATS_P4(ale_da_eq_sa_drop),
13129a391c7bSWingMan Kwok GBENU_STATS_P4(ale_unknown_ucast),
13139a391c7bSWingMan Kwok GBENU_STATS_P4(ale_unknown_ucast_bytes),
13149a391c7bSWingMan Kwok GBENU_STATS_P4(ale_unknown_mcast),
13159a391c7bSWingMan Kwok GBENU_STATS_P4(ale_unknown_mcast_bytes),
13169a391c7bSWingMan Kwok GBENU_STATS_P4(ale_unknown_bcast),
13179a391c7bSWingMan Kwok GBENU_STATS_P4(ale_unknown_bcast_bytes),
13185be4001eSWingMan Kwok GBENU_STATS_P4(ale_pol_match),
13195be4001eSWingMan Kwok GBENU_STATS_P4(ale_pol_match_red),
13205be4001eSWingMan Kwok GBENU_STATS_P4(ale_pol_match_yellow),
13219a391c7bSWingMan Kwok GBENU_STATS_P4(tx_mem_protect_err),
13225be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri0_drop),
13235be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri1_drop),
13245be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri2_drop),
13255be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri3_drop),
13265be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri4_drop),
13275be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri5_drop),
13285be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri6_drop),
13295be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri7_drop),
13305be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri0_drop_bcnt),
13315be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri1_drop_bcnt),
13325be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri2_drop_bcnt),
13335be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri3_drop_bcnt),
13345be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri4_drop_bcnt),
13355be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri5_drop_bcnt),
13365be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri6_drop_bcnt),
13375be4001eSWingMan Kwok GBENU_STATS_P4(tx_pri7_drop_bcnt),
13389a391c7bSWingMan Kwok /* GBENU Module 5 */
13399a391c7bSWingMan Kwok GBENU_STATS_P5(rx_good_frames),
13409a391c7bSWingMan Kwok GBENU_STATS_P5(rx_broadcast_frames),
13419a391c7bSWingMan Kwok GBENU_STATS_P5(rx_multicast_frames),
13429a391c7bSWingMan Kwok GBENU_STATS_P5(rx_pause_frames),
13439a391c7bSWingMan Kwok GBENU_STATS_P5(rx_crc_errors),
13449a391c7bSWingMan Kwok GBENU_STATS_P5(rx_align_code_errors),
13459a391c7bSWingMan Kwok GBENU_STATS_P5(rx_oversized_frames),
13469a391c7bSWingMan Kwok GBENU_STATS_P5(rx_jabber_frames),
13479a391c7bSWingMan Kwok GBENU_STATS_P5(rx_undersized_frames),
13489a391c7bSWingMan Kwok GBENU_STATS_P5(rx_fragments),
13499a391c7bSWingMan Kwok GBENU_STATS_P5(ale_drop),
13509a391c7bSWingMan Kwok GBENU_STATS_P5(ale_overrun_drop),
13519a391c7bSWingMan Kwok GBENU_STATS_P5(rx_bytes),
13529a391c7bSWingMan Kwok GBENU_STATS_P5(tx_good_frames),
13539a391c7bSWingMan Kwok GBENU_STATS_P5(tx_broadcast_frames),
13549a391c7bSWingMan Kwok GBENU_STATS_P5(tx_multicast_frames),
13559a391c7bSWingMan Kwok GBENU_STATS_P5(tx_pause_frames),
13569a391c7bSWingMan Kwok GBENU_STATS_P5(tx_deferred_frames),
13579a391c7bSWingMan Kwok GBENU_STATS_P5(tx_collision_frames),
13589a391c7bSWingMan Kwok GBENU_STATS_P5(tx_single_coll_frames),
13599a391c7bSWingMan Kwok GBENU_STATS_P5(tx_mult_coll_frames),
13609a391c7bSWingMan Kwok GBENU_STATS_P5(tx_excessive_collisions),
13619a391c7bSWingMan Kwok GBENU_STATS_P5(tx_late_collisions),
13629a391c7bSWingMan Kwok GBENU_STATS_P5(rx_ipg_error),
13639a391c7bSWingMan Kwok GBENU_STATS_P5(tx_carrier_sense_errors),
13649a391c7bSWingMan Kwok GBENU_STATS_P5(tx_bytes),
13659a391c7bSWingMan Kwok GBENU_STATS_P5(tx_64B_frames),
13669a391c7bSWingMan Kwok GBENU_STATS_P5(tx_65_to_127B_frames),
13679a391c7bSWingMan Kwok GBENU_STATS_P5(tx_128_to_255B_frames),
13689a391c7bSWingMan Kwok GBENU_STATS_P5(tx_256_to_511B_frames),
13699a391c7bSWingMan Kwok GBENU_STATS_P5(tx_512_to_1023B_frames),
13709a391c7bSWingMan Kwok GBENU_STATS_P5(tx_1024B_frames),
13719a391c7bSWingMan Kwok GBENU_STATS_P5(net_bytes),
13729a391c7bSWingMan Kwok GBENU_STATS_P5(rx_bottom_fifo_drop),
13739a391c7bSWingMan Kwok GBENU_STATS_P5(rx_port_mask_drop),
13749a391c7bSWingMan Kwok GBENU_STATS_P5(rx_top_fifo_drop),
13759a391c7bSWingMan Kwok GBENU_STATS_P5(ale_rate_limit_drop),
13769a391c7bSWingMan Kwok GBENU_STATS_P5(ale_vid_ingress_drop),
13779a391c7bSWingMan Kwok GBENU_STATS_P5(ale_da_eq_sa_drop),
13789a391c7bSWingMan Kwok GBENU_STATS_P5(ale_unknown_ucast),
13799a391c7bSWingMan Kwok GBENU_STATS_P5(ale_unknown_ucast_bytes),
13809a391c7bSWingMan Kwok GBENU_STATS_P5(ale_unknown_mcast),
13819a391c7bSWingMan Kwok GBENU_STATS_P5(ale_unknown_mcast_bytes),
13829a391c7bSWingMan Kwok GBENU_STATS_P5(ale_unknown_bcast),
13839a391c7bSWingMan Kwok GBENU_STATS_P5(ale_unknown_bcast_bytes),
13845be4001eSWingMan Kwok GBENU_STATS_P5(ale_pol_match),
13855be4001eSWingMan Kwok GBENU_STATS_P5(ale_pol_match_red),
13865be4001eSWingMan Kwok GBENU_STATS_P5(ale_pol_match_yellow),
13879a391c7bSWingMan Kwok GBENU_STATS_P5(tx_mem_protect_err),
13885be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri0_drop),
13895be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri1_drop),
13905be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri2_drop),
13915be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri3_drop),
13925be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri4_drop),
13935be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri5_drop),
13945be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri6_drop),
13955be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri7_drop),
13965be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri0_drop_bcnt),
13975be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri1_drop_bcnt),
13985be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri2_drop_bcnt),
13995be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri3_drop_bcnt),
14005be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri4_drop_bcnt),
14015be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri5_drop_bcnt),
14025be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri6_drop_bcnt),
14035be4001eSWingMan Kwok GBENU_STATS_P5(tx_pri7_drop_bcnt),
14049a391c7bSWingMan Kwok /* GBENU Module 6 */
14059a391c7bSWingMan Kwok GBENU_STATS_P6(rx_good_frames),
14069a391c7bSWingMan Kwok GBENU_STATS_P6(rx_broadcast_frames),
14079a391c7bSWingMan Kwok GBENU_STATS_P6(rx_multicast_frames),
14089a391c7bSWingMan Kwok GBENU_STATS_P6(rx_pause_frames),
14099a391c7bSWingMan Kwok GBENU_STATS_P6(rx_crc_errors),
14109a391c7bSWingMan Kwok GBENU_STATS_P6(rx_align_code_errors),
14119a391c7bSWingMan Kwok GBENU_STATS_P6(rx_oversized_frames),
14129a391c7bSWingMan Kwok GBENU_STATS_P6(rx_jabber_frames),
14139a391c7bSWingMan Kwok GBENU_STATS_P6(rx_undersized_frames),
14149a391c7bSWingMan Kwok GBENU_STATS_P6(rx_fragments),
14159a391c7bSWingMan Kwok GBENU_STATS_P6(ale_drop),
14169a391c7bSWingMan Kwok GBENU_STATS_P6(ale_overrun_drop),
14179a391c7bSWingMan Kwok GBENU_STATS_P6(rx_bytes),
14189a391c7bSWingMan Kwok GBENU_STATS_P6(tx_good_frames),
14199a391c7bSWingMan Kwok GBENU_STATS_P6(tx_broadcast_frames),
14209a391c7bSWingMan Kwok GBENU_STATS_P6(tx_multicast_frames),
14219a391c7bSWingMan Kwok GBENU_STATS_P6(tx_pause_frames),
14229a391c7bSWingMan Kwok GBENU_STATS_P6(tx_deferred_frames),
14239a391c7bSWingMan Kwok GBENU_STATS_P6(tx_collision_frames),
14249a391c7bSWingMan Kwok GBENU_STATS_P6(tx_single_coll_frames),
14259a391c7bSWingMan Kwok GBENU_STATS_P6(tx_mult_coll_frames),
14269a391c7bSWingMan Kwok GBENU_STATS_P6(tx_excessive_collisions),
14279a391c7bSWingMan Kwok GBENU_STATS_P6(tx_late_collisions),
14289a391c7bSWingMan Kwok GBENU_STATS_P6(rx_ipg_error),
14299a391c7bSWingMan Kwok GBENU_STATS_P6(tx_carrier_sense_errors),
14309a391c7bSWingMan Kwok GBENU_STATS_P6(tx_bytes),
14319a391c7bSWingMan Kwok GBENU_STATS_P6(tx_64B_frames),
14329a391c7bSWingMan Kwok GBENU_STATS_P6(tx_65_to_127B_frames),
14339a391c7bSWingMan Kwok GBENU_STATS_P6(tx_128_to_255B_frames),
14349a391c7bSWingMan Kwok GBENU_STATS_P6(tx_256_to_511B_frames),
14359a391c7bSWingMan Kwok GBENU_STATS_P6(tx_512_to_1023B_frames),
14369a391c7bSWingMan Kwok GBENU_STATS_P6(tx_1024B_frames),
14379a391c7bSWingMan Kwok GBENU_STATS_P6(net_bytes),
14389a391c7bSWingMan Kwok GBENU_STATS_P6(rx_bottom_fifo_drop),
14399a391c7bSWingMan Kwok GBENU_STATS_P6(rx_port_mask_drop),
14409a391c7bSWingMan Kwok GBENU_STATS_P6(rx_top_fifo_drop),
14419a391c7bSWingMan Kwok GBENU_STATS_P6(ale_rate_limit_drop),
14429a391c7bSWingMan Kwok GBENU_STATS_P6(ale_vid_ingress_drop),
14439a391c7bSWingMan Kwok GBENU_STATS_P6(ale_da_eq_sa_drop),
14449a391c7bSWingMan Kwok GBENU_STATS_P6(ale_unknown_ucast),
14459a391c7bSWingMan Kwok GBENU_STATS_P6(ale_unknown_ucast_bytes),
14469a391c7bSWingMan Kwok GBENU_STATS_P6(ale_unknown_mcast),
14479a391c7bSWingMan Kwok GBENU_STATS_P6(ale_unknown_mcast_bytes),
14489a391c7bSWingMan Kwok GBENU_STATS_P6(ale_unknown_bcast),
14499a391c7bSWingMan Kwok GBENU_STATS_P6(ale_unknown_bcast_bytes),
14505be4001eSWingMan Kwok GBENU_STATS_P6(ale_pol_match),
14515be4001eSWingMan Kwok GBENU_STATS_P6(ale_pol_match_red),
14525be4001eSWingMan Kwok GBENU_STATS_P6(ale_pol_match_yellow),
14539a391c7bSWingMan Kwok GBENU_STATS_P6(tx_mem_protect_err),
14545be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri0_drop),
14555be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri1_drop),
14565be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri2_drop),
14575be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri3_drop),
14585be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri4_drop),
14595be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri5_drop),
14605be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri6_drop),
14615be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri7_drop),
14625be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri0_drop_bcnt),
14635be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri1_drop_bcnt),
14645be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri2_drop_bcnt),
14655be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri3_drop_bcnt),
14665be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri4_drop_bcnt),
14675be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri5_drop_bcnt),
14685be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri6_drop_bcnt),
14695be4001eSWingMan Kwok GBENU_STATS_P6(tx_pri7_drop_bcnt),
14709a391c7bSWingMan Kwok /* GBENU Module 7 */
14719a391c7bSWingMan Kwok GBENU_STATS_P7(rx_good_frames),
14729a391c7bSWingMan Kwok GBENU_STATS_P7(rx_broadcast_frames),
14739a391c7bSWingMan Kwok GBENU_STATS_P7(rx_multicast_frames),
14749a391c7bSWingMan Kwok GBENU_STATS_P7(rx_pause_frames),
14759a391c7bSWingMan Kwok GBENU_STATS_P7(rx_crc_errors),
14769a391c7bSWingMan Kwok GBENU_STATS_P7(rx_align_code_errors),
14779a391c7bSWingMan Kwok GBENU_STATS_P7(rx_oversized_frames),
14789a391c7bSWingMan Kwok GBENU_STATS_P7(rx_jabber_frames),
14799a391c7bSWingMan Kwok GBENU_STATS_P7(rx_undersized_frames),
14809a391c7bSWingMan Kwok GBENU_STATS_P7(rx_fragments),
14819a391c7bSWingMan Kwok GBENU_STATS_P7(ale_drop),
14829a391c7bSWingMan Kwok GBENU_STATS_P7(ale_overrun_drop),
14839a391c7bSWingMan Kwok GBENU_STATS_P7(rx_bytes),
14849a391c7bSWingMan Kwok GBENU_STATS_P7(tx_good_frames),
14859a391c7bSWingMan Kwok GBENU_STATS_P7(tx_broadcast_frames),
14869a391c7bSWingMan Kwok GBENU_STATS_P7(tx_multicast_frames),
14879a391c7bSWingMan Kwok GBENU_STATS_P7(tx_pause_frames),
14889a391c7bSWingMan Kwok GBENU_STATS_P7(tx_deferred_frames),
14899a391c7bSWingMan Kwok GBENU_STATS_P7(tx_collision_frames),
14909a391c7bSWingMan Kwok GBENU_STATS_P7(tx_single_coll_frames),
14919a391c7bSWingMan Kwok GBENU_STATS_P7(tx_mult_coll_frames),
14929a391c7bSWingMan Kwok GBENU_STATS_P7(tx_excessive_collisions),
14939a391c7bSWingMan Kwok GBENU_STATS_P7(tx_late_collisions),
14949a391c7bSWingMan Kwok GBENU_STATS_P7(rx_ipg_error),
14959a391c7bSWingMan Kwok GBENU_STATS_P7(tx_carrier_sense_errors),
14969a391c7bSWingMan Kwok GBENU_STATS_P7(tx_bytes),
14979a391c7bSWingMan Kwok GBENU_STATS_P7(tx_64B_frames),
14989a391c7bSWingMan Kwok GBENU_STATS_P7(tx_65_to_127B_frames),
14999a391c7bSWingMan Kwok GBENU_STATS_P7(tx_128_to_255B_frames),
15009a391c7bSWingMan Kwok GBENU_STATS_P7(tx_256_to_511B_frames),
15019a391c7bSWingMan Kwok GBENU_STATS_P7(tx_512_to_1023B_frames),
15029a391c7bSWingMan Kwok GBENU_STATS_P7(tx_1024B_frames),
15039a391c7bSWingMan Kwok GBENU_STATS_P7(net_bytes),
15049a391c7bSWingMan Kwok GBENU_STATS_P7(rx_bottom_fifo_drop),
15059a391c7bSWingMan Kwok GBENU_STATS_P7(rx_port_mask_drop),
15069a391c7bSWingMan Kwok GBENU_STATS_P7(rx_top_fifo_drop),
15079a391c7bSWingMan Kwok GBENU_STATS_P7(ale_rate_limit_drop),
15089a391c7bSWingMan Kwok GBENU_STATS_P7(ale_vid_ingress_drop),
15099a391c7bSWingMan Kwok GBENU_STATS_P7(ale_da_eq_sa_drop),
15109a391c7bSWingMan Kwok GBENU_STATS_P7(ale_unknown_ucast),
15119a391c7bSWingMan Kwok GBENU_STATS_P7(ale_unknown_ucast_bytes),
15129a391c7bSWingMan Kwok GBENU_STATS_P7(ale_unknown_mcast),
15139a391c7bSWingMan Kwok GBENU_STATS_P7(ale_unknown_mcast_bytes),
15149a391c7bSWingMan Kwok GBENU_STATS_P7(ale_unknown_bcast),
15159a391c7bSWingMan Kwok GBENU_STATS_P7(ale_unknown_bcast_bytes),
15165be4001eSWingMan Kwok GBENU_STATS_P7(ale_pol_match),
15175be4001eSWingMan Kwok GBENU_STATS_P7(ale_pol_match_red),
15185be4001eSWingMan Kwok GBENU_STATS_P7(ale_pol_match_yellow),
15199a391c7bSWingMan Kwok GBENU_STATS_P7(tx_mem_protect_err),
15205be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri0_drop),
15215be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri1_drop),
15225be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri2_drop),
15235be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri3_drop),
15245be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri4_drop),
15255be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri5_drop),
15265be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri6_drop),
15275be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri7_drop),
15285be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri0_drop_bcnt),
15295be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri1_drop_bcnt),
15305be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri2_drop_bcnt),
15315be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri3_drop_bcnt),
15325be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri4_drop_bcnt),
15335be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri5_drop_bcnt),
15345be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri6_drop_bcnt),
15355be4001eSWingMan Kwok GBENU_STATS_P7(tx_pri7_drop_bcnt),
15369a391c7bSWingMan Kwok /* GBENU Module 8 */
15379a391c7bSWingMan Kwok GBENU_STATS_P8(rx_good_frames),
15389a391c7bSWingMan Kwok GBENU_STATS_P8(rx_broadcast_frames),
15399a391c7bSWingMan Kwok GBENU_STATS_P8(rx_multicast_frames),
15409a391c7bSWingMan Kwok GBENU_STATS_P8(rx_pause_frames),
15419a391c7bSWingMan Kwok GBENU_STATS_P8(rx_crc_errors),
15429a391c7bSWingMan Kwok GBENU_STATS_P8(rx_align_code_errors),
15439a391c7bSWingMan Kwok GBENU_STATS_P8(rx_oversized_frames),
15449a391c7bSWingMan Kwok GBENU_STATS_P8(rx_jabber_frames),
15459a391c7bSWingMan Kwok GBENU_STATS_P8(rx_undersized_frames),
15469a391c7bSWingMan Kwok GBENU_STATS_P8(rx_fragments),
15479a391c7bSWingMan Kwok GBENU_STATS_P8(ale_drop),
15489a391c7bSWingMan Kwok GBENU_STATS_P8(ale_overrun_drop),
15499a391c7bSWingMan Kwok GBENU_STATS_P8(rx_bytes),
15509a391c7bSWingMan Kwok GBENU_STATS_P8(tx_good_frames),
15519a391c7bSWingMan Kwok GBENU_STATS_P8(tx_broadcast_frames),
15529a391c7bSWingMan Kwok GBENU_STATS_P8(tx_multicast_frames),
15539a391c7bSWingMan Kwok GBENU_STATS_P8(tx_pause_frames),
15549a391c7bSWingMan Kwok GBENU_STATS_P8(tx_deferred_frames),
15559a391c7bSWingMan Kwok GBENU_STATS_P8(tx_collision_frames),
15569a391c7bSWingMan Kwok GBENU_STATS_P8(tx_single_coll_frames),
15579a391c7bSWingMan Kwok GBENU_STATS_P8(tx_mult_coll_frames),
15589a391c7bSWingMan Kwok GBENU_STATS_P8(tx_excessive_collisions),
15599a391c7bSWingMan Kwok GBENU_STATS_P8(tx_late_collisions),
15609a391c7bSWingMan Kwok GBENU_STATS_P8(rx_ipg_error),
15619a391c7bSWingMan Kwok GBENU_STATS_P8(tx_carrier_sense_errors),
15629a391c7bSWingMan Kwok GBENU_STATS_P8(tx_bytes),
15639a391c7bSWingMan Kwok GBENU_STATS_P8(tx_64B_frames),
15649a391c7bSWingMan Kwok GBENU_STATS_P8(tx_65_to_127B_frames),
15659a391c7bSWingMan Kwok GBENU_STATS_P8(tx_128_to_255B_frames),
15669a391c7bSWingMan Kwok GBENU_STATS_P8(tx_256_to_511B_frames),
15679a391c7bSWingMan Kwok GBENU_STATS_P8(tx_512_to_1023B_frames),
15689a391c7bSWingMan Kwok GBENU_STATS_P8(tx_1024B_frames),
15699a391c7bSWingMan Kwok GBENU_STATS_P8(net_bytes),
15709a391c7bSWingMan Kwok GBENU_STATS_P8(rx_bottom_fifo_drop),
15719a391c7bSWingMan Kwok GBENU_STATS_P8(rx_port_mask_drop),
15729a391c7bSWingMan Kwok GBENU_STATS_P8(rx_top_fifo_drop),
15739a391c7bSWingMan Kwok GBENU_STATS_P8(ale_rate_limit_drop),
15749a391c7bSWingMan Kwok GBENU_STATS_P8(ale_vid_ingress_drop),
15759a391c7bSWingMan Kwok GBENU_STATS_P8(ale_da_eq_sa_drop),
15769a391c7bSWingMan Kwok GBENU_STATS_P8(ale_unknown_ucast),
15779a391c7bSWingMan Kwok GBENU_STATS_P8(ale_unknown_ucast_bytes),
15789a391c7bSWingMan Kwok GBENU_STATS_P8(ale_unknown_mcast),
15799a391c7bSWingMan Kwok GBENU_STATS_P8(ale_unknown_mcast_bytes),
15809a391c7bSWingMan Kwok GBENU_STATS_P8(ale_unknown_bcast),
15819a391c7bSWingMan Kwok GBENU_STATS_P8(ale_unknown_bcast_bytes),
15825be4001eSWingMan Kwok GBENU_STATS_P8(ale_pol_match),
15835be4001eSWingMan Kwok GBENU_STATS_P8(ale_pol_match_red),
15845be4001eSWingMan Kwok GBENU_STATS_P8(ale_pol_match_yellow),
15859a391c7bSWingMan Kwok GBENU_STATS_P8(tx_mem_protect_err),
15865be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri0_drop),
15875be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri1_drop),
15885be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri2_drop),
15895be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri3_drop),
15905be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri4_drop),
15915be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri5_drop),
15925be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri6_drop),
15935be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri7_drop),
15945be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri0_drop_bcnt),
15955be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri1_drop_bcnt),
15965be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri2_drop_bcnt),
15975be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri3_drop_bcnt),
15985be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri4_drop_bcnt),
15995be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri5_drop_bcnt),
16005be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri6_drop_bcnt),
16015be4001eSWingMan Kwok GBENU_STATS_P8(tx_pri7_drop_bcnt),
16029a391c7bSWingMan Kwok };
16039a391c7bSWingMan Kwok
1604da866ba0SKaricheri, Muralidharan #define XGBE_STATS0_INFO(field) \
1605da866ba0SKaricheri, Muralidharan { \
1606da866ba0SKaricheri, Muralidharan "GBE_0:"#field, XGBE_STATS0_MODULE, \
1607c593642cSPankaj Bharadiya sizeof_field(struct xgbe_hw_stats, field), \
1608da866ba0SKaricheri, Muralidharan offsetof(struct xgbe_hw_stats, field) \
1609da866ba0SKaricheri, Muralidharan }
161090cff9e2SWingman Kwok
1611da866ba0SKaricheri, Muralidharan #define XGBE_STATS1_INFO(field) \
1612da866ba0SKaricheri, Muralidharan { \
1613da866ba0SKaricheri, Muralidharan "GBE_1:"#field, XGBE_STATS1_MODULE, \
1614c593642cSPankaj Bharadiya sizeof_field(struct xgbe_hw_stats, field), \
1615da866ba0SKaricheri, Muralidharan offsetof(struct xgbe_hw_stats, field) \
1616da866ba0SKaricheri, Muralidharan }
161790cff9e2SWingman Kwok
1618da866ba0SKaricheri, Muralidharan #define XGBE_STATS2_INFO(field) \
1619da866ba0SKaricheri, Muralidharan { \
1620da866ba0SKaricheri, Muralidharan "GBE_2:"#field, XGBE_STATS2_MODULE, \
1621c593642cSPankaj Bharadiya sizeof_field(struct xgbe_hw_stats, field), \
1622da866ba0SKaricheri, Muralidharan offsetof(struct xgbe_hw_stats, field) \
1623da866ba0SKaricheri, Muralidharan }
162490cff9e2SWingman Kwok
162590cff9e2SWingman Kwok static const struct netcp_ethtool_stat xgbe10_et_stats[] = {
162690cff9e2SWingman Kwok /* GBE module 0 */
1627da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_good_frames),
1628da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_broadcast_frames),
1629da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_multicast_frames),
1630da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_oversized_frames),
1631da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_undersized_frames),
1632da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(overrun_type4),
1633da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(overrun_type5),
1634da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_bytes),
1635da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_good_frames),
1636da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_broadcast_frames),
1637da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_multicast_frames),
1638da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_bytes),
1639da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_64byte_frames),
1640da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_65_to_127byte_frames),
1641da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_128_to_255byte_frames),
1642da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_256_to_511byte_frames),
1643da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_512_to_1023byte_frames),
1644da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(tx_1024byte_frames),
1645da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(net_bytes),
1646da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_sof_overruns),
1647da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_mof_overruns),
1648da866ba0SKaricheri, Muralidharan XGBE_STATS0_INFO(rx_dma_overruns),
164990cff9e2SWingman Kwok /* XGBE module 1 */
1650da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_good_frames),
1651da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_broadcast_frames),
1652da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_multicast_frames),
1653da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_pause_frames),
1654da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_crc_errors),
1655da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_align_code_errors),
1656da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_oversized_frames),
1657da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_jabber_frames),
1658da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_undersized_frames),
1659da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_fragments),
1660da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(overrun_type4),
1661da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(overrun_type5),
1662da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_bytes),
1663da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_good_frames),
1664da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_broadcast_frames),
1665da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_multicast_frames),
1666da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_pause_frames),
1667da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_deferred_frames),
1668da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_collision_frames),
1669da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_single_coll_frames),
1670da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_mult_coll_frames),
1671da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_excessive_collisions),
1672da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_late_collisions),
1673da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_underrun),
1674da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_carrier_sense_errors),
1675da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_bytes),
1676da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_64byte_frames),
1677da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_65_to_127byte_frames),
1678da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_128_to_255byte_frames),
1679da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_256_to_511byte_frames),
1680da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_512_to_1023byte_frames),
1681da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(tx_1024byte_frames),
1682da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(net_bytes),
1683da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_sof_overruns),
1684da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_mof_overruns),
1685da866ba0SKaricheri, Muralidharan XGBE_STATS1_INFO(rx_dma_overruns),
168690cff9e2SWingman Kwok /* XGBE module 2 */
1687da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_good_frames),
1688da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_broadcast_frames),
1689da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_multicast_frames),
1690da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_pause_frames),
1691da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_crc_errors),
1692da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_align_code_errors),
1693da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_oversized_frames),
1694da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_jabber_frames),
1695da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_undersized_frames),
1696da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_fragments),
1697da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(overrun_type4),
1698da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(overrun_type5),
1699da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_bytes),
1700da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_good_frames),
1701da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_broadcast_frames),
1702da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_multicast_frames),
1703da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_pause_frames),
1704da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_deferred_frames),
1705da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_collision_frames),
1706da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_single_coll_frames),
1707da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_mult_coll_frames),
1708da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_excessive_collisions),
1709da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_late_collisions),
1710da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_underrun),
1711da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_carrier_sense_errors),
1712da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_bytes),
1713da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_64byte_frames),
1714da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_65_to_127byte_frames),
1715da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_128_to_255byte_frames),
1716da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_256_to_511byte_frames),
1717da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_512_to_1023byte_frames),
1718da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(tx_1024byte_frames),
1719da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(net_bytes),
1720da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_sof_overruns),
1721da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_mof_overruns),
1722da866ba0SKaricheri, Muralidharan XGBE_STATS2_INFO(rx_dma_overruns),
172390cff9e2SWingman Kwok };
172490cff9e2SWingman Kwok
17256f8d3f33SWingman Kwok #define for_each_intf(i, priv) \
17266f8d3f33SWingman Kwok list_for_each_entry((i), &(priv)->gbe_intf_head, gbe_intf_list)
17276f8d3f33SWingman Kwok
17286f8d3f33SWingman Kwok #define for_each_sec_slave(slave, priv) \
17296f8d3f33SWingman Kwok list_for_each_entry((slave), &(priv)->secondary_slaves, slave_list)
17306f8d3f33SWingman Kwok
17316f8d3f33SWingman Kwok #define first_sec_slave(priv) \
17326f8d3f33SWingman Kwok list_first_entry(&priv->secondary_slaves, \
17336f8d3f33SWingman Kwok struct gbe_slave, slave_list)
17346f8d3f33SWingman Kwok
keystone_get_drvinfo(struct net_device * ndev,struct ethtool_drvinfo * info)17356f8d3f33SWingman Kwok static void keystone_get_drvinfo(struct net_device *ndev,
17366f8d3f33SWingman Kwok struct ethtool_drvinfo *info)
17376f8d3f33SWingman Kwok {
17386f8d3f33SWingman Kwok strncpy(info->driver, NETCP_DRIVER_NAME, sizeof(info->driver));
17396f8d3f33SWingman Kwok strncpy(info->version, NETCP_DRIVER_VERSION, sizeof(info->version));
17406f8d3f33SWingman Kwok }
17416f8d3f33SWingman Kwok
keystone_get_msglevel(struct net_device * ndev)17426f8d3f33SWingman Kwok static u32 keystone_get_msglevel(struct net_device *ndev)
17436f8d3f33SWingman Kwok {
17446f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev);
17456f8d3f33SWingman Kwok
17466f8d3f33SWingman Kwok return netcp->msg_enable;
17476f8d3f33SWingman Kwok }
17486f8d3f33SWingman Kwok
keystone_set_msglevel(struct net_device * ndev,u32 value)17496f8d3f33SWingman Kwok static void keystone_set_msglevel(struct net_device *ndev, u32 value)
17506f8d3f33SWingman Kwok {
17516f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev);
17526f8d3f33SWingman Kwok
17536f8d3f33SWingman Kwok netcp->msg_enable = value;
17546f8d3f33SWingman Kwok }
17556f8d3f33SWingman Kwok
keystone_get_intf_data(struct netcp_intf * netcp)1756e9838ef2SWingMan Kwok static struct gbe_intf *keystone_get_intf_data(struct netcp_intf *netcp)
1757e9838ef2SWingMan Kwok {
1758e9838ef2SWingMan Kwok struct gbe_intf *gbe_intf;
1759e9838ef2SWingMan Kwok
1760e9838ef2SWingMan Kwok gbe_intf = netcp_module_get_intf_data(&gbe_module, netcp);
1761e9838ef2SWingMan Kwok if (!gbe_intf)
1762e9838ef2SWingMan Kwok gbe_intf = netcp_module_get_intf_data(&xgbe_module, netcp);
1763e9838ef2SWingMan Kwok
1764e9838ef2SWingMan Kwok return gbe_intf;
1765e9838ef2SWingMan Kwok }
1766e9838ef2SWingMan Kwok
keystone_get_stat_strings(struct net_device * ndev,uint32_t stringset,uint8_t * data)17676f8d3f33SWingman Kwok static void keystone_get_stat_strings(struct net_device *ndev,
17686f8d3f33SWingman Kwok uint32_t stringset, uint8_t *data)
17696f8d3f33SWingman Kwok {
17706f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev);
17716f8d3f33SWingman Kwok struct gbe_intf *gbe_intf;
17726f8d3f33SWingman Kwok struct gbe_priv *gbe_dev;
17736f8d3f33SWingman Kwok int i;
17746f8d3f33SWingman Kwok
1775e9838ef2SWingMan Kwok gbe_intf = keystone_get_intf_data(netcp);
17766f8d3f33SWingman Kwok if (!gbe_intf)
17776f8d3f33SWingman Kwok return;
17786f8d3f33SWingman Kwok gbe_dev = gbe_intf->gbe_dev;
17796f8d3f33SWingman Kwok
17806f8d3f33SWingman Kwok switch (stringset) {
17816f8d3f33SWingman Kwok case ETH_SS_STATS:
17826f8d3f33SWingman Kwok for (i = 0; i < gbe_dev->num_et_stats; i++) {
17836f8d3f33SWingman Kwok memcpy(data, gbe_dev->et_stats[i].desc,
17846f8d3f33SWingman Kwok ETH_GSTRING_LEN);
17856f8d3f33SWingman Kwok data += ETH_GSTRING_LEN;
17866f8d3f33SWingman Kwok }
17876f8d3f33SWingman Kwok break;
17886f8d3f33SWingman Kwok case ETH_SS_TEST:
17896f8d3f33SWingman Kwok break;
17906f8d3f33SWingman Kwok }
17916f8d3f33SWingman Kwok }
17926f8d3f33SWingman Kwok
keystone_get_sset_count(struct net_device * ndev,int stringset)17936f8d3f33SWingman Kwok static int keystone_get_sset_count(struct net_device *ndev, int stringset)
17946f8d3f33SWingman Kwok {
17956f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev);
17966f8d3f33SWingman Kwok struct gbe_intf *gbe_intf;
17976f8d3f33SWingman Kwok struct gbe_priv *gbe_dev;
17986f8d3f33SWingman Kwok
1799e9838ef2SWingMan Kwok gbe_intf = keystone_get_intf_data(netcp);
18006f8d3f33SWingman Kwok if (!gbe_intf)
18016f8d3f33SWingman Kwok return -EINVAL;
18026f8d3f33SWingman Kwok gbe_dev = gbe_intf->gbe_dev;
18036f8d3f33SWingman Kwok
18046f8d3f33SWingman Kwok switch (stringset) {
18056f8d3f33SWingman Kwok case ETH_SS_TEST:
18066f8d3f33SWingman Kwok return 0;
18076f8d3f33SWingman Kwok case ETH_SS_STATS:
18086f8d3f33SWingman Kwok return gbe_dev->num_et_stats;
18096f8d3f33SWingman Kwok default:
18106f8d3f33SWingman Kwok return -EINVAL;
18116f8d3f33SWingman Kwok }
18126f8d3f33SWingman Kwok }
18136f8d3f33SWingman Kwok
gbe_reset_mod_stats(struct gbe_priv * gbe_dev,int stats_mod)1814489e8a2fSWingMan Kwok static void gbe_reset_mod_stats(struct gbe_priv *gbe_dev, int stats_mod)
1815489e8a2fSWingMan Kwok {
1816489e8a2fSWingMan Kwok void __iomem *base = gbe_dev->hw_stats_regs[stats_mod];
1817489e8a2fSWingMan Kwok u32 __iomem *p_stats_entry;
1818489e8a2fSWingMan Kwok int i;
1819489e8a2fSWingMan Kwok
1820489e8a2fSWingMan Kwok for (i = 0; i < gbe_dev->num_et_stats; i++) {
1821489e8a2fSWingMan Kwok if (gbe_dev->et_stats[i].type == stats_mod) {
1822489e8a2fSWingMan Kwok p_stats_entry = base + gbe_dev->et_stats[i].offset;
1823489e8a2fSWingMan Kwok gbe_dev->hw_stats[i] = 0;
1824489e8a2fSWingMan Kwok gbe_dev->hw_stats_prev[i] = readl(p_stats_entry);
1825489e8a2fSWingMan Kwok }
1826489e8a2fSWingMan Kwok }
1827489e8a2fSWingMan Kwok }
1828489e8a2fSWingMan Kwok
gbe_update_hw_stats_entry(struct gbe_priv * gbe_dev,int et_stats_entry)1829fbf64c19SWingMan Kwok static inline void gbe_update_hw_stats_entry(struct gbe_priv *gbe_dev,
1830fbf64c19SWingMan Kwok int et_stats_entry)
18316f8d3f33SWingman Kwok {
18326f8d3f33SWingman Kwok void __iomem *base = NULL;
1833489e8a2fSWingMan Kwok u32 __iomem *p_stats_entry;
1834489e8a2fSWingMan Kwok u32 curr, delta;
18356f8d3f33SWingman Kwok
1836fbf64c19SWingMan Kwok /* The hw_stats_regs pointers are already
1837fbf64c19SWingMan Kwok * properly set to point to the right base:
1838fbf64c19SWingMan Kwok */
1839fbf64c19SWingMan Kwok base = gbe_dev->hw_stats_regs[gbe_dev->et_stats[et_stats_entry].type];
1840489e8a2fSWingMan Kwok p_stats_entry = base + gbe_dev->et_stats[et_stats_entry].offset;
1841489e8a2fSWingMan Kwok curr = readl(p_stats_entry);
1842489e8a2fSWingMan Kwok delta = curr - gbe_dev->hw_stats_prev[et_stats_entry];
1843489e8a2fSWingMan Kwok gbe_dev->hw_stats_prev[et_stats_entry] = curr;
1844489e8a2fSWingMan Kwok gbe_dev->hw_stats[et_stats_entry] += delta;
18456f8d3f33SWingman Kwok }
1846fbf64c19SWingMan Kwok
gbe_update_stats(struct gbe_priv * gbe_dev,uint64_t * data)1847fbf64c19SWingMan Kwok static void gbe_update_stats(struct gbe_priv *gbe_dev, uint64_t *data)
1848fbf64c19SWingMan Kwok {
1849fbf64c19SWingMan Kwok int i;
1850fbf64c19SWingMan Kwok
1851fbf64c19SWingMan Kwok for (i = 0; i < gbe_dev->num_et_stats; i++) {
1852fbf64c19SWingMan Kwok gbe_update_hw_stats_entry(gbe_dev, i);
1853fbf64c19SWingMan Kwok
1854fbf64c19SWingMan Kwok if (data)
1855fbf64c19SWingMan Kwok data[i] = gbe_dev->hw_stats[i];
1856fbf64c19SWingMan Kwok }
1857fbf64c19SWingMan Kwok }
1858fbf64c19SWingMan Kwok
gbe_stats_mod_visible_ver14(struct gbe_priv * gbe_dev,int stats_mod)1859fbf64c19SWingMan Kwok static inline void gbe_stats_mod_visible_ver14(struct gbe_priv *gbe_dev,
1860fbf64c19SWingMan Kwok int stats_mod)
1861fbf64c19SWingMan Kwok {
1862fbf64c19SWingMan Kwok u32 val;
1863fbf64c19SWingMan Kwok
1864fbf64c19SWingMan Kwok val = readl(GBE_REG_ADDR(gbe_dev, switch_regs, stat_port_en));
1865fbf64c19SWingMan Kwok
1866fbf64c19SWingMan Kwok switch (stats_mod) {
1867fbf64c19SWingMan Kwok case GBE_STATSA_MODULE:
1868fbf64c19SWingMan Kwok case GBE_STATSB_MODULE:
1869fbf64c19SWingMan Kwok val &= ~GBE_STATS_CD_SEL;
1870fbf64c19SWingMan Kwok break;
1871fbf64c19SWingMan Kwok case GBE_STATSC_MODULE:
1872fbf64c19SWingMan Kwok case GBE_STATSD_MODULE:
1873fbf64c19SWingMan Kwok val |= GBE_STATS_CD_SEL;
1874fbf64c19SWingMan Kwok break;
1875fbf64c19SWingMan Kwok default:
1876fbf64c19SWingMan Kwok return;
1877fbf64c19SWingMan Kwok }
1878fbf64c19SWingMan Kwok
1879fbf64c19SWingMan Kwok /* make the stat module visible */
1880fbf64c19SWingMan Kwok writel(val, GBE_REG_ADDR(gbe_dev, switch_regs, stat_port_en));
18816f8d3f33SWingman Kwok }
18826f8d3f33SWingman Kwok
gbe_reset_mod_stats_ver14(struct gbe_priv * gbe_dev,int stats_mod)1883489e8a2fSWingMan Kwok static void gbe_reset_mod_stats_ver14(struct gbe_priv *gbe_dev, int stats_mod)
1884489e8a2fSWingMan Kwok {
1885489e8a2fSWingMan Kwok gbe_stats_mod_visible_ver14(gbe_dev, stats_mod);
1886489e8a2fSWingMan Kwok gbe_reset_mod_stats(gbe_dev, stats_mod);
1887489e8a2fSWingMan Kwok }
1888489e8a2fSWingMan Kwok
gbe_update_stats_ver14(struct gbe_priv * gbe_dev,uint64_t * data)18896f8d3f33SWingman Kwok static void gbe_update_stats_ver14(struct gbe_priv *gbe_dev, uint64_t *data)
18906f8d3f33SWingman Kwok {
1891fbf64c19SWingMan Kwok u32 half_num_et_stats = (gbe_dev->num_et_stats / 2);
1892fbf64c19SWingMan Kwok int et_entry, j, pair;
18936f8d3f33SWingman Kwok
18946f8d3f33SWingman Kwok for (pair = 0; pair < 2; pair++) {
1895fbf64c19SWingMan Kwok gbe_stats_mod_visible_ver14(gbe_dev, (pair ?
1896fbf64c19SWingMan Kwok GBE_STATSC_MODULE :
1897fbf64c19SWingMan Kwok GBE_STATSA_MODULE));
18986f8d3f33SWingman Kwok
1899fbf64c19SWingMan Kwok for (j = 0; j < half_num_et_stats; j++) {
1900fbf64c19SWingMan Kwok et_entry = pair * half_num_et_stats + j;
1901fbf64c19SWingMan Kwok gbe_update_hw_stats_entry(gbe_dev, et_entry);
19026f8d3f33SWingman Kwok
19036f8d3f33SWingman Kwok if (data)
1904fbf64c19SWingMan Kwok data[et_entry] = gbe_dev->hw_stats[et_entry];
19056f8d3f33SWingman Kwok }
19066f8d3f33SWingman Kwok }
19076f8d3f33SWingman Kwok }
19086f8d3f33SWingman Kwok
keystone_get_ethtool_stats(struct net_device * ndev,struct ethtool_stats * stats,uint64_t * data)19096f8d3f33SWingman Kwok static void keystone_get_ethtool_stats(struct net_device *ndev,
19106f8d3f33SWingman Kwok struct ethtool_stats *stats,
19116f8d3f33SWingman Kwok uint64_t *data)
19126f8d3f33SWingman Kwok {
19136f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev);
19146f8d3f33SWingman Kwok struct gbe_intf *gbe_intf;
19156f8d3f33SWingman Kwok struct gbe_priv *gbe_dev;
19166f8d3f33SWingman Kwok
1917e9838ef2SWingMan Kwok gbe_intf = keystone_get_intf_data(netcp);
19186f8d3f33SWingman Kwok if (!gbe_intf)
19196f8d3f33SWingman Kwok return;
19206f8d3f33SWingman Kwok
19216f8d3f33SWingman Kwok gbe_dev = gbe_intf->gbe_dev;
19226f8d3f33SWingman Kwok spin_lock_bh(&gbe_dev->hw_stats_lock);
19232953586dSMurali Karicheri if (IS_SS_ID_VER_14(gbe_dev))
19246f8d3f33SWingman Kwok gbe_update_stats_ver14(gbe_dev, data);
192590cff9e2SWingman Kwok else
192690cff9e2SWingman Kwok gbe_update_stats(gbe_dev, data);
19276f8d3f33SWingman Kwok spin_unlock_bh(&gbe_dev->hw_stats_lock);
19286f8d3f33SWingman Kwok }
19296f8d3f33SWingman Kwok
keystone_get_link_ksettings(struct net_device * ndev,struct ethtool_link_ksettings * cmd)193086e3a040SPhilippe Reynes static int keystone_get_link_ksettings(struct net_device *ndev,
193186e3a040SPhilippe Reynes struct ethtool_link_ksettings *cmd)
19326f8d3f33SWingman Kwok {
19336f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev);
19346f8d3f33SWingman Kwok struct phy_device *phy = ndev->phydev;
19356f8d3f33SWingman Kwok struct gbe_intf *gbe_intf;
19366f8d3f33SWingman Kwok
19376f8d3f33SWingman Kwok if (!phy)
19386f8d3f33SWingman Kwok return -EINVAL;
19396f8d3f33SWingman Kwok
1940e9838ef2SWingMan Kwok gbe_intf = keystone_get_intf_data(netcp);
19416f8d3f33SWingman Kwok if (!gbe_intf)
19426f8d3f33SWingman Kwok return -EINVAL;
19436f8d3f33SWingman Kwok
19446f8d3f33SWingman Kwok if (!gbe_intf->slave)
19456f8d3f33SWingman Kwok return -EINVAL;
19466f8d3f33SWingman Kwok
19475514174fSyuval.shaia@oracle.com phy_ethtool_ksettings_get(phy, cmd);
194886e3a040SPhilippe Reynes cmd->base.port = gbe_intf->slave->phy_port_t;
19496f8d3f33SWingman Kwok
19505514174fSyuval.shaia@oracle.com return 0;
19516f8d3f33SWingman Kwok }
19526f8d3f33SWingman Kwok
keystone_set_link_ksettings(struct net_device * ndev,const struct ethtool_link_ksettings * cmd)195386e3a040SPhilippe Reynes static int keystone_set_link_ksettings(struct net_device *ndev,
195486e3a040SPhilippe Reynes const struct ethtool_link_ksettings *cmd)
19556f8d3f33SWingman Kwok {
19566f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev);
19576f8d3f33SWingman Kwok struct phy_device *phy = ndev->phydev;
19586f8d3f33SWingman Kwok struct gbe_intf *gbe_intf;
195986e3a040SPhilippe Reynes u8 port = cmd->base.port;
196086e3a040SPhilippe Reynes u32 advertising, supported;
196186e3a040SPhilippe Reynes u32 features;
196286e3a040SPhilippe Reynes
196386e3a040SPhilippe Reynes ethtool_convert_link_mode_to_legacy_u32(&advertising,
196486e3a040SPhilippe Reynes cmd->link_modes.advertising);
196586e3a040SPhilippe Reynes ethtool_convert_link_mode_to_legacy_u32(&supported,
196686e3a040SPhilippe Reynes cmd->link_modes.supported);
196786e3a040SPhilippe Reynes features = advertising & supported;
19686f8d3f33SWingman Kwok
19696f8d3f33SWingman Kwok if (!phy)
19706f8d3f33SWingman Kwok return -EINVAL;
19716f8d3f33SWingman Kwok
1972e9838ef2SWingMan Kwok gbe_intf = keystone_get_intf_data(netcp);
19736f8d3f33SWingman Kwok if (!gbe_intf)
19746f8d3f33SWingman Kwok return -EINVAL;
19756f8d3f33SWingman Kwok
19766f8d3f33SWingman Kwok if (!gbe_intf->slave)
19776f8d3f33SWingman Kwok return -EINVAL;
19786f8d3f33SWingman Kwok
197986e3a040SPhilippe Reynes if (port != gbe_intf->slave->phy_port_t) {
198086e3a040SPhilippe Reynes if ((port == PORT_TP) && !(features & ADVERTISED_TP))
19816f8d3f33SWingman Kwok return -EINVAL;
19826f8d3f33SWingman Kwok
198386e3a040SPhilippe Reynes if ((port == PORT_AUI) && !(features & ADVERTISED_AUI))
19846f8d3f33SWingman Kwok return -EINVAL;
19856f8d3f33SWingman Kwok
198686e3a040SPhilippe Reynes if ((port == PORT_BNC) && !(features & ADVERTISED_BNC))
19876f8d3f33SWingman Kwok return -EINVAL;
19886f8d3f33SWingman Kwok
198986e3a040SPhilippe Reynes if ((port == PORT_MII) && !(features & ADVERTISED_MII))
19906f8d3f33SWingman Kwok return -EINVAL;
19916f8d3f33SWingman Kwok
199286e3a040SPhilippe Reynes if ((port == PORT_FIBRE) && !(features & ADVERTISED_FIBRE))
19936f8d3f33SWingman Kwok return -EINVAL;
19946f8d3f33SWingman Kwok }
19956f8d3f33SWingman Kwok
199686e3a040SPhilippe Reynes gbe_intf->slave->phy_port_t = port;
199786e3a040SPhilippe Reynes return phy_ethtool_ksettings_set(phy, cmd);
19986f8d3f33SWingman Kwok }
19996f8d3f33SWingman Kwok
20006246168bSWingMan Kwok #if IS_ENABLED(CONFIG_TI_CPTS)
keystone_get_ts_info(struct net_device * ndev,struct ethtool_ts_info * info)20016246168bSWingMan Kwok static int keystone_get_ts_info(struct net_device *ndev,
20026246168bSWingMan Kwok struct ethtool_ts_info *info)
20036246168bSWingMan Kwok {
20046246168bSWingMan Kwok struct netcp_intf *netcp = netdev_priv(ndev);
20056246168bSWingMan Kwok struct gbe_intf *gbe_intf;
20066246168bSWingMan Kwok
20076246168bSWingMan Kwok gbe_intf = netcp_module_get_intf_data(&gbe_module, netcp);
20086246168bSWingMan Kwok if (!gbe_intf || !gbe_intf->gbe_dev->cpts)
20096246168bSWingMan Kwok return -EINVAL;
20106246168bSWingMan Kwok
20116246168bSWingMan Kwok info->so_timestamping =
20126246168bSWingMan Kwok SOF_TIMESTAMPING_TX_HARDWARE |
20136246168bSWingMan Kwok SOF_TIMESTAMPING_TX_SOFTWARE |
20146246168bSWingMan Kwok SOF_TIMESTAMPING_RX_HARDWARE |
20156246168bSWingMan Kwok SOF_TIMESTAMPING_RX_SOFTWARE |
20166246168bSWingMan Kwok SOF_TIMESTAMPING_SOFTWARE |
20176246168bSWingMan Kwok SOF_TIMESTAMPING_RAW_HARDWARE;
20186246168bSWingMan Kwok info->phc_index = gbe_intf->gbe_dev->cpts->phc_index;
20196246168bSWingMan Kwok info->tx_types =
20206246168bSWingMan Kwok (1 << HWTSTAMP_TX_OFF) |
20216246168bSWingMan Kwok (1 << HWTSTAMP_TX_ON);
20226246168bSWingMan Kwok info->rx_filters =
20236246168bSWingMan Kwok (1 << HWTSTAMP_FILTER_NONE) |
20246246168bSWingMan Kwok (1 << HWTSTAMP_FILTER_PTP_V1_L4_EVENT) |
20256246168bSWingMan Kwok (1 << HWTSTAMP_FILTER_PTP_V2_EVENT);
20266246168bSWingMan Kwok return 0;
20276246168bSWingMan Kwok }
20286246168bSWingMan Kwok #else
keystone_get_ts_info(struct net_device * ndev,struct ethtool_ts_info * info)20296246168bSWingMan Kwok static int keystone_get_ts_info(struct net_device *ndev,
20306246168bSWingMan Kwok struct ethtool_ts_info *info)
20316246168bSWingMan Kwok {
20326246168bSWingMan Kwok info->so_timestamping =
20336246168bSWingMan Kwok SOF_TIMESTAMPING_TX_SOFTWARE |
20346246168bSWingMan Kwok SOF_TIMESTAMPING_RX_SOFTWARE |
20356246168bSWingMan Kwok SOF_TIMESTAMPING_SOFTWARE;
20366246168bSWingMan Kwok info->phc_index = -1;
20376246168bSWingMan Kwok info->tx_types = 0;
20386246168bSWingMan Kwok info->rx_filters = 0;
20396246168bSWingMan Kwok return 0;
20406246168bSWingMan Kwok }
20416246168bSWingMan Kwok #endif /* CONFIG_TI_CPTS */
20426246168bSWingMan Kwok
20436f8d3f33SWingman Kwok static const struct ethtool_ops keystone_ethtool_ops = {
20446f8d3f33SWingman Kwok .get_drvinfo = keystone_get_drvinfo,
20456f8d3f33SWingman Kwok .get_link = ethtool_op_get_link,
20466f8d3f33SWingman Kwok .get_msglevel = keystone_get_msglevel,
20476f8d3f33SWingman Kwok .set_msglevel = keystone_set_msglevel,
20486f8d3f33SWingman Kwok .get_strings = keystone_get_stat_strings,
20496f8d3f33SWingman Kwok .get_sset_count = keystone_get_sset_count,
20506f8d3f33SWingman Kwok .get_ethtool_stats = keystone_get_ethtool_stats,
205186e3a040SPhilippe Reynes .get_link_ksettings = keystone_get_link_ksettings,
205286e3a040SPhilippe Reynes .set_link_ksettings = keystone_set_link_ksettings,
20536246168bSWingMan Kwok .get_ts_info = keystone_get_ts_info,
20546f8d3f33SWingman Kwok };
20556f8d3f33SWingman Kwok
gbe_set_slave_mac(struct gbe_slave * slave,struct gbe_intf * gbe_intf)20566f8d3f33SWingman Kwok static void gbe_set_slave_mac(struct gbe_slave *slave,
20576f8d3f33SWingman Kwok struct gbe_intf *gbe_intf)
20586f8d3f33SWingman Kwok {
20596f8d3f33SWingman Kwok struct net_device *ndev = gbe_intf->ndev;
20606f8d3f33SWingman Kwok
20616f8d3f33SWingman Kwok writel(mac_hi(ndev->dev_addr), GBE_REG_ADDR(slave, port_regs, sa_hi));
20626f8d3f33SWingman Kwok writel(mac_lo(ndev->dev_addr), GBE_REG_ADDR(slave, port_regs, sa_lo));
20636f8d3f33SWingman Kwok }
20646f8d3f33SWingman Kwok
gbe_get_slave_port(struct gbe_priv * priv,u32 slave_num)20656f8d3f33SWingman Kwok static int gbe_get_slave_port(struct gbe_priv *priv, u32 slave_num)
20666f8d3f33SWingman Kwok {
20676f8d3f33SWingman Kwok if (priv->host_port == 0)
20686f8d3f33SWingman Kwok return slave_num + 1;
20696f8d3f33SWingman Kwok
20706f8d3f33SWingman Kwok return slave_num;
20716f8d3f33SWingman Kwok }
20726f8d3f33SWingman Kwok
netcp_ethss_link_state_action(struct gbe_priv * gbe_dev,struct net_device * ndev,struct gbe_slave * slave,int up)20736f8d3f33SWingman Kwok static void netcp_ethss_link_state_action(struct gbe_priv *gbe_dev,
20746f8d3f33SWingman Kwok struct net_device *ndev,
20756f8d3f33SWingman Kwok struct gbe_slave *slave,
20766f8d3f33SWingman Kwok int up)
20776f8d3f33SWingman Kwok {
20786f8d3f33SWingman Kwok struct phy_device *phy = slave->phy;
20796f8d3f33SWingman Kwok u32 mac_control = 0;
20806f8d3f33SWingman Kwok
20816f8d3f33SWingman Kwok if (up) {
20826f8d3f33SWingman Kwok mac_control = slave->mac_control;
208390cff9e2SWingman Kwok if (phy && (phy->speed == SPEED_1000)) {
20846f8d3f33SWingman Kwok mac_control |= MACSL_GIG_MODE;
208590cff9e2SWingman Kwok mac_control &= ~MACSL_XGIG_MODE;
208690cff9e2SWingman Kwok } else if (phy && (phy->speed == SPEED_10000)) {
208790cff9e2SWingman Kwok mac_control |= MACSL_XGIG_MODE;
208890cff9e2SWingman Kwok mac_control &= ~MACSL_GIG_MODE;
208990cff9e2SWingman Kwok }
20906f8d3f33SWingman Kwok
20916f8d3f33SWingman Kwok writel(mac_control, GBE_REG_ADDR(slave, emac_regs,
20926f8d3f33SWingman Kwok mac_control));
20936f8d3f33SWingman Kwok
20946f8d3f33SWingman Kwok cpsw_ale_control_set(gbe_dev->ale, slave->port_num,
20956f8d3f33SWingman Kwok ALE_PORT_STATE,
20966f8d3f33SWingman Kwok ALE_PORT_STATE_FORWARD);
20976f8d3f33SWingman Kwok
20988e046d68SKaricheri, Muralidharan if (ndev && slave->open &&
2099478e9a5fSMurali Karicheri ((slave->link_interface != SGMII_LINK_MAC_PHY) &&
2100478e9a5fSMurali Karicheri (slave->link_interface != RGMII_LINK_MAC_PHY) &&
2101478e9a5fSMurali Karicheri (slave->link_interface != XGMII_LINK_MAC_PHY)))
21026f8d3f33SWingman Kwok netif_carrier_on(ndev);
21036f8d3f33SWingman Kwok } else {
21046f8d3f33SWingman Kwok writel(mac_control, GBE_REG_ADDR(slave, emac_regs,
21056f8d3f33SWingman Kwok mac_control));
21066f8d3f33SWingman Kwok cpsw_ale_control_set(gbe_dev->ale, slave->port_num,
21076f8d3f33SWingman Kwok ALE_PORT_STATE,
21086f8d3f33SWingman Kwok ALE_PORT_STATE_DISABLE);
21098e046d68SKaricheri, Muralidharan if (ndev &&
2110478e9a5fSMurali Karicheri ((slave->link_interface != SGMII_LINK_MAC_PHY) &&
2111478e9a5fSMurali Karicheri (slave->link_interface != RGMII_LINK_MAC_PHY) &&
2112478e9a5fSMurali Karicheri (slave->link_interface != XGMII_LINK_MAC_PHY)))
21136f8d3f33SWingman Kwok netif_carrier_off(ndev);
21146f8d3f33SWingman Kwok }
21156f8d3f33SWingman Kwok
21166f8d3f33SWingman Kwok if (phy)
21176f8d3f33SWingman Kwok phy_print_status(phy);
21186f8d3f33SWingman Kwok }
21196f8d3f33SWingman Kwok
gbe_phy_link_status(struct gbe_slave * slave)21206f8d3f33SWingman Kwok static bool gbe_phy_link_status(struct gbe_slave *slave)
21216f8d3f33SWingman Kwok {
21226f8d3f33SWingman Kwok return !slave->phy || slave->phy->link;
21236f8d3f33SWingman Kwok }
21246f8d3f33SWingman Kwok
21257771f2b4SMurali Karicheri #define RGMII_REG_STATUS_LINK BIT(0)
21267771f2b4SMurali Karicheri
netcp_2u_rgmii_get_port_link(struct gbe_priv * gbe_dev,bool * status)21277771f2b4SMurali Karicheri static void netcp_2u_rgmii_get_port_link(struct gbe_priv *gbe_dev, bool *status)
21287771f2b4SMurali Karicheri {
21297771f2b4SMurali Karicheri u32 val = 0;
21307771f2b4SMurali Karicheri
21317771f2b4SMurali Karicheri val = readl(GBE_REG_ADDR(gbe_dev, ss_regs, rgmii_status));
21327771f2b4SMurali Karicheri *status = !!(val & RGMII_REG_STATUS_LINK);
21337771f2b4SMurali Karicheri }
21347771f2b4SMurali Karicheri
netcp_ethss_update_link_state(struct gbe_priv * gbe_dev,struct gbe_slave * slave,struct net_device * ndev)21356f8d3f33SWingman Kwok static void netcp_ethss_update_link_state(struct gbe_priv *gbe_dev,
21366f8d3f33SWingman Kwok struct gbe_slave *slave,
21376f8d3f33SWingman Kwok struct net_device *ndev)
21386f8d3f33SWingman Kwok {
21397771f2b4SMurali Karicheri bool sw_link_state = true, phy_link_state;
21407771f2b4SMurali Karicheri int sp = slave->slave_num, link_state;
21416f8d3f33SWingman Kwok
21426f8d3f33SWingman Kwok if (!slave->open)
21436f8d3f33SWingman Kwok return;
21446f8d3f33SWingman Kwok
21457771f2b4SMurali Karicheri if (SLAVE_LINK_IS_RGMII(slave))
21467771f2b4SMurali Karicheri netcp_2u_rgmii_get_port_link(gbe_dev,
21477771f2b4SMurali Karicheri &sw_link_state);
21487771f2b4SMurali Karicheri if (SLAVE_LINK_IS_SGMII(slave))
21497771f2b4SMurali Karicheri sw_link_state =
21508c85151dSWingMan Kwok netcp_sgmii_get_port_link(SGMII_BASE(gbe_dev, sp), sp);
21519a391c7bSWingMan Kwok
21526f8d3f33SWingman Kwok phy_link_state = gbe_phy_link_status(slave);
21537771f2b4SMurali Karicheri link_state = phy_link_state & sw_link_state;
21546f8d3f33SWingman Kwok
21556f8d3f33SWingman Kwok if (atomic_xchg(&slave->link_state, link_state) != link_state)
21566f8d3f33SWingman Kwok netcp_ethss_link_state_action(gbe_dev, ndev, slave,
21576f8d3f33SWingman Kwok link_state);
21586f8d3f33SWingman Kwok }
21596f8d3f33SWingman Kwok
xgbe_adjust_link(struct net_device * ndev)216090cff9e2SWingman Kwok static void xgbe_adjust_link(struct net_device *ndev)
216190cff9e2SWingman Kwok {
216290cff9e2SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev);
216390cff9e2SWingman Kwok struct gbe_intf *gbe_intf;
216490cff9e2SWingman Kwok
216590cff9e2SWingman Kwok gbe_intf = netcp_module_get_intf_data(&xgbe_module, netcp);
216690cff9e2SWingman Kwok if (!gbe_intf)
216790cff9e2SWingman Kwok return;
216890cff9e2SWingman Kwok
216990cff9e2SWingman Kwok netcp_ethss_update_link_state(gbe_intf->gbe_dev, gbe_intf->slave,
217090cff9e2SWingman Kwok ndev);
217190cff9e2SWingman Kwok }
217290cff9e2SWingman Kwok
gbe_adjust_link(struct net_device * ndev)21736f8d3f33SWingman Kwok static void gbe_adjust_link(struct net_device *ndev)
21746f8d3f33SWingman Kwok {
21756f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev);
21766f8d3f33SWingman Kwok struct gbe_intf *gbe_intf;
21776f8d3f33SWingman Kwok
21786f8d3f33SWingman Kwok gbe_intf = netcp_module_get_intf_data(&gbe_module, netcp);
21796f8d3f33SWingman Kwok if (!gbe_intf)
21806f8d3f33SWingman Kwok return;
21816f8d3f33SWingman Kwok
21826f8d3f33SWingman Kwok netcp_ethss_update_link_state(gbe_intf->gbe_dev, gbe_intf->slave,
21836f8d3f33SWingman Kwok ndev);
21846f8d3f33SWingman Kwok }
21856f8d3f33SWingman Kwok
gbe_adjust_link_sec_slaves(struct net_device * ndev)21866f8d3f33SWingman Kwok static void gbe_adjust_link_sec_slaves(struct net_device *ndev)
21876f8d3f33SWingman Kwok {
21886f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = netdev_priv(ndev);
21896f8d3f33SWingman Kwok struct gbe_slave *slave;
21906f8d3f33SWingman Kwok
21916f8d3f33SWingman Kwok for_each_sec_slave(slave, gbe_dev)
21926f8d3f33SWingman Kwok netcp_ethss_update_link_state(gbe_dev, slave, NULL);
21936f8d3f33SWingman Kwok }
21946f8d3f33SWingman Kwok
21956f8d3f33SWingman Kwok /* Reset EMAC
21966f8d3f33SWingman Kwok * Soft reset is set and polled until clear, or until a timeout occurs
21976f8d3f33SWingman Kwok */
gbe_port_reset(struct gbe_slave * slave)21986f8d3f33SWingman Kwok static int gbe_port_reset(struct gbe_slave *slave)
21996f8d3f33SWingman Kwok {
22006f8d3f33SWingman Kwok u32 i, v;
22016f8d3f33SWingman Kwok
22026f8d3f33SWingman Kwok /* Set the soft reset bit */
22036f8d3f33SWingman Kwok writel(SOFT_RESET, GBE_REG_ADDR(slave, emac_regs, soft_reset));
22046f8d3f33SWingman Kwok
22056f8d3f33SWingman Kwok /* Wait for the bit to clear */
22066f8d3f33SWingman Kwok for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) {
22076f8d3f33SWingman Kwok v = readl(GBE_REG_ADDR(slave, emac_regs, soft_reset));
22086f8d3f33SWingman Kwok if ((v & SOFT_RESET_MASK) != SOFT_RESET)
22096f8d3f33SWingman Kwok return 0;
22106f8d3f33SWingman Kwok }
22116f8d3f33SWingman Kwok
22126f8d3f33SWingman Kwok /* Timeout on the reset */
22136f8d3f33SWingman Kwok return GMACSL_RET_WARN_RESET_INCOMPLETE;
22146f8d3f33SWingman Kwok }
22156f8d3f33SWingman Kwok
22166f8d3f33SWingman Kwok /* Configure EMAC */
gbe_port_config(struct gbe_priv * gbe_dev,struct gbe_slave * slave,int max_rx_len)22176f8d3f33SWingman Kwok static void gbe_port_config(struct gbe_priv *gbe_dev, struct gbe_slave *slave,
22186f8d3f33SWingman Kwok int max_rx_len)
22196f8d3f33SWingman Kwok {
22209a391c7bSWingMan Kwok void __iomem *rx_maxlen_reg;
222190cff9e2SWingman Kwok u32 xgmii_mode;
222290cff9e2SWingman Kwok
22236f8d3f33SWingman Kwok if (max_rx_len > NETCP_MAX_FRAME_SIZE)
22246f8d3f33SWingman Kwok max_rx_len = NETCP_MAX_FRAME_SIZE;
22256f8d3f33SWingman Kwok
222690cff9e2SWingman Kwok /* Enable correct MII mode at SS level */
22272953586dSMurali Karicheri if (IS_SS_ID_XGBE(gbe_dev) &&
222890cff9e2SWingman Kwok (slave->link_interface >= XGMII_LINK_MAC_PHY)) {
222990cff9e2SWingman Kwok xgmii_mode = readl(GBE_REG_ADDR(gbe_dev, ss_regs, control));
223090cff9e2SWingman Kwok xgmii_mode |= (1 << slave->slave_num);
223190cff9e2SWingman Kwok writel(xgmii_mode, GBE_REG_ADDR(gbe_dev, ss_regs, control));
223290cff9e2SWingman Kwok }
223390cff9e2SWingman Kwok
22349a391c7bSWingMan Kwok if (IS_SS_ID_MU(gbe_dev))
22359a391c7bSWingMan Kwok rx_maxlen_reg = GBE_REG_ADDR(slave, port_regs, rx_maxlen);
22369a391c7bSWingMan Kwok else
22379a391c7bSWingMan Kwok rx_maxlen_reg = GBE_REG_ADDR(slave, emac_regs, rx_maxlen);
22389a391c7bSWingMan Kwok
22399a391c7bSWingMan Kwok writel(max_rx_len, rx_maxlen_reg);
22406f8d3f33SWingman Kwok writel(slave->mac_control, GBE_REG_ADDR(slave, emac_regs, mac_control));
22416f8d3f33SWingman Kwok }
22426f8d3f33SWingman Kwok
gbe_sgmii_rtreset(struct gbe_priv * priv,struct gbe_slave * slave,bool set)22437025e88aSWingMan Kwok static void gbe_sgmii_rtreset(struct gbe_priv *priv,
22447025e88aSWingMan Kwok struct gbe_slave *slave, bool set)
22457025e88aSWingMan Kwok {
22467025e88aSWingMan Kwok if (SLAVE_LINK_IS_XGMII(slave))
22477025e88aSWingMan Kwok return;
22487025e88aSWingMan Kwok
22498c85151dSWingMan Kwok netcp_sgmii_rtreset(SGMII_BASE(priv, slave->slave_num),
22508c85151dSWingMan Kwok slave->slave_num, set);
22517025e88aSWingMan Kwok }
22527025e88aSWingMan Kwok
gbe_slave_stop(struct gbe_intf * intf)22536f8d3f33SWingman Kwok static void gbe_slave_stop(struct gbe_intf *intf)
22546f8d3f33SWingman Kwok {
22556f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = intf->gbe_dev;
22566f8d3f33SWingman Kwok struct gbe_slave *slave = intf->slave;
22576f8d3f33SWingman Kwok
2258775f9535SMurali Karicheri if (!IS_SS_ID_2U(gbe_dev))
22597025e88aSWingMan Kwok gbe_sgmii_rtreset(gbe_dev, slave, true);
22606f8d3f33SWingman Kwok gbe_port_reset(slave);
22616f8d3f33SWingman Kwok /* Disable forwarding */
22626f8d3f33SWingman Kwok cpsw_ale_control_set(gbe_dev->ale, slave->port_num,
22636f8d3f33SWingman Kwok ALE_PORT_STATE, ALE_PORT_STATE_DISABLE);
22646f8d3f33SWingman Kwok cpsw_ale_del_mcast(gbe_dev->ale, intf->ndev->broadcast,
22656f8d3f33SWingman Kwok 1 << slave->port_num, 0, 0);
22666f8d3f33SWingman Kwok
22676f8d3f33SWingman Kwok if (!slave->phy)
22686f8d3f33SWingman Kwok return;
22696f8d3f33SWingman Kwok
22706f8d3f33SWingman Kwok phy_stop(slave->phy);
22716f8d3f33SWingman Kwok phy_disconnect(slave->phy);
22726f8d3f33SWingman Kwok slave->phy = NULL;
22736f8d3f33SWingman Kwok }
22746f8d3f33SWingman Kwok
gbe_sgmii_config(struct gbe_priv * priv,struct gbe_slave * slave)22756f8d3f33SWingman Kwok static void gbe_sgmii_config(struct gbe_priv *priv, struct gbe_slave *slave)
22766f8d3f33SWingman Kwok {
22778c85151dSWingMan Kwok if (SLAVE_LINK_IS_XGMII(slave))
22788c85151dSWingMan Kwok return;
22796f8d3f33SWingman Kwok
22808c85151dSWingMan Kwok netcp_sgmii_reset(SGMII_BASE(priv, slave->slave_num), slave->slave_num);
22818c85151dSWingMan Kwok netcp_sgmii_config(SGMII_BASE(priv, slave->slave_num), slave->slave_num,
22826f8d3f33SWingman Kwok slave->link_interface);
22836f8d3f33SWingman Kwok }
22846f8d3f33SWingman Kwok
gbe_slave_open(struct gbe_intf * gbe_intf)22856f8d3f33SWingman Kwok static int gbe_slave_open(struct gbe_intf *gbe_intf)
22866f8d3f33SWingman Kwok {
22876f8d3f33SWingman Kwok struct gbe_priv *priv = gbe_intf->gbe_dev;
22886f8d3f33SWingman Kwok struct gbe_slave *slave = gbe_intf->slave;
22896f8d3f33SWingman Kwok phy_interface_t phy_mode;
22906f8d3f33SWingman Kwok bool has_phy = false;
22910c65b2b9SAndrew Lunn int err;
22926f8d3f33SWingman Kwok
22936f8d3f33SWingman Kwok void (*hndlr)(struct net_device *) = gbe_adjust_link;
22946f8d3f33SWingman Kwok
2295775f9535SMurali Karicheri if (!IS_SS_ID_2U(priv))
22966f8d3f33SWingman Kwok gbe_sgmii_config(priv, slave);
22976f8d3f33SWingman Kwok gbe_port_reset(slave);
2298775f9535SMurali Karicheri if (!IS_SS_ID_2U(priv))
22997025e88aSWingMan Kwok gbe_sgmii_rtreset(priv, slave, false);
23006f8d3f33SWingman Kwok gbe_port_config(priv, slave, priv->rx_packet_max);
23016f8d3f33SWingman Kwok gbe_set_slave_mac(slave, gbe_intf);
230265c45064SMurali Karicheri /* For NU & 2U switch, map the vlan priorities to zero
230365c45064SMurali Karicheri * as we only configure to use priority 0
230465c45064SMurali Karicheri */
230565c45064SMurali Karicheri if (IS_SS_ID_MU(priv))
230665c45064SMurali Karicheri writel(HOST_TX_PRI_MAP_DEFAULT,
230765c45064SMurali Karicheri GBE_REG_ADDR(slave, port_regs, rx_pri_map));
230865c45064SMurali Karicheri
23096f8d3f33SWingman Kwok /* enable forwarding */
23106f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, slave->port_num,
23116f8d3f33SWingman Kwok ALE_PORT_STATE, ALE_PORT_STATE_FORWARD);
23126f8d3f33SWingman Kwok cpsw_ale_add_mcast(priv->ale, gbe_intf->ndev->broadcast,
23136f8d3f33SWingman Kwok 1 << slave->port_num, 0, 0, ALE_MCAST_FWD_2);
23146f8d3f33SWingman Kwok
23156f8d3f33SWingman Kwok if (slave->link_interface == SGMII_LINK_MAC_PHY) {
23166f8d3f33SWingman Kwok has_phy = true;
23176f8d3f33SWingman Kwok phy_mode = PHY_INTERFACE_MODE_SGMII;
23186f8d3f33SWingman Kwok slave->phy_port_t = PORT_MII;
23197b647b93SMurali Karicheri } else if (slave->link_interface == RGMII_LINK_MAC_PHY) {
23207b647b93SMurali Karicheri has_phy = true;
23210c65b2b9SAndrew Lunn err = of_get_phy_mode(slave->node, &phy_mode);
23227b647b93SMurali Karicheri /* if phy-mode is not present, default to
23237b647b93SMurali Karicheri * PHY_INTERFACE_MODE_RGMII
23247b647b93SMurali Karicheri */
23250c65b2b9SAndrew Lunn if (err)
23267b647b93SMurali Karicheri phy_mode = PHY_INTERFACE_MODE_RGMII;
23277b647b93SMurali Karicheri
23287b647b93SMurali Karicheri if (!phy_interface_mode_is_rgmii(phy_mode)) {
23297b647b93SMurali Karicheri dev_err(priv->dev,
23307b647b93SMurali Karicheri "Unsupported phy mode %d\n", phy_mode);
23317b647b93SMurali Karicheri return -EINVAL;
23327b647b93SMurali Karicheri }
23337b647b93SMurali Karicheri slave->phy_port_t = PORT_MII;
23346f8d3f33SWingman Kwok } else if (slave->link_interface == XGMII_LINK_MAC_PHY) {
23356f8d3f33SWingman Kwok has_phy = true;
23366f8d3f33SWingman Kwok phy_mode = PHY_INTERFACE_MODE_NA;
23376f8d3f33SWingman Kwok slave->phy_port_t = PORT_FIBRE;
23386f8d3f33SWingman Kwok }
23396f8d3f33SWingman Kwok
23406f8d3f33SWingman Kwok if (has_phy) {
23412953586dSMurali Karicheri if (IS_SS_ID_XGBE(priv))
234290cff9e2SWingman Kwok hndlr = xgbe_adjust_link;
234390cff9e2SWingman Kwok
23446f8d3f33SWingman Kwok slave->phy = of_phy_connect(gbe_intf->ndev,
23456f8d3f33SWingman Kwok slave->phy_node,
23466f8d3f33SWingman Kwok hndlr, 0,
23476f8d3f33SWingman Kwok phy_mode);
23486f8d3f33SWingman Kwok if (!slave->phy) {
23496f8d3f33SWingman Kwok dev_err(priv->dev, "phy not found on slave %d\n",
23506f8d3f33SWingman Kwok slave->slave_num);
23516f8d3f33SWingman Kwok return -ENODEV;
23526f8d3f33SWingman Kwok }
23536f8d3f33SWingman Kwok dev_dbg(priv->dev, "phy found: id is: 0x%s\n",
235484eff6d1SAndrew Lunn phydev_name(slave->phy));
23556f8d3f33SWingman Kwok phy_start(slave->phy);
23566f8d3f33SWingman Kwok }
23576f8d3f33SWingman Kwok return 0;
23586f8d3f33SWingman Kwok }
23596f8d3f33SWingman Kwok
gbe_init_host_port(struct gbe_priv * priv)23606f8d3f33SWingman Kwok static void gbe_init_host_port(struct gbe_priv *priv)
23616f8d3f33SWingman Kwok {
23626f8d3f33SWingman Kwok int bypass_en = 1;
23639a391c7bSWingMan Kwok
23649a391c7bSWingMan Kwok /* Host Tx Pri */
23654c0ef231SWingMan Kwok if (IS_SS_ID_NU(priv) || IS_SS_ID_XGBE(priv))
23669a391c7bSWingMan Kwok writel(HOST_TX_PRI_MAP_DEFAULT,
23679a391c7bSWingMan Kwok GBE_REG_ADDR(priv, host_port_regs, tx_pri_map));
23689a391c7bSWingMan Kwok
23696f8d3f33SWingman Kwok /* Max length register */
23706f8d3f33SWingman Kwok writel(NETCP_MAX_FRAME_SIZE, GBE_REG_ADDR(priv, host_port_regs,
23716f8d3f33SWingman Kwok rx_maxlen));
23726f8d3f33SWingman Kwok
23736f8d3f33SWingman Kwok cpsw_ale_start(priv->ale);
23746f8d3f33SWingman Kwok
23756f8d3f33SWingman Kwok if (priv->enable_ale)
23766f8d3f33SWingman Kwok bypass_en = 0;
23776f8d3f33SWingman Kwok
23786f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, 0, ALE_BYPASS, bypass_en);
23796f8d3f33SWingman Kwok
23806f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, 0, ALE_NO_PORT_VLAN, 1);
23816f8d3f33SWingman Kwok
23826f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, priv->host_port,
23836f8d3f33SWingman Kwok ALE_PORT_STATE, ALE_PORT_STATE_FORWARD);
23846f8d3f33SWingman Kwok
23856f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, 0,
23866f8d3f33SWingman Kwok ALE_PORT_UNKNOWN_VLAN_MEMBER,
23876f8d3f33SWingman Kwok GBE_PORT_MASK(priv->ale_ports));
23886f8d3f33SWingman Kwok
23896f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, 0,
23906f8d3f33SWingman Kwok ALE_PORT_UNKNOWN_MCAST_FLOOD,
23916f8d3f33SWingman Kwok GBE_PORT_MASK(priv->ale_ports - 1));
23926f8d3f33SWingman Kwok
23936f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, 0,
23946f8d3f33SWingman Kwok ALE_PORT_UNKNOWN_REG_MCAST_FLOOD,
23956f8d3f33SWingman Kwok GBE_PORT_MASK(priv->ale_ports));
23966f8d3f33SWingman Kwok
23976f8d3f33SWingman Kwok cpsw_ale_control_set(priv->ale, 0,
23986f8d3f33SWingman Kwok ALE_PORT_UNTAGGED_EGRESS,
23996f8d3f33SWingman Kwok GBE_PORT_MASK(priv->ale_ports));
24006f8d3f33SWingman Kwok }
24016f8d3f33SWingman Kwok
gbe_add_mcast_addr(struct gbe_intf * gbe_intf,u8 * addr)24026f8d3f33SWingman Kwok static void gbe_add_mcast_addr(struct gbe_intf *gbe_intf, u8 *addr)
24036f8d3f33SWingman Kwok {
24046f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev;
24056f8d3f33SWingman Kwok u16 vlan_id;
24066f8d3f33SWingman Kwok
24076f8d3f33SWingman Kwok cpsw_ale_add_mcast(gbe_dev->ale, addr,
24086f8d3f33SWingman Kwok GBE_PORT_MASK(gbe_dev->ale_ports), 0, 0,
24096f8d3f33SWingman Kwok ALE_MCAST_FWD_2);
24106f8d3f33SWingman Kwok for_each_set_bit(vlan_id, gbe_intf->active_vlans, VLAN_N_VID) {
24116f8d3f33SWingman Kwok cpsw_ale_add_mcast(gbe_dev->ale, addr,
24126f8d3f33SWingman Kwok GBE_PORT_MASK(gbe_dev->ale_ports),
24136f8d3f33SWingman Kwok ALE_VLAN, vlan_id, ALE_MCAST_FWD_2);
24146f8d3f33SWingman Kwok }
24156f8d3f33SWingman Kwok }
24166f8d3f33SWingman Kwok
gbe_add_ucast_addr(struct gbe_intf * gbe_intf,u8 * addr)24176f8d3f33SWingman Kwok static void gbe_add_ucast_addr(struct gbe_intf *gbe_intf, u8 *addr)
24186f8d3f33SWingman Kwok {
24196f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev;
24206f8d3f33SWingman Kwok u16 vlan_id;
24216f8d3f33SWingman Kwok
24226f8d3f33SWingman Kwok cpsw_ale_add_ucast(gbe_dev->ale, addr, gbe_dev->host_port, 0, 0);
24236f8d3f33SWingman Kwok
24246f8d3f33SWingman Kwok for_each_set_bit(vlan_id, gbe_intf->active_vlans, VLAN_N_VID)
24256f8d3f33SWingman Kwok cpsw_ale_add_ucast(gbe_dev->ale, addr, gbe_dev->host_port,
24266f8d3f33SWingman Kwok ALE_VLAN, vlan_id);
24276f8d3f33SWingman Kwok }
24286f8d3f33SWingman Kwok
gbe_del_mcast_addr(struct gbe_intf * gbe_intf,u8 * addr)24296f8d3f33SWingman Kwok static void gbe_del_mcast_addr(struct gbe_intf *gbe_intf, u8 *addr)
24306f8d3f33SWingman Kwok {
24316f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev;
24326f8d3f33SWingman Kwok u16 vlan_id;
24336f8d3f33SWingman Kwok
24346f8d3f33SWingman Kwok cpsw_ale_del_mcast(gbe_dev->ale, addr, 0, 0, 0);
24356f8d3f33SWingman Kwok
24366f8d3f33SWingman Kwok for_each_set_bit(vlan_id, gbe_intf->active_vlans, VLAN_N_VID) {
24376f8d3f33SWingman Kwok cpsw_ale_del_mcast(gbe_dev->ale, addr, 0, ALE_VLAN, vlan_id);
24386f8d3f33SWingman Kwok }
24396f8d3f33SWingman Kwok }
24406f8d3f33SWingman Kwok
gbe_del_ucast_addr(struct gbe_intf * gbe_intf,u8 * addr)24416f8d3f33SWingman Kwok static void gbe_del_ucast_addr(struct gbe_intf *gbe_intf, u8 *addr)
24426f8d3f33SWingman Kwok {
24436f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev;
24446f8d3f33SWingman Kwok u16 vlan_id;
24456f8d3f33SWingman Kwok
24466f8d3f33SWingman Kwok cpsw_ale_del_ucast(gbe_dev->ale, addr, gbe_dev->host_port, 0, 0);
24476f8d3f33SWingman Kwok
24486f8d3f33SWingman Kwok for_each_set_bit(vlan_id, gbe_intf->active_vlans, VLAN_N_VID) {
24496f8d3f33SWingman Kwok cpsw_ale_del_ucast(gbe_dev->ale, addr, gbe_dev->host_port,
24506f8d3f33SWingman Kwok ALE_VLAN, vlan_id);
24516f8d3f33SWingman Kwok }
24526f8d3f33SWingman Kwok }
24536f8d3f33SWingman Kwok
gbe_add_addr(void * intf_priv,struct netcp_addr * naddr)24546f8d3f33SWingman Kwok static int gbe_add_addr(void *intf_priv, struct netcp_addr *naddr)
24556f8d3f33SWingman Kwok {
24566f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv;
24576f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev;
24586f8d3f33SWingman Kwok
24596f8d3f33SWingman Kwok dev_dbg(gbe_dev->dev, "ethss adding address %pM, type %d\n",
24606f8d3f33SWingman Kwok naddr->addr, naddr->type);
24616f8d3f33SWingman Kwok
24626f8d3f33SWingman Kwok switch (naddr->type) {
24636f8d3f33SWingman Kwok case ADDR_MCAST:
24646f8d3f33SWingman Kwok case ADDR_BCAST:
24656f8d3f33SWingman Kwok gbe_add_mcast_addr(gbe_intf, naddr->addr);
24666f8d3f33SWingman Kwok break;
24676f8d3f33SWingman Kwok case ADDR_UCAST:
24686f8d3f33SWingman Kwok case ADDR_DEV:
24696f8d3f33SWingman Kwok gbe_add_ucast_addr(gbe_intf, naddr->addr);
24706f8d3f33SWingman Kwok break;
24716f8d3f33SWingman Kwok case ADDR_ANY:
24726f8d3f33SWingman Kwok /* nothing to do for promiscuous */
24736f8d3f33SWingman Kwok default:
24746f8d3f33SWingman Kwok break;
24756f8d3f33SWingman Kwok }
24766f8d3f33SWingman Kwok
24776f8d3f33SWingman Kwok return 0;
24786f8d3f33SWingman Kwok }
24796f8d3f33SWingman Kwok
gbe_del_addr(void * intf_priv,struct netcp_addr * naddr)24806f8d3f33SWingman Kwok static int gbe_del_addr(void *intf_priv, struct netcp_addr *naddr)
24816f8d3f33SWingman Kwok {
24826f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv;
24836f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev;
24846f8d3f33SWingman Kwok
24856f8d3f33SWingman Kwok dev_dbg(gbe_dev->dev, "ethss deleting address %pM, type %d\n",
24866f8d3f33SWingman Kwok naddr->addr, naddr->type);
24876f8d3f33SWingman Kwok
24886f8d3f33SWingman Kwok switch (naddr->type) {
24896f8d3f33SWingman Kwok case ADDR_MCAST:
24906f8d3f33SWingman Kwok case ADDR_BCAST:
24916f8d3f33SWingman Kwok gbe_del_mcast_addr(gbe_intf, naddr->addr);
24926f8d3f33SWingman Kwok break;
24936f8d3f33SWingman Kwok case ADDR_UCAST:
24946f8d3f33SWingman Kwok case ADDR_DEV:
24956f8d3f33SWingman Kwok gbe_del_ucast_addr(gbe_intf, naddr->addr);
24966f8d3f33SWingman Kwok break;
24976f8d3f33SWingman Kwok case ADDR_ANY:
24986f8d3f33SWingman Kwok /* nothing to do for promiscuous */
24996f8d3f33SWingman Kwok default:
25006f8d3f33SWingman Kwok break;
25016f8d3f33SWingman Kwok }
25026f8d3f33SWingman Kwok
25036f8d3f33SWingman Kwok return 0;
25046f8d3f33SWingman Kwok }
25056f8d3f33SWingman Kwok
gbe_add_vid(void * intf_priv,int vid)25066f8d3f33SWingman Kwok static int gbe_add_vid(void *intf_priv, int vid)
25076f8d3f33SWingman Kwok {
25086f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv;
25096f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev;
25106f8d3f33SWingman Kwok
25116f8d3f33SWingman Kwok set_bit(vid, gbe_intf->active_vlans);
25126f8d3f33SWingman Kwok
25136f8d3f33SWingman Kwok cpsw_ale_add_vlan(gbe_dev->ale, vid,
25146f8d3f33SWingman Kwok GBE_PORT_MASK(gbe_dev->ale_ports),
25156f8d3f33SWingman Kwok GBE_MASK_NO_PORTS,
25166f8d3f33SWingman Kwok GBE_PORT_MASK(gbe_dev->ale_ports),
25176f8d3f33SWingman Kwok GBE_PORT_MASK(gbe_dev->ale_ports - 1));
25186f8d3f33SWingman Kwok
25196f8d3f33SWingman Kwok return 0;
25206f8d3f33SWingman Kwok }
25216f8d3f33SWingman Kwok
gbe_del_vid(void * intf_priv,int vid)25226f8d3f33SWingman Kwok static int gbe_del_vid(void *intf_priv, int vid)
25236f8d3f33SWingman Kwok {
25246f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv;
25256f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev;
25266f8d3f33SWingman Kwok
25276f8d3f33SWingman Kwok cpsw_ale_del_vlan(gbe_dev->ale, vid, 0);
25286f8d3f33SWingman Kwok clear_bit(vid, gbe_intf->active_vlans);
25296f8d3f33SWingman Kwok return 0;
25306f8d3f33SWingman Kwok }
25316f8d3f33SWingman Kwok
25326246168bSWingMan Kwok #if IS_ENABLED(CONFIG_TI_CPTS)
25336246168bSWingMan Kwok
gbe_txtstamp(void * context,struct sk_buff * skb)25346246168bSWingMan Kwok static void gbe_txtstamp(void *context, struct sk_buff *skb)
25356246168bSWingMan Kwok {
25366246168bSWingMan Kwok struct gbe_intf *gbe_intf = context;
25376246168bSWingMan Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev;
25386246168bSWingMan Kwok
25396246168bSWingMan Kwok cpts_tx_timestamp(gbe_dev->cpts, skb);
25406246168bSWingMan Kwok }
25416246168bSWingMan Kwok
gbe_need_txtstamp(struct gbe_intf * gbe_intf,const struct netcp_packet * p_info)25426246168bSWingMan Kwok static bool gbe_need_txtstamp(struct gbe_intf *gbe_intf,
25436246168bSWingMan Kwok const struct netcp_packet *p_info)
25446246168bSWingMan Kwok {
25456246168bSWingMan Kwok struct sk_buff *skb = p_info->skb;
25466246168bSWingMan Kwok
25470ccf59baSIvan Khoronzhuk return cpts_can_timestamp(gbe_intf->gbe_dev->cpts, skb);
25486246168bSWingMan Kwok }
25496246168bSWingMan Kwok
gbe_txtstamp_mark_pkt(struct gbe_intf * gbe_intf,struct netcp_packet * p_info)25506246168bSWingMan Kwok static int gbe_txtstamp_mark_pkt(struct gbe_intf *gbe_intf,
25516246168bSWingMan Kwok struct netcp_packet *p_info)
25526246168bSWingMan Kwok {
25536246168bSWingMan Kwok struct phy_device *phydev = p_info->skb->dev->phydev;
25546246168bSWingMan Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev;
25556246168bSWingMan Kwok
25566246168bSWingMan Kwok if (!(skb_shinfo(p_info->skb)->tx_flags & SKBTX_HW_TSTAMP) ||
2557a9423120SIvan Khoronzhuk !gbe_dev->tx_ts_enabled)
25586246168bSWingMan Kwok return 0;
25596246168bSWingMan Kwok
25606246168bSWingMan Kwok /* If phy has the txtstamp api, assume it will do it.
25616246168bSWingMan Kwok * We mark it here because skb_tx_timestamp() is called
25626246168bSWingMan Kwok * after all the txhooks are called.
25636246168bSWingMan Kwok */
2564bfd57b59SRichard Cochran if (phy_has_txtstamp(phydev)) {
25656246168bSWingMan Kwok skb_shinfo(p_info->skb)->tx_flags |= SKBTX_IN_PROGRESS;
25666246168bSWingMan Kwok return 0;
25676246168bSWingMan Kwok }
25686246168bSWingMan Kwok
25696246168bSWingMan Kwok if (gbe_need_txtstamp(gbe_intf, p_info)) {
25706246168bSWingMan Kwok p_info->txtstamp = gbe_txtstamp;
25716246168bSWingMan Kwok p_info->ts_context = (void *)gbe_intf;
25726246168bSWingMan Kwok skb_shinfo(p_info->skb)->tx_flags |= SKBTX_IN_PROGRESS;
25736246168bSWingMan Kwok }
25746246168bSWingMan Kwok
25756246168bSWingMan Kwok return 0;
25766246168bSWingMan Kwok }
25776246168bSWingMan Kwok
gbe_rxtstamp(struct gbe_intf * gbe_intf,struct netcp_packet * p_info)25786246168bSWingMan Kwok static int gbe_rxtstamp(struct gbe_intf *gbe_intf, struct netcp_packet *p_info)
25796246168bSWingMan Kwok {
25806246168bSWingMan Kwok struct phy_device *phydev = p_info->skb->dev->phydev;
25816246168bSWingMan Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev;
25826246168bSWingMan Kwok
25836246168bSWingMan Kwok if (p_info->rxtstamp_complete)
25846246168bSWingMan Kwok return 0;
25856246168bSWingMan Kwok
2586bfd57b59SRichard Cochran if (phy_has_rxtstamp(phydev)) {
25876246168bSWingMan Kwok p_info->rxtstamp_complete = true;
25886246168bSWingMan Kwok return 0;
25896246168bSWingMan Kwok }
25906246168bSWingMan Kwok
2591a9423120SIvan Khoronzhuk if (gbe_dev->rx_ts_enabled)
25926246168bSWingMan Kwok cpts_rx_timestamp(gbe_dev->cpts, p_info->skb);
2593a9423120SIvan Khoronzhuk
25946246168bSWingMan Kwok p_info->rxtstamp_complete = true;
25956246168bSWingMan Kwok
25966246168bSWingMan Kwok return 0;
25976246168bSWingMan Kwok }
25986246168bSWingMan Kwok
gbe_hwtstamp_get(struct gbe_intf * gbe_intf,struct ifreq * ifr)25996246168bSWingMan Kwok static int gbe_hwtstamp_get(struct gbe_intf *gbe_intf, struct ifreq *ifr)
26006246168bSWingMan Kwok {
26016246168bSWingMan Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev;
26026246168bSWingMan Kwok struct cpts *cpts = gbe_dev->cpts;
26036246168bSWingMan Kwok struct hwtstamp_config cfg;
26046246168bSWingMan Kwok
26056246168bSWingMan Kwok if (!cpts)
26066246168bSWingMan Kwok return -EOPNOTSUPP;
26076246168bSWingMan Kwok
26086246168bSWingMan Kwok cfg.flags = 0;
2609a9423120SIvan Khoronzhuk cfg.tx_type = gbe_dev->tx_ts_enabled ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
2610a9423120SIvan Khoronzhuk cfg.rx_filter = gbe_dev->rx_ts_enabled;
26116246168bSWingMan Kwok
26126246168bSWingMan Kwok return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
26136246168bSWingMan Kwok }
26146246168bSWingMan Kwok
gbe_hwtstamp(struct gbe_intf * gbe_intf)26156246168bSWingMan Kwok static void gbe_hwtstamp(struct gbe_intf *gbe_intf)
26166246168bSWingMan Kwok {
26176246168bSWingMan Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev;
26186246168bSWingMan Kwok struct gbe_slave *slave = gbe_intf->slave;
26196246168bSWingMan Kwok u32 ts_en, seq_id, ctl;
26206246168bSWingMan Kwok
2621a9423120SIvan Khoronzhuk if (!gbe_dev->rx_ts_enabled &&
2622a9423120SIvan Khoronzhuk !gbe_dev->tx_ts_enabled) {
26236246168bSWingMan Kwok writel(0, GBE_REG_ADDR(slave, port_regs, ts_ctl));
26246246168bSWingMan Kwok return;
26256246168bSWingMan Kwok }
26266246168bSWingMan Kwok
26276246168bSWingMan Kwok seq_id = (30 << TS_SEQ_ID_OFS_SHIFT) | ETH_P_1588;
26286246168bSWingMan Kwok ts_en = EVENT_MSG_BITS << TS_MSG_TYPE_EN_SHIFT;
26296246168bSWingMan Kwok ctl = ETH_P_1588 | TS_TTL_NONZERO |
26306246168bSWingMan Kwok (slave->ts_ctl.dst_port_map << TS_CTL_DST_PORT_SHIFT) |
26316246168bSWingMan Kwok (slave->ts_ctl.uni ? TS_UNI_EN :
26326246168bSWingMan Kwok slave->ts_ctl.maddr_map << TS_CTL_MADDR_SHIFT);
26336246168bSWingMan Kwok
2634a9423120SIvan Khoronzhuk if (gbe_dev->tx_ts_enabled)
26356246168bSWingMan Kwok ts_en |= (TS_TX_ANX_ALL_EN | TS_TX_VLAN_LT1_EN);
26366246168bSWingMan Kwok
2637a9423120SIvan Khoronzhuk if (gbe_dev->rx_ts_enabled)
26386246168bSWingMan Kwok ts_en |= (TS_RX_ANX_ALL_EN | TS_RX_VLAN_LT1_EN);
26396246168bSWingMan Kwok
26406246168bSWingMan Kwok writel(ts_en, GBE_REG_ADDR(slave, port_regs, ts_ctl));
26416246168bSWingMan Kwok writel(seq_id, GBE_REG_ADDR(slave, port_regs, ts_seq_ltype));
26426246168bSWingMan Kwok writel(ctl, GBE_REG_ADDR(slave, port_regs, ts_ctl_ltype2));
26436246168bSWingMan Kwok }
26446246168bSWingMan Kwok
gbe_hwtstamp_set(struct gbe_intf * gbe_intf,struct ifreq * ifr)26456246168bSWingMan Kwok static int gbe_hwtstamp_set(struct gbe_intf *gbe_intf, struct ifreq *ifr)
26466246168bSWingMan Kwok {
26476246168bSWingMan Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev;
26486246168bSWingMan Kwok struct cpts *cpts = gbe_dev->cpts;
26496246168bSWingMan Kwok struct hwtstamp_config cfg;
26506246168bSWingMan Kwok
26516246168bSWingMan Kwok if (!cpts)
26526246168bSWingMan Kwok return -EOPNOTSUPP;
26536246168bSWingMan Kwok
26546246168bSWingMan Kwok if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
26556246168bSWingMan Kwok return -EFAULT;
26566246168bSWingMan Kwok
26576246168bSWingMan Kwok switch (cfg.tx_type) {
26586246168bSWingMan Kwok case HWTSTAMP_TX_OFF:
2659a9423120SIvan Khoronzhuk gbe_dev->tx_ts_enabled = 0;
26606246168bSWingMan Kwok break;
26616246168bSWingMan Kwok case HWTSTAMP_TX_ON:
2662a9423120SIvan Khoronzhuk gbe_dev->tx_ts_enabled = 1;
26636246168bSWingMan Kwok break;
26646246168bSWingMan Kwok default:
26656246168bSWingMan Kwok return -ERANGE;
26666246168bSWingMan Kwok }
26676246168bSWingMan Kwok
26686246168bSWingMan Kwok switch (cfg.rx_filter) {
26696246168bSWingMan Kwok case HWTSTAMP_FILTER_NONE:
2670a9423120SIvan Khoronzhuk gbe_dev->rx_ts_enabled = HWTSTAMP_FILTER_NONE;
26716246168bSWingMan Kwok break;
26726246168bSWingMan Kwok case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
26736246168bSWingMan Kwok case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
26746246168bSWingMan Kwok case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
2675a9423120SIvan Khoronzhuk gbe_dev->rx_ts_enabled = HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
26766246168bSWingMan Kwok cfg.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
26776246168bSWingMan Kwok break;
26786246168bSWingMan Kwok case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
26796246168bSWingMan Kwok case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
26806246168bSWingMan Kwok case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
26816246168bSWingMan Kwok case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
26826246168bSWingMan Kwok case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
26836246168bSWingMan Kwok case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
26846246168bSWingMan Kwok case HWTSTAMP_FILTER_PTP_V2_EVENT:
26856246168bSWingMan Kwok case HWTSTAMP_FILTER_PTP_V2_SYNC:
26866246168bSWingMan Kwok case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
2687a9423120SIvan Khoronzhuk gbe_dev->rx_ts_enabled = HWTSTAMP_FILTER_PTP_V2_EVENT;
26886246168bSWingMan Kwok cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
26896246168bSWingMan Kwok break;
26906246168bSWingMan Kwok default:
26916246168bSWingMan Kwok return -ERANGE;
26926246168bSWingMan Kwok }
26936246168bSWingMan Kwok
26946246168bSWingMan Kwok gbe_hwtstamp(gbe_intf);
26956246168bSWingMan Kwok
26966246168bSWingMan Kwok return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
26976246168bSWingMan Kwok }
26986246168bSWingMan Kwok
gbe_register_cpts(struct gbe_priv * gbe_dev)26996246168bSWingMan Kwok static void gbe_register_cpts(struct gbe_priv *gbe_dev)
27006246168bSWingMan Kwok {
27016246168bSWingMan Kwok if (!gbe_dev->cpts)
27026246168bSWingMan Kwok return;
27036246168bSWingMan Kwok
27046246168bSWingMan Kwok if (gbe_dev->cpts_registered > 0)
27056246168bSWingMan Kwok goto done;
27066246168bSWingMan Kwok
27076246168bSWingMan Kwok if (cpts_register(gbe_dev->cpts)) {
27086246168bSWingMan Kwok dev_err(gbe_dev->dev, "error registering cpts device\n");
27096246168bSWingMan Kwok return;
27106246168bSWingMan Kwok }
27116246168bSWingMan Kwok
27126246168bSWingMan Kwok done:
27136246168bSWingMan Kwok ++gbe_dev->cpts_registered;
27146246168bSWingMan Kwok }
27156246168bSWingMan Kwok
gbe_unregister_cpts(struct gbe_priv * gbe_dev)27166246168bSWingMan Kwok static void gbe_unregister_cpts(struct gbe_priv *gbe_dev)
27176246168bSWingMan Kwok {
27186246168bSWingMan Kwok if (!gbe_dev->cpts || (gbe_dev->cpts_registered <= 0))
27196246168bSWingMan Kwok return;
27206246168bSWingMan Kwok
27216246168bSWingMan Kwok if (--gbe_dev->cpts_registered)
27226246168bSWingMan Kwok return;
27236246168bSWingMan Kwok
27246246168bSWingMan Kwok cpts_unregister(gbe_dev->cpts);
27256246168bSWingMan Kwok }
27266246168bSWingMan Kwok #else
gbe_txtstamp_mark_pkt(struct gbe_intf * gbe_intf,struct netcp_packet * p_info)27276246168bSWingMan Kwok static inline int gbe_txtstamp_mark_pkt(struct gbe_intf *gbe_intf,
27286246168bSWingMan Kwok struct netcp_packet *p_info)
27296246168bSWingMan Kwok {
27306246168bSWingMan Kwok return 0;
27316246168bSWingMan Kwok }
27326246168bSWingMan Kwok
gbe_rxtstamp(struct gbe_intf * gbe_intf,struct netcp_packet * p_info)27336246168bSWingMan Kwok static inline int gbe_rxtstamp(struct gbe_intf *gbe_intf,
27346246168bSWingMan Kwok struct netcp_packet *p_info)
27356246168bSWingMan Kwok {
27366246168bSWingMan Kwok return 0;
27376246168bSWingMan Kwok }
27386246168bSWingMan Kwok
gbe_hwtstamp(struct gbe_intf * gbe_intf,struct ifreq * ifr,int cmd)27396246168bSWingMan Kwok static inline int gbe_hwtstamp(struct gbe_intf *gbe_intf,
27406246168bSWingMan Kwok struct ifreq *ifr, int cmd)
27416246168bSWingMan Kwok {
27426246168bSWingMan Kwok return -EOPNOTSUPP;
27436246168bSWingMan Kwok }
27446246168bSWingMan Kwok
gbe_register_cpts(struct gbe_priv * gbe_dev)27456246168bSWingMan Kwok static inline void gbe_register_cpts(struct gbe_priv *gbe_dev)
27466246168bSWingMan Kwok {
27476246168bSWingMan Kwok }
27486246168bSWingMan Kwok
gbe_unregister_cpts(struct gbe_priv * gbe_dev)27496246168bSWingMan Kwok static inline void gbe_unregister_cpts(struct gbe_priv *gbe_dev)
27506246168bSWingMan Kwok {
27516246168bSWingMan Kwok }
27526246168bSWingMan Kwok
gbe_hwtstamp_get(struct gbe_intf * gbe_intf,struct ifreq * req)27536246168bSWingMan Kwok static inline int gbe_hwtstamp_get(struct gbe_intf *gbe_intf, struct ifreq *req)
27546246168bSWingMan Kwok {
27556246168bSWingMan Kwok return -EOPNOTSUPP;
27566246168bSWingMan Kwok }
27576246168bSWingMan Kwok
gbe_hwtstamp_set(struct gbe_intf * gbe_intf,struct ifreq * req)27586246168bSWingMan Kwok static inline int gbe_hwtstamp_set(struct gbe_intf *gbe_intf, struct ifreq *req)
27596246168bSWingMan Kwok {
27606246168bSWingMan Kwok return -EOPNOTSUPP;
27616246168bSWingMan Kwok }
27626246168bSWingMan Kwok #endif /* CONFIG_TI_CPTS */
27636246168bSWingMan Kwok
gbe_set_rx_mode(void * intf_priv,bool promisc)27648585661bSWingMan Kwok static int gbe_set_rx_mode(void *intf_priv, bool promisc)
27658585661bSWingMan Kwok {
27668585661bSWingMan Kwok struct gbe_intf *gbe_intf = intf_priv;
27678585661bSWingMan Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev;
27688585661bSWingMan Kwok struct cpsw_ale *ale = gbe_dev->ale;
27698585661bSWingMan Kwok unsigned long timeout;
27708585661bSWingMan Kwok int i, ret = -ETIMEDOUT;
27718585661bSWingMan Kwok
27728585661bSWingMan Kwok /* Disable(1)/Enable(0) Learn for all ports (host is port 0 and
27738585661bSWingMan Kwok * slaves are port 1 and up
27748585661bSWingMan Kwok */
27758585661bSWingMan Kwok for (i = 0; i <= gbe_dev->num_slaves; i++) {
27768585661bSWingMan Kwok cpsw_ale_control_set(ale, i,
27778585661bSWingMan Kwok ALE_PORT_NOLEARN, !!promisc);
27788585661bSWingMan Kwok cpsw_ale_control_set(ale, i,
27798585661bSWingMan Kwok ALE_PORT_NO_SA_UPDATE, !!promisc);
27808585661bSWingMan Kwok }
27818585661bSWingMan Kwok
27828585661bSWingMan Kwok if (!promisc) {
27838585661bSWingMan Kwok /* Don't Flood All Unicast Packets to Host port */
27848585661bSWingMan Kwok cpsw_ale_control_set(ale, 0, ALE_P0_UNI_FLOOD, 0);
27858585661bSWingMan Kwok dev_vdbg(gbe_dev->dev, "promiscuous mode disabled\n");
27868585661bSWingMan Kwok return 0;
27878585661bSWingMan Kwok }
27888585661bSWingMan Kwok
27898585661bSWingMan Kwok timeout = jiffies + HZ;
27908585661bSWingMan Kwok
27918585661bSWingMan Kwok /* Clear All Untouched entries */
27928585661bSWingMan Kwok cpsw_ale_control_set(ale, 0, ALE_AGEOUT, 1);
27938585661bSWingMan Kwok do {
27948585661bSWingMan Kwok cpu_relax();
27958585661bSWingMan Kwok if (cpsw_ale_control_get(ale, 0, ALE_AGEOUT)) {
27968585661bSWingMan Kwok ret = 0;
27978585661bSWingMan Kwok break;
27988585661bSWingMan Kwok }
27998585661bSWingMan Kwok
28008585661bSWingMan Kwok } while (time_after(timeout, jiffies));
28018585661bSWingMan Kwok
28028585661bSWingMan Kwok /* Make sure it is not a false timeout */
28038585661bSWingMan Kwok if (ret && !cpsw_ale_control_get(ale, 0, ALE_AGEOUT))
28048585661bSWingMan Kwok return ret;
28058585661bSWingMan Kwok
28068585661bSWingMan Kwok cpsw_ale_control_set(ale, 0, ALE_AGEOUT, 1);
28078585661bSWingMan Kwok
28088585661bSWingMan Kwok /* Clear all mcast from ALE */
28098585661bSWingMan Kwok cpsw_ale_flush_multicast(ale,
28108585661bSWingMan Kwok GBE_PORT_MASK(gbe_dev->ale_ports),
28118585661bSWingMan Kwok -1);
28128585661bSWingMan Kwok
28138585661bSWingMan Kwok /* Flood All Unicast Packets to Host port */
28148585661bSWingMan Kwok cpsw_ale_control_set(ale, 0, ALE_P0_UNI_FLOOD, 1);
28158585661bSWingMan Kwok dev_vdbg(gbe_dev->dev, "promiscuous mode enabled\n");
28168585661bSWingMan Kwok return ret;
28178585661bSWingMan Kwok }
28188585661bSWingMan Kwok
gbe_ioctl(void * intf_priv,struct ifreq * req,int cmd)28196f8d3f33SWingman Kwok static int gbe_ioctl(void *intf_priv, struct ifreq *req, int cmd)
28206f8d3f33SWingman Kwok {
28216f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv;
28226f8d3f33SWingman Kwok struct phy_device *phy = gbe_intf->slave->phy;
28236246168bSWingMan Kwok
2824bfd57b59SRichard Cochran if (!phy_has_hwtstamp(phy)) {
28256246168bSWingMan Kwok switch (cmd) {
28266246168bSWingMan Kwok case SIOCGHWTSTAMP:
28276246168bSWingMan Kwok return gbe_hwtstamp_get(gbe_intf, req);
28286246168bSWingMan Kwok case SIOCSHWTSTAMP:
28296246168bSWingMan Kwok return gbe_hwtstamp_set(gbe_intf, req);
28306246168bSWingMan Kwok }
28316246168bSWingMan Kwok }
28326f8d3f33SWingman Kwok
28336f8d3f33SWingman Kwok if (phy)
28346246168bSWingMan Kwok return phy_mii_ioctl(phy, req, cmd);
28356f8d3f33SWingman Kwok
28366246168bSWingMan Kwok return -EOPNOTSUPP;
28376f8d3f33SWingman Kwok }
28386f8d3f33SWingman Kwok
netcp_ethss_timer(struct timer_list * t)2839e99e88a9SKees Cook static void netcp_ethss_timer(struct timer_list *t)
28406f8d3f33SWingman Kwok {
2841e99e88a9SKees Cook struct gbe_priv *gbe_dev = from_timer(gbe_dev, t, timer);
28426f8d3f33SWingman Kwok struct gbe_intf *gbe_intf;
28436f8d3f33SWingman Kwok struct gbe_slave *slave;
28446f8d3f33SWingman Kwok
28456f8d3f33SWingman Kwok /* Check & update SGMII link state of interfaces */
28466f8d3f33SWingman Kwok for_each_intf(gbe_intf, gbe_dev) {
28476f8d3f33SWingman Kwok if (!gbe_intf->slave->open)
28486f8d3f33SWingman Kwok continue;
28496f8d3f33SWingman Kwok netcp_ethss_update_link_state(gbe_dev, gbe_intf->slave,
28506f8d3f33SWingman Kwok gbe_intf->ndev);
28516f8d3f33SWingman Kwok }
28526f8d3f33SWingman Kwok
28536f8d3f33SWingman Kwok /* Check & update SGMII link state of secondary ports */
28546f8d3f33SWingman Kwok for_each_sec_slave(slave, gbe_dev) {
28556f8d3f33SWingman Kwok netcp_ethss_update_link_state(gbe_dev, slave, NULL);
28566f8d3f33SWingman Kwok }
28576f8d3f33SWingman Kwok
2858c0f54edbSWingMan Kwok /* A timer runs as a BH, no need to block them */
2859c0f54edbSWingMan Kwok spin_lock(&gbe_dev->hw_stats_lock);
28606f8d3f33SWingman Kwok
28612953586dSMurali Karicheri if (IS_SS_ID_VER_14(gbe_dev))
28626f8d3f33SWingman Kwok gbe_update_stats_ver14(gbe_dev, NULL);
28636f8d3f33SWingman Kwok else
28646f8d3f33SWingman Kwok gbe_update_stats(gbe_dev, NULL);
28656f8d3f33SWingman Kwok
2866c0f54edbSWingMan Kwok spin_unlock(&gbe_dev->hw_stats_lock);
28676f8d3f33SWingman Kwok
28686f8d3f33SWingman Kwok gbe_dev->timer.expires = jiffies + GBE_TIMER_INTERVAL;
28696f8d3f33SWingman Kwok add_timer(&gbe_dev->timer);
28706f8d3f33SWingman Kwok }
28716f8d3f33SWingman Kwok
gbe_txhook(int order,void * data,struct netcp_packet * p_info)28726246168bSWingMan Kwok static int gbe_txhook(int order, void *data, struct netcp_packet *p_info)
28736f8d3f33SWingman Kwok {
28746f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = data;
28756f8d3f33SWingman Kwok
28766f8d3f33SWingman Kwok p_info->tx_pipe = &gbe_intf->tx_pipe;
28776246168bSWingMan Kwok
28786246168bSWingMan Kwok return gbe_txtstamp_mark_pkt(gbe_intf, p_info);
28796246168bSWingMan Kwok }
28806246168bSWingMan Kwok
gbe_rxhook(int order,void * data,struct netcp_packet * p_info)28816246168bSWingMan Kwok static int gbe_rxhook(int order, void *data, struct netcp_packet *p_info)
28826246168bSWingMan Kwok {
28836246168bSWingMan Kwok struct gbe_intf *gbe_intf = data;
28846246168bSWingMan Kwok
28856246168bSWingMan Kwok return gbe_rxtstamp(gbe_intf, p_info);
28866f8d3f33SWingman Kwok }
28876f8d3f33SWingman Kwok
gbe_open(void * intf_priv,struct net_device * ndev)28886f8d3f33SWingman Kwok static int gbe_open(void *intf_priv, struct net_device *ndev)
28896f8d3f33SWingman Kwok {
28906f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv;
28916f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev;
28926f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev);
28936f8d3f33SWingman Kwok struct gbe_slave *slave = gbe_intf->slave;
28946f8d3f33SWingman Kwok int port_num = slave->port_num;
28954cd85a61SKaricheri, Muralidharan u32 reg, val;
28966f8d3f33SWingman Kwok int ret;
28976f8d3f33SWingman Kwok
28986f8d3f33SWingman Kwok reg = readl(GBE_REG_ADDR(gbe_dev, switch_regs, id_ver));
28996f8d3f33SWingman Kwok dev_dbg(gbe_dev->dev, "initializing gbe version %d.%d (%d) GBE identification value 0x%x\n",
29006f8d3f33SWingman Kwok GBE_MAJOR_VERSION(reg), GBE_MINOR_VERSION(reg),
29016f8d3f33SWingman Kwok GBE_RTL_VERSION(reg), GBE_IDENT(reg));
29026f8d3f33SWingman Kwok
29039a391c7bSWingMan Kwok /* For 10G and on NetCP 1.5, use directed to port */
29042953586dSMurali Karicheri if (IS_SS_ID_XGBE(gbe_dev) || IS_SS_ID_MU(gbe_dev))
2905e170f409SKaricheri, Muralidharan gbe_intf->tx_pipe.flags = SWITCH_TO_PORT_IN_TAGINFO;
29066f8d3f33SWingman Kwok
2907e170f409SKaricheri, Muralidharan if (gbe_dev->enable_ale)
2908e170f409SKaricheri, Muralidharan gbe_intf->tx_pipe.switch_to_port = 0;
2909e170f409SKaricheri, Muralidharan else
2910e170f409SKaricheri, Muralidharan gbe_intf->tx_pipe.switch_to_port = port_num;
2911e170f409SKaricheri, Muralidharan
2912e170f409SKaricheri, Muralidharan dev_dbg(gbe_dev->dev,
2913e170f409SKaricheri, Muralidharan "opened TX channel %s: %p with to port %d, flags %d\n",
29146f8d3f33SWingman Kwok gbe_intf->tx_pipe.dma_chan_name,
29156f8d3f33SWingman Kwok gbe_intf->tx_pipe.dma_channel,
2916e170f409SKaricheri, Muralidharan gbe_intf->tx_pipe.switch_to_port,
2917e170f409SKaricheri, Muralidharan gbe_intf->tx_pipe.flags);
29186f8d3f33SWingman Kwok
29196f8d3f33SWingman Kwok gbe_slave_stop(gbe_intf);
29206f8d3f33SWingman Kwok
29216f8d3f33SWingman Kwok /* disable priority elevation and enable statistics on all ports */
29226f8d3f33SWingman Kwok writel(0, GBE_REG_ADDR(gbe_dev, switch_regs, ptype));
29236f8d3f33SWingman Kwok
29246f8d3f33SWingman Kwok /* Control register */
29254cd85a61SKaricheri, Muralidharan val = GBE_CTL_P0_ENABLE;
29264cd85a61SKaricheri, Muralidharan if (IS_SS_ID_MU(gbe_dev)) {
29274cd85a61SKaricheri, Muralidharan val |= ETH_SW_CTL_P0_TX_CRC_REMOVE;
29284cd85a61SKaricheri, Muralidharan netcp->hw_cap = ETH_SW_CAN_REMOVE_ETH_FCS;
29294cd85a61SKaricheri, Muralidharan }
29304cd85a61SKaricheri, Muralidharan writel(val, GBE_REG_ADDR(gbe_dev, switch_regs, control));
29316f8d3f33SWingman Kwok
29326f8d3f33SWingman Kwok /* All statistics enabled and STAT AB visible by default */
29339a391c7bSWingMan Kwok writel(gbe_dev->stats_en_mask, GBE_REG_ADDR(gbe_dev, switch_regs,
29346f8d3f33SWingman Kwok stat_port_en));
29356f8d3f33SWingman Kwok
29366f8d3f33SWingman Kwok ret = gbe_slave_open(gbe_intf);
29376f8d3f33SWingman Kwok if (ret)
29386f8d3f33SWingman Kwok goto fail;
29396f8d3f33SWingman Kwok
29406246168bSWingMan Kwok netcp_register_txhook(netcp, GBE_TXHOOK_ORDER, gbe_txhook, gbe_intf);
29416246168bSWingMan Kwok netcp_register_rxhook(netcp, GBE_RXHOOK_ORDER, gbe_rxhook, gbe_intf);
29426f8d3f33SWingman Kwok
29436f8d3f33SWingman Kwok slave->open = true;
29446f8d3f33SWingman Kwok netcp_ethss_update_link_state(gbe_dev, slave, ndev);
29456246168bSWingMan Kwok
29466246168bSWingMan Kwok gbe_register_cpts(gbe_dev);
29476246168bSWingMan Kwok
29486f8d3f33SWingman Kwok return 0;
29496f8d3f33SWingman Kwok
29506f8d3f33SWingman Kwok fail:
29516f8d3f33SWingman Kwok gbe_slave_stop(gbe_intf);
29526f8d3f33SWingman Kwok return ret;
29536f8d3f33SWingman Kwok }
29546f8d3f33SWingman Kwok
gbe_close(void * intf_priv,struct net_device * ndev)29556f8d3f33SWingman Kwok static int gbe_close(void *intf_priv, struct net_device *ndev)
29566f8d3f33SWingman Kwok {
29576f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv;
29586f8d3f33SWingman Kwok struct netcp_intf *netcp = netdev_priv(ndev);
29596246168bSWingMan Kwok struct gbe_priv *gbe_dev = gbe_intf->gbe_dev;
29606246168bSWingMan Kwok
29616246168bSWingMan Kwok gbe_unregister_cpts(gbe_dev);
29626f8d3f33SWingman Kwok
29636f8d3f33SWingman Kwok gbe_slave_stop(gbe_intf);
29646246168bSWingMan Kwok
29656246168bSWingMan Kwok netcp_unregister_rxhook(netcp, GBE_RXHOOK_ORDER, gbe_rxhook, gbe_intf);
29666246168bSWingMan Kwok netcp_unregister_txhook(netcp, GBE_TXHOOK_ORDER, gbe_txhook, gbe_intf);
29676f8d3f33SWingman Kwok
29686f8d3f33SWingman Kwok gbe_intf->slave->open = false;
29696f8d3f33SWingman Kwok atomic_set(&gbe_intf->slave->link_state, NETCP_LINK_STATE_INVALID);
29706f8d3f33SWingman Kwok return 0;
29716f8d3f33SWingman Kwok }
29726f8d3f33SWingman Kwok
29736246168bSWingMan Kwok #if IS_ENABLED(CONFIG_TI_CPTS)
init_slave_ts_ctl(struct gbe_slave * slave)29746246168bSWingMan Kwok static void init_slave_ts_ctl(struct gbe_slave *slave)
29756246168bSWingMan Kwok {
29766246168bSWingMan Kwok slave->ts_ctl.uni = 1;
29776246168bSWingMan Kwok slave->ts_ctl.dst_port_map =
29786246168bSWingMan Kwok (TS_CTL_DST_PORT >> TS_CTL_DST_PORT_SHIFT) & 0x3;
29796246168bSWingMan Kwok slave->ts_ctl.maddr_map =
29806246168bSWingMan Kwok (TS_CTL_MADDR_ALL >> TS_CTL_MADDR_SHIFT) & 0x1f;
29816246168bSWingMan Kwok }
29826246168bSWingMan Kwok
29836246168bSWingMan Kwok #else
init_slave_ts_ctl(struct gbe_slave * slave)29846246168bSWingMan Kwok static void init_slave_ts_ctl(struct gbe_slave *slave)
29856246168bSWingMan Kwok {
29866246168bSWingMan Kwok }
29876246168bSWingMan Kwok #endif /* CONFIG_TI_CPTS */
29886246168bSWingMan Kwok
init_slave(struct gbe_priv * gbe_dev,struct gbe_slave * slave,struct device_node * node)29896f8d3f33SWingman Kwok static int init_slave(struct gbe_priv *gbe_dev, struct gbe_slave *slave,
29906f8d3f33SWingman Kwok struct device_node *node)
29916f8d3f33SWingman Kwok {
29926f8d3f33SWingman Kwok int port_reg_num;
29936f8d3f33SWingman Kwok u32 port_reg_ofs, emac_reg_ofs;
29949a391c7bSWingMan Kwok u32 port_reg_blk_sz, emac_reg_blk_sz;
29956f8d3f33SWingman Kwok
29966f8d3f33SWingman Kwok if (of_property_read_u32(node, "slave-port", &slave->slave_num)) {
29976f8d3f33SWingman Kwok dev_err(gbe_dev->dev, "missing slave-port parameter\n");
29986f8d3f33SWingman Kwok return -EINVAL;
29996f8d3f33SWingman Kwok }
30006f8d3f33SWingman Kwok
30016f8d3f33SWingman Kwok if (of_property_read_u32(node, "link-interface",
30026f8d3f33SWingman Kwok &slave->link_interface)) {
30036f8d3f33SWingman Kwok dev_warn(gbe_dev->dev,
30046f8d3f33SWingman Kwok "missing link-interface value defaulting to 1G mac-phy link\n");
30056f8d3f33SWingman Kwok slave->link_interface = SGMII_LINK_MAC_PHY;
30066f8d3f33SWingman Kwok }
30076f8d3f33SWingman Kwok
30087b647b93SMurali Karicheri slave->node = node;
30096f8d3f33SWingman Kwok slave->open = false;
30100cead3a6SKaricheri, Muralidharan if ((slave->link_interface == SGMII_LINK_MAC_PHY) ||
3011478e9a5fSMurali Karicheri (slave->link_interface == RGMII_LINK_MAC_PHY) ||
30120cead3a6SKaricheri, Muralidharan (slave->link_interface == XGMII_LINK_MAC_PHY))
30136f8d3f33SWingman Kwok slave->phy_node = of_parse_phandle(node, "phy-handle", 0);
30146f8d3f33SWingman Kwok slave->port_num = gbe_get_slave_port(gbe_dev, slave->slave_num);
30156f8d3f33SWingman Kwok
301690cff9e2SWingman Kwok if (slave->link_interface >= XGMII_LINK_MAC_PHY)
301790cff9e2SWingman Kwok slave->mac_control = GBE_DEF_10G_MAC_CONTROL;
301890cff9e2SWingman Kwok else
30196f8d3f33SWingman Kwok slave->mac_control = GBE_DEF_1G_MAC_CONTROL;
30206f8d3f33SWingman Kwok
30216f8d3f33SWingman Kwok /* Emac regs memmap are contiguous but port regs are not */
30226f8d3f33SWingman Kwok port_reg_num = slave->slave_num;
30232953586dSMurali Karicheri if (IS_SS_ID_VER_14(gbe_dev)) {
30246f8d3f33SWingman Kwok if (slave->slave_num > 1) {
30256f8d3f33SWingman Kwok port_reg_ofs = GBE13_SLAVE_PORT2_OFFSET;
30266f8d3f33SWingman Kwok port_reg_num -= 2;
30276f8d3f33SWingman Kwok } else {
30286f8d3f33SWingman Kwok port_reg_ofs = GBE13_SLAVE_PORT_OFFSET;
30296f8d3f33SWingman Kwok }
30309a391c7bSWingMan Kwok emac_reg_ofs = GBE13_EMAC_OFFSET;
30319a391c7bSWingMan Kwok port_reg_blk_sz = 0x30;
30329a391c7bSWingMan Kwok emac_reg_blk_sz = 0x40;
30339a391c7bSWingMan Kwok } else if (IS_SS_ID_MU(gbe_dev)) {
30349a391c7bSWingMan Kwok port_reg_ofs = GBENU_SLAVE_PORT_OFFSET;
30359a391c7bSWingMan Kwok emac_reg_ofs = GBENU_EMAC_OFFSET;
30369a391c7bSWingMan Kwok port_reg_blk_sz = 0x1000;
30379a391c7bSWingMan Kwok emac_reg_blk_sz = 0x1000;
30382953586dSMurali Karicheri } else if (IS_SS_ID_XGBE(gbe_dev)) {
303990cff9e2SWingman Kwok port_reg_ofs = XGBE10_SLAVE_PORT_OFFSET;
30409a391c7bSWingMan Kwok emac_reg_ofs = XGBE10_EMAC_OFFSET;
30419a391c7bSWingMan Kwok port_reg_blk_sz = 0x30;
30429a391c7bSWingMan Kwok emac_reg_blk_sz = 0x40;
30436f8d3f33SWingman Kwok } else {
30446f8d3f33SWingman Kwok dev_err(gbe_dev->dev, "unknown ethss(0x%x)\n",
30456f8d3f33SWingman Kwok gbe_dev->ss_version);
30466f8d3f33SWingman Kwok return -EINVAL;
30476f8d3f33SWingman Kwok }
30486f8d3f33SWingman Kwok
304921e0e0ddSKaricheri, Muralidharan slave->port_regs = gbe_dev->switch_regs + port_reg_ofs +
30509a391c7bSWingMan Kwok (port_reg_blk_sz * port_reg_num);
305121e0e0ddSKaricheri, Muralidharan slave->emac_regs = gbe_dev->switch_regs + emac_reg_ofs +
30529a391c7bSWingMan Kwok (emac_reg_blk_sz * slave->slave_num);
30536f8d3f33SWingman Kwok
30542953586dSMurali Karicheri if (IS_SS_ID_VER_14(gbe_dev)) {
30556f8d3f33SWingman Kwok /* Initialize slave port register offsets */
30566f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, port_vlan);
30576f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, tx_pri_map);
30586f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, sa_lo);
30596f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, sa_hi);
30606f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, ts_ctl);
30616f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, ts_seq_ltype);
30626f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, ts_vlan);
30636f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, ts_ctl_ltype2);
30646f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, port_regs, ts_ctl2);
30656f8d3f33SWingman Kwok
30666f8d3f33SWingman Kwok /* Initialize EMAC register offsets */
30676f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, emac_regs, mac_control);
30686f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, emac_regs, soft_reset);
30696f8d3f33SWingman Kwok GBE_SET_REG_OFS(slave, emac_regs, rx_maxlen);
30706f8d3f33SWingman Kwok
30719a391c7bSWingMan Kwok } else if (IS_SS_ID_MU(gbe_dev)) {
30729a391c7bSWingMan Kwok /* Initialize slave port register offsets */
30739a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, port_vlan);
30749a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, tx_pri_map);
307565c45064SMurali Karicheri GBENU_SET_REG_OFS(slave, port_regs, rx_pri_map);
30769a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, sa_lo);
30779a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, sa_hi);
30789a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, ts_ctl);
30799a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, ts_seq_ltype);
30809a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, ts_vlan);
30819a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, ts_ctl_ltype2);
30829a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, ts_ctl2);
30839a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, port_regs, rx_maxlen);
30849a391c7bSWingMan Kwok
30859a391c7bSWingMan Kwok /* Initialize EMAC register offsets */
30869a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, emac_regs, mac_control);
30879a391c7bSWingMan Kwok GBENU_SET_REG_OFS(slave, emac_regs, soft_reset);
30889a391c7bSWingMan Kwok
30892953586dSMurali Karicheri } else if (IS_SS_ID_XGBE(gbe_dev)) {
309090cff9e2SWingman Kwok /* Initialize slave port register offsets */
309190cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, port_vlan);
309290cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, tx_pri_map);
309390cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, sa_lo);
309490cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, sa_hi);
309590cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, ts_ctl);
309690cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, ts_seq_ltype);
309790cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, ts_vlan);
309890cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, ts_ctl_ltype2);
309990cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, port_regs, ts_ctl2);
310090cff9e2SWingman Kwok
310190cff9e2SWingman Kwok /* Initialize EMAC register offsets */
310290cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, emac_regs, mac_control);
310390cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, emac_regs, soft_reset);
310490cff9e2SWingman Kwok XGBE_SET_REG_OFS(slave, emac_regs, rx_maxlen);
31056f8d3f33SWingman Kwok }
31066f8d3f33SWingman Kwok
31076f8d3f33SWingman Kwok atomic_set(&slave->link_state, NETCP_LINK_STATE_INVALID);
31086246168bSWingMan Kwok
31096246168bSWingMan Kwok init_slave_ts_ctl(slave);
31106f8d3f33SWingman Kwok return 0;
31116f8d3f33SWingman Kwok }
31126f8d3f33SWingman Kwok
init_secondary_ports(struct gbe_priv * gbe_dev,struct device_node * node)31136f8d3f33SWingman Kwok static void init_secondary_ports(struct gbe_priv *gbe_dev,
31146f8d3f33SWingman Kwok struct device_node *node)
31156f8d3f33SWingman Kwok {
31166f8d3f33SWingman Kwok struct device *dev = gbe_dev->dev;
31176f8d3f33SWingman Kwok phy_interface_t phy_mode;
31186f8d3f33SWingman Kwok struct gbe_priv **priv;
31196f8d3f33SWingman Kwok struct device_node *port;
31206f8d3f33SWingman Kwok struct gbe_slave *slave;
31216f8d3f33SWingman Kwok bool mac_phy_link = false;
31226f8d3f33SWingman Kwok
31236f8d3f33SWingman Kwok for_each_child_of_node(node, port) {
31246f8d3f33SWingman Kwok slave = devm_kzalloc(dev, sizeof(*slave), GFP_KERNEL);
31256f8d3f33SWingman Kwok if (!slave) {
312621c328dcSRob Herring dev_err(dev, "memory alloc failed for secondary port(%pOFn), skipping...\n",
312721c328dcSRob Herring port);
31286f8d3f33SWingman Kwok continue;
31296f8d3f33SWingman Kwok }
31306f8d3f33SWingman Kwok
31316f8d3f33SWingman Kwok if (init_slave(gbe_dev, slave, port)) {
31326f8d3f33SWingman Kwok dev_err(dev,
313321c328dcSRob Herring "Failed to initialize secondary port(%pOFn), skipping...\n",
313421c328dcSRob Herring port);
31356f8d3f33SWingman Kwok devm_kfree(dev, slave);
31366f8d3f33SWingman Kwok continue;
31376f8d3f33SWingman Kwok }
31386f8d3f33SWingman Kwok
3139775f9535SMurali Karicheri if (!IS_SS_ID_2U(gbe_dev))
31406f8d3f33SWingman Kwok gbe_sgmii_config(gbe_dev, slave);
31416f8d3f33SWingman Kwok gbe_port_reset(slave);
31426f8d3f33SWingman Kwok gbe_port_config(gbe_dev, slave, gbe_dev->rx_packet_max);
31436f8d3f33SWingman Kwok list_add_tail(&slave->slave_list, &gbe_dev->secondary_slaves);
31446f8d3f33SWingman Kwok gbe_dev->num_slaves++;
314590cff9e2SWingman Kwok if ((slave->link_interface == SGMII_LINK_MAC_PHY) ||
314690cff9e2SWingman Kwok (slave->link_interface == XGMII_LINK_MAC_PHY))
31476f8d3f33SWingman Kwok mac_phy_link = true;
31486f8d3f33SWingman Kwok
31496f8d3f33SWingman Kwok slave->open = true;
3150bd252796SJulia Lawall if (gbe_dev->num_slaves >= gbe_dev->max_num_slaves) {
3151bd252796SJulia Lawall of_node_put(port);
31529a391c7bSWingMan Kwok break;
31536f8d3f33SWingman Kwok }
3154bd252796SJulia Lawall }
31556f8d3f33SWingman Kwok
31566f8d3f33SWingman Kwok /* of_phy_connect() is needed only for MAC-PHY interface */
31576f8d3f33SWingman Kwok if (!mac_phy_link)
31586f8d3f33SWingman Kwok return;
31596f8d3f33SWingman Kwok
31606f8d3f33SWingman Kwok /* Allocate dummy netdev device for attaching to phy device */
31616f8d3f33SWingman Kwok gbe_dev->dummy_ndev = alloc_netdev(sizeof(gbe_dev), "dummy",
31626f8d3f33SWingman Kwok NET_NAME_UNKNOWN, ether_setup);
31636f8d3f33SWingman Kwok if (!gbe_dev->dummy_ndev) {
31646f8d3f33SWingman Kwok dev_err(dev,
31656f8d3f33SWingman Kwok "Failed to allocate dummy netdev for secondary ports, skipping phy_connect()...\n");
31666f8d3f33SWingman Kwok return;
31676f8d3f33SWingman Kwok }
31686f8d3f33SWingman Kwok priv = netdev_priv(gbe_dev->dummy_ndev);
31696f8d3f33SWingman Kwok *priv = gbe_dev;
31706f8d3f33SWingman Kwok
31716f8d3f33SWingman Kwok if (slave->link_interface == SGMII_LINK_MAC_PHY) {
31726f8d3f33SWingman Kwok phy_mode = PHY_INTERFACE_MODE_SGMII;
31736f8d3f33SWingman Kwok slave->phy_port_t = PORT_MII;
3174478e9a5fSMurali Karicheri } else if (slave->link_interface == RGMII_LINK_MAC_PHY) {
3175478e9a5fSMurali Karicheri phy_mode = PHY_INTERFACE_MODE_RGMII;
3176478e9a5fSMurali Karicheri slave->phy_port_t = PORT_MII;
31776f8d3f33SWingman Kwok } else {
31786f8d3f33SWingman Kwok phy_mode = PHY_INTERFACE_MODE_NA;
31796f8d3f33SWingman Kwok slave->phy_port_t = PORT_FIBRE;
31806f8d3f33SWingman Kwok }
31816f8d3f33SWingman Kwok
31826f8d3f33SWingman Kwok for_each_sec_slave(slave, gbe_dev) {
318390cff9e2SWingman Kwok if ((slave->link_interface != SGMII_LINK_MAC_PHY) &&
3184478e9a5fSMurali Karicheri (slave->link_interface != RGMII_LINK_MAC_PHY) &&
318590cff9e2SWingman Kwok (slave->link_interface != XGMII_LINK_MAC_PHY))
31866f8d3f33SWingman Kwok continue;
31876f8d3f33SWingman Kwok slave->phy =
31886f8d3f33SWingman Kwok of_phy_connect(gbe_dev->dummy_ndev,
31896f8d3f33SWingman Kwok slave->phy_node,
31906f8d3f33SWingman Kwok gbe_adjust_link_sec_slaves,
31916f8d3f33SWingman Kwok 0, phy_mode);
31926f8d3f33SWingman Kwok if (!slave->phy) {
31936f8d3f33SWingman Kwok dev_err(dev, "phy not found for slave %d\n",
31946f8d3f33SWingman Kwok slave->slave_num);
31956f8d3f33SWingman Kwok } else {
31966f8d3f33SWingman Kwok dev_dbg(dev, "phy found: id is: 0x%s\n",
319784eff6d1SAndrew Lunn phydev_name(slave->phy));
31986f8d3f33SWingman Kwok phy_start(slave->phy);
31996f8d3f33SWingman Kwok }
32006f8d3f33SWingman Kwok }
32016f8d3f33SWingman Kwok }
32026f8d3f33SWingman Kwok
free_secondary_ports(struct gbe_priv * gbe_dev)32036f8d3f33SWingman Kwok static void free_secondary_ports(struct gbe_priv *gbe_dev)
32046f8d3f33SWingman Kwok {
32056f8d3f33SWingman Kwok struct gbe_slave *slave;
32066f8d3f33SWingman Kwok
3207c20afae7SKaricheri, Muralidharan while (!list_empty(&gbe_dev->secondary_slaves)) {
32086f8d3f33SWingman Kwok slave = first_sec_slave(gbe_dev);
3209c20afae7SKaricheri, Muralidharan
32106f8d3f33SWingman Kwok if (slave->phy)
32116f8d3f33SWingman Kwok phy_disconnect(slave->phy);
32126f8d3f33SWingman Kwok list_del(&slave->slave_list);
32136f8d3f33SWingman Kwok }
32146f8d3f33SWingman Kwok if (gbe_dev->dummy_ndev)
32156f8d3f33SWingman Kwok free_netdev(gbe_dev->dummy_ndev);
32166f8d3f33SWingman Kwok }
32176f8d3f33SWingman Kwok
set_xgbe_ethss10_priv(struct gbe_priv * gbe_dev,struct device_node * node)321890cff9e2SWingman Kwok static int set_xgbe_ethss10_priv(struct gbe_priv *gbe_dev,
321990cff9e2SWingman Kwok struct device_node *node)
322090cff9e2SWingman Kwok {
322190cff9e2SWingman Kwok struct resource res;
322290cff9e2SWingman Kwok void __iomem *regs;
322390cff9e2SWingman Kwok int ret, i;
322490cff9e2SWingman Kwok
32259a391c7bSWingMan Kwok ret = of_address_to_resource(node, XGBE_SS_REG_INDEX, &res);
322690cff9e2SWingman Kwok if (ret) {
322721e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev,
322821c328dcSRob Herring "Can't xlate xgbe of node(%pOFn) ss address at %d\n",
322921c328dcSRob Herring node, XGBE_SS_REG_INDEX);
323090cff9e2SWingman Kwok return ret;
323190cff9e2SWingman Kwok }
323290cff9e2SWingman Kwok
323390cff9e2SWingman Kwok regs = devm_ioremap_resource(gbe_dev->dev, &res);
323490cff9e2SWingman Kwok if (IS_ERR(regs)) {
323521e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, "Failed to map xgbe ss register base\n");
323690cff9e2SWingman Kwok return PTR_ERR(regs);
323790cff9e2SWingman Kwok }
323890cff9e2SWingman Kwok gbe_dev->ss_regs = regs;
323990cff9e2SWingman Kwok
324021e0e0ddSKaricheri, Muralidharan ret = of_address_to_resource(node, XGBE_SM_REG_INDEX, &res);
324121e0e0ddSKaricheri, Muralidharan if (ret) {
324221e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev,
324321c328dcSRob Herring "Can't xlate xgbe of node(%pOFn) sm address at %d\n",
324421c328dcSRob Herring node, XGBE_SM_REG_INDEX);
324521e0e0ddSKaricheri, Muralidharan return ret;
324621e0e0ddSKaricheri, Muralidharan }
324721e0e0ddSKaricheri, Muralidharan
324821e0e0ddSKaricheri, Muralidharan regs = devm_ioremap_resource(gbe_dev->dev, &res);
324921e0e0ddSKaricheri, Muralidharan if (IS_ERR(regs)) {
325021e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev, "Failed to map xgbe sm register base\n");
325121e0e0ddSKaricheri, Muralidharan return PTR_ERR(regs);
325221e0e0ddSKaricheri, Muralidharan }
325321e0e0ddSKaricheri, Muralidharan gbe_dev->switch_regs = regs;
325421e0e0ddSKaricheri, Muralidharan
325590cff9e2SWingman Kwok ret = of_address_to_resource(node, XGBE_SERDES_REG_INDEX, &res);
325690cff9e2SWingman Kwok if (ret) {
325721e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev,
325821c328dcSRob Herring "Can't xlate xgbe serdes of node(%pOFn) address at %d\n",
325921c328dcSRob Herring node, XGBE_SERDES_REG_INDEX);
326090cff9e2SWingman Kwok return ret;
326190cff9e2SWingman Kwok }
326290cff9e2SWingman Kwok
326390cff9e2SWingman Kwok regs = devm_ioremap_resource(gbe_dev->dev, &res);
326490cff9e2SWingman Kwok if (IS_ERR(regs)) {
326590cff9e2SWingman Kwok dev_err(gbe_dev->dev, "Failed to map xgbe serdes register base\n");
326690cff9e2SWingman Kwok return PTR_ERR(regs);
326790cff9e2SWingman Kwok }
326890cff9e2SWingman Kwok gbe_dev->xgbe_serdes_regs = regs;
326990cff9e2SWingman Kwok
3270489e8a2fSWingMan Kwok gbe_dev->num_stats_mods = gbe_dev->max_num_ports;
3271208c6b9aSWingMan Kwok gbe_dev->et_stats = xgbe10_et_stats;
3272208c6b9aSWingMan Kwok gbe_dev->num_et_stats = ARRAY_SIZE(xgbe10_et_stats);
3273208c6b9aSWingMan Kwok
3274a86854d0SKees Cook gbe_dev->hw_stats = devm_kcalloc(gbe_dev->dev,
3275a86854d0SKees Cook gbe_dev->num_et_stats, sizeof(u64),
327690cff9e2SWingman Kwok GFP_KERNEL);
327790cff9e2SWingman Kwok if (!gbe_dev->hw_stats) {
327890cff9e2SWingman Kwok dev_err(gbe_dev->dev, "hw_stats memory allocation failed\n");
327990cff9e2SWingman Kwok return -ENOMEM;
328090cff9e2SWingman Kwok }
328190cff9e2SWingman Kwok
3282489e8a2fSWingMan Kwok gbe_dev->hw_stats_prev =
3283a86854d0SKees Cook devm_kcalloc(gbe_dev->dev,
3284a86854d0SKees Cook gbe_dev->num_et_stats, sizeof(u32),
3285489e8a2fSWingMan Kwok GFP_KERNEL);
3286489e8a2fSWingMan Kwok if (!gbe_dev->hw_stats_prev) {
3287489e8a2fSWingMan Kwok dev_err(gbe_dev->dev,
3288489e8a2fSWingMan Kwok "hw_stats_prev memory allocation failed\n");
3289489e8a2fSWingMan Kwok return -ENOMEM;
3290489e8a2fSWingMan Kwok }
3291489e8a2fSWingMan Kwok
329290cff9e2SWingman Kwok gbe_dev->ss_version = XGBE_SS_VERSION_10;
329390cff9e2SWingman Kwok gbe_dev->sgmii_port_regs = gbe_dev->ss_regs +
329490cff9e2SWingman Kwok XGBE10_SGMII_MODULE_OFFSET;
329590cff9e2SWingman Kwok gbe_dev->host_port_regs = gbe_dev->ss_regs + XGBE10_HOST_PORT_OFFSET;
329690cff9e2SWingman Kwok
32979a391c7bSWingMan Kwok for (i = 0; i < gbe_dev->max_num_ports; i++)
329821e0e0ddSKaricheri, Muralidharan gbe_dev->hw_stats_regs[i] = gbe_dev->switch_regs +
329990cff9e2SWingman Kwok XGBE10_HW_STATS_OFFSET + (GBE_HW_STATS_REG_MAP_SZ * i);
330090cff9e2SWingman Kwok
33019a391c7bSWingMan Kwok gbe_dev->ale_reg = gbe_dev->switch_regs + XGBE10_ALE_OFFSET;
33026246168bSWingMan Kwok gbe_dev->cpts_reg = gbe_dev->switch_regs + XGBE10_CPTS_OFFSET;
33039a391c7bSWingMan Kwok gbe_dev->ale_ports = gbe_dev->max_num_ports;
330490cff9e2SWingman Kwok gbe_dev->host_port = XGBE10_HOST_PORT_NUM;
33059a391c7bSWingMan Kwok gbe_dev->stats_en_mask = (1 << (gbe_dev->max_num_ports)) - 1;
330690cff9e2SWingman Kwok
330790cff9e2SWingman Kwok /* Subsystem registers */
330890cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, ss_regs, id_ver);
330990cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, ss_regs, control);
331090cff9e2SWingman Kwok
331190cff9e2SWingman Kwok /* Switch module registers */
331290cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, switch_regs, id_ver);
331390cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, switch_regs, control);
331490cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, switch_regs, ptype);
331590cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, switch_regs, stat_port_en);
331690cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, switch_regs, flow_control);
331790cff9e2SWingman Kwok
331890cff9e2SWingman Kwok /* Host port registers */
331990cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, host_port_regs, port_vlan);
332090cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, host_port_regs, tx_pri_map);
332190cff9e2SWingman Kwok XGBE_SET_REG_OFS(gbe_dev, host_port_regs, rx_maxlen);
332290cff9e2SWingman Kwok return 0;
332390cff9e2SWingman Kwok }
332490cff9e2SWingman Kwok
get_gbe_resource_version(struct gbe_priv * gbe_dev,struct device_node * node)33256f8d3f33SWingman Kwok static int get_gbe_resource_version(struct gbe_priv *gbe_dev,
33266f8d3f33SWingman Kwok struct device_node *node)
33276f8d3f33SWingman Kwok {
33286f8d3f33SWingman Kwok struct resource res;
33296f8d3f33SWingman Kwok void __iomem *regs;
33306f8d3f33SWingman Kwok int ret;
33316f8d3f33SWingman Kwok
333221e0e0ddSKaricheri, Muralidharan ret = of_address_to_resource(node, GBE_SS_REG_INDEX, &res);
33336f8d3f33SWingman Kwok if (ret) {
333421e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev,
333521c328dcSRob Herring "Can't translate of node(%pOFn) of gbe ss address at %d\n",
333621c328dcSRob Herring node, GBE_SS_REG_INDEX);
33376f8d3f33SWingman Kwok return ret;
33386f8d3f33SWingman Kwok }
33396f8d3f33SWingman Kwok
33406f8d3f33SWingman Kwok regs = devm_ioremap_resource(gbe_dev->dev, &res);
33416f8d3f33SWingman Kwok if (IS_ERR(regs)) {
33426f8d3f33SWingman Kwok dev_err(gbe_dev->dev, "Failed to map gbe register base\n");
33436f8d3f33SWingman Kwok return PTR_ERR(regs);
33446f8d3f33SWingman Kwok }
33456f8d3f33SWingman Kwok gbe_dev->ss_regs = regs;
33466f8d3f33SWingman Kwok gbe_dev->ss_version = readl(gbe_dev->ss_regs);
33476f8d3f33SWingman Kwok return 0;
33486f8d3f33SWingman Kwok }
33496f8d3f33SWingman Kwok
set_gbe_ethss14_priv(struct gbe_priv * gbe_dev,struct device_node * node)33506f8d3f33SWingman Kwok static int set_gbe_ethss14_priv(struct gbe_priv *gbe_dev,
33516f8d3f33SWingman Kwok struct device_node *node)
33526f8d3f33SWingman Kwok {
335321e0e0ddSKaricheri, Muralidharan struct resource res;
33546f8d3f33SWingman Kwok void __iomem *regs;
335521e0e0ddSKaricheri, Muralidharan int i, ret;
335621e0e0ddSKaricheri, Muralidharan
335721e0e0ddSKaricheri, Muralidharan ret = of_address_to_resource(node, GBE_SGMII34_REG_INDEX, &res);
335821e0e0ddSKaricheri, Muralidharan if (ret) {
335921e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev,
336021c328dcSRob Herring "Can't translate of gbe node(%pOFn) address at index %d\n",
336121c328dcSRob Herring node, GBE_SGMII34_REG_INDEX);
336221e0e0ddSKaricheri, Muralidharan return ret;
336321e0e0ddSKaricheri, Muralidharan }
336421e0e0ddSKaricheri, Muralidharan
336521e0e0ddSKaricheri, Muralidharan regs = devm_ioremap_resource(gbe_dev->dev, &res);
336621e0e0ddSKaricheri, Muralidharan if (IS_ERR(regs)) {
336721e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev,
336821e0e0ddSKaricheri, Muralidharan "Failed to map gbe sgmii port34 register base\n");
336921e0e0ddSKaricheri, Muralidharan return PTR_ERR(regs);
337021e0e0ddSKaricheri, Muralidharan }
337121e0e0ddSKaricheri, Muralidharan gbe_dev->sgmii_port34_regs = regs;
337221e0e0ddSKaricheri, Muralidharan
337321e0e0ddSKaricheri, Muralidharan ret = of_address_to_resource(node, GBE_SM_REG_INDEX, &res);
337421e0e0ddSKaricheri, Muralidharan if (ret) {
337521e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev,
337621c328dcSRob Herring "Can't translate of gbe node(%pOFn) address at index %d\n",
337721c328dcSRob Herring node, GBE_SM_REG_INDEX);
337821e0e0ddSKaricheri, Muralidharan return ret;
337921e0e0ddSKaricheri, Muralidharan }
338021e0e0ddSKaricheri, Muralidharan
338121e0e0ddSKaricheri, Muralidharan regs = devm_ioremap_resource(gbe_dev->dev, &res);
338221e0e0ddSKaricheri, Muralidharan if (IS_ERR(regs)) {
338321e0e0ddSKaricheri, Muralidharan dev_err(gbe_dev->dev,
338421e0e0ddSKaricheri, Muralidharan "Failed to map gbe switch module register base\n");
338521e0e0ddSKaricheri, Muralidharan return PTR_ERR(regs);
338621e0e0ddSKaricheri, Muralidharan }
338721e0e0ddSKaricheri, Muralidharan gbe_dev->switch_regs = regs;
33886f8d3f33SWingman Kwok
3389489e8a2fSWingMan Kwok gbe_dev->num_stats_mods = gbe_dev->max_num_slaves;
3390208c6b9aSWingMan Kwok gbe_dev->et_stats = gbe13_et_stats;
3391208c6b9aSWingMan Kwok gbe_dev->num_et_stats = ARRAY_SIZE(gbe13_et_stats);
3392208c6b9aSWingMan Kwok
3393a86854d0SKees Cook gbe_dev->hw_stats = devm_kcalloc(gbe_dev->dev,
3394a86854d0SKees Cook gbe_dev->num_et_stats, sizeof(u64),
33956f8d3f33SWingman Kwok GFP_KERNEL);
33966f8d3f33SWingman Kwok if (!gbe_dev->hw_stats) {
33976f8d3f33SWingman Kwok dev_err(gbe_dev->dev, "hw_stats memory allocation failed\n");
33986f8d3f33SWingman Kwok return -ENOMEM;
33996f8d3f33SWingman Kwok }
34006f8d3f33SWingman Kwok
3401489e8a2fSWingMan Kwok gbe_dev->hw_stats_prev =
3402a86854d0SKees Cook devm_kcalloc(gbe_dev->dev,
3403a86854d0SKees Cook gbe_dev->num_et_stats, sizeof(u32),
3404489e8a2fSWingMan Kwok GFP_KERNEL);
3405489e8a2fSWingMan Kwok if (!gbe_dev->hw_stats_prev) {
3406489e8a2fSWingMan Kwok dev_err(gbe_dev->dev,
3407489e8a2fSWingMan Kwok "hw_stats_prev memory allocation failed\n");
3408489e8a2fSWingMan Kwok return -ENOMEM;
3409489e8a2fSWingMan Kwok }
3410489e8a2fSWingMan Kwok
341121e0e0ddSKaricheri, Muralidharan gbe_dev->sgmii_port_regs = gbe_dev->ss_regs + GBE13_SGMII_MODULE_OFFSET;
341221e0e0ddSKaricheri, Muralidharan gbe_dev->host_port_regs = gbe_dev->switch_regs + GBE13_HOST_PORT_OFFSET;
34136f8d3f33SWingman Kwok
3414a94bcd09SWingMan Kwok /* K2HK has only 2 hw stats modules visible at a time, so
3415a94bcd09SWingMan Kwok * module 0 & 2 points to one base and
3416a94bcd09SWingMan Kwok * module 1 & 3 points to the other base
3417a94bcd09SWingMan Kwok */
34189a391c7bSWingMan Kwok for (i = 0; i < gbe_dev->max_num_slaves; i++) {
341921e0e0ddSKaricheri, Muralidharan gbe_dev->hw_stats_regs[i] =
342021e0e0ddSKaricheri, Muralidharan gbe_dev->switch_regs + GBE13_HW_STATS_OFFSET +
3421a94bcd09SWingMan Kwok (GBE_HW_STATS_REG_MAP_SZ * (i & 0x1));
342221e0e0ddSKaricheri, Muralidharan }
34236f8d3f33SWingman Kwok
34246246168bSWingMan Kwok gbe_dev->cpts_reg = gbe_dev->switch_regs + GBE13_CPTS_OFFSET;
342521e0e0ddSKaricheri, Muralidharan gbe_dev->ale_reg = gbe_dev->switch_regs + GBE13_ALE_OFFSET;
34269a391c7bSWingMan Kwok gbe_dev->ale_ports = gbe_dev->max_num_ports;
34276f8d3f33SWingman Kwok gbe_dev->host_port = GBE13_HOST_PORT_NUM;
34289a391c7bSWingMan Kwok gbe_dev->stats_en_mask = GBE13_REG_VAL_STAT_ENABLE_ALL;
34296f8d3f33SWingman Kwok
34306f8d3f33SWingman Kwok /* Subsystem registers */
34316f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, ss_regs, id_ver);
34326f8d3f33SWingman Kwok
34336f8d3f33SWingman Kwok /* Switch module registers */
34346f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, switch_regs, id_ver);
34356f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, switch_regs, control);
34366f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, switch_regs, soft_reset);
34376f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, switch_regs, stat_port_en);
34386f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, switch_regs, ptype);
34396f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, switch_regs, flow_control);
34406f8d3f33SWingman Kwok
34416f8d3f33SWingman Kwok /* Host port registers */
34426f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, host_port_regs, port_vlan);
34436f8d3f33SWingman Kwok GBE_SET_REG_OFS(gbe_dev, host_port_regs, rx_maxlen);
34446f8d3f33SWingman Kwok return 0;
34456f8d3f33SWingman Kwok }
34466f8d3f33SWingman Kwok
set_gbenu_ethss_priv(struct gbe_priv * gbe_dev,struct device_node * node)34479a391c7bSWingMan Kwok static int set_gbenu_ethss_priv(struct gbe_priv *gbe_dev,
34489a391c7bSWingMan Kwok struct device_node *node)
34499a391c7bSWingMan Kwok {
34509a391c7bSWingMan Kwok struct resource res;
34519a391c7bSWingMan Kwok void __iomem *regs;
34529a391c7bSWingMan Kwok int i, ret;
34539a391c7bSWingMan Kwok
3454489e8a2fSWingMan Kwok gbe_dev->num_stats_mods = gbe_dev->max_num_ports;
3455208c6b9aSWingMan Kwok gbe_dev->et_stats = gbenu_et_stats;
3456208c6b9aSWingMan Kwok
3457dc07ec97SMurali Karicheri if (IS_SS_ID_MU(gbe_dev))
3458208c6b9aSWingMan Kwok gbe_dev->num_et_stats = GBENU_ET_STATS_HOST_SIZE +
3459208c6b9aSWingMan Kwok (gbe_dev->max_num_slaves * GBENU_ET_STATS_PORT_SIZE);
3460208c6b9aSWingMan Kwok else
3461208c6b9aSWingMan Kwok gbe_dev->num_et_stats = GBENU_ET_STATS_HOST_SIZE +
3462208c6b9aSWingMan Kwok GBENU_ET_STATS_PORT_SIZE;
3463208c6b9aSWingMan Kwok
3464a86854d0SKees Cook gbe_dev->hw_stats = devm_kcalloc(gbe_dev->dev,
3465a86854d0SKees Cook gbe_dev->num_et_stats, sizeof(u64),
34669a391c7bSWingMan Kwok GFP_KERNEL);
34679a391c7bSWingMan Kwok if (!gbe_dev->hw_stats) {
34689a391c7bSWingMan Kwok dev_err(gbe_dev->dev, "hw_stats memory allocation failed\n");
34699a391c7bSWingMan Kwok return -ENOMEM;
34709a391c7bSWingMan Kwok }
34719a391c7bSWingMan Kwok
3472489e8a2fSWingMan Kwok gbe_dev->hw_stats_prev =
3473a86854d0SKees Cook devm_kcalloc(gbe_dev->dev,
3474a86854d0SKees Cook gbe_dev->num_et_stats, sizeof(u32),
3475489e8a2fSWingMan Kwok GFP_KERNEL);
3476489e8a2fSWingMan Kwok if (!gbe_dev->hw_stats_prev) {
3477489e8a2fSWingMan Kwok dev_err(gbe_dev->dev,
3478489e8a2fSWingMan Kwok "hw_stats_prev memory allocation failed\n");
3479489e8a2fSWingMan Kwok return -ENOMEM;
3480489e8a2fSWingMan Kwok }
3481489e8a2fSWingMan Kwok
34829a391c7bSWingMan Kwok ret = of_address_to_resource(node, GBENU_SM_REG_INDEX, &res);
34839a391c7bSWingMan Kwok if (ret) {
34849a391c7bSWingMan Kwok dev_err(gbe_dev->dev,
348521c328dcSRob Herring "Can't translate of gbenu node(%pOFn) addr at index %d\n",
348621c328dcSRob Herring node, GBENU_SM_REG_INDEX);
34879a391c7bSWingMan Kwok return ret;
34889a391c7bSWingMan Kwok }
34899a391c7bSWingMan Kwok
34909a391c7bSWingMan Kwok regs = devm_ioremap_resource(gbe_dev->dev, &res);
34919a391c7bSWingMan Kwok if (IS_ERR(regs)) {
34929a391c7bSWingMan Kwok dev_err(gbe_dev->dev,
34939a391c7bSWingMan Kwok "Failed to map gbenu switch module register base\n");
34949a391c7bSWingMan Kwok return PTR_ERR(regs);
34959a391c7bSWingMan Kwok }
34969a391c7bSWingMan Kwok gbe_dev->switch_regs = regs;
34979a391c7bSWingMan Kwok
3498775f9535SMurali Karicheri if (!IS_SS_ID_2U(gbe_dev))
3499775f9535SMurali Karicheri gbe_dev->sgmii_port_regs =
3500775f9535SMurali Karicheri gbe_dev->ss_regs + GBENU_SGMII_MODULE_OFFSET;
35018c85151dSWingMan Kwok
35028c85151dSWingMan Kwok /* Although sgmii modules are mem mapped to one contiguous
35038c85151dSWingMan Kwok * region on GBENU devices, setting sgmii_port34_regs allows
35048c85151dSWingMan Kwok * consistent code when accessing sgmii api
35058c85151dSWingMan Kwok */
35068c85151dSWingMan Kwok gbe_dev->sgmii_port34_regs = gbe_dev->sgmii_port_regs +
35078c85151dSWingMan Kwok (2 * GBENU_SGMII_MODULE_SIZE);
35088c85151dSWingMan Kwok
35099a391c7bSWingMan Kwok gbe_dev->host_port_regs = gbe_dev->switch_regs + GBENU_HOST_PORT_OFFSET;
35109a391c7bSWingMan Kwok
35119a391c7bSWingMan Kwok for (i = 0; i < (gbe_dev->max_num_ports); i++)
35129a391c7bSWingMan Kwok gbe_dev->hw_stats_regs[i] = gbe_dev->switch_regs +
35139a391c7bSWingMan Kwok GBENU_HW_STATS_OFFSET + (GBENU_HW_STATS_REG_MAP_SZ * i);
35149a391c7bSWingMan Kwok
35156246168bSWingMan Kwok gbe_dev->cpts_reg = gbe_dev->switch_regs + GBENU_CPTS_OFFSET;
35169a391c7bSWingMan Kwok gbe_dev->ale_reg = gbe_dev->switch_regs + GBENU_ALE_OFFSET;
35179a391c7bSWingMan Kwok gbe_dev->ale_ports = gbe_dev->max_num_ports;
35189a391c7bSWingMan Kwok gbe_dev->host_port = GBENU_HOST_PORT_NUM;
35199a391c7bSWingMan Kwok gbe_dev->stats_en_mask = (1 << (gbe_dev->max_num_ports)) - 1;
35209a391c7bSWingMan Kwok
35219a391c7bSWingMan Kwok /* Subsystem registers */
35229a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, ss_regs, id_ver);
35237771f2b4SMurali Karicheri /* ok to set for MU, but used by 2U only */
35247771f2b4SMurali Karicheri GBENU_SET_REG_OFS(gbe_dev, ss_regs, rgmii_status);
35259a391c7bSWingMan Kwok
35269a391c7bSWingMan Kwok /* Switch module registers */
35279a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, switch_regs, id_ver);
35289a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, switch_regs, control);
35299a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, switch_regs, stat_port_en);
35309a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, switch_regs, ptype);
35319a391c7bSWingMan Kwok
35329a391c7bSWingMan Kwok /* Host port registers */
35339a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, host_port_regs, port_vlan);
35349a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, host_port_regs, rx_maxlen);
35359a391c7bSWingMan Kwok
35369a391c7bSWingMan Kwok /* For NU only. 2U does not need tx_pri_map.
35379a391c7bSWingMan Kwok * NU cppi port 0 tx pkt streaming interface has (n-1)*8 egress threads
35389a391c7bSWingMan Kwok * while 2U has only 1 such thread
35399a391c7bSWingMan Kwok */
35409a391c7bSWingMan Kwok GBENU_SET_REG_OFS(gbe_dev, host_port_regs, tx_pri_map);
35419a391c7bSWingMan Kwok return 0;
35429a391c7bSWingMan Kwok }
35439a391c7bSWingMan Kwok
gbe_probe(struct netcp_device * netcp_device,struct device * dev,struct device_node * node,void ** inst_priv)35446f8d3f33SWingman Kwok static int gbe_probe(struct netcp_device *netcp_device, struct device *dev,
35456f8d3f33SWingman Kwok struct device_node *node, void **inst_priv)
35466f8d3f33SWingman Kwok {
3547c8ad1451SGrygorii Strashko struct device_node *interfaces, *interface, *cpts_node;
35486f8d3f33SWingman Kwok struct device_node *secondary_ports;
35496f8d3f33SWingman Kwok struct cpsw_ale_params ale_params;
35506f8d3f33SWingman Kwok struct gbe_priv *gbe_dev;
35516f8d3f33SWingman Kwok u32 slave_num;
3552489e8a2fSWingMan Kwok int i, ret = 0;
35536f8d3f33SWingman Kwok
35546f8d3f33SWingman Kwok if (!node) {
35556f8d3f33SWingman Kwok dev_err(dev, "device tree info unavailable\n");
35566f8d3f33SWingman Kwok return -ENODEV;
35576f8d3f33SWingman Kwok }
35586f8d3f33SWingman Kwok
35596f8d3f33SWingman Kwok gbe_dev = devm_kzalloc(dev, sizeof(struct gbe_priv), GFP_KERNEL);
35606f8d3f33SWingman Kwok if (!gbe_dev)
35616f8d3f33SWingman Kwok return -ENOMEM;
35626f8d3f33SWingman Kwok
35639a391c7bSWingMan Kwok if (of_device_is_compatible(node, "ti,netcp-gbe-5") ||
35649a391c7bSWingMan Kwok of_device_is_compatible(node, "ti,netcp-gbe")) {
35659a391c7bSWingMan Kwok gbe_dev->max_num_slaves = 4;
35669a391c7bSWingMan Kwok } else if (of_device_is_compatible(node, "ti,netcp-gbe-9")) {
35679a391c7bSWingMan Kwok gbe_dev->max_num_slaves = 8;
35689a391c7bSWingMan Kwok } else if (of_device_is_compatible(node, "ti,netcp-gbe-2")) {
35699a391c7bSWingMan Kwok gbe_dev->max_num_slaves = 1;
35708585661bSWingMan Kwok gbe_module.set_rx_mode = gbe_set_rx_mode;
35719a391c7bSWingMan Kwok } else if (of_device_is_compatible(node, "ti,netcp-xgbe")) {
35729a391c7bSWingMan Kwok gbe_dev->max_num_slaves = 2;
35739a391c7bSWingMan Kwok } else {
35749a391c7bSWingMan Kwok dev_err(dev, "device tree node for unknown device\n");
35759a391c7bSWingMan Kwok return -EINVAL;
35769a391c7bSWingMan Kwok }
35779a391c7bSWingMan Kwok gbe_dev->max_num_ports = gbe_dev->max_num_slaves + 1;
35789a391c7bSWingMan Kwok
35796f8d3f33SWingman Kwok gbe_dev->dev = dev;
35806f8d3f33SWingman Kwok gbe_dev->netcp_device = netcp_device;
35816f8d3f33SWingman Kwok gbe_dev->rx_packet_max = NETCP_MAX_FRAME_SIZE;
35826f8d3f33SWingman Kwok
35836f8d3f33SWingman Kwok /* init the hw stats lock */
35846f8d3f33SWingman Kwok spin_lock_init(&gbe_dev->hw_stats_lock);
35856f8d3f33SWingman Kwok
3586*1a87e641SRob Herring gbe_dev->enable_ale = of_property_read_bool(node, "enable-ale");
3587*1a87e641SRob Herring if (gbe_dev->enable_ale)
35886f8d3f33SWingman Kwok dev_info(dev, "ALE enabled\n");
3589*1a87e641SRob Herring else
35906f8d3f33SWingman Kwok dev_dbg(dev, "ALE bypass enabled*\n");
35916f8d3f33SWingman Kwok
35926f8d3f33SWingman Kwok ret = of_property_read_u32(node, "tx-queue",
35936f8d3f33SWingman Kwok &gbe_dev->tx_queue_id);
35946f8d3f33SWingman Kwok if (ret < 0) {
35956f8d3f33SWingman Kwok dev_err(dev, "missing tx_queue parameter\n");
35966f8d3f33SWingman Kwok gbe_dev->tx_queue_id = GBE_TX_QUEUE;
35976f8d3f33SWingman Kwok }
35986f8d3f33SWingman Kwok
35996f8d3f33SWingman Kwok ret = of_property_read_string(node, "tx-channel",
36006f8d3f33SWingman Kwok &gbe_dev->dma_chan_name);
36016f8d3f33SWingman Kwok if (ret < 0) {
36026f8d3f33SWingman Kwok dev_err(dev, "missing \"tx-channel\" parameter\n");
360331a184b7SKaricheri, Muralidharan return -EINVAL;
36046f8d3f33SWingman Kwok }
36056f8d3f33SWingman Kwok
3606bf5849f1SRob Herring if (of_node_name_eq(node, "gbe")) {
36076f8d3f33SWingman Kwok ret = get_gbe_resource_version(gbe_dev, node);
36086f8d3f33SWingman Kwok if (ret)
360931a184b7SKaricheri, Muralidharan return ret;
36106f8d3f33SWingman Kwok
36119a391c7bSWingMan Kwok dev_dbg(dev, "ss_version: 0x%08x\n", gbe_dev->ss_version);
36129a391c7bSWingMan Kwok
36132953586dSMurali Karicheri if (IS_SS_ID_VER_14(gbe_dev))
36146f8d3f33SWingman Kwok ret = set_gbe_ethss14_priv(gbe_dev, node);
36159a391c7bSWingMan Kwok else if (IS_SS_ID_MU(gbe_dev))
36169a391c7bSWingMan Kwok ret = set_gbenu_ethss_priv(gbe_dev, node);
36179a391c7bSWingMan Kwok else
36189a391c7bSWingMan Kwok ret = -ENODEV;
36199a391c7bSWingMan Kwok
3620bf5849f1SRob Herring } else if (of_node_name_eq(node, "xgbe")) {
362190cff9e2SWingman Kwok ret = set_xgbe_ethss10_priv(gbe_dev, node);
362290cff9e2SWingman Kwok if (ret)
362331a184b7SKaricheri, Muralidharan return ret;
362490cff9e2SWingman Kwok ret = netcp_xgbe_serdes_init(gbe_dev->xgbe_serdes_regs,
362590cff9e2SWingman Kwok gbe_dev->ss_regs);
36266f8d3f33SWingman Kwok } else {
362721c328dcSRob Herring dev_err(dev, "unknown GBE node(%pOFn)\n", node);
36286f8d3f33SWingman Kwok ret = -ENODEV;
36296f8d3f33SWingman Kwok }
36306f8d3f33SWingman Kwok
363131a184b7SKaricheri, Muralidharan if (ret)
363231a184b7SKaricheri, Muralidharan return ret;
363331a184b7SKaricheri, Muralidharan
36346f8d3f33SWingman Kwok interfaces = of_get_child_by_name(node, "interfaces");
36356f8d3f33SWingman Kwok if (!interfaces)
36366f8d3f33SWingman Kwok dev_err(dev, "could not find interfaces\n");
36376f8d3f33SWingman Kwok
36386f8d3f33SWingman Kwok ret = netcp_txpipe_init(&gbe_dev->tx_pipe, netcp_device,
36396f8d3f33SWingman Kwok gbe_dev->dma_chan_name, gbe_dev->tx_queue_id);
364075eac7b5SWen Yang if (ret) {
364175eac7b5SWen Yang of_node_put(interfaces);
364231a184b7SKaricheri, Muralidharan return ret;
364375eac7b5SWen Yang }
36446f8d3f33SWingman Kwok
36456f8d3f33SWingman Kwok ret = netcp_txpipe_open(&gbe_dev->tx_pipe);
364675eac7b5SWen Yang if (ret) {
364775eac7b5SWen Yang of_node_put(interfaces);
364831a184b7SKaricheri, Muralidharan return ret;
364975eac7b5SWen Yang }
36506f8d3f33SWingman Kwok
36516f8d3f33SWingman Kwok /* Create network interfaces */
36526f8d3f33SWingman Kwok INIT_LIST_HEAD(&gbe_dev->gbe_intf_head);
36536f8d3f33SWingman Kwok for_each_child_of_node(interfaces, interface) {
36546f8d3f33SWingman Kwok ret = of_property_read_u32(interface, "slave-port", &slave_num);
36556f8d3f33SWingman Kwok if (ret) {
365621c328dcSRob Herring dev_err(dev, "missing slave-port parameter, skipping interface configuration for %pOFn\n",
365721c328dcSRob Herring interface);
36586f8d3f33SWingman Kwok continue;
36596f8d3f33SWingman Kwok }
36606f8d3f33SWingman Kwok gbe_dev->num_slaves++;
3661bd252796SJulia Lawall if (gbe_dev->num_slaves >= gbe_dev->max_num_slaves) {
3662bd252796SJulia Lawall of_node_put(interface);
36639a391c7bSWingMan Kwok break;
36646f8d3f33SWingman Kwok }
3665bd252796SJulia Lawall }
366631a184b7SKaricheri, Muralidharan of_node_put(interfaces);
36676f8d3f33SWingman Kwok
36686f8d3f33SWingman Kwok if (!gbe_dev->num_slaves)
36696f8d3f33SWingman Kwok dev_warn(dev, "No network interface configured\n");
36706f8d3f33SWingman Kwok
36716f8d3f33SWingman Kwok /* Initialize Secondary slave ports */
36726f8d3f33SWingman Kwok secondary_ports = of_get_child_by_name(node, "secondary-slave-ports");
36736f8d3f33SWingman Kwok INIT_LIST_HEAD(&gbe_dev->secondary_slaves);
36749a391c7bSWingMan Kwok if (secondary_ports && (gbe_dev->num_slaves < gbe_dev->max_num_slaves))
36756f8d3f33SWingman Kwok init_secondary_ports(gbe_dev, secondary_ports);
36766f8d3f33SWingman Kwok of_node_put(secondary_ports);
36776f8d3f33SWingman Kwok
36786f8d3f33SWingman Kwok if (!gbe_dev->num_slaves) {
367931a184b7SKaricheri, Muralidharan dev_err(dev,
368031a184b7SKaricheri, Muralidharan "No network interface or secondary ports configured\n");
36816f8d3f33SWingman Kwok ret = -ENODEV;
368231a184b7SKaricheri, Muralidharan goto free_sec_ports;
36836f8d3f33SWingman Kwok }
36846f8d3f33SWingman Kwok
36856f8d3f33SWingman Kwok memset(&ale_params, 0, sizeof(ale_params));
36866f8d3f33SWingman Kwok ale_params.dev = gbe_dev->dev;
36876f8d3f33SWingman Kwok ale_params.ale_regs = gbe_dev->ale_reg;
36886f8d3f33SWingman Kwok ale_params.ale_ageout = GBE_DEFAULT_ALE_AGEOUT;
36896f8d3f33SWingman Kwok ale_params.ale_ports = gbe_dev->ale_ports;
36906dcbd0d9SGrygorii Strashko ale_params.dev_id = "cpsw";
36916dcbd0d9SGrygorii Strashko if (IS_SS_ID_NU(gbe_dev))
36926dcbd0d9SGrygorii Strashko ale_params.dev_id = "66ak2el";
36936dcbd0d9SGrygorii Strashko else if (IS_SS_ID_2U(gbe_dev))
36946dcbd0d9SGrygorii Strashko ale_params.dev_id = "66ak2g";
36956dcbd0d9SGrygorii Strashko else if (IS_SS_ID_XGBE(gbe_dev))
36966dcbd0d9SGrygorii Strashko ale_params.dev_id = "66ak2h-xgbe";
36976dcbd0d9SGrygorii Strashko
36986f8d3f33SWingman Kwok gbe_dev->ale = cpsw_ale_create(&ale_params);
36993469660dSWei Yongjun if (IS_ERR(gbe_dev->ale)) {
37006f8d3f33SWingman Kwok dev_err(gbe_dev->dev, "error initializing ale engine\n");
37013469660dSWei Yongjun ret = PTR_ERR(gbe_dev->ale);
370231a184b7SKaricheri, Muralidharan goto free_sec_ports;
37036f8d3f33SWingman Kwok } else {
37046f8d3f33SWingman Kwok dev_dbg(gbe_dev->dev, "Created a gbe ale engine\n");
37056f8d3f33SWingman Kwok }
37066f8d3f33SWingman Kwok
3707c8ad1451SGrygorii Strashko cpts_node = of_get_child_by_name(node, "cpts");
3708c8ad1451SGrygorii Strashko if (!cpts_node)
3709c8ad1451SGrygorii Strashko cpts_node = of_node_get(node);
3710c8ad1451SGrygorii Strashko
3711b78aba49SGrygorii Strashko gbe_dev->cpts = cpts_create(gbe_dev->dev, gbe_dev->cpts_reg,
3712b78aba49SGrygorii Strashko cpts_node, 0);
3713c8ad1451SGrygorii Strashko of_node_put(cpts_node);
37146246168bSWingMan Kwok if (IS_ENABLED(CONFIG_TI_CPTS) && IS_ERR(gbe_dev->cpts)) {
37156246168bSWingMan Kwok ret = PTR_ERR(gbe_dev->cpts);
37166246168bSWingMan Kwok goto free_sec_ports;
37176246168bSWingMan Kwok }
37186246168bSWingMan Kwok
37196f8d3f33SWingman Kwok /* initialize host port */
37206f8d3f33SWingman Kwok gbe_init_host_port(gbe_dev);
37216f8d3f33SWingman Kwok
3722489e8a2fSWingMan Kwok spin_lock_bh(&gbe_dev->hw_stats_lock);
3723489e8a2fSWingMan Kwok for (i = 0; i < gbe_dev->num_stats_mods; i++) {
37242953586dSMurali Karicheri if (IS_SS_ID_VER_14(gbe_dev))
3725489e8a2fSWingMan Kwok gbe_reset_mod_stats_ver14(gbe_dev, i);
3726489e8a2fSWingMan Kwok else
3727489e8a2fSWingMan Kwok gbe_reset_mod_stats(gbe_dev, i);
3728489e8a2fSWingMan Kwok }
3729489e8a2fSWingMan Kwok spin_unlock_bh(&gbe_dev->hw_stats_lock);
3730489e8a2fSWingMan Kwok
3731e99e88a9SKees Cook timer_setup(&gbe_dev->timer, netcp_ethss_timer, 0);
37326f8d3f33SWingman Kwok gbe_dev->timer.expires = jiffies + GBE_TIMER_INTERVAL;
37336f8d3f33SWingman Kwok add_timer(&gbe_dev->timer);
37346f8d3f33SWingman Kwok *inst_priv = gbe_dev;
37356f8d3f33SWingman Kwok return 0;
37366f8d3f33SWingman Kwok
373731a184b7SKaricheri, Muralidharan free_sec_ports:
373831a184b7SKaricheri, Muralidharan free_secondary_ports(gbe_dev);
37396f8d3f33SWingman Kwok return ret;
37406f8d3f33SWingman Kwok }
37416f8d3f33SWingman Kwok
gbe_attach(void * inst_priv,struct net_device * ndev,struct device_node * node,void ** intf_priv)37426f8d3f33SWingman Kwok static int gbe_attach(void *inst_priv, struct net_device *ndev,
37436f8d3f33SWingman Kwok struct device_node *node, void **intf_priv)
37446f8d3f33SWingman Kwok {
37456f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = inst_priv;
37466f8d3f33SWingman Kwok struct gbe_intf *gbe_intf;
37476f8d3f33SWingman Kwok int ret;
37486f8d3f33SWingman Kwok
37496f8d3f33SWingman Kwok if (!node) {
37506f8d3f33SWingman Kwok dev_err(gbe_dev->dev, "interface node not available\n");
37516f8d3f33SWingman Kwok return -ENODEV;
37526f8d3f33SWingman Kwok }
37536f8d3f33SWingman Kwok
37546f8d3f33SWingman Kwok gbe_intf = devm_kzalloc(gbe_dev->dev, sizeof(*gbe_intf), GFP_KERNEL);
37556f8d3f33SWingman Kwok if (!gbe_intf)
37566f8d3f33SWingman Kwok return -ENOMEM;
37576f8d3f33SWingman Kwok
37586f8d3f33SWingman Kwok gbe_intf->ndev = ndev;
37596f8d3f33SWingman Kwok gbe_intf->dev = gbe_dev->dev;
37606f8d3f33SWingman Kwok gbe_intf->gbe_dev = gbe_dev;
37616f8d3f33SWingman Kwok
37626f8d3f33SWingman Kwok gbe_intf->slave = devm_kzalloc(gbe_dev->dev,
37636f8d3f33SWingman Kwok sizeof(*gbe_intf->slave),
37646f8d3f33SWingman Kwok GFP_KERNEL);
37656f8d3f33SWingman Kwok if (!gbe_intf->slave) {
37666f8d3f33SWingman Kwok ret = -ENOMEM;
37676f8d3f33SWingman Kwok goto fail;
37686f8d3f33SWingman Kwok }
37696f8d3f33SWingman Kwok
37706f8d3f33SWingman Kwok if (init_slave(gbe_dev, gbe_intf->slave, node)) {
37716f8d3f33SWingman Kwok ret = -ENODEV;
37726f8d3f33SWingman Kwok goto fail;
37736f8d3f33SWingman Kwok }
37746f8d3f33SWingman Kwok
37756f8d3f33SWingman Kwok gbe_intf->tx_pipe = gbe_dev->tx_pipe;
37766f8d3f33SWingman Kwok ndev->ethtool_ops = &keystone_ethtool_ops;
37776f8d3f33SWingman Kwok list_add_tail(&gbe_intf->gbe_intf_list, &gbe_dev->gbe_intf_head);
37786f8d3f33SWingman Kwok *intf_priv = gbe_intf;
37796f8d3f33SWingman Kwok return 0;
37806f8d3f33SWingman Kwok
37816f8d3f33SWingman Kwok fail:
37826f8d3f33SWingman Kwok if (gbe_intf->slave)
37836f8d3f33SWingman Kwok devm_kfree(gbe_dev->dev, gbe_intf->slave);
37846f8d3f33SWingman Kwok if (gbe_intf)
37856f8d3f33SWingman Kwok devm_kfree(gbe_dev->dev, gbe_intf);
37866f8d3f33SWingman Kwok return ret;
37876f8d3f33SWingman Kwok }
37886f8d3f33SWingman Kwok
gbe_release(void * intf_priv)37896f8d3f33SWingman Kwok static int gbe_release(void *intf_priv)
37906f8d3f33SWingman Kwok {
37916f8d3f33SWingman Kwok struct gbe_intf *gbe_intf = intf_priv;
37926f8d3f33SWingman Kwok
37936f8d3f33SWingman Kwok gbe_intf->ndev->ethtool_ops = NULL;
37946f8d3f33SWingman Kwok list_del(&gbe_intf->gbe_intf_list);
37956f8d3f33SWingman Kwok devm_kfree(gbe_intf->dev, gbe_intf->slave);
37966f8d3f33SWingman Kwok devm_kfree(gbe_intf->dev, gbe_intf);
37976f8d3f33SWingman Kwok return 0;
37986f8d3f33SWingman Kwok }
37996f8d3f33SWingman Kwok
gbe_remove(struct netcp_device * netcp_device,void * inst_priv)38006f8d3f33SWingman Kwok static int gbe_remove(struct netcp_device *netcp_device, void *inst_priv)
38016f8d3f33SWingman Kwok {
38026f8d3f33SWingman Kwok struct gbe_priv *gbe_dev = inst_priv;
38036f8d3f33SWingman Kwok
38046f8d3f33SWingman Kwok del_timer_sync(&gbe_dev->timer);
38056246168bSWingMan Kwok cpts_release(gbe_dev->cpts);
38066f8d3f33SWingman Kwok cpsw_ale_stop(gbe_dev->ale);
38076f8d3f33SWingman Kwok netcp_txpipe_close(&gbe_dev->tx_pipe);
38086f8d3f33SWingman Kwok free_secondary_ports(gbe_dev);
38096f8d3f33SWingman Kwok
38106f8d3f33SWingman Kwok if (!list_empty(&gbe_dev->gbe_intf_head))
381131a184b7SKaricheri, Muralidharan dev_alert(gbe_dev->dev,
381231a184b7SKaricheri, Muralidharan "unreleased ethss interfaces present\n");
38136f8d3f33SWingman Kwok
38146f8d3f33SWingman Kwok return 0;
38156f8d3f33SWingman Kwok }
38166f8d3f33SWingman Kwok
38176f8d3f33SWingman Kwok static struct netcp_module gbe_module = {
38186f8d3f33SWingman Kwok .name = GBE_MODULE_NAME,
38196f8d3f33SWingman Kwok .owner = THIS_MODULE,
38206f8d3f33SWingman Kwok .primary = true,
38216f8d3f33SWingman Kwok .probe = gbe_probe,
38226f8d3f33SWingman Kwok .open = gbe_open,
38236f8d3f33SWingman Kwok .close = gbe_close,
38246f8d3f33SWingman Kwok .remove = gbe_remove,
38256f8d3f33SWingman Kwok .attach = gbe_attach,
38266f8d3f33SWingman Kwok .release = gbe_release,
38276f8d3f33SWingman Kwok .add_addr = gbe_add_addr,
38286f8d3f33SWingman Kwok .del_addr = gbe_del_addr,
38296f8d3f33SWingman Kwok .add_vid = gbe_add_vid,
38306f8d3f33SWingman Kwok .del_vid = gbe_del_vid,
38316f8d3f33SWingman Kwok .ioctl = gbe_ioctl,
38326f8d3f33SWingman Kwok };
38336f8d3f33SWingman Kwok
383490cff9e2SWingman Kwok static struct netcp_module xgbe_module = {
383590cff9e2SWingman Kwok .name = XGBE_MODULE_NAME,
383690cff9e2SWingman Kwok .owner = THIS_MODULE,
383790cff9e2SWingman Kwok .primary = true,
383890cff9e2SWingman Kwok .probe = gbe_probe,
383990cff9e2SWingman Kwok .open = gbe_open,
384090cff9e2SWingman Kwok .close = gbe_close,
384190cff9e2SWingman Kwok .remove = gbe_remove,
384290cff9e2SWingman Kwok .attach = gbe_attach,
384390cff9e2SWingman Kwok .release = gbe_release,
384490cff9e2SWingman Kwok .add_addr = gbe_add_addr,
384590cff9e2SWingman Kwok .del_addr = gbe_del_addr,
384690cff9e2SWingman Kwok .add_vid = gbe_add_vid,
384790cff9e2SWingman Kwok .del_vid = gbe_del_vid,
384890cff9e2SWingman Kwok .ioctl = gbe_ioctl,
384990cff9e2SWingman Kwok };
385090cff9e2SWingman Kwok
keystone_gbe_init(void)38516f8d3f33SWingman Kwok static int __init keystone_gbe_init(void)
38526f8d3f33SWingman Kwok {
38536f8d3f33SWingman Kwok int ret;
38546f8d3f33SWingman Kwok
38556f8d3f33SWingman Kwok ret = netcp_register_module(&gbe_module);
38566f8d3f33SWingman Kwok if (ret)
38576f8d3f33SWingman Kwok return ret;
38586f8d3f33SWingman Kwok
385990cff9e2SWingman Kwok ret = netcp_register_module(&xgbe_module);
386090cff9e2SWingman Kwok if (ret)
386190cff9e2SWingman Kwok return ret;
386290cff9e2SWingman Kwok
38636f8d3f33SWingman Kwok return 0;
38646f8d3f33SWingman Kwok }
38656f8d3f33SWingman Kwok module_init(keystone_gbe_init);
38666f8d3f33SWingman Kwok
keystone_gbe_exit(void)38676f8d3f33SWingman Kwok static void __exit keystone_gbe_exit(void)
38686f8d3f33SWingman Kwok {
38696f8d3f33SWingman Kwok netcp_unregister_module(&gbe_module);
387090cff9e2SWingman Kwok netcp_unregister_module(&xgbe_module);
38716f8d3f33SWingman Kwok }
38726f8d3f33SWingman Kwok module_exit(keystone_gbe_exit);
387358c11b5fSKaricheri, Muralidharan
387458c11b5fSKaricheri, Muralidharan MODULE_LICENSE("GPL v2");
387558c11b5fSKaricheri, Muralidharan MODULE_DESCRIPTION("TI NETCP ETHSS driver for Keystone SOCs");
387658c11b5fSKaricheri, Muralidharan MODULE_AUTHOR("Sandeep Nair <sandeep_n@ti.com");
3877