1// SPDX-License-Identifier: GPL-2.0
2/* Texas Instruments K3 AM65 Ethernet Switch SubSystem Driver ethtool ops
3 *
4 * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/
5 *
6 */
7
8#include <linux/net_tstamp.h>
9#include <linux/phylink.h>
10#include <linux/platform_device.h>
11#include <linux/pm_runtime.h>
12
13#include "am65-cpsw-nuss.h"
14#include "am65-cpsw-qos.h"
15#include "cpsw_ale.h"
16#include "am65-cpts.h"
17
18#define AM65_CPSW_REGDUMP_VER 0x1
19
20enum {
21	AM65_CPSW_REGDUMP_MOD_NUSS = 1,
22	AM65_CPSW_REGDUMP_MOD_RGMII_STATUS = 2,
23	AM65_CPSW_REGDUMP_MOD_MDIO = 3,
24	AM65_CPSW_REGDUMP_MOD_CPSW = 4,
25	AM65_CPSW_REGDUMP_MOD_CPSW_P0 = 5,
26	AM65_CPSW_REGDUMP_MOD_CPSW_P1 = 6,
27	AM65_CPSW_REGDUMP_MOD_CPSW_CPTS = 7,
28	AM65_CPSW_REGDUMP_MOD_CPSW_ALE = 8,
29	AM65_CPSW_REGDUMP_MOD_CPSW_ALE_TBL = 9,
30	AM65_CPSW_REGDUMP_MOD_LAST,
31};
32
33/**
34 * struct am65_cpsw_regdump_hdr - regdump record header
35 *
36 * @module_id: CPSW module ID
37 * @len: CPSW module registers space length in u32
38 */
39
40struct am65_cpsw_regdump_hdr {
41	u32 module_id;
42	u32 len;
43};
44
45/**
46 * struct am65_cpsw_regdump_item - regdump module description
47 *
48 * @hdr: CPSW module header
49 * @start_ofs: CPSW module registers start addr
50 * @end_ofs: CPSW module registers end addr
51 *
52 * Registers dump provided in the format:
53 *  u32 : module ID
54 *  u32 : dump length
55 *  u32[..len]: registers values
56 */
57struct am65_cpsw_regdump_item {
58	struct am65_cpsw_regdump_hdr hdr;
59	u32 start_ofs;
60	u32 end_ofs;
61};
62
63#define AM65_CPSW_REGDUMP_REC(mod, start, end) { \
64	.hdr.module_id = (mod), \
65	.hdr.len = (end + 4 - start) * 2 + \
66		   sizeof(struct am65_cpsw_regdump_hdr), \
67	.start_ofs = (start), \
68	.end_ofs = end, \
69}
70
71static const struct am65_cpsw_regdump_item am65_cpsw_regdump[] = {
72	AM65_CPSW_REGDUMP_REC(AM65_CPSW_REGDUMP_MOD_NUSS, 0x0, 0x1c),
73	AM65_CPSW_REGDUMP_REC(AM65_CPSW_REGDUMP_MOD_RGMII_STATUS, 0x30, 0x4c),
74	AM65_CPSW_REGDUMP_REC(AM65_CPSW_REGDUMP_MOD_MDIO, 0xf00, 0xffc),
75	AM65_CPSW_REGDUMP_REC(AM65_CPSW_REGDUMP_MOD_CPSW, 0x20000, 0x2011c),
76	AM65_CPSW_REGDUMP_REC(AM65_CPSW_REGDUMP_MOD_CPSW_P0, 0x21000, 0x21320),
77	AM65_CPSW_REGDUMP_REC(AM65_CPSW_REGDUMP_MOD_CPSW_P1, 0x22000, 0x223a4),
78	AM65_CPSW_REGDUMP_REC(AM65_CPSW_REGDUMP_MOD_CPSW_CPTS,
79			      0x3d000, 0x3d048),
80	AM65_CPSW_REGDUMP_REC(AM65_CPSW_REGDUMP_MOD_CPSW_ALE, 0x3e000, 0x3e13c),
81	AM65_CPSW_REGDUMP_REC(AM65_CPSW_REGDUMP_MOD_CPSW_ALE_TBL, 0, 0),
82};
83
84struct am65_cpsw_stats_regs {
85	u32	rx_good_frames;
86	u32	rx_broadcast_frames;
87	u32	rx_multicast_frames;
88	u32	rx_pause_frames;		/* slave */
89	u32	rx_crc_errors;
90	u32	rx_align_code_errors;		/* slave */
91	u32	rx_oversized_frames;
92	u32	rx_jabber_frames;		/* slave */
93	u32	rx_undersized_frames;
94	u32	rx_fragments;			/* slave */
95	u32	ale_drop;
96	u32	ale_overrun_drop;
97	u32	rx_octets;
98	u32	tx_good_frames;
99	u32	tx_broadcast_frames;
100	u32	tx_multicast_frames;
101	u32	tx_pause_frames;		/* slave */
102	u32	tx_deferred_frames;		/* slave */
103	u32	tx_collision_frames;		/* slave */
104	u32	tx_single_coll_frames;		/* slave */
105	u32	tx_mult_coll_frames;		/* slave */
106	u32	tx_excessive_collisions;	/* slave */
107	u32	tx_late_collisions;		/* slave */
108	u32	rx_ipg_error;			/* slave 10G only */
109	u32	tx_carrier_sense_errors;	/* slave */
110	u32	tx_octets;
111	u32	tx_64B_frames;
112	u32	tx_65_to_127B_frames;
113	u32	tx_128_to_255B_frames;
114	u32	tx_256_to_511B_frames;
115	u32	tx_512_to_1023B_frames;
116	u32	tx_1024B_frames;
117	u32	net_octets;
118	u32	rx_bottom_fifo_drop;
119	u32	rx_port_mask_drop;
120	u32	rx_top_fifo_drop;
121	u32	ale_rate_limit_drop;
122	u32	ale_vid_ingress_drop;
123	u32	ale_da_eq_sa_drop;
124	u32	ale_block_drop;			/* K3 */
125	u32	ale_secure_drop;		/* K3 */
126	u32	ale_auth_drop;			/* K3 */
127	u32	ale_unknown_ucast;
128	u32	ale_unknown_ucast_bytes;
129	u32	ale_unknown_mcast;
130	u32	ale_unknown_mcast_bytes;
131	u32	ale_unknown_bcast;
132	u32	ale_unknown_bcast_bytes;
133	u32	ale_pol_match;
134	u32	ale_pol_match_red;
135	u32	ale_pol_match_yellow;
136	u32	ale_mcast_sa_drop;		/* K3 */
137	u32	ale_dual_vlan_drop;		/* K3 */
138	u32	ale_len_err_drop;		/* K3 */
139	u32	ale_ip_next_hdr_drop;		/* K3 */
140	u32	ale_ipv4_frag_drop;		/* K3 */
141	u32	__rsvd_1[24];
142	u32	iet_rx_assembly_err;		/* K3 slave */
143	u32	iet_rx_assembly_ok;		/* K3 slave */
144	u32	iet_rx_smd_err;			/* K3 slave */
145	u32	iet_rx_frag;			/* K3 slave */
146	u32	iet_tx_hold;			/* K3 slave */
147	u32	iet_tx_frag;			/* K3 slave */
148	u32	__rsvd_2[9];
149	u32	tx_mem_protect_err;
150	/* following NU only */
151	u32	tx_pri0;
152	u32	tx_pri1;
153	u32	tx_pri2;
154	u32	tx_pri3;
155	u32	tx_pri4;
156	u32	tx_pri5;
157	u32	tx_pri6;
158	u32	tx_pri7;
159	u32	tx_pri0_bcnt;
160	u32	tx_pri1_bcnt;
161	u32	tx_pri2_bcnt;
162	u32	tx_pri3_bcnt;
163	u32	tx_pri4_bcnt;
164	u32	tx_pri5_bcnt;
165	u32	tx_pri6_bcnt;
166	u32	tx_pri7_bcnt;
167	u32	tx_pri0_drop;
168	u32	tx_pri1_drop;
169	u32	tx_pri2_drop;
170	u32	tx_pri3_drop;
171	u32	tx_pri4_drop;
172	u32	tx_pri5_drop;
173	u32	tx_pri6_drop;
174	u32	tx_pri7_drop;
175	u32	tx_pri0_drop_bcnt;
176	u32	tx_pri1_drop_bcnt;
177	u32	tx_pri2_drop_bcnt;
178	u32	tx_pri3_drop_bcnt;
179	u32	tx_pri4_drop_bcnt;
180	u32	tx_pri5_drop_bcnt;
181	u32	tx_pri6_drop_bcnt;
182	u32	tx_pri7_drop_bcnt;
183};
184
185struct am65_cpsw_ethtool_stat {
186	char desc[ETH_GSTRING_LEN];
187	int offset;
188};
189
190#define AM65_CPSW_STATS(prefix, field)			\
191{							\
192	#prefix#field,					\
193	offsetof(struct am65_cpsw_stats_regs, field)	\
194}
195
196static const struct am65_cpsw_ethtool_stat am65_host_stats[] = {
197	AM65_CPSW_STATS(p0_, rx_good_frames),
198	AM65_CPSW_STATS(p0_, rx_broadcast_frames),
199	AM65_CPSW_STATS(p0_, rx_multicast_frames),
200	AM65_CPSW_STATS(p0_, rx_crc_errors),
201	AM65_CPSW_STATS(p0_, rx_oversized_frames),
202	AM65_CPSW_STATS(p0_, rx_undersized_frames),
203	AM65_CPSW_STATS(p0_, ale_drop),
204	AM65_CPSW_STATS(p0_, ale_overrun_drop),
205	AM65_CPSW_STATS(p0_, rx_octets),
206	AM65_CPSW_STATS(p0_, tx_good_frames),
207	AM65_CPSW_STATS(p0_, tx_broadcast_frames),
208	AM65_CPSW_STATS(p0_, tx_multicast_frames),
209	AM65_CPSW_STATS(p0_, tx_octets),
210	AM65_CPSW_STATS(p0_, tx_64B_frames),
211	AM65_CPSW_STATS(p0_, tx_65_to_127B_frames),
212	AM65_CPSW_STATS(p0_, tx_128_to_255B_frames),
213	AM65_CPSW_STATS(p0_, tx_256_to_511B_frames),
214	AM65_CPSW_STATS(p0_, tx_512_to_1023B_frames),
215	AM65_CPSW_STATS(p0_, tx_1024B_frames),
216	AM65_CPSW_STATS(p0_, net_octets),
217	AM65_CPSW_STATS(p0_, rx_bottom_fifo_drop),
218	AM65_CPSW_STATS(p0_, rx_port_mask_drop),
219	AM65_CPSW_STATS(p0_, rx_top_fifo_drop),
220	AM65_CPSW_STATS(p0_, ale_rate_limit_drop),
221	AM65_CPSW_STATS(p0_, ale_vid_ingress_drop),
222	AM65_CPSW_STATS(p0_, ale_da_eq_sa_drop),
223	AM65_CPSW_STATS(p0_, ale_block_drop),
224	AM65_CPSW_STATS(p0_, ale_secure_drop),
225	AM65_CPSW_STATS(p0_, ale_auth_drop),
226	AM65_CPSW_STATS(p0_, ale_unknown_ucast),
227	AM65_CPSW_STATS(p0_, ale_unknown_ucast_bytes),
228	AM65_CPSW_STATS(p0_, ale_unknown_mcast),
229	AM65_CPSW_STATS(p0_, ale_unknown_mcast_bytes),
230	AM65_CPSW_STATS(p0_, ale_unknown_bcast),
231	AM65_CPSW_STATS(p0_, ale_unknown_bcast_bytes),
232	AM65_CPSW_STATS(p0_, ale_pol_match),
233	AM65_CPSW_STATS(p0_, ale_pol_match_red),
234	AM65_CPSW_STATS(p0_, ale_pol_match_yellow),
235	AM65_CPSW_STATS(p0_, ale_mcast_sa_drop),
236	AM65_CPSW_STATS(p0_, ale_dual_vlan_drop),
237	AM65_CPSW_STATS(p0_, ale_len_err_drop),
238	AM65_CPSW_STATS(p0_, ale_ip_next_hdr_drop),
239	AM65_CPSW_STATS(p0_, ale_ipv4_frag_drop),
240	AM65_CPSW_STATS(p0_, tx_mem_protect_err),
241	AM65_CPSW_STATS(p0_, tx_pri0),
242	AM65_CPSW_STATS(p0_, tx_pri1),
243	AM65_CPSW_STATS(p0_, tx_pri2),
244	AM65_CPSW_STATS(p0_, tx_pri3),
245	AM65_CPSW_STATS(p0_, tx_pri4),
246	AM65_CPSW_STATS(p0_, tx_pri5),
247	AM65_CPSW_STATS(p0_, tx_pri6),
248	AM65_CPSW_STATS(p0_, tx_pri7),
249	AM65_CPSW_STATS(p0_, tx_pri0_bcnt),
250	AM65_CPSW_STATS(p0_, tx_pri1_bcnt),
251	AM65_CPSW_STATS(p0_, tx_pri2_bcnt),
252	AM65_CPSW_STATS(p0_, tx_pri3_bcnt),
253	AM65_CPSW_STATS(p0_, tx_pri4_bcnt),
254	AM65_CPSW_STATS(p0_, tx_pri5_bcnt),
255	AM65_CPSW_STATS(p0_, tx_pri6_bcnt),
256	AM65_CPSW_STATS(p0_, tx_pri7_bcnt),
257	AM65_CPSW_STATS(p0_, tx_pri0_drop),
258	AM65_CPSW_STATS(p0_, tx_pri1_drop),
259	AM65_CPSW_STATS(p0_, tx_pri2_drop),
260	AM65_CPSW_STATS(p0_, tx_pri3_drop),
261	AM65_CPSW_STATS(p0_, tx_pri4_drop),
262	AM65_CPSW_STATS(p0_, tx_pri5_drop),
263	AM65_CPSW_STATS(p0_, tx_pri6_drop),
264	AM65_CPSW_STATS(p0_, tx_pri7_drop),
265	AM65_CPSW_STATS(p0_, tx_pri0_drop_bcnt),
266	AM65_CPSW_STATS(p0_, tx_pri1_drop_bcnt),
267	AM65_CPSW_STATS(p0_, tx_pri2_drop_bcnt),
268	AM65_CPSW_STATS(p0_, tx_pri3_drop_bcnt),
269	AM65_CPSW_STATS(p0_, tx_pri4_drop_bcnt),
270	AM65_CPSW_STATS(p0_, tx_pri5_drop_bcnt),
271	AM65_CPSW_STATS(p0_, tx_pri6_drop_bcnt),
272	AM65_CPSW_STATS(p0_, tx_pri7_drop_bcnt),
273};
274
275static const struct am65_cpsw_ethtool_stat am65_slave_stats[] = {
276	AM65_CPSW_STATS(, rx_good_frames),
277	AM65_CPSW_STATS(, rx_broadcast_frames),
278	AM65_CPSW_STATS(, rx_multicast_frames),
279	AM65_CPSW_STATS(, rx_pause_frames),
280	AM65_CPSW_STATS(, rx_crc_errors),
281	AM65_CPSW_STATS(, rx_align_code_errors),
282	AM65_CPSW_STATS(, rx_oversized_frames),
283	AM65_CPSW_STATS(, rx_jabber_frames),
284	AM65_CPSW_STATS(, rx_undersized_frames),
285	AM65_CPSW_STATS(, rx_fragments),
286	AM65_CPSW_STATS(, ale_drop),
287	AM65_CPSW_STATS(, ale_overrun_drop),
288	AM65_CPSW_STATS(, rx_octets),
289	AM65_CPSW_STATS(, tx_good_frames),
290	AM65_CPSW_STATS(, tx_broadcast_frames),
291	AM65_CPSW_STATS(, tx_multicast_frames),
292	AM65_CPSW_STATS(, tx_pause_frames),
293	AM65_CPSW_STATS(, tx_deferred_frames),
294	AM65_CPSW_STATS(, tx_collision_frames),
295	AM65_CPSW_STATS(, tx_single_coll_frames),
296	AM65_CPSW_STATS(, tx_mult_coll_frames),
297	AM65_CPSW_STATS(, tx_excessive_collisions),
298	AM65_CPSW_STATS(, tx_late_collisions),
299	AM65_CPSW_STATS(, rx_ipg_error),
300	AM65_CPSW_STATS(, tx_carrier_sense_errors),
301	AM65_CPSW_STATS(, tx_octets),
302	AM65_CPSW_STATS(, tx_64B_frames),
303	AM65_CPSW_STATS(, tx_65_to_127B_frames),
304	AM65_CPSW_STATS(, tx_128_to_255B_frames),
305	AM65_CPSW_STATS(, tx_256_to_511B_frames),
306	AM65_CPSW_STATS(, tx_512_to_1023B_frames),
307	AM65_CPSW_STATS(, tx_1024B_frames),
308	AM65_CPSW_STATS(, net_octets),
309	AM65_CPSW_STATS(, rx_bottom_fifo_drop),
310	AM65_CPSW_STATS(, rx_port_mask_drop),
311	AM65_CPSW_STATS(, rx_top_fifo_drop),
312	AM65_CPSW_STATS(, ale_rate_limit_drop),
313	AM65_CPSW_STATS(, ale_vid_ingress_drop),
314	AM65_CPSW_STATS(, ale_da_eq_sa_drop),
315	AM65_CPSW_STATS(, ale_block_drop),
316	AM65_CPSW_STATS(, ale_secure_drop),
317	AM65_CPSW_STATS(, ale_auth_drop),
318	AM65_CPSW_STATS(, ale_unknown_ucast),
319	AM65_CPSW_STATS(, ale_unknown_ucast_bytes),
320	AM65_CPSW_STATS(, ale_unknown_mcast),
321	AM65_CPSW_STATS(, ale_unknown_mcast_bytes),
322	AM65_CPSW_STATS(, ale_unknown_bcast),
323	AM65_CPSW_STATS(, ale_unknown_bcast_bytes),
324	AM65_CPSW_STATS(, ale_pol_match),
325	AM65_CPSW_STATS(, ale_pol_match_red),
326	AM65_CPSW_STATS(, ale_pol_match_yellow),
327	AM65_CPSW_STATS(, ale_mcast_sa_drop),
328	AM65_CPSW_STATS(, ale_dual_vlan_drop),
329	AM65_CPSW_STATS(, ale_len_err_drop),
330	AM65_CPSW_STATS(, ale_ip_next_hdr_drop),
331	AM65_CPSW_STATS(, ale_ipv4_frag_drop),
332	AM65_CPSW_STATS(, iet_rx_assembly_err),
333	AM65_CPSW_STATS(, iet_rx_assembly_ok),
334	AM65_CPSW_STATS(, iet_rx_smd_err),
335	AM65_CPSW_STATS(, iet_rx_frag),
336	AM65_CPSW_STATS(, iet_tx_hold),
337	AM65_CPSW_STATS(, iet_tx_frag),
338	AM65_CPSW_STATS(, tx_mem_protect_err),
339	AM65_CPSW_STATS(, tx_pri0),
340	AM65_CPSW_STATS(, tx_pri1),
341	AM65_CPSW_STATS(, tx_pri2),
342	AM65_CPSW_STATS(, tx_pri3),
343	AM65_CPSW_STATS(, tx_pri4),
344	AM65_CPSW_STATS(, tx_pri5),
345	AM65_CPSW_STATS(, tx_pri6),
346	AM65_CPSW_STATS(, tx_pri7),
347	AM65_CPSW_STATS(, tx_pri0_bcnt),
348	AM65_CPSW_STATS(, tx_pri1_bcnt),
349	AM65_CPSW_STATS(, tx_pri2_bcnt),
350	AM65_CPSW_STATS(, tx_pri3_bcnt),
351	AM65_CPSW_STATS(, tx_pri4_bcnt),
352	AM65_CPSW_STATS(, tx_pri5_bcnt),
353	AM65_CPSW_STATS(, tx_pri6_bcnt),
354	AM65_CPSW_STATS(, tx_pri7_bcnt),
355	AM65_CPSW_STATS(, tx_pri0_drop),
356	AM65_CPSW_STATS(, tx_pri1_drop),
357	AM65_CPSW_STATS(, tx_pri2_drop),
358	AM65_CPSW_STATS(, tx_pri3_drop),
359	AM65_CPSW_STATS(, tx_pri4_drop),
360	AM65_CPSW_STATS(, tx_pri5_drop),
361	AM65_CPSW_STATS(, tx_pri6_drop),
362	AM65_CPSW_STATS(, tx_pri7_drop),
363	AM65_CPSW_STATS(, tx_pri0_drop_bcnt),
364	AM65_CPSW_STATS(, tx_pri1_drop_bcnt),
365	AM65_CPSW_STATS(, tx_pri2_drop_bcnt),
366	AM65_CPSW_STATS(, tx_pri3_drop_bcnt),
367	AM65_CPSW_STATS(, tx_pri4_drop_bcnt),
368	AM65_CPSW_STATS(, tx_pri5_drop_bcnt),
369	AM65_CPSW_STATS(, tx_pri6_drop_bcnt),
370	AM65_CPSW_STATS(, tx_pri7_drop_bcnt),
371};
372
373/* Ethtool priv_flags */
374static const char am65_cpsw_ethtool_priv_flags[][ETH_GSTRING_LEN] = {
375#define	AM65_CPSW_PRIV_P0_RX_PTYPE_RROBIN	BIT(0)
376	"p0-rx-ptype-rrobin",
377};
378
379static int am65_cpsw_ethtool_op_begin(struct net_device *ndev)
380{
381	struct am65_cpsw_common *common = am65_ndev_to_common(ndev);
382	int ret;
383
384	ret = pm_runtime_resume_and_get(common->dev);
385	if (ret < 0)
386		dev_err(common->dev, "ethtool begin failed %d\n", ret);
387
388	return ret;
389}
390
391static void am65_cpsw_ethtool_op_complete(struct net_device *ndev)
392{
393	struct am65_cpsw_common *common = am65_ndev_to_common(ndev);
394	int ret;
395
396	ret = pm_runtime_put(common->dev);
397	if (ret < 0 && ret != -EBUSY)
398		dev_err(common->dev, "ethtool complete failed %d\n", ret);
399}
400
401static void am65_cpsw_get_drvinfo(struct net_device *ndev,
402				  struct ethtool_drvinfo *info)
403{
404	struct am65_cpsw_common *common = am65_ndev_to_common(ndev);
405
406	strscpy(info->driver, dev_driver_string(common->dev),
407		sizeof(info->driver));
408	strscpy(info->bus_info, dev_name(common->dev), sizeof(info->bus_info));
409}
410
411static u32 am65_cpsw_get_msglevel(struct net_device *ndev)
412{
413	struct am65_cpsw_ndev_priv *priv = am65_ndev_to_priv(ndev);
414
415	return priv->msg_enable;
416}
417
418static void am65_cpsw_set_msglevel(struct net_device *ndev, u32 value)
419{
420	struct am65_cpsw_ndev_priv *priv = am65_ndev_to_priv(ndev);
421
422	priv->msg_enable = value;
423}
424
425static void am65_cpsw_get_channels(struct net_device *ndev,
426				   struct ethtool_channels *ch)
427{
428	struct am65_cpsw_common *common = am65_ndev_to_common(ndev);
429
430	ch->max_rx = AM65_CPSW_MAX_RX_QUEUES;
431	ch->max_tx = AM65_CPSW_MAX_TX_QUEUES;
432	ch->rx_count = AM65_CPSW_MAX_RX_QUEUES;
433	ch->tx_count = common->tx_ch_num;
434}
435
436static int am65_cpsw_set_channels(struct net_device *ndev,
437				  struct ethtool_channels *chs)
438{
439	struct am65_cpsw_common *common = am65_ndev_to_common(ndev);
440
441	if (!chs->rx_count || !chs->tx_count)
442		return -EINVAL;
443
444	/* Check if interface is up. Can change the num queues when
445	 * the interface is down.
446	 */
447	if (common->usage_count)
448		return -EBUSY;
449
450	am65_cpsw_nuss_remove_tx_chns(common);
451
452	return am65_cpsw_nuss_update_tx_chns(common, chs->tx_count);
453}
454
455static void
456am65_cpsw_get_ringparam(struct net_device *ndev,
457			struct ethtool_ringparam *ering,
458			struct kernel_ethtool_ringparam *kernel_ering,
459			struct netlink_ext_ack *extack)
460{
461	struct am65_cpsw_common *common = am65_ndev_to_common(ndev);
462
463	/* not supported */
464	ering->tx_pending = common->tx_chns[0].descs_num;
465	ering->rx_pending = common->rx_chns.descs_num;
466}
467
468static void am65_cpsw_get_pauseparam(struct net_device *ndev,
469				     struct ethtool_pauseparam *pause)
470{
471	struct am65_cpsw_slave_data *salve = am65_ndev_to_slave(ndev);
472
473	phylink_ethtool_get_pauseparam(salve->phylink, pause);
474}
475
476static int am65_cpsw_set_pauseparam(struct net_device *ndev,
477				    struct ethtool_pauseparam *pause)
478{
479	struct am65_cpsw_slave_data *salve = am65_ndev_to_slave(ndev);
480
481	return phylink_ethtool_set_pauseparam(salve->phylink, pause);
482}
483
484static void am65_cpsw_get_wol(struct net_device *ndev,
485			      struct ethtool_wolinfo *wol)
486{
487	struct am65_cpsw_slave_data *salve = am65_ndev_to_slave(ndev);
488
489	phylink_ethtool_get_wol(salve->phylink, wol);
490}
491
492static int am65_cpsw_set_wol(struct net_device *ndev,
493			     struct ethtool_wolinfo *wol)
494{
495	struct am65_cpsw_slave_data *salve = am65_ndev_to_slave(ndev);
496
497	return phylink_ethtool_set_wol(salve->phylink, wol);
498}
499
500static int am65_cpsw_get_link_ksettings(struct net_device *ndev,
501					struct ethtool_link_ksettings *ecmd)
502{
503	struct am65_cpsw_slave_data *salve = am65_ndev_to_slave(ndev);
504
505	return phylink_ethtool_ksettings_get(salve->phylink, ecmd);
506}
507
508static int
509am65_cpsw_set_link_ksettings(struct net_device *ndev,
510			     const struct ethtool_link_ksettings *ecmd)
511{
512	struct am65_cpsw_slave_data *salve = am65_ndev_to_slave(ndev);
513
514	return phylink_ethtool_ksettings_set(salve->phylink, ecmd);
515}
516
517static int am65_cpsw_get_eee(struct net_device *ndev, struct ethtool_keee *edata)
518{
519	struct am65_cpsw_slave_data *salve = am65_ndev_to_slave(ndev);
520
521	return phylink_ethtool_get_eee(salve->phylink, edata);
522}
523
524static int am65_cpsw_set_eee(struct net_device *ndev, struct ethtool_keee *edata)
525{
526	struct am65_cpsw_slave_data *salve = am65_ndev_to_slave(ndev);
527
528	return phylink_ethtool_set_eee(salve->phylink, edata);
529}
530
531static int am65_cpsw_nway_reset(struct net_device *ndev)
532{
533	struct am65_cpsw_slave_data *salve = am65_ndev_to_slave(ndev);
534
535	return phylink_ethtool_nway_reset(salve->phylink);
536}
537
538static int am65_cpsw_get_regs_len(struct net_device *ndev)
539{
540	struct am65_cpsw_common *common = am65_ndev_to_common(ndev);
541	u32 ale_entries, i, regdump_len = 0;
542
543	ale_entries = cpsw_ale_get_num_entries(common->ale);
544	for (i = 0; i < ARRAY_SIZE(am65_cpsw_regdump); i++) {
545		if (am65_cpsw_regdump[i].hdr.module_id ==
546		    AM65_CPSW_REGDUMP_MOD_CPSW_ALE_TBL) {
547			regdump_len += sizeof(struct am65_cpsw_regdump_hdr);
548			regdump_len += ale_entries *
549				       ALE_ENTRY_WORDS * sizeof(u32);
550			continue;
551		}
552		regdump_len += am65_cpsw_regdump[i].hdr.len;
553	}
554
555	return regdump_len;
556}
557
558static void am65_cpsw_get_regs(struct net_device *ndev,
559			       struct ethtool_regs *regs, void *p)
560{
561	struct am65_cpsw_common *common = am65_ndev_to_common(ndev);
562	u32 ale_entries, i, j, pos, *reg = p;
563
564	/* update CPSW IP version */
565	regs->version = AM65_CPSW_REGDUMP_VER;
566	ale_entries = cpsw_ale_get_num_entries(common->ale);
567
568	pos = 0;
569	for (i = 0; i < ARRAY_SIZE(am65_cpsw_regdump); i++) {
570		reg[pos++] = am65_cpsw_regdump[i].hdr.module_id;
571
572		if (am65_cpsw_regdump[i].hdr.module_id ==
573		    AM65_CPSW_REGDUMP_MOD_CPSW_ALE_TBL) {
574			u32 ale_tbl_len = ale_entries *
575					  ALE_ENTRY_WORDS * sizeof(u32) +
576					  sizeof(struct am65_cpsw_regdump_hdr);
577			reg[pos++] = ale_tbl_len;
578			cpsw_ale_dump(common->ale, &reg[pos]);
579			pos += ale_tbl_len;
580			continue;
581		}
582
583		reg[pos++] = am65_cpsw_regdump[i].hdr.len;
584
585		j = am65_cpsw_regdump[i].start_ofs;
586		do {
587			reg[pos++] = j;
588			reg[pos++] = readl_relaxed(common->ss_base + j);
589			j += sizeof(u32);
590		} while (j <= am65_cpsw_regdump[i].end_ofs);
591	}
592}
593
594static int am65_cpsw_get_sset_count(struct net_device *ndev, int sset)
595{
596	switch (sset) {
597	case ETH_SS_STATS:
598		return ARRAY_SIZE(am65_host_stats) +
599		       ARRAY_SIZE(am65_slave_stats);
600	case ETH_SS_PRIV_FLAGS:
601		return ARRAY_SIZE(am65_cpsw_ethtool_priv_flags);
602	default:
603		return -EOPNOTSUPP;
604	}
605}
606
607static void am65_cpsw_get_strings(struct net_device *ndev,
608				  u32 stringset, u8 *data)
609{
610	const struct am65_cpsw_ethtool_stat *hw_stats;
611	u32 i, num_stats;
612	u8 *p = data;
613
614	switch (stringset) {
615	case ETH_SS_STATS:
616		num_stats = ARRAY_SIZE(am65_host_stats);
617		hw_stats = am65_host_stats;
618		for (i = 0; i < num_stats; i++) {
619			memcpy(p, hw_stats[i].desc, ETH_GSTRING_LEN);
620			p += ETH_GSTRING_LEN;
621		}
622
623		num_stats = ARRAY_SIZE(am65_slave_stats);
624		hw_stats = am65_slave_stats;
625		for (i = 0; i < num_stats; i++) {
626			memcpy(p, hw_stats[i].desc, ETH_GSTRING_LEN);
627			p += ETH_GSTRING_LEN;
628		}
629		break;
630	case ETH_SS_PRIV_FLAGS:
631		num_stats = ARRAY_SIZE(am65_cpsw_ethtool_priv_flags);
632
633		for (i = 0; i < num_stats; i++) {
634			memcpy(p, am65_cpsw_ethtool_priv_flags[i],
635			       ETH_GSTRING_LEN);
636			p += ETH_GSTRING_LEN;
637		}
638		break;
639	}
640}
641
642static void am65_cpsw_get_ethtool_stats(struct net_device *ndev,
643					struct ethtool_stats *stats, u64 *data)
644{
645	struct am65_cpsw_common *common = am65_ndev_to_common(ndev);
646	const struct am65_cpsw_ethtool_stat *hw_stats;
647	struct am65_cpsw_host *host_p;
648	struct am65_cpsw_port *port;
649	u32 i, num_stats;
650
651	host_p = am65_common_get_host(common);
652	port = am65_ndev_to_port(ndev);
653	num_stats = ARRAY_SIZE(am65_host_stats);
654	hw_stats = am65_host_stats;
655	for (i = 0; i < num_stats; i++)
656		*data++ = readl_relaxed(host_p->stat_base +
657					hw_stats[i].offset);
658
659	num_stats = ARRAY_SIZE(am65_slave_stats);
660	hw_stats = am65_slave_stats;
661	for (i = 0; i < num_stats; i++)
662		*data++ = readl_relaxed(port->stat_base +
663					hw_stats[i].offset);
664}
665
666static void am65_cpsw_get_eth_mac_stats(struct net_device *ndev,
667					struct ethtool_eth_mac_stats *s)
668{
669	struct am65_cpsw_port *port = am65_ndev_to_port(ndev);
670	struct am65_cpsw_stats_regs __iomem *stats;
671
672	stats = port->stat_base;
673
674	if (s->src != ETHTOOL_MAC_STATS_SRC_AGGREGATE)
675		return;
676
677	s->FramesTransmittedOK = readl_relaxed(&stats->tx_good_frames);
678	s->SingleCollisionFrames = readl_relaxed(&stats->tx_single_coll_frames);
679	s->MultipleCollisionFrames = readl_relaxed(&stats->tx_mult_coll_frames);
680	s->FramesReceivedOK = readl_relaxed(&stats->rx_good_frames);
681	s->FrameCheckSequenceErrors = readl_relaxed(&stats->rx_crc_errors);
682	s->AlignmentErrors = readl_relaxed(&stats->rx_align_code_errors);
683	s->OctetsTransmittedOK = readl_relaxed(&stats->tx_octets);
684	s->FramesWithDeferredXmissions = readl_relaxed(&stats->tx_deferred_frames);
685	s->LateCollisions = readl_relaxed(&stats->tx_late_collisions);
686	s->CarrierSenseErrors = readl_relaxed(&stats->tx_carrier_sense_errors);
687	s->OctetsReceivedOK = readl_relaxed(&stats->rx_octets);
688	s->MulticastFramesXmittedOK = readl_relaxed(&stats->tx_multicast_frames);
689	s->BroadcastFramesXmittedOK = readl_relaxed(&stats->tx_broadcast_frames);
690	s->MulticastFramesReceivedOK = readl_relaxed(&stats->rx_multicast_frames);
691	s->BroadcastFramesReceivedOK = readl_relaxed(&stats->rx_broadcast_frames);
692};
693
694static int am65_cpsw_get_ethtool_ts_info(struct net_device *ndev,
695					 struct ethtool_ts_info *info)
696{
697	struct am65_cpsw_common *common = am65_ndev_to_common(ndev);
698
699	if (!IS_ENABLED(CONFIG_TI_K3_AM65_CPTS))
700		return ethtool_op_get_ts_info(ndev, info);
701
702	info->so_timestamping =
703		SOF_TIMESTAMPING_TX_HARDWARE |
704		SOF_TIMESTAMPING_TX_SOFTWARE |
705		SOF_TIMESTAMPING_RX_HARDWARE |
706		SOF_TIMESTAMPING_RX_SOFTWARE |
707		SOF_TIMESTAMPING_SOFTWARE |
708		SOF_TIMESTAMPING_RAW_HARDWARE;
709	info->phc_index = am65_cpts_phc_index(common->cpts);
710	info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON);
711	info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) | BIT(HWTSTAMP_FILTER_ALL);
712	return 0;
713}
714
715static u32 am65_cpsw_get_ethtool_priv_flags(struct net_device *ndev)
716{
717	struct am65_cpsw_common *common = am65_ndev_to_common(ndev);
718	u32 priv_flags = 0;
719
720	if (common->pf_p0_rx_ptype_rrobin)
721		priv_flags |= AM65_CPSW_PRIV_P0_RX_PTYPE_RROBIN;
722
723	return priv_flags;
724}
725
726static int am65_cpsw_set_ethtool_priv_flags(struct net_device *ndev, u32 flags)
727{
728	struct am65_cpsw_common *common = am65_ndev_to_common(ndev);
729	int rrobin;
730
731	rrobin = !!(flags & AM65_CPSW_PRIV_P0_RX_PTYPE_RROBIN);
732
733	if (common->usage_count)
734		return -EBUSY;
735
736	if (common->est_enabled && rrobin) {
737		netdev_err(ndev,
738			   "p0-rx-ptype-rrobin flag conflicts with QOS\n");
739		return -EINVAL;
740	}
741
742	common->pf_p0_rx_ptype_rrobin = rrobin;
743
744	return 0;
745}
746
747static void am65_cpsw_port_iet_rx_enable(struct am65_cpsw_port *port, bool enable)
748{
749	u32 val;
750
751	val = readl(port->port_base + AM65_CPSW_PN_REG_CTL);
752	if (enable)
753		val |= AM65_CPSW_PN_CTL_IET_PORT_EN;
754	else
755		val &= ~AM65_CPSW_PN_CTL_IET_PORT_EN;
756
757	writel(val, port->port_base + AM65_CPSW_PN_REG_CTL);
758	am65_cpsw_iet_common_enable(port->common);
759}
760
761static void am65_cpsw_port_iet_tx_enable(struct am65_cpsw_port *port, bool enable)
762{
763	u32 val;
764
765	val = readl(port->port_base + AM65_CPSW_PN_REG_IET_CTRL);
766	if (enable)
767		val |= AM65_CPSW_PN_IET_MAC_PENABLE;
768	else
769		val &= ~AM65_CPSW_PN_IET_MAC_PENABLE;
770
771	writel(val, port->port_base + AM65_CPSW_PN_REG_IET_CTRL);
772}
773
774static int am65_cpsw_get_mm(struct net_device *ndev, struct ethtool_mm_state *state)
775{
776	struct am65_cpsw_port *port = am65_ndev_to_port(ndev);
777	struct am65_cpsw_ndev_priv *priv = netdev_priv(ndev);
778	u32 port_ctrl, iet_ctrl, iet_status;
779	u32 add_frag_size;
780
781	if (!IS_ENABLED(CONFIG_TI_AM65_CPSW_QOS))
782		return -EOPNOTSUPP;
783
784	mutex_lock(&priv->mm_lock);
785
786	iet_ctrl = readl(port->port_base + AM65_CPSW_PN_REG_IET_CTRL);
787	port_ctrl = readl(port->port_base + AM65_CPSW_PN_REG_CTL);
788
789	state->tx_enabled = !!(iet_ctrl & AM65_CPSW_PN_IET_MAC_PENABLE);
790	state->pmac_enabled = !!(port_ctrl & AM65_CPSW_PN_CTL_IET_PORT_EN);
791
792	iet_status = readl(port->port_base + AM65_CPSW_PN_REG_IET_STATUS);
793
794	if (iet_ctrl & AM65_CPSW_PN_IET_MAC_DISABLEVERIFY)
795		state->verify_status = ETHTOOL_MM_VERIFY_STATUS_DISABLED;
796	else if (iet_status & AM65_CPSW_PN_MAC_VERIFIED)
797		state->verify_status = ETHTOOL_MM_VERIFY_STATUS_SUCCEEDED;
798	else if (iet_status & AM65_CPSW_PN_MAC_VERIFY_FAIL)
799		state->verify_status = ETHTOOL_MM_VERIFY_STATUS_FAILED;
800	else
801		state->verify_status = ETHTOOL_MM_VERIFY_STATUS_UNKNOWN;
802
803	add_frag_size = AM65_CPSW_PN_IET_MAC_GET_ADDFRAGSIZE(iet_ctrl);
804	state->tx_min_frag_size = ethtool_mm_frag_size_add_to_min(add_frag_size);
805
806	/* Errata i2208: RX min fragment size cannot be less than 124 */
807	state->rx_min_frag_size = 124;
808
809	/* FPE active if common tx_enabled and verification success or disabled (forced) */
810	state->tx_active = state->tx_enabled &&
811			   (state->verify_status == ETHTOOL_MM_VERIFY_STATUS_SUCCEEDED ||
812			    state->verify_status == ETHTOOL_MM_VERIFY_STATUS_DISABLED);
813	state->verify_enabled = !(iet_ctrl & AM65_CPSW_PN_IET_MAC_DISABLEVERIFY);
814
815	state->verify_time = port->qos.iet.verify_time_ms;
816
817	/* 802.3-2018 clause 30.14.1.6, says that the aMACMergeVerifyTime
818	 * variable has a range between 1 and 128 ms inclusive. Limit to that.
819	 */
820	state->max_verify_time = 128;
821
822	mutex_unlock(&priv->mm_lock);
823
824	return 0;
825}
826
827static int am65_cpsw_set_mm(struct net_device *ndev, struct ethtool_mm_cfg *cfg,
828			    struct netlink_ext_ack *extack)
829{
830	struct am65_cpsw_port *port = am65_ndev_to_port(ndev);
831	struct am65_cpsw_ndev_priv *priv = netdev_priv(ndev);
832	struct am65_cpsw_iet *iet = &port->qos.iet;
833	u32 val, add_frag_size;
834	int err;
835
836	if (!IS_ENABLED(CONFIG_TI_AM65_CPSW_QOS))
837		return -EOPNOTSUPP;
838
839	err = ethtool_mm_frag_size_min_to_add(cfg->tx_min_frag_size, &add_frag_size, extack);
840	if (err)
841		return err;
842
843	mutex_lock(&priv->mm_lock);
844
845	if (cfg->pmac_enabled) {
846		/* change TX & RX FIFO MAX_BLKS as per TRM recommendation */
847		if (!iet->original_max_blks)
848			iet->original_max_blks = readl(port->port_base + AM65_CPSW_PN_REG_MAX_BLKS);
849
850		writel(AM65_CPSW_PN_TX_RX_MAX_BLKS_IET,
851		       port->port_base + AM65_CPSW_PN_REG_MAX_BLKS);
852	} else if (iet->original_max_blks) {
853		/* restore RX & TX FIFO MAX_BLKS */
854		writel(iet->original_max_blks,
855		       port->port_base + AM65_CPSW_PN_REG_MAX_BLKS);
856	}
857
858	am65_cpsw_port_iet_rx_enable(port, cfg->pmac_enabled);
859	am65_cpsw_port_iet_tx_enable(port, cfg->tx_enabled);
860
861	val = readl(port->port_base + AM65_CPSW_PN_REG_IET_CTRL);
862	if (cfg->verify_enabled) {
863		val &= ~AM65_CPSW_PN_IET_MAC_DISABLEVERIFY;
864		/* Reset Verify state machine. Verification won't start here.
865		 * Verification will be done once link-up.
866		 */
867		val |= AM65_CPSW_PN_IET_MAC_LINKFAIL;
868	} else {
869		val |= AM65_CPSW_PN_IET_MAC_DISABLEVERIFY;
870		/* Clear LINKFAIL to allow verify/response packets */
871		val &= ~AM65_CPSW_PN_IET_MAC_LINKFAIL;
872	}
873
874	val &= ~AM65_CPSW_PN_IET_MAC_MAC_ADDFRAGSIZE_MASK;
875	val |= AM65_CPSW_PN_IET_MAC_SET_ADDFRAGSIZE(add_frag_size);
876	writel(val, port->port_base + AM65_CPSW_PN_REG_IET_CTRL);
877
878	/* verify_timeout_count can only be set at valid link */
879	port->qos.iet.verify_time_ms = cfg->verify_time;
880
881	/* enable/disable preemption based on link status */
882	am65_cpsw_iet_commit_preemptible_tcs(port);
883
884	mutex_unlock(&priv->mm_lock);
885
886	return 0;
887}
888
889static void am65_cpsw_get_mm_stats(struct net_device *ndev,
890				   struct ethtool_mm_stats *s)
891{
892	struct am65_cpsw_port *port = am65_ndev_to_port(ndev);
893	void __iomem *base = port->stat_base;
894
895	s->MACMergeFrameAssOkCount = readl(base + AM65_CPSW_STATN_IET_RX_ASSEMBLY_OK);
896	s->MACMergeFrameAssErrorCount = readl(base + AM65_CPSW_STATN_IET_RX_ASSEMBLY_ERROR);
897	s->MACMergeFrameSmdErrorCount = readl(base + AM65_CPSW_STATN_IET_RX_SMD_ERROR);
898	/* CPSW Functional Spec states:
899	 * "The IET stat aMACMergeFragCountRx is derived by adding the
900	 *  Receive Assembly Error count to this value. i.e. AM65_CPSW_STATN_IET_RX_FRAG"
901	 */
902	s->MACMergeFragCountRx = readl(base + AM65_CPSW_STATN_IET_RX_FRAG) + s->MACMergeFrameAssErrorCount;
903	s->MACMergeFragCountTx = readl(base + AM65_CPSW_STATN_IET_TX_FRAG);
904	s->MACMergeHoldCount = readl(base + AM65_CPSW_STATN_IET_TX_HOLD);
905}
906
907static int am65_cpsw_get_coalesce(struct net_device *ndev, struct ethtool_coalesce *coal,
908				  struct kernel_ethtool_coalesce *kernel_coal,
909				  struct netlink_ext_ack *extack)
910{
911	struct am65_cpsw_common *common = am65_ndev_to_common(ndev);
912	struct am65_cpsw_tx_chn *tx_chn;
913
914	tx_chn = &common->tx_chns[0];
915
916	coal->rx_coalesce_usecs = common->rx_pace_timeout / 1000;
917	coal->tx_coalesce_usecs = tx_chn->tx_pace_timeout / 1000;
918
919	return 0;
920}
921
922static int am65_cpsw_get_per_queue_coalesce(struct net_device *ndev, u32 queue,
923					    struct ethtool_coalesce *coal)
924{
925	struct am65_cpsw_common *common = am65_ndev_to_common(ndev);
926	struct am65_cpsw_tx_chn *tx_chn;
927
928	if (queue >= AM65_CPSW_MAX_TX_QUEUES)
929		return -EINVAL;
930
931	tx_chn = &common->tx_chns[queue];
932
933	coal->tx_coalesce_usecs = tx_chn->tx_pace_timeout / 1000;
934
935	return 0;
936}
937
938static int am65_cpsw_set_coalesce(struct net_device *ndev, struct ethtool_coalesce *coal,
939				  struct kernel_ethtool_coalesce *kernel_coal,
940				  struct netlink_ext_ack *extack)
941{
942	struct am65_cpsw_common *common = am65_ndev_to_common(ndev);
943	struct am65_cpsw_tx_chn *tx_chn;
944
945	tx_chn = &common->tx_chns[0];
946
947	if (coal->rx_coalesce_usecs && coal->rx_coalesce_usecs < 20)
948		return -EINVAL;
949
950	if (coal->tx_coalesce_usecs && coal->tx_coalesce_usecs < 20)
951		return -EINVAL;
952
953	common->rx_pace_timeout = coal->rx_coalesce_usecs * 1000;
954	tx_chn->tx_pace_timeout = coal->tx_coalesce_usecs * 1000;
955
956	return 0;
957}
958
959static int am65_cpsw_set_per_queue_coalesce(struct net_device *ndev, u32 queue,
960					    struct ethtool_coalesce *coal)
961{
962	struct am65_cpsw_common *common = am65_ndev_to_common(ndev);
963	struct am65_cpsw_tx_chn *tx_chn;
964
965	if (queue >= AM65_CPSW_MAX_TX_QUEUES)
966		return -EINVAL;
967
968	tx_chn = &common->tx_chns[queue];
969
970	if (coal->tx_coalesce_usecs && coal->tx_coalesce_usecs < 20) {
971		dev_info(common->dev, "defaulting to min value of 20us for tx-usecs for tx-%u\n",
972			 queue);
973		coal->tx_coalesce_usecs = 20;
974	}
975
976	tx_chn->tx_pace_timeout = coal->tx_coalesce_usecs * 1000;
977
978	return 0;
979}
980
981const struct ethtool_ops am65_cpsw_ethtool_ops_slave = {
982	.begin			= am65_cpsw_ethtool_op_begin,
983	.complete		= am65_cpsw_ethtool_op_complete,
984	.get_drvinfo		= am65_cpsw_get_drvinfo,
985	.get_msglevel		= am65_cpsw_get_msglevel,
986	.set_msglevel		= am65_cpsw_set_msglevel,
987	.get_channels		= am65_cpsw_get_channels,
988	.set_channels		= am65_cpsw_set_channels,
989	.get_ringparam		= am65_cpsw_get_ringparam,
990	.get_regs_len		= am65_cpsw_get_regs_len,
991	.get_regs		= am65_cpsw_get_regs,
992	.get_sset_count		= am65_cpsw_get_sset_count,
993	.get_strings		= am65_cpsw_get_strings,
994	.get_ethtool_stats	= am65_cpsw_get_ethtool_stats,
995	.get_eth_mac_stats	= am65_cpsw_get_eth_mac_stats,
996	.get_ts_info		= am65_cpsw_get_ethtool_ts_info,
997	.get_priv_flags		= am65_cpsw_get_ethtool_priv_flags,
998	.set_priv_flags		= am65_cpsw_set_ethtool_priv_flags,
999	.supported_coalesce_params = ETHTOOL_COALESCE_USECS,
1000	.get_coalesce           = am65_cpsw_get_coalesce,
1001	.set_coalesce           = am65_cpsw_set_coalesce,
1002	.get_per_queue_coalesce = am65_cpsw_get_per_queue_coalesce,
1003	.set_per_queue_coalesce = am65_cpsw_set_per_queue_coalesce,
1004
1005	.get_link		= ethtool_op_get_link,
1006	.get_link_ksettings	= am65_cpsw_get_link_ksettings,
1007	.set_link_ksettings	= am65_cpsw_set_link_ksettings,
1008	.get_pauseparam		= am65_cpsw_get_pauseparam,
1009	.set_pauseparam		= am65_cpsw_set_pauseparam,
1010	.get_wol		= am65_cpsw_get_wol,
1011	.set_wol		= am65_cpsw_set_wol,
1012	.get_eee		= am65_cpsw_get_eee,
1013	.set_eee		= am65_cpsw_set_eee,
1014	.nway_reset		= am65_cpsw_nway_reset,
1015	.get_mm			= am65_cpsw_get_mm,
1016	.set_mm			= am65_cpsw_set_mm,
1017	.get_mm_stats		= am65_cpsw_get_mm_stats,
1018};
1019