xref: /linux/drivers/net/ethernet/hisilicon/hibmcge/hbg_ethtool.c (revision 51574da8dce3c08f388893d727292364a1db8cc0)
1e8d13548SJijie Shao // SPDX-License-Identifier: GPL-2.0+
2e8d13548SJijie Shao // Copyright (c) 2024 Hisilicon Limited.
3e8d13548SJijie Shao 
4e8d13548SJijie Shao #include <linux/ethtool.h>
5e8d13548SJijie Shao #include <linux/phy.h>
6*51574da8SJijie Shao #include "hbg_common.h"
7e8d13548SJijie Shao #include "hbg_ethtool.h"
8*51574da8SJijie Shao #include "hbg_hw.h"
9*51574da8SJijie Shao 
10*51574da8SJijie Shao enum hbg_reg_dump_type {
11*51574da8SJijie Shao 	HBG_DUMP_REG_TYPE_SPEC = 0,
12*51574da8SJijie Shao 	HBG_DUMP_REG_TYPE_MDIO,
13*51574da8SJijie Shao 	HBG_DUMP_REG_TYPE_GMAC,
14*51574da8SJijie Shao 	HBG_DUMP_REG_TYPE_PCU,
15*51574da8SJijie Shao };
16*51574da8SJijie Shao 
17*51574da8SJijie Shao struct hbg_reg_info {
18*51574da8SJijie Shao 	u32 type;
19*51574da8SJijie Shao 	u32 offset;
20*51574da8SJijie Shao 	u32 val;
21*51574da8SJijie Shao };
22*51574da8SJijie Shao 
23*51574da8SJijie Shao #define HBG_DUMP_SPEC_I(offset) {HBG_DUMP_REG_TYPE_SPEC, offset, 0}
24*51574da8SJijie Shao #define HBG_DUMP_MDIO_I(offset) {HBG_DUMP_REG_TYPE_MDIO, offset, 0}
25*51574da8SJijie Shao #define HBG_DUMP_GMAC_I(offset) {HBG_DUMP_REG_TYPE_GMAC, offset, 0}
26*51574da8SJijie Shao #define HBG_DUMP_PCU_I(offset) {HBG_DUMP_REG_TYPE_PCU, offset, 0}
27*51574da8SJijie Shao 
28*51574da8SJijie Shao static const struct hbg_reg_info hbg_dump_reg_infos[] = {
29*51574da8SJijie Shao 	/* dev specs */
30*51574da8SJijie Shao 	HBG_DUMP_SPEC_I(HBG_REG_SPEC_VALID_ADDR),
31*51574da8SJijie Shao 	HBG_DUMP_SPEC_I(HBG_REG_EVENT_REQ_ADDR),
32*51574da8SJijie Shao 	HBG_DUMP_SPEC_I(HBG_REG_MAC_ID_ADDR),
33*51574da8SJijie Shao 	HBG_DUMP_SPEC_I(HBG_REG_PHY_ID_ADDR),
34*51574da8SJijie Shao 	HBG_DUMP_SPEC_I(HBG_REG_MAC_ADDR_ADDR),
35*51574da8SJijie Shao 	HBG_DUMP_SPEC_I(HBG_REG_MAC_ADDR_HIGH_ADDR),
36*51574da8SJijie Shao 	HBG_DUMP_SPEC_I(HBG_REG_UC_MAC_NUM_ADDR),
37*51574da8SJijie Shao 	HBG_DUMP_SPEC_I(HBG_REG_MDIO_FREQ_ADDR),
38*51574da8SJijie Shao 	HBG_DUMP_SPEC_I(HBG_REG_MAX_MTU_ADDR),
39*51574da8SJijie Shao 	HBG_DUMP_SPEC_I(HBG_REG_MIN_MTU_ADDR),
40*51574da8SJijie Shao 	HBG_DUMP_SPEC_I(HBG_REG_TX_FIFO_NUM_ADDR),
41*51574da8SJijie Shao 	HBG_DUMP_SPEC_I(HBG_REG_RX_FIFO_NUM_ADDR),
42*51574da8SJijie Shao 	HBG_DUMP_SPEC_I(HBG_REG_VLAN_LAYERS_ADDR),
43*51574da8SJijie Shao 
44*51574da8SJijie Shao 	/* mdio */
45*51574da8SJijie Shao 	HBG_DUMP_MDIO_I(HBG_REG_MDIO_COMMAND_ADDR),
46*51574da8SJijie Shao 	HBG_DUMP_MDIO_I(HBG_REG_MDIO_ADDR_ADDR),
47*51574da8SJijie Shao 	HBG_DUMP_MDIO_I(HBG_REG_MDIO_WDATA_ADDR),
48*51574da8SJijie Shao 	HBG_DUMP_MDIO_I(HBG_REG_MDIO_RDATA_ADDR),
49*51574da8SJijie Shao 	HBG_DUMP_MDIO_I(HBG_REG_MDIO_STA_ADDR),
50*51574da8SJijie Shao 
51*51574da8SJijie Shao 	/* gmac */
52*51574da8SJijie Shao 	HBG_DUMP_GMAC_I(HBG_REG_DUPLEX_TYPE_ADDR),
53*51574da8SJijie Shao 	HBG_DUMP_GMAC_I(HBG_REG_FD_FC_TYPE_ADDR),
54*51574da8SJijie Shao 	HBG_DUMP_GMAC_I(HBG_REG_FC_TX_TIMER_ADDR),
55*51574da8SJijie Shao 	HBG_DUMP_GMAC_I(HBG_REG_FD_FC_ADDR_LOW_ADDR),
56*51574da8SJijie Shao 	HBG_DUMP_GMAC_I(HBG_REG_FD_FC_ADDR_HIGH_ADDR),
57*51574da8SJijie Shao 	HBG_DUMP_GMAC_I(HBG_REG_MAX_FRAME_SIZE_ADDR),
58*51574da8SJijie Shao 	HBG_DUMP_GMAC_I(HBG_REG_PORT_MODE_ADDR),
59*51574da8SJijie Shao 	HBG_DUMP_GMAC_I(HBG_REG_PORT_ENABLE_ADDR),
60*51574da8SJijie Shao 	HBG_DUMP_GMAC_I(HBG_REG_PAUSE_ENABLE_ADDR),
61*51574da8SJijie Shao 	HBG_DUMP_GMAC_I(HBG_REG_AN_NEG_STATE_ADDR),
62*51574da8SJijie Shao 	HBG_DUMP_GMAC_I(HBG_REG_TRANSMIT_CTRL_ADDR),
63*51574da8SJijie Shao 	HBG_DUMP_GMAC_I(HBG_REG_REC_FILT_CTRL_ADDR),
64*51574da8SJijie Shao 	HBG_DUMP_GMAC_I(HBG_REG_LINE_LOOP_BACK_ADDR),
65*51574da8SJijie Shao 	HBG_DUMP_GMAC_I(HBG_REG_CF_CRC_STRIP_ADDR),
66*51574da8SJijie Shao 	HBG_DUMP_GMAC_I(HBG_REG_MODE_CHANGE_EN_ADDR),
67*51574da8SJijie Shao 	HBG_DUMP_GMAC_I(HBG_REG_LOOP_REG_ADDR),
68*51574da8SJijie Shao 	HBG_DUMP_GMAC_I(HBG_REG_RECV_CTRL_ADDR),
69*51574da8SJijie Shao 	HBG_DUMP_GMAC_I(HBG_REG_VLAN_CODE_ADDR),
70*51574da8SJijie Shao 	HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_LOW_0_ADDR),
71*51574da8SJijie Shao 	HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_HIGH_0_ADDR),
72*51574da8SJijie Shao 	HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_LOW_1_ADDR),
73*51574da8SJijie Shao 	HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_HIGH_1_ADDR),
74*51574da8SJijie Shao 	HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_LOW_2_ADDR),
75*51574da8SJijie Shao 	HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_HIGH_2_ADDR),
76*51574da8SJijie Shao 	HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_LOW_3_ADDR),
77*51574da8SJijie Shao 	HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_HIGH_3_ADDR),
78*51574da8SJijie Shao 	HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_LOW_4_ADDR),
79*51574da8SJijie Shao 	HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_HIGH_4_ADDR),
80*51574da8SJijie Shao 	HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_LOW_5_ADDR),
81*51574da8SJijie Shao 	HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_HIGH_5_ADDR),
82*51574da8SJijie Shao 
83*51574da8SJijie Shao 	/* pcu */
84*51574da8SJijie Shao 	HBG_DUMP_PCU_I(HBG_REG_TX_FIFO_THRSLD_ADDR),
85*51574da8SJijie Shao 	HBG_DUMP_PCU_I(HBG_REG_RX_FIFO_THRSLD_ADDR),
86*51574da8SJijie Shao 	HBG_DUMP_PCU_I(HBG_REG_CFG_FIFO_THRSLD_ADDR),
87*51574da8SJijie Shao 	HBG_DUMP_PCU_I(HBG_REG_CF_INTRPT_MSK_ADDR),
88*51574da8SJijie Shao 	HBG_DUMP_PCU_I(HBG_REG_CF_INTRPT_STAT_ADDR),
89*51574da8SJijie Shao 	HBG_DUMP_PCU_I(HBG_REG_CF_INTRPT_CLR_ADDR),
90*51574da8SJijie Shao 	HBG_DUMP_PCU_I(HBG_REG_TX_BUS_ERR_ADDR_ADDR),
91*51574da8SJijie Shao 	HBG_DUMP_PCU_I(HBG_REG_RX_BUS_ERR_ADDR_ADDR),
92*51574da8SJijie Shao 	HBG_DUMP_PCU_I(HBG_REG_MAX_FRAME_LEN_ADDR),
93*51574da8SJijie Shao 	HBG_DUMP_PCU_I(HBG_REG_DEBUG_ST_MCH_ADDR),
94*51574da8SJijie Shao 	HBG_DUMP_PCU_I(HBG_REG_FIFO_CURR_STATUS_ADDR),
95*51574da8SJijie Shao 	HBG_DUMP_PCU_I(HBG_REG_FIFO_HIST_STATUS_ADDR),
96*51574da8SJijie Shao 	HBG_DUMP_PCU_I(HBG_REG_CF_CFF_DATA_NUM_ADDR),
97*51574da8SJijie Shao 	HBG_DUMP_PCU_I(HBG_REG_CF_TX_PAUSE_ADDR),
98*51574da8SJijie Shao 	HBG_DUMP_PCU_I(HBG_REG_RX_CFF_ADDR_ADDR),
99*51574da8SJijie Shao 	HBG_DUMP_PCU_I(HBG_REG_RX_BUF_SIZE_ADDR),
100*51574da8SJijie Shao 	HBG_DUMP_PCU_I(HBG_REG_BUS_CTRL_ADDR),
101*51574da8SJijie Shao 	HBG_DUMP_PCU_I(HBG_REG_RX_CTRL_ADDR),
102*51574da8SJijie Shao 	HBG_DUMP_PCU_I(HBG_REG_RX_PKT_MODE_ADDR),
103*51574da8SJijie Shao 	HBG_DUMP_PCU_I(HBG_REG_DBG_ST0_ADDR),
104*51574da8SJijie Shao 	HBG_DUMP_PCU_I(HBG_REG_DBG_ST1_ADDR),
105*51574da8SJijie Shao 	HBG_DUMP_PCU_I(HBG_REG_DBG_ST2_ADDR),
106*51574da8SJijie Shao 	HBG_DUMP_PCU_I(HBG_REG_BUS_RST_EN_ADDR),
107*51574da8SJijie Shao 	HBG_DUMP_PCU_I(HBG_REG_CF_IND_TXINT_MSK_ADDR),
108*51574da8SJijie Shao 	HBG_DUMP_PCU_I(HBG_REG_CF_IND_TXINT_STAT_ADDR),
109*51574da8SJijie Shao 	HBG_DUMP_PCU_I(HBG_REG_CF_IND_TXINT_CLR_ADDR),
110*51574da8SJijie Shao 	HBG_DUMP_PCU_I(HBG_REG_CF_IND_RXINT_MSK_ADDR),
111*51574da8SJijie Shao 	HBG_DUMP_PCU_I(HBG_REG_CF_IND_RXINT_STAT_ADDR),
112*51574da8SJijie Shao 	HBG_DUMP_PCU_I(HBG_REG_CF_IND_RXINT_CLR_ADDR),
113*51574da8SJijie Shao };
114*51574da8SJijie Shao 
115*51574da8SJijie Shao static const u32 hbg_dump_type_base_array[] = {
116*51574da8SJijie Shao 	[HBG_DUMP_REG_TYPE_SPEC] = 0,
117*51574da8SJijie Shao 	[HBG_DUMP_REG_TYPE_MDIO] = HBG_REG_MDIO_BASE,
118*51574da8SJijie Shao 	[HBG_DUMP_REG_TYPE_GMAC] = HBG_REG_SGMII_BASE,
119*51574da8SJijie Shao 	[HBG_DUMP_REG_TYPE_PCU] = HBG_REG_SGMII_BASE,
120*51574da8SJijie Shao };
121*51574da8SJijie Shao 
122*51574da8SJijie Shao static int hbg_ethtool_get_regs_len(struct net_device *netdev)
123*51574da8SJijie Shao {
124*51574da8SJijie Shao 	return ARRAY_SIZE(hbg_dump_reg_infos) * sizeof(struct hbg_reg_info);
125*51574da8SJijie Shao }
126*51574da8SJijie Shao 
127*51574da8SJijie Shao static void hbg_ethtool_get_regs(struct net_device *netdev,
128*51574da8SJijie Shao 				 struct ethtool_regs *regs, void *data)
129*51574da8SJijie Shao {
130*51574da8SJijie Shao 	struct hbg_priv *priv = netdev_priv(netdev);
131*51574da8SJijie Shao 	struct hbg_reg_info *info;
132*51574da8SJijie Shao 	u32 i, offset = 0;
133*51574da8SJijie Shao 
134*51574da8SJijie Shao 	regs->version = 0;
135*51574da8SJijie Shao 	for (i = 0; i < ARRAY_SIZE(hbg_dump_reg_infos); i++) {
136*51574da8SJijie Shao 		info = data + offset;
137*51574da8SJijie Shao 
138*51574da8SJijie Shao 		*info = hbg_dump_reg_infos[i];
139*51574da8SJijie Shao 		info->val = hbg_reg_read(priv, info->offset);
140*51574da8SJijie Shao 		info->offset -= hbg_dump_type_base_array[info->type];
141*51574da8SJijie Shao 
142*51574da8SJijie Shao 		offset += sizeof(*info);
143*51574da8SJijie Shao 	}
144*51574da8SJijie Shao }
145e8d13548SJijie Shao 
146e8d13548SJijie Shao static const struct ethtool_ops hbg_ethtool_ops = {
147e8d13548SJijie Shao 	.get_link		= ethtool_op_get_link,
148e8d13548SJijie Shao 	.get_link_ksettings	= phy_ethtool_get_link_ksettings,
149e8d13548SJijie Shao 	.set_link_ksettings	= phy_ethtool_set_link_ksettings,
150*51574da8SJijie Shao 	.get_regs_len		= hbg_ethtool_get_regs_len,
151*51574da8SJijie Shao 	.get_regs		= hbg_ethtool_get_regs,
152e8d13548SJijie Shao };
153e8d13548SJijie Shao 
154e8d13548SJijie Shao void hbg_ethtool_set_ops(struct net_device *netdev)
155e8d13548SJijie Shao {
156e8d13548SJijie Shao 	netdev->ethtool_ops = &hbg_ethtool_ops;
157e8d13548SJijie Shao }
158