xref: /linux/drivers/net/ethernet/qualcomm/emac/emac-ethtool.c (revision e5a52fd2b8cdb700b3c07b030e050a49ef3156b9)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (c) 2016, The Linux Foundation. All rights reserved.
3  */
4 
5 #include <linux/ethtool.h>
6 #include <linux/phy.h>
7 
8 #include "emac.h"
9 
10 static const char * const emac_ethtool_stat_strings[] = {
11 	"rx_ok",
12 	"rx_bcast",
13 	"rx_mcast",
14 	"rx_pause",
15 	"rx_ctrl",
16 	"rx_fcs_err",
17 	"rx_len_err",
18 	"rx_byte_cnt",
19 	"rx_runt",
20 	"rx_frag",
21 	"rx_sz_64",
22 	"rx_sz_65_127",
23 	"rx_sz_128_255",
24 	"rx_sz_256_511",
25 	"rx_sz_512_1023",
26 	"rx_sz_1024_1518",
27 	"rx_sz_1519_max",
28 	"rx_sz_ov",
29 	"rx_rxf_ov",
30 	"rx_align_err",
31 	"rx_bcast_byte_cnt",
32 	"rx_mcast_byte_cnt",
33 	"rx_err_addr",
34 	"rx_crc_align",
35 	"rx_jabbers",
36 	"tx_ok",
37 	"tx_bcast",
38 	"tx_mcast",
39 	"tx_pause",
40 	"tx_exc_defer",
41 	"tx_ctrl",
42 	"tx_defer",
43 	"tx_byte_cnt",
44 	"tx_sz_64",
45 	"tx_sz_65_127",
46 	"tx_sz_128_255",
47 	"tx_sz_256_511",
48 	"tx_sz_512_1023",
49 	"tx_sz_1024_1518",
50 	"tx_sz_1519_max",
51 	"tx_1_col",
52 	"tx_2_col",
53 	"tx_late_col",
54 	"tx_abort_col",
55 	"tx_underrun",
56 	"tx_rd_eop",
57 	"tx_len_err",
58 	"tx_trunc",
59 	"tx_bcast_byte",
60 	"tx_mcast_byte",
61 	"tx_col",
62 };
63 
64 #define EMAC_STATS_LEN	ARRAY_SIZE(emac_ethtool_stat_strings)
65 
66 static u32 emac_get_msglevel(struct net_device *netdev)
67 {
68 	struct emac_adapter *adpt = netdev_priv(netdev);
69 
70 	return adpt->msg_enable;
71 }
72 
73 static void emac_set_msglevel(struct net_device *netdev, u32 data)
74 {
75 	struct emac_adapter *adpt = netdev_priv(netdev);
76 
77 	adpt->msg_enable = data;
78 }
79 
80 static int emac_get_sset_count(struct net_device *netdev, int sset)
81 {
82 	switch (sset) {
83 	case ETH_SS_PRIV_FLAGS:
84 		return 1;
85 	case ETH_SS_STATS:
86 		return EMAC_STATS_LEN;
87 	default:
88 		return -EOPNOTSUPP;
89 	}
90 }
91 
92 static void emac_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
93 {
94 	unsigned int i;
95 
96 	switch (stringset) {
97 	case ETH_SS_PRIV_FLAGS:
98 		strcpy(data, "single-pause-mode");
99 		break;
100 
101 	case ETH_SS_STATS:
102 		for (i = 0; i < EMAC_STATS_LEN; i++) {
103 			strlcpy(data, emac_ethtool_stat_strings[i],
104 				ETH_GSTRING_LEN);
105 			data += ETH_GSTRING_LEN;
106 		}
107 		break;
108 	}
109 }
110 
111 static void emac_get_ethtool_stats(struct net_device *netdev,
112 				   struct ethtool_stats *stats,
113 				   u64 *data)
114 {
115 	struct emac_adapter *adpt = netdev_priv(netdev);
116 
117 	spin_lock(&adpt->stats.lock);
118 
119 	emac_update_hw_stats(adpt);
120 	memcpy(data, &adpt->stats, EMAC_STATS_LEN * sizeof(u64));
121 
122 	spin_unlock(&adpt->stats.lock);
123 }
124 
125 static int emac_nway_reset(struct net_device *netdev)
126 {
127 	struct phy_device *phydev = netdev->phydev;
128 
129 	if (!phydev)
130 		return -ENODEV;
131 
132 	return genphy_restart_aneg(phydev);
133 }
134 
135 static void emac_get_ringparam(struct net_device *netdev,
136 			       struct ethtool_ringparam *ring)
137 {
138 	struct emac_adapter *adpt = netdev_priv(netdev);
139 
140 	ring->rx_max_pending = EMAC_MAX_RX_DESCS;
141 	ring->tx_max_pending = EMAC_MAX_TX_DESCS;
142 	ring->rx_pending = adpt->rx_desc_cnt;
143 	ring->tx_pending = adpt->tx_desc_cnt;
144 }
145 
146 static int emac_set_ringparam(struct net_device *netdev,
147 			      struct ethtool_ringparam *ring)
148 {
149 	struct emac_adapter *adpt = netdev_priv(netdev);
150 
151 	/* We don't have separate queues/rings for small/large frames, so
152 	 * reject any attempt to specify those values separately.
153 	 */
154 	if (ring->rx_mini_pending || ring->rx_jumbo_pending)
155 		return -EINVAL;
156 
157 	adpt->tx_desc_cnt =
158 		clamp_val(ring->tx_pending, EMAC_MIN_TX_DESCS, EMAC_MAX_TX_DESCS);
159 
160 	adpt->rx_desc_cnt =
161 		clamp_val(ring->rx_pending, EMAC_MIN_RX_DESCS, EMAC_MAX_RX_DESCS);
162 
163 	if (netif_running(netdev))
164 		return emac_reinit_locked(adpt);
165 
166 	return 0;
167 }
168 
169 static void emac_get_pauseparam(struct net_device *netdev,
170 				struct ethtool_pauseparam *pause)
171 {
172 	struct emac_adapter *adpt = netdev_priv(netdev);
173 
174 	pause->autoneg = adpt->automatic ? AUTONEG_ENABLE : AUTONEG_DISABLE;
175 	pause->rx_pause = adpt->rx_flow_control ? 1 : 0;
176 	pause->tx_pause = adpt->tx_flow_control ? 1 : 0;
177 }
178 
179 static int emac_set_pauseparam(struct net_device *netdev,
180 			       struct ethtool_pauseparam *pause)
181 {
182 	struct emac_adapter *adpt = netdev_priv(netdev);
183 
184 	adpt->automatic = pause->autoneg == AUTONEG_ENABLE;
185 	adpt->rx_flow_control = pause->rx_pause != 0;
186 	adpt->tx_flow_control = pause->tx_pause != 0;
187 
188 	if (netif_running(netdev))
189 		return emac_reinit_locked(adpt);
190 
191 	return 0;
192 }
193 
194 /* Selected registers that might want to track during runtime. */
195 static const u16 emac_regs[] = {
196 	EMAC_DMA_MAS_CTRL,
197 	EMAC_MAC_CTRL,
198 	EMAC_TXQ_CTRL_0,
199 	EMAC_RXQ_CTRL_0,
200 	EMAC_DMA_CTRL,
201 	EMAC_INT_MASK,
202 	EMAC_AXI_MAST_CTRL,
203 	EMAC_CORE_HW_VERSION,
204 	EMAC_MISC_CTRL,
205 };
206 
207 /* Every time emac_regs[] above is changed, increase this version number. */
208 #define EMAC_REGS_VERSION	0
209 
210 #define EMAC_MAX_REG_SIZE	ARRAY_SIZE(emac_regs)
211 
212 static void emac_get_regs(struct net_device *netdev,
213 			  struct ethtool_regs *regs, void *buff)
214 {
215 	struct emac_adapter *adpt = netdev_priv(netdev);
216 	u32 *val = buff;
217 	unsigned int i;
218 
219 	regs->version = EMAC_REGS_VERSION;
220 	regs->len = EMAC_MAX_REG_SIZE * sizeof(u32);
221 
222 	for (i = 0; i < EMAC_MAX_REG_SIZE; i++)
223 		val[i] = readl(adpt->base + emac_regs[i]);
224 }
225 
226 static int emac_get_regs_len(struct net_device *netdev)
227 {
228 	return EMAC_MAX_REG_SIZE * sizeof(u32);
229 }
230 
231 #define EMAC_PRIV_ENABLE_SINGLE_PAUSE	BIT(0)
232 
233 static int emac_set_priv_flags(struct net_device *netdev, u32 flags)
234 {
235 	struct emac_adapter *adpt = netdev_priv(netdev);
236 
237 	adpt->single_pause_mode = !!(flags & EMAC_PRIV_ENABLE_SINGLE_PAUSE);
238 
239 	if (netif_running(netdev))
240 		return emac_reinit_locked(adpt);
241 
242 	return 0;
243 }
244 
245 static u32 emac_get_priv_flags(struct net_device *netdev)
246 {
247 	struct emac_adapter *adpt = netdev_priv(netdev);
248 
249 	return adpt->single_pause_mode ? EMAC_PRIV_ENABLE_SINGLE_PAUSE : 0;
250 }
251 
252 static const struct ethtool_ops emac_ethtool_ops = {
253 	.get_link_ksettings = phy_ethtool_get_link_ksettings,
254 	.set_link_ksettings = phy_ethtool_set_link_ksettings,
255 
256 	.get_msglevel    = emac_get_msglevel,
257 	.set_msglevel    = emac_set_msglevel,
258 
259 	.get_sset_count  = emac_get_sset_count,
260 	.get_strings = emac_get_strings,
261 	.get_ethtool_stats = emac_get_ethtool_stats,
262 
263 	.get_ringparam = emac_get_ringparam,
264 	.set_ringparam = emac_set_ringparam,
265 
266 	.get_pauseparam = emac_get_pauseparam,
267 	.set_pauseparam = emac_set_pauseparam,
268 
269 	.nway_reset = emac_nway_reset,
270 
271 	.get_link = ethtool_op_get_link,
272 
273 	.get_regs_len    = emac_get_regs_len,
274 	.get_regs        = emac_get_regs,
275 
276 	.set_priv_flags = emac_set_priv_flags,
277 	.get_priv_flags = emac_get_priv_flags,
278 };
279 
280 void emac_set_ethtool_ops(struct net_device *netdev)
281 {
282 	netdev->ethtool_ops = &emac_ethtool_ops;
283 }
284