File Index
Files and directories
Sign in
FILE

hbg_ethtool.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/ethernet/hisilicon/hibmcge/hbg_ethtool.c C
  1// SPDX-License-Identifier: GPL-2.0+
  2// Copyright (c) 2024 Hisilicon Limited.
  3
  4#include <linux/ethtool.h>
  5#include <linux/phy.h>
  6#include <linux/rtnetlink.h>
  7#include "hbg_common.h"
  8#include "hbg_err.h"
  9#include "hbg_ethtool.h"
 10#include "hbg_hw.h"
 11
 12struct hbg_ethtool_stats {
 13	char name[ETH_GSTRING_LEN];
 14	unsigned long offset;
 15	u32 reg; /* set to 0 if stats is not updated via dump reg */
 16};
 17
 18#define HBG_STATS_I(stats) { #stats, HBG_STATS_FIELD_OFF(stats), 0}
 19#define HBG_STATS_REG_I(stats, reg) { #stats, HBG_STATS_FIELD_OFF(stats), reg}
 20
 21static const struct hbg_ethtool_stats hbg_ethtool_stats_info[] = {
 22	HBG_STATS_I(rx_desc_l2_err_cnt),
 23	HBG_STATS_I(rx_desc_pkt_len_err_cnt),
 24	HBG_STATS_I(rx_desc_l3_wrong_head_cnt),
 25	HBG_STATS_I(rx_desc_l3_csum_err_cnt),
 26	HBG_STATS_I(rx_desc_l3_len_err_cnt),
 27	HBG_STATS_I(rx_desc_l3_zero_ttl_cnt),
 28	HBG_STATS_I(rx_desc_l3_other_cnt),
 29	HBG_STATS_I(rx_desc_l4_wrong_head_cnt),
 30	HBG_STATS_I(rx_desc_l4_len_err_cnt),
 31	HBG_STATS_I(rx_desc_l4_csum_err_cnt),
 32	HBG_STATS_I(rx_desc_l4_zero_port_num_cnt),
 33	HBG_STATS_I(rx_desc_l4_other_cnt),
 34	HBG_STATS_I(rx_desc_ip_ver_err_cnt),
 35	HBG_STATS_I(rx_desc_ipv4_pkt_cnt),
 36	HBG_STATS_I(rx_desc_ipv6_pkt_cnt),
 37	HBG_STATS_I(rx_desc_no_ip_pkt_cnt),
 38	HBG_STATS_I(rx_desc_ip_pkt_cnt),
 39	HBG_STATS_I(rx_desc_tcp_pkt_cnt),
 40	HBG_STATS_I(rx_desc_udp_pkt_cnt),
 41	HBG_STATS_I(rx_desc_vlan_pkt_cnt),
 42	HBG_STATS_I(rx_desc_icmp_pkt_cnt),
 43	HBG_STATS_I(rx_desc_arp_pkt_cnt),
 44	HBG_STATS_I(rx_desc_rarp_pkt_cnt),
 45	HBG_STATS_I(rx_desc_multicast_pkt_cnt),
 46	HBG_STATS_I(rx_desc_broadcast_pkt_cnt),
 47	HBG_STATS_I(rx_desc_ipsec_pkt_cnt),
 48	HBG_STATS_I(rx_desc_ip_opt_pkt_cnt),
 49	HBG_STATS_I(rx_desc_key_not_match_cnt),
 50
 51	HBG_STATS_REG_I(rx_octets_bad_cnt, HBG_REG_RX_OCTETS_BAD_ADDR),
 52	HBG_STATS_REG_I(rx_octets_total_filt_cnt,
 53			HBG_REG_RX_OCTETS_TOTAL_FILT_ADDR),
 54	HBG_STATS_REG_I(rx_uc_pkt_cnt, HBG_REG_RX_UC_PKTS_ADDR),
 55	HBG_STATS_REG_I(rx_vlan_pkt_cnt, HBG_REG_RX_TAGGED_ADDR),
 56	HBG_STATS_REG_I(rx_filt_pkt_cnt, HBG_REG_RX_FILT_PKT_CNT_ADDR),
 57	HBG_STATS_REG_I(rx_data_error_cnt, HBG_REG_RX_DATA_ERR_ADDR),
 58	HBG_STATS_REG_I(rx_frame_long_err_cnt, HBG_REG_RX_LONG_ERRORS_ADDR),
 59	HBG_STATS_REG_I(rx_jabber_err_cnt, HBG_REG_RX_JABBER_ERRORS_ADDR),
 60	HBG_STATS_REG_I(rx_frame_very_long_err_cnt,
 61			HBG_REG_RX_VERY_LONG_ERR_CNT_ADDR),
 62	HBG_STATS_REG_I(rx_frame_runt_err_cnt, HBG_REG_RX_RUNT_ERR_CNT_ADDR),
 63	HBG_STATS_REG_I(rx_frame_short_err_cnt, HBG_REG_RX_SHORT_ERR_CNT_ADDR),
 64	HBG_STATS_REG_I(rx_overflow_cnt, HBG_REG_RX_OVER_FLOW_CNT_ADDR),
 65	HBG_STATS_REG_I(rx_bufrq_err_cnt, HBG_REG_RX_BUFRQ_ERR_CNT_ADDR),
 66	HBG_STATS_REG_I(rx_we_err_cnt, HBG_REG_RX_WE_ERR_CNT_ADDR),
 67	HBG_STATS_REG_I(rx_overrun_cnt, HBG_REG_RX_OVERRUN_CNT_ADDR),
 68	HBG_STATS_REG_I(rx_lengthfield_err_cnt,
 69			HBG_REG_RX_LENGTHFIELD_ERR_CNT_ADDR),
 70	HBG_STATS_REG_I(rx_fail_comma_cnt, HBG_REG_RX_FAIL_COMMA_CNT_ADDR),
 71	HBG_STATS_I(rx_dma_err_cnt),
 72	HBG_STATS_I(rx_fifo_less_empty_thrsld_cnt),
 73
 74	HBG_STATS_REG_I(tx_uc_pkt_cnt, HBG_REG_TX_UC_PKTS_ADDR),
 75	HBG_STATS_REG_I(tx_vlan_pkt_cnt, HBG_REG_TX_TAGGED_ADDR),
 76	HBG_STATS_REG_I(tx_octets_bad_cnt, HBG_REG_OCTETS_TRANSMITTED_BAD_ADDR),
 77
 78	HBG_STATS_REG_I(tx_underrun_err_cnt, HBG_REG_TX_UNDERRUN_ADDR),
 79	HBG_STATS_REG_I(tx_add_cs_fail_cnt, HBG_REG_TX_CS_FAIL_CNT_ADDR),
 80	HBG_STATS_REG_I(tx_bufrl_err_cnt, HBG_REG_TX_BUFRL_ERR_CNT_ADDR),
 81	HBG_STATS_REG_I(tx_crc_err_cnt, HBG_REG_TX_CRC_ERROR_ADDR),
 82	HBG_STATS_REG_I(tx_drop_cnt, HBG_REG_TX_DROP_CNT_ADDR),
 83	HBG_STATS_REG_I(tx_excessive_length_drop_cnt,
 84			HBG_REG_TX_EXCESSIVE_LENGTH_DROP_ADDR),
 85	HBG_STATS_I(tx_dma_err_cnt),
 86	HBG_STATS_I(tx_timeout_cnt),
 87	HBG_STATS_I(reset_fail_cnt),
 88};
 89
 90static const struct hbg_ethtool_stats hbg_ethtool_rmon_stats_info[] = {
 91	HBG_STATS_I(rx_desc_frag_cnt),
 92	HBG_STATS_REG_I(rx_framesize_64, HBG_REG_RX_PKTS_64OCTETS_ADDR),
 93	HBG_STATS_REG_I(rx_framesize_65_127,
 94			HBG_REG_RX_PKTS_65TO127OCTETS_ADDR),
 95	HBG_STATS_REG_I(rx_framesize_128_255,
 96			HBG_REG_RX_PKTS_128TO255OCTETS_ADDR),
 97	HBG_STATS_REG_I(rx_framesize_256_511,
 98			HBG_REG_RX_PKTS_256TO511OCTETS_ADDR),
 99	HBG_STATS_REG_I(rx_framesize_512_1023,
100			HBG_REG_RX_PKTS_512TO1023OCTETS_ADDR),
101	HBG_STATS_REG_I(rx_framesize_1024_1518,
102			HBG_REG_RX_PKTS_1024TO1518OCTETS_ADDR),
103	HBG_STATS_REG_I(rx_framesize_bt_1518,
104			HBG_REG_RX_PKTS_1519TOMAXOCTETS_ADDR),
105	HBG_STATS_REG_I(tx_framesize_64, HBG_REG_TX_PKTS_64OCTETS_ADDR),
106	HBG_STATS_REG_I(tx_framesize_65_127,
107			HBG_REG_TX_PKTS_65TO127OCTETS_ADDR),
108	HBG_STATS_REG_I(tx_framesize_128_255,
109			HBG_REG_TX_PKTS_128TO255OCTETS_ADDR),
110	HBG_STATS_REG_I(tx_framesize_256_511,
111			HBG_REG_TX_PKTS_256TO511OCTETS_ADDR),
112	HBG_STATS_REG_I(tx_framesize_512_1023,
113			HBG_REG_TX_PKTS_512TO1023OCTETS_ADDR),
114	HBG_STATS_REG_I(tx_framesize_1024_1518,
115			HBG_REG_TX_PKTS_1024TO1518OCTETS_ADDR),
116	HBG_STATS_REG_I(tx_framesize_bt_1518,
117			HBG_REG_TX_PKTS_1519TOMAXOCTETS_ADDR),
118};
119
120static const struct hbg_ethtool_stats hbg_ethtool_mac_stats_info[] = {
121	HBG_STATS_REG_I(rx_mc_pkt_cnt, HBG_REG_RX_MC_PKTS_ADDR),
122	HBG_STATS_REG_I(rx_bc_pkt_cnt, HBG_REG_RX_BC_PKTS_ADDR),
123	HBG_STATS_REG_I(rx_align_error_cnt, HBG_REG_RX_ALIGN_ERRORS_ADDR),
124	HBG_STATS_REG_I(rx_octets_total_ok_cnt,
125			HBG_REG_RX_OCTETS_TOTAL_OK_ADDR),
126	HBG_STATS_REG_I(rx_trans_pkt_cnt, HBG_REG_RX_TRANS_PKG_CNT_ADDR),
127	HBG_STATS_REG_I(rx_fcs_error_cnt, HBG_REG_RX_FCS_ERRORS_ADDR),
128	HBG_STATS_REG_I(tx_mc_pkt_cnt, HBG_REG_TX_MC_PKTS_ADDR),
129	HBG_STATS_REG_I(tx_bc_pkt_cnt, HBG_REG_TX_BC_PKTS_ADDR),
130	HBG_STATS_REG_I(tx_octets_total_ok_cnt,
131			HBG_REG_OCTETS_TRANSMITTED_OK_ADDR),
132	HBG_STATS_REG_I(tx_trans_pkt_cnt, HBG_REG_TX_TRANS_PKG_CNT_ADDR),
133};
134
135static const struct hbg_ethtool_stats hbg_ethtool_ctrl_stats_info[] = {
136	HBG_STATS_REG_I(rx_pause_macctl_frame_cnt,
137			HBG_REG_RX_PAUSE_MACCTL_FRAMCOUNTER_ADDR),
138	HBG_STATS_REG_I(tx_pause_frame_cnt, HBG_REG_TX_PAUSE_FRAMES_ADDR),
139	HBG_STATS_REG_I(rx_unknown_macctl_frame_cnt,
140			HBG_REG_RX_UNKNOWN_MACCTL_FRAMCOUNTER_ADDR),
141};
142
143enum hbg_reg_dump_type {
144	HBG_DUMP_REG_TYPE_SPEC = 0,
145	HBG_DUMP_REG_TYPE_MDIO,
146	HBG_DUMP_REG_TYPE_GMAC,
147	HBG_DUMP_REG_TYPE_PCU,
148};
149
150struct hbg_reg_info {
151	u32 type;
152	u32 offset;
153	u32 val;
154};
155
156#define HBG_DUMP_SPEC_I(offset) {HBG_DUMP_REG_TYPE_SPEC, offset, 0}
157#define HBG_DUMP_MDIO_I(offset) {HBG_DUMP_REG_TYPE_MDIO, offset, 0}
158#define HBG_DUMP_GMAC_I(offset) {HBG_DUMP_REG_TYPE_GMAC, offset, 0}
159#define HBG_DUMP_PCU_I(offset) {HBG_DUMP_REG_TYPE_PCU, offset, 0}
160
161static const struct hbg_reg_info hbg_dump_reg_infos[] = {
162	/* dev specs */
163	HBG_DUMP_SPEC_I(HBG_REG_SPEC_VALID_ADDR),
164	HBG_DUMP_SPEC_I(HBG_REG_EVENT_REQ_ADDR),
165	HBG_DUMP_SPEC_I(HBG_REG_MAC_ID_ADDR),
166	HBG_DUMP_SPEC_I(HBG_REG_PHY_ID_ADDR),
167	HBG_DUMP_SPEC_I(HBG_REG_MAC_ADDR_ADDR),
168	HBG_DUMP_SPEC_I(HBG_REG_MAC_ADDR_HIGH_ADDR),
169	HBG_DUMP_SPEC_I(HBG_REG_UC_MAC_NUM_ADDR),
170	HBG_DUMP_SPEC_I(HBG_REG_MDIO_FREQ_ADDR),
171	HBG_DUMP_SPEC_I(HBG_REG_MAX_MTU_ADDR),
172	HBG_DUMP_SPEC_I(HBG_REG_MIN_MTU_ADDR),
173	HBG_DUMP_SPEC_I(HBG_REG_TX_FIFO_NUM_ADDR),
174	HBG_DUMP_SPEC_I(HBG_REG_RX_FIFO_NUM_ADDR),
175	HBG_DUMP_SPEC_I(HBG_REG_VLAN_LAYERS_ADDR),
176
177	/* mdio */
178	HBG_DUMP_MDIO_I(HBG_REG_MDIO_COMMAND_ADDR),
179	HBG_DUMP_MDIO_I(HBG_REG_MDIO_ADDR_ADDR),
180	HBG_DUMP_MDIO_I(HBG_REG_MDIO_WDATA_ADDR),
181	HBG_DUMP_MDIO_I(HBG_REG_MDIO_RDATA_ADDR),
182	HBG_DUMP_MDIO_I(HBG_REG_MDIO_STA_ADDR),
183
184	/* gmac */
185	HBG_DUMP_GMAC_I(HBG_REG_DUPLEX_TYPE_ADDR),
186	HBG_DUMP_GMAC_I(HBG_REG_FD_FC_TYPE_ADDR),
187	HBG_DUMP_GMAC_I(HBG_REG_FC_TX_TIMER_ADDR),
188	HBG_DUMP_GMAC_I(HBG_REG_FD_FC_ADDR_LOW_ADDR),
189	HBG_DUMP_GMAC_I(HBG_REG_FD_FC_ADDR_HIGH_ADDR),
190	HBG_DUMP_GMAC_I(HBG_REG_MAX_FRAME_SIZE_ADDR),
191	HBG_DUMP_GMAC_I(HBG_REG_PORT_MODE_ADDR),
192	HBG_DUMP_GMAC_I(HBG_REG_PORT_ENABLE_ADDR),
193	HBG_DUMP_GMAC_I(HBG_REG_PAUSE_ENABLE_ADDR),
194	HBG_DUMP_GMAC_I(HBG_REG_AN_NEG_STATE_ADDR),
195	HBG_DUMP_GMAC_I(HBG_REG_TRANSMIT_CTRL_ADDR),
196	HBG_DUMP_GMAC_I(HBG_REG_REC_FILT_CTRL_ADDR),
197	HBG_DUMP_GMAC_I(HBG_REG_LINE_LOOP_BACK_ADDR),
198	HBG_DUMP_GMAC_I(HBG_REG_CF_CRC_STRIP_ADDR),
199	HBG_DUMP_GMAC_I(HBG_REG_MODE_CHANGE_EN_ADDR),
200	HBG_DUMP_GMAC_I(HBG_REG_LOOP_REG_ADDR),
201	HBG_DUMP_GMAC_I(HBG_REG_RECV_CTRL_ADDR),
202	HBG_DUMP_GMAC_I(HBG_REG_VLAN_CODE_ADDR),
203	HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_LOW_0_ADDR),
204	HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_HIGH_0_ADDR),
205	HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_LOW_1_ADDR),
206	HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_HIGH_1_ADDR),
207	HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_LOW_2_ADDR),
208	HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_HIGH_2_ADDR),
209	HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_LOW_3_ADDR),
210	HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_HIGH_3_ADDR),
211	HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_LOW_4_ADDR),
212	HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_HIGH_4_ADDR),
213	HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_LOW_5_ADDR),
214	HBG_DUMP_GMAC_I(HBG_REG_STATION_ADDR_HIGH_5_ADDR),
215
216	/* pcu */
217	HBG_DUMP_PCU_I(HBG_REG_TX_FIFO_THRSLD_ADDR),
218	HBG_DUMP_PCU_I(HBG_REG_RX_FIFO_THRSLD_ADDR),
219	HBG_DUMP_PCU_I(HBG_REG_CFG_FIFO_THRSLD_ADDR),
220	HBG_DUMP_PCU_I(HBG_REG_CF_INTRPT_MSK_ADDR),
221	HBG_DUMP_PCU_I(HBG_REG_CF_INTRPT_STAT_ADDR),
222	HBG_DUMP_PCU_I(HBG_REG_CF_INTRPT_CLR_ADDR),
223	HBG_DUMP_PCU_I(HBG_REG_TX_BUS_ERR_ADDR_ADDR),
224	HBG_DUMP_PCU_I(HBG_REG_RX_BUS_ERR_ADDR_ADDR),
225	HBG_DUMP_PCU_I(HBG_REG_MAX_FRAME_LEN_ADDR),
226	HBG_DUMP_PCU_I(HBG_REG_DEBUG_ST_MCH_ADDR),
227	HBG_DUMP_PCU_I(HBG_REG_FIFO_CURR_STATUS_ADDR),
228	HBG_DUMP_PCU_I(HBG_REG_FIFO_HIST_STATUS_ADDR),
229	HBG_DUMP_PCU_I(HBG_REG_CF_CFF_DATA_NUM_ADDR),
230	HBG_DUMP_PCU_I(HBG_REG_CF_TX_PAUSE_ADDR),
231	HBG_DUMP_PCU_I(HBG_REG_RX_CFF_ADDR_ADDR),
232	HBG_DUMP_PCU_I(HBG_REG_RX_BUF_SIZE_ADDR),
233	HBG_DUMP_PCU_I(HBG_REG_BUS_CTRL_ADDR),
234	HBG_DUMP_PCU_I(HBG_REG_RX_CTRL_ADDR),
235	HBG_DUMP_PCU_I(HBG_REG_RX_PKT_MODE_ADDR),
236	HBG_DUMP_PCU_I(HBG_REG_DBG_ST0_ADDR),
237	HBG_DUMP_PCU_I(HBG_REG_DBG_ST1_ADDR),
238	HBG_DUMP_PCU_I(HBG_REG_DBG_ST2_ADDR),
239	HBG_DUMP_PCU_I(HBG_REG_BUS_RST_EN_ADDR),
240	HBG_DUMP_PCU_I(HBG_REG_CF_IND_TXINT_MSK_ADDR),
241	HBG_DUMP_PCU_I(HBG_REG_CF_IND_TXINT_STAT_ADDR),
242	HBG_DUMP_PCU_I(HBG_REG_CF_IND_TXINT_CLR_ADDR),
243	HBG_DUMP_PCU_I(HBG_REG_CF_IND_RXINT_MSK_ADDR),
244	HBG_DUMP_PCU_I(HBG_REG_CF_IND_RXINT_STAT_ADDR),
245	HBG_DUMP_PCU_I(HBG_REG_CF_IND_RXINT_CLR_ADDR),
246};
247
248static const u32 hbg_dump_type_base_array[] = {
249	[HBG_DUMP_REG_TYPE_SPEC] = 0,
250	[HBG_DUMP_REG_TYPE_MDIO] = HBG_REG_MDIO_BASE,
251	[HBG_DUMP_REG_TYPE_GMAC] = HBG_REG_SGMII_BASE,
252	[HBG_DUMP_REG_TYPE_PCU] = HBG_REG_SGMII_BASE,
253};
254
255static int hbg_ethtool_get_regs_len(struct net_device *netdev)
256{
257	return ARRAY_SIZE(hbg_dump_reg_infos) * sizeof(struct hbg_reg_info);
258}
259
260static void hbg_ethtool_get_regs(struct net_device *netdev,
261				 struct ethtool_regs *regs, void *data)
262{
263	struct hbg_priv *priv = netdev_priv(netdev);
264	struct hbg_reg_info *info;
265	u32 i, offset = 0;
266
267	regs->version = 0;
268	for (i = 0; i < ARRAY_SIZE(hbg_dump_reg_infos); i++) {
269		info = data + offset;
270
271		*info = hbg_dump_reg_infos[i];
272		info->val = hbg_reg_read(priv, info->offset);
273		info->offset -= hbg_dump_type_base_array[info->type];
274
275		offset += sizeof(*info);
276	}
277}
278
279static void hbg_ethtool_get_pauseparam(struct net_device *net_dev,
280				       struct ethtool_pauseparam *param)
281{
282	struct hbg_priv *priv = netdev_priv(net_dev);
283
284	param->autoneg = priv->mac.pause_autoneg;
285	hbg_hw_get_pause_enable(priv, &param->tx_pause, &param->rx_pause);
286}
287
288static int hbg_ethtool_set_pauseparam(struct net_device *net_dev,
289				      struct ethtool_pauseparam *param)
290{
291	struct hbg_priv *priv = netdev_priv(net_dev);
292
293	priv->mac.pause_autoneg = param->autoneg;
294	phy_set_asym_pause(priv->mac.phydev, param->rx_pause, param->tx_pause);
295
296	if (!param->autoneg)
297		hbg_hw_set_pause_enable(priv, param->tx_pause, param->rx_pause);
298
299	priv->user_def.pause_param = *param;
300	return 0;
301}
302
303static int hbg_ethtool_reset(struct net_device *netdev, u32 *flags)
304{
305	struct hbg_priv *priv = netdev_priv(netdev);
306
307	if (*flags != ETH_RESET_DEDICATED)
308		return -EOPNOTSUPP;
309
310	*flags = 0;
311	return hbg_reset(priv);
312}
313
314static void hbg_update_stats_by_info(struct hbg_priv *priv,
315				     const struct hbg_ethtool_stats *info,
316				     u32 info_len)
317{
318	const struct hbg_ethtool_stats *stats;
319	u32 i;
320
321	if (test_bit(HBG_NIC_STATE_RESETTING, &priv->state))
322		return;
323
324	for (i = 0; i < info_len; i++) {
325		stats = &info[i];
326		if (!stats->reg)
327			continue;
328
329		HBG_STATS_U(&priv->stats, stats->offset,
330			    hbg_reg_read(priv, stats->reg));
331	}
332}
333
334void hbg_update_stats(struct hbg_priv *priv)
335{
336	hbg_update_stats_by_info(priv, hbg_ethtool_stats_info,
337				 ARRAY_SIZE(hbg_ethtool_stats_info));
338	hbg_update_stats_by_info(priv, hbg_ethtool_rmon_stats_info,
339				 ARRAY_SIZE(hbg_ethtool_rmon_stats_info));
340	hbg_update_stats_by_info(priv, hbg_ethtool_mac_stats_info,
341				 ARRAY_SIZE(hbg_ethtool_mac_stats_info));
342	hbg_update_stats_by_info(priv, hbg_ethtool_ctrl_stats_info,
343				 ARRAY_SIZE(hbg_ethtool_ctrl_stats_info));
344}
345
346static int hbg_ethtool_get_sset_count(struct net_device *netdev, int stringset)
347{
348	if (stringset != ETH_SS_STATS)
349		return -EOPNOTSUPP;
350
351	return ARRAY_SIZE(hbg_ethtool_stats_info);
352}
353
354static void hbg_ethtool_get_strings(struct net_device *netdev,
355				    u32 stringset, u8 *data)
356{
357	u32 i;
358
359	if (stringset != ETH_SS_STATS)
360		return;
361
362	for (i = 0; i < ARRAY_SIZE(hbg_ethtool_stats_info); i++)
363		ethtool_puts(&data, hbg_ethtool_stats_info[i].name);
364}
365
366static void hbg_ethtool_get_stats(struct net_device *netdev,
367				  struct ethtool_stats *stats, u64 *data)
368{
369	struct hbg_priv *priv = netdev_priv(netdev);
370	u32 i;
371
372	hbg_update_stats(priv);
373	for (i = 0; i < ARRAY_SIZE(hbg_ethtool_stats_info); i++)
374		*data++ = HBG_STATS_R(&priv->stats,
375				      hbg_ethtool_stats_info[i].offset);
376}
377
378static void hbg_ethtool_get_pause_stats(struct net_device *netdev,
379					struct ethtool_pause_stats *epstats)
380{
381	struct hbg_priv *priv = netdev_priv(netdev);
382	struct hbg_stats *stats = &priv->stats;
383
384	hbg_update_stats(priv);
385	epstats->rx_pause_frames = stats->rx_pause_macctl_frame_cnt;
386	epstats->tx_pause_frames = stats->tx_pause_frame_cnt;
387}
388
389static void hbg_ethtool_get_eth_mac_stats(struct net_device *netdev,
390					  struct ethtool_eth_mac_stats *emstats)
391{
392	struct hbg_priv *priv = netdev_priv(netdev);
393	struct hbg_stats *stats = &priv->stats;
394
395	hbg_update_stats(priv);
396	emstats->FramesTransmittedOK = stats->tx_trans_pkt_cnt;
397	emstats->FramesReceivedOK = stats->rx_trans_pkt_cnt;
398	emstats->FrameCheckSequenceErrors = stats->rx_fcs_error_cnt;
399	emstats->AlignmentErrors = stats->rx_align_error_cnt;
400	emstats->OctetsTransmittedOK = stats->tx_octets_total_ok_cnt;
401	emstats->OctetsReceivedOK = stats->rx_octets_total_ok_cnt;
402
403	emstats->MulticastFramesXmittedOK = stats->tx_mc_pkt_cnt;
404	emstats->BroadcastFramesXmittedOK = stats->tx_bc_pkt_cnt;
405	emstats->MulticastFramesReceivedOK = stats->rx_mc_pkt_cnt;
406	emstats->BroadcastFramesReceivedOK = stats->rx_bc_pkt_cnt;
407	emstats->InRangeLengthErrors = stats->rx_fcs_error_cnt +
408				       stats->rx_jabber_err_cnt +
409				       stats->rx_unknown_macctl_frame_cnt +
410				       stats->rx_bufrq_err_cnt +
411				       stats->rx_we_err_cnt;
412	emstats->OutOfRangeLengthField = stats->rx_frame_short_err_cnt +
413					 stats->rx_frame_runt_err_cnt +
414					 stats->rx_lengthfield_err_cnt +
415					 stats->rx_frame_long_err_cnt +
416					 stats->rx_frame_very_long_err_cnt;
417	emstats->FrameTooLongErrors = stats->rx_frame_long_err_cnt +
418				      stats->rx_frame_very_long_err_cnt;
419}
420
421static void
422hbg_ethtool_get_eth_ctrl_stats(struct net_device *netdev,
423			       struct ethtool_eth_ctrl_stats *ecstats)
424{
425	struct hbg_priv *priv = netdev_priv(netdev);
426	struct hbg_stats *s = &priv->stats;
427
428	hbg_update_stats(priv);
429	ecstats->MACControlFramesTransmitted = s->tx_pause_frame_cnt;
430	ecstats->MACControlFramesReceived = s->rx_pause_macctl_frame_cnt;
431	ecstats->UnsupportedOpcodesReceived = s->rx_unknown_macctl_frame_cnt;
432}
433
434static const struct ethtool_rmon_hist_range hbg_rmon_ranges[] = {
435	{    0,    64 },
436	{   65,   127 },
437	{  128,   255 },
438	{  256,   511 },
439	{  512,  1023 },
440	{ 1024,  1518 },
441	{ 1519,  4095 },
442};
443
444static void
445hbg_ethtool_get_rmon_stats(struct net_device *netdev,
446			   struct ethtool_rmon_stats *rmon_stats,
447			   const struct ethtool_rmon_hist_range **ranges)
448{
449	struct hbg_priv *priv = netdev_priv(netdev);
450	struct hbg_stats *stats = &priv->stats;
451
452	hbg_update_stats(priv);
453	rmon_stats->undersize_pkts = stats->rx_frame_short_err_cnt +
454				     stats->rx_frame_runt_err_cnt +
455				     stats->rx_lengthfield_err_cnt;
456	rmon_stats->oversize_pkts = stats->rx_frame_long_err_cnt +
457				    stats->rx_frame_very_long_err_cnt;
458	rmon_stats->fragments = stats->rx_desc_frag_cnt;
459	rmon_stats->hist[0] = stats->rx_framesize_64;
460	rmon_stats->hist[1] = stats->rx_framesize_65_127;
461	rmon_stats->hist[2] = stats->rx_framesize_128_255;
462	rmon_stats->hist[3] = stats->rx_framesize_256_511;
463	rmon_stats->hist[4] = stats->rx_framesize_512_1023;
464	rmon_stats->hist[5] = stats->rx_framesize_1024_1518;
465	rmon_stats->hist[6] = stats->rx_framesize_bt_1518;
466
467	rmon_stats->hist_tx[0] = stats->tx_framesize_64;
468	rmon_stats->hist_tx[1] = stats->tx_framesize_65_127;
469	rmon_stats->hist_tx[2] = stats->tx_framesize_128_255;
470	rmon_stats->hist_tx[3] = stats->tx_framesize_256_511;
471	rmon_stats->hist_tx[4] = stats->tx_framesize_512_1023;
472	rmon_stats->hist_tx[5] = stats->tx_framesize_1024_1518;
473	rmon_stats->hist_tx[6] = stats->tx_framesize_bt_1518;
474
475	*ranges = hbg_rmon_ranges;
476}
477
478static const struct ethtool_ops hbg_ethtool_ops = {
479	.get_link		= ethtool_op_get_link,
480	.get_link_ksettings	= phy_ethtool_get_link_ksettings,
481	.set_link_ksettings	= phy_ethtool_set_link_ksettings,
482	.get_regs_len		= hbg_ethtool_get_regs_len,
483	.get_regs		= hbg_ethtool_get_regs,
484	.get_pauseparam         = hbg_ethtool_get_pauseparam,
485	.set_pauseparam         = hbg_ethtool_set_pauseparam,
486	.reset			= hbg_ethtool_reset,
487	.nway_reset		= phy_ethtool_nway_reset,
488	.get_sset_count		= hbg_ethtool_get_sset_count,
489	.get_strings		= hbg_ethtool_get_strings,
490	.get_ethtool_stats	= hbg_ethtool_get_stats,
491	.get_pause_stats	= hbg_ethtool_get_pause_stats,
492	.get_eth_mac_stats	= hbg_ethtool_get_eth_mac_stats,
493	.get_eth_ctrl_stats	= hbg_ethtool_get_eth_ctrl_stats,
494	.get_rmon_stats		= hbg_ethtool_get_rmon_stats,
495};
496
497void hbg_ethtool_set_ops(struct net_device *netdev)
498{
499	netdev->ethtool_ops = &hbg_ethtool_ops;
500}
~/ Read-only file preview.