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