xref: /OK3568_Linux_fs/kernel/drivers/net/ethernet/apm/xgene-v2/ethtool.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Applied Micro X-Gene SoC Ethernet v2 Driver
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (c) 2017, Applied Micro Circuits Corporation
6*4882a593Smuzhiyun  * Author(s): Iyappan Subramanian <isubramanian@apm.com>
7*4882a593Smuzhiyun  *	      Keyur Chudgar <kchudgar@apm.com>
8*4882a593Smuzhiyun  */
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include "main.h"
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #define XGE_STAT(m)		{ #m, offsetof(struct xge_pdata, stats.m) }
13*4882a593Smuzhiyun #define XGE_EXTD_STAT(m, n)					\
14*4882a593Smuzhiyun 	{							\
15*4882a593Smuzhiyun 		#m,						\
16*4882a593Smuzhiyun 		n,						\
17*4882a593Smuzhiyun 		0						\
18*4882a593Smuzhiyun 	}
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun static const struct xge_gstrings_stats gstrings_stats[] = {
21*4882a593Smuzhiyun 	XGE_STAT(rx_packets),
22*4882a593Smuzhiyun 	XGE_STAT(tx_packets),
23*4882a593Smuzhiyun 	XGE_STAT(rx_bytes),
24*4882a593Smuzhiyun 	XGE_STAT(tx_bytes),
25*4882a593Smuzhiyun 	XGE_STAT(rx_errors)
26*4882a593Smuzhiyun };
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun static struct xge_gstrings_extd_stats gstrings_extd_stats[] = {
29*4882a593Smuzhiyun 	XGE_EXTD_STAT(tx_rx_64b_frame_cntr, TR64),
30*4882a593Smuzhiyun 	XGE_EXTD_STAT(tx_rx_127b_frame_cntr, TR127),
31*4882a593Smuzhiyun 	XGE_EXTD_STAT(tx_rx_255b_frame_cntr, TR255),
32*4882a593Smuzhiyun 	XGE_EXTD_STAT(tx_rx_511b_frame_cntr, TR511),
33*4882a593Smuzhiyun 	XGE_EXTD_STAT(tx_rx_1023b_frame_cntr, TR1K),
34*4882a593Smuzhiyun 	XGE_EXTD_STAT(tx_rx_1518b_frame_cntr, TRMAX),
35*4882a593Smuzhiyun 	XGE_EXTD_STAT(tx_rx_1522b_frame_cntr, TRMGV),
36*4882a593Smuzhiyun 	XGE_EXTD_STAT(rx_fcs_error_cntr, RFCS),
37*4882a593Smuzhiyun 	XGE_EXTD_STAT(rx_multicast_pkt_cntr, RMCA),
38*4882a593Smuzhiyun 	XGE_EXTD_STAT(rx_broadcast_pkt_cntr, RBCA),
39*4882a593Smuzhiyun 	XGE_EXTD_STAT(rx_ctrl_frame_pkt_cntr, RXCF),
40*4882a593Smuzhiyun 	XGE_EXTD_STAT(rx_pause_frame_pkt_cntr, RXPF),
41*4882a593Smuzhiyun 	XGE_EXTD_STAT(rx_unk_opcode_cntr, RXUO),
42*4882a593Smuzhiyun 	XGE_EXTD_STAT(rx_align_err_cntr, RALN),
43*4882a593Smuzhiyun 	XGE_EXTD_STAT(rx_frame_len_err_cntr, RFLR),
44*4882a593Smuzhiyun 	XGE_EXTD_STAT(rx_code_err_cntr, RCDE),
45*4882a593Smuzhiyun 	XGE_EXTD_STAT(rx_carrier_sense_err_cntr, RCSE),
46*4882a593Smuzhiyun 	XGE_EXTD_STAT(rx_undersize_pkt_cntr, RUND),
47*4882a593Smuzhiyun 	XGE_EXTD_STAT(rx_oversize_pkt_cntr, ROVR),
48*4882a593Smuzhiyun 	XGE_EXTD_STAT(rx_fragments_cntr, RFRG),
49*4882a593Smuzhiyun 	XGE_EXTD_STAT(rx_jabber_cntr, RJBR),
50*4882a593Smuzhiyun 	XGE_EXTD_STAT(rx_dropped_pkt_cntr, RDRP),
51*4882a593Smuzhiyun 	XGE_EXTD_STAT(tx_multicast_pkt_cntr, TMCA),
52*4882a593Smuzhiyun 	XGE_EXTD_STAT(tx_broadcast_pkt_cntr, TBCA),
53*4882a593Smuzhiyun 	XGE_EXTD_STAT(tx_pause_ctrl_frame_cntr, TXPF),
54*4882a593Smuzhiyun 	XGE_EXTD_STAT(tx_defer_pkt_cntr, TDFR),
55*4882a593Smuzhiyun 	XGE_EXTD_STAT(tx_excv_defer_pkt_cntr, TEDF),
56*4882a593Smuzhiyun 	XGE_EXTD_STAT(tx_single_col_pkt_cntr, TSCL),
57*4882a593Smuzhiyun 	XGE_EXTD_STAT(tx_multi_col_pkt_cntr, TMCL),
58*4882a593Smuzhiyun 	XGE_EXTD_STAT(tx_late_col_pkt_cntr, TLCL),
59*4882a593Smuzhiyun 	XGE_EXTD_STAT(tx_excv_col_pkt_cntr, TXCL),
60*4882a593Smuzhiyun 	XGE_EXTD_STAT(tx_total_col_cntr, TNCL),
61*4882a593Smuzhiyun 	XGE_EXTD_STAT(tx_pause_frames_hnrd_cntr, TPFH),
62*4882a593Smuzhiyun 	XGE_EXTD_STAT(tx_drop_frame_cntr, TDRP),
63*4882a593Smuzhiyun 	XGE_EXTD_STAT(tx_jabber_frame_cntr, TJBR),
64*4882a593Smuzhiyun 	XGE_EXTD_STAT(tx_fcs_error_cntr, TFCS),
65*4882a593Smuzhiyun 	XGE_EXTD_STAT(tx_ctrl_frame_cntr, TXCF),
66*4882a593Smuzhiyun 	XGE_EXTD_STAT(tx_oversize_frame_cntr, TOVR),
67*4882a593Smuzhiyun 	XGE_EXTD_STAT(tx_undersize_frame_cntr, TUND),
68*4882a593Smuzhiyun 	XGE_EXTD_STAT(tx_fragments_cntr, TFRG)
69*4882a593Smuzhiyun };
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun #define XGE_STATS_LEN		ARRAY_SIZE(gstrings_stats)
72*4882a593Smuzhiyun #define XGE_EXTD_STATS_LEN	ARRAY_SIZE(gstrings_extd_stats)
73*4882a593Smuzhiyun 
xge_mac_get_extd_stats(struct xge_pdata * pdata)74*4882a593Smuzhiyun static void xge_mac_get_extd_stats(struct xge_pdata *pdata)
75*4882a593Smuzhiyun {
76*4882a593Smuzhiyun 	u32 data;
77*4882a593Smuzhiyun 	int i;
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun 	for (i = 0; i < XGE_EXTD_STATS_LEN; i++) {
80*4882a593Smuzhiyun 		data = xge_rd_csr(pdata, gstrings_extd_stats[i].addr);
81*4882a593Smuzhiyun 		gstrings_extd_stats[i].value += data;
82*4882a593Smuzhiyun 	}
83*4882a593Smuzhiyun }
84*4882a593Smuzhiyun 
xge_get_drvinfo(struct net_device * ndev,struct ethtool_drvinfo * info)85*4882a593Smuzhiyun static void xge_get_drvinfo(struct net_device *ndev,
86*4882a593Smuzhiyun 			    struct ethtool_drvinfo *info)
87*4882a593Smuzhiyun {
88*4882a593Smuzhiyun 	struct xge_pdata *pdata = netdev_priv(ndev);
89*4882a593Smuzhiyun 	struct platform_device *pdev = pdata->pdev;
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun 	strcpy(info->driver, "xgene-enet-v2");
92*4882a593Smuzhiyun 	sprintf(info->bus_info, "%s", pdev->name);
93*4882a593Smuzhiyun }
94*4882a593Smuzhiyun 
xge_get_strings(struct net_device * ndev,u32 stringset,u8 * data)95*4882a593Smuzhiyun static void xge_get_strings(struct net_device *ndev, u32 stringset, u8 *data)
96*4882a593Smuzhiyun {
97*4882a593Smuzhiyun 	u8 *p = data;
98*4882a593Smuzhiyun 	int i;
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun 	if (stringset != ETH_SS_STATS)
101*4882a593Smuzhiyun 		return;
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun 	for (i = 0; i < XGE_STATS_LEN; i++) {
104*4882a593Smuzhiyun 		memcpy(p, gstrings_stats[i].name, ETH_GSTRING_LEN);
105*4882a593Smuzhiyun 		p += ETH_GSTRING_LEN;
106*4882a593Smuzhiyun 	}
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun 	for (i = 0; i < XGE_EXTD_STATS_LEN; i++) {
109*4882a593Smuzhiyun 		memcpy(p, gstrings_extd_stats[i].name, ETH_GSTRING_LEN);
110*4882a593Smuzhiyun 		p += ETH_GSTRING_LEN;
111*4882a593Smuzhiyun 	}
112*4882a593Smuzhiyun }
113*4882a593Smuzhiyun 
xge_get_sset_count(struct net_device * ndev,int sset)114*4882a593Smuzhiyun static int xge_get_sset_count(struct net_device *ndev, int sset)
115*4882a593Smuzhiyun {
116*4882a593Smuzhiyun 	if (sset != ETH_SS_STATS)
117*4882a593Smuzhiyun 		return -EINVAL;
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun 	return XGE_STATS_LEN + XGE_EXTD_STATS_LEN;
120*4882a593Smuzhiyun }
121*4882a593Smuzhiyun 
xge_get_ethtool_stats(struct net_device * ndev,struct ethtool_stats * dummy,u64 * data)122*4882a593Smuzhiyun static void xge_get_ethtool_stats(struct net_device *ndev,
123*4882a593Smuzhiyun 				  struct ethtool_stats *dummy,
124*4882a593Smuzhiyun 				  u64 *data)
125*4882a593Smuzhiyun {
126*4882a593Smuzhiyun 	void *pdata = netdev_priv(ndev);
127*4882a593Smuzhiyun 	int i;
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun 	for (i = 0; i < XGE_STATS_LEN; i++)
130*4882a593Smuzhiyun 		*data++ = *(u64 *)(pdata + gstrings_stats[i].offset);
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun 	xge_mac_get_extd_stats(pdata);
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun 	for (i = 0; i < XGE_EXTD_STATS_LEN; i++)
135*4882a593Smuzhiyun 		*data++ = gstrings_extd_stats[i].value;
136*4882a593Smuzhiyun }
137*4882a593Smuzhiyun 
xge_get_link_ksettings(struct net_device * ndev,struct ethtool_link_ksettings * cmd)138*4882a593Smuzhiyun static int xge_get_link_ksettings(struct net_device *ndev,
139*4882a593Smuzhiyun 				  struct ethtool_link_ksettings *cmd)
140*4882a593Smuzhiyun {
141*4882a593Smuzhiyun 	struct phy_device *phydev = ndev->phydev;
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun 	if (!phydev)
144*4882a593Smuzhiyun 		return -ENODEV;
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun 	phy_ethtool_ksettings_get(phydev, cmd);
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun 	return 0;
149*4882a593Smuzhiyun }
150*4882a593Smuzhiyun 
xge_set_link_ksettings(struct net_device * ndev,const struct ethtool_link_ksettings * cmd)151*4882a593Smuzhiyun static int xge_set_link_ksettings(struct net_device *ndev,
152*4882a593Smuzhiyun 				  const struct ethtool_link_ksettings *cmd)
153*4882a593Smuzhiyun {
154*4882a593Smuzhiyun 	struct phy_device *phydev = ndev->phydev;
155*4882a593Smuzhiyun 
156*4882a593Smuzhiyun 	if (!phydev)
157*4882a593Smuzhiyun 		return -ENODEV;
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun 	return phy_ethtool_ksettings_set(phydev, cmd);
160*4882a593Smuzhiyun }
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun static const struct ethtool_ops xge_ethtool_ops = {
163*4882a593Smuzhiyun 	.get_drvinfo = xge_get_drvinfo,
164*4882a593Smuzhiyun 	.get_link = ethtool_op_get_link,
165*4882a593Smuzhiyun 	.get_strings = xge_get_strings,
166*4882a593Smuzhiyun 	.get_sset_count = xge_get_sset_count,
167*4882a593Smuzhiyun 	.get_ethtool_stats = xge_get_ethtool_stats,
168*4882a593Smuzhiyun 	.get_link_ksettings = xge_get_link_ksettings,
169*4882a593Smuzhiyun 	.set_link_ksettings = xge_set_link_ksettings,
170*4882a593Smuzhiyun };
171*4882a593Smuzhiyun 
xge_set_ethtool_ops(struct net_device * ndev)172*4882a593Smuzhiyun void xge_set_ethtool_ops(struct net_device *ndev)
173*4882a593Smuzhiyun {
174*4882a593Smuzhiyun 	ndev->ethtool_ops = &xge_ethtool_ops;
175*4882a593Smuzhiyun }
176