GNU Linux-libre 6.8.9-gnu
[releases.git] / drivers / net / ethernet / ti / am65-cpsw-ethtool.c
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
20 enum {
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
40 struct 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  */
57 struct 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
71 static 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
84 struct 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
185 struct 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
196 static 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
275 static 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 */
374 static 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
379 static 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
391 static 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
401 static 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
411 static 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
418 static 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
425 static 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
436 static 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
455 static void
456 am65_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
468 static 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
476 static 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
484 static 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
492 static 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
500 static 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
508 static int
509 am65_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
517 static int am65_cpsw_get_eee(struct net_device *ndev, struct ethtool_eee *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
524 static int am65_cpsw_set_eee(struct net_device *ndev, struct ethtool_eee *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
531 static 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
538 static 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
558 static 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
594 static 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
607 static 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
642 static 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
666 static 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
694 static 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
715 static 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
726 static 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
747 static 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
761 static 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
774 static 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
827 static 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
889 static 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
907 static 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
922 static 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
938 static 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
959 static 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
981 const 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 };