1 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
2 /* Copyright 2017-2019 NXP */
4 #include <linux/net_tstamp.h>
5 #include <linux/module.h>
8 static const u32 enetc_si_regs
[] = {
9 ENETC_SIMR
, ENETC_SIPMAR0
, ENETC_SIPMAR1
, ENETC_SICBDRMR
,
10 ENETC_SICBDRSR
, ENETC_SICBDRBAR0
, ENETC_SICBDRBAR1
, ENETC_SICBDRPIR
,
11 ENETC_SICBDRCIR
, ENETC_SICBDRLENR
, ENETC_SICAPR0
, ENETC_SICAPR1
,
15 static const u32 enetc_txbdr_regs
[] = {
16 ENETC_TBMR
, ENETC_TBSR
, ENETC_TBBAR0
, ENETC_TBBAR1
,
17 ENETC_TBPIR
, ENETC_TBCIR
, ENETC_TBLENR
, ENETC_TBIER
20 static const u32 enetc_rxbdr_regs
[] = {
21 ENETC_RBMR
, ENETC_RBSR
, ENETC_RBBSR
, ENETC_RBCIR
, ENETC_RBBAR0
,
22 ENETC_RBBAR1
, ENETC_RBPIR
, ENETC_RBLENR
, ENETC_RBICIR0
, ENETC_RBIER
25 static const u32 enetc_port_regs
[] = {
26 ENETC_PMR
, ENETC_PSR
, ENETC_PSIPMR
, ENETC_PSIPMAR0(0),
27 ENETC_PSIPMAR1(0), ENETC_PTXMBAR
, ENETC_PCAPR0
, ENETC_PCAPR1
,
28 ENETC_PSICFGR0(0), ENETC_PRFSCAPR
, ENETC_PTCMSDUR(0),
29 ENETC_PM0_CMD_CFG
, ENETC_PM0_MAXFRM
, ENETC_PM0_IF_MODE
32 static int enetc_get_reglen(struct net_device
*ndev
)
34 struct enetc_ndev_priv
*priv
= netdev_priv(ndev
);
35 struct enetc_hw
*hw
= &priv
->si
->hw
;
38 len
= ARRAY_SIZE(enetc_si_regs
);
39 len
+= ARRAY_SIZE(enetc_txbdr_regs
) * priv
->num_tx_rings
;
40 len
+= ARRAY_SIZE(enetc_rxbdr_regs
) * priv
->num_rx_rings
;
43 len
+= ARRAY_SIZE(enetc_port_regs
);
45 len
*= sizeof(u32
) * 2; /* store 2 entries per reg: addr and value */
50 static void enetc_get_regs(struct net_device
*ndev
, struct ethtool_regs
*regs
,
53 struct enetc_ndev_priv
*priv
= netdev_priv(ndev
);
54 struct enetc_hw
*hw
= &priv
->si
->hw
;
55 u32
*buf
= (u32
*)regbuf
;
59 for (i
= 0; i
< ARRAY_SIZE(enetc_si_regs
); i
++) {
60 *buf
++ = enetc_si_regs
[i
];
61 *buf
++ = enetc_rd(hw
, enetc_si_regs
[i
]);
64 for (i
= 0; i
< priv
->num_tx_rings
; i
++) {
65 for (j
= 0; j
< ARRAY_SIZE(enetc_txbdr_regs
); j
++) {
66 addr
= ENETC_BDR(TX
, i
, enetc_txbdr_regs
[j
]);
69 *buf
++ = enetc_rd(hw
, addr
);
73 for (i
= 0; i
< priv
->num_rx_rings
; i
++) {
74 for (j
= 0; j
< ARRAY_SIZE(enetc_rxbdr_regs
); j
++) {
75 addr
= ENETC_BDR(RX
, i
, enetc_rxbdr_regs
[j
]);
78 *buf
++ = enetc_rd(hw
, addr
);
85 for (i
= 0; i
< ARRAY_SIZE(enetc_port_regs
); i
++) {
86 addr
= ENETC_PORT_BASE
+ enetc_port_regs
[i
];
88 *buf
++ = enetc_rd(hw
, addr
);
94 char name
[ETH_GSTRING_LEN
];
95 } enetc_si_counters
[] = {
96 { ENETC_SIROCT
, "SI rx octets" },
97 { ENETC_SIRFRM
, "SI rx frames" },
98 { ENETC_SIRUCA
, "SI rx u-cast frames" },
99 { ENETC_SIRMCA
, "SI rx m-cast frames" },
100 { ENETC_SITOCT
, "SI tx octets" },
101 { ENETC_SITFRM
, "SI tx frames" },
102 { ENETC_SITUCA
, "SI tx u-cast frames" },
103 { ENETC_SITMCA
, "SI tx m-cast frames" },
104 { ENETC_RBDCR(0), "Rx ring 0 discarded frames" },
105 { ENETC_RBDCR(1), "Rx ring 1 discarded frames" },
106 { ENETC_RBDCR(2), "Rx ring 2 discarded frames" },
107 { ENETC_RBDCR(3), "Rx ring 3 discarded frames" },
108 { ENETC_RBDCR(4), "Rx ring 4 discarded frames" },
109 { ENETC_RBDCR(5), "Rx ring 5 discarded frames" },
110 { ENETC_RBDCR(6), "Rx ring 6 discarded frames" },
111 { ENETC_RBDCR(7), "Rx ring 7 discarded frames" },
112 { ENETC_RBDCR(8), "Rx ring 8 discarded frames" },
113 { ENETC_RBDCR(9), "Rx ring 9 discarded frames" },
114 { ENETC_RBDCR(10), "Rx ring 10 discarded frames" },
115 { ENETC_RBDCR(11), "Rx ring 11 discarded frames" },
116 { ENETC_RBDCR(12), "Rx ring 12 discarded frames" },
117 { ENETC_RBDCR(13), "Rx ring 13 discarded frames" },
118 { ENETC_RBDCR(14), "Rx ring 14 discarded frames" },
119 { ENETC_RBDCR(15), "Rx ring 15 discarded frames" },
122 static const struct {
124 char name
[ETH_GSTRING_LEN
];
125 } enetc_port_counters
[] = {
126 { ENETC_PM0_REOCT
, "MAC rx ethernet octets" },
127 { ENETC_PM0_RALN
, "MAC rx alignment errors" },
128 { ENETC_PM0_RXPF
, "MAC rx valid pause frames" },
129 { ENETC_PM0_RFRM
, "MAC rx valid frames" },
130 { ENETC_PM0_RFCS
, "MAC rx fcs errors" },
131 { ENETC_PM0_RVLAN
, "MAC rx VLAN frames" },
132 { ENETC_PM0_RERR
, "MAC rx frame errors" },
133 { ENETC_PM0_RUCA
, "MAC rx unicast frames" },
134 { ENETC_PM0_RMCA
, "MAC rx multicast frames" },
135 { ENETC_PM0_RBCA
, "MAC rx broadcast frames" },
136 { ENETC_PM0_RDRP
, "MAC rx dropped packets" },
137 { ENETC_PM0_RPKT
, "MAC rx packets" },
138 { ENETC_PM0_RUND
, "MAC rx undersized packets" },
139 { ENETC_PM0_R64
, "MAC rx 64 byte packets" },
140 { ENETC_PM0_R127
, "MAC rx 65-127 byte packets" },
141 { ENETC_PM0_R255
, "MAC rx 128-255 byte packets" },
142 { ENETC_PM0_R511
, "MAC rx 256-511 byte packets" },
143 { ENETC_PM0_R1023
, "MAC rx 512-1023 byte packets" },
144 { ENETC_PM0_R1518
, "MAC rx 1024-1518 byte packets" },
145 { ENETC_PM0_R1519X
, "MAC rx 1519 to max-octet packets" },
146 { ENETC_PM0_ROVR
, "MAC rx oversized packets" },
147 { ENETC_PM0_RJBR
, "MAC rx jabber packets" },
148 { ENETC_PM0_RFRG
, "MAC rx fragment packets" },
149 { ENETC_PM0_RCNP
, "MAC rx control packets" },
150 { ENETC_PM0_RDRNTP
, "MAC rx fifo drop" },
151 { ENETC_PM0_TEOCT
, "MAC tx ethernet octets" },
152 { ENETC_PM0_TOCT
, "MAC tx octets" },
153 { ENETC_PM0_TCRSE
, "MAC tx carrier sense errors" },
154 { ENETC_PM0_TXPF
, "MAC tx valid pause frames" },
155 { ENETC_PM0_TFRM
, "MAC tx frames" },
156 { ENETC_PM0_TFCS
, "MAC tx fcs errors" },
157 { ENETC_PM0_TVLAN
, "MAC tx VLAN frames" },
158 { ENETC_PM0_TERR
, "MAC tx frames" },
159 { ENETC_PM0_TUCA
, "MAC tx unicast frames" },
160 { ENETC_PM0_TMCA
, "MAC tx multicast frames" },
161 { ENETC_PM0_TBCA
, "MAC tx broadcast frames" },
162 { ENETC_PM0_TPKT
, "MAC tx packets" },
163 { ENETC_PM0_TUND
, "MAC tx undersized packets" },
164 { ENETC_PM0_T127
, "MAC tx 65-127 byte packets" },
165 { ENETC_PM0_T1023
, "MAC tx 512-1023 byte packets" },
166 { ENETC_PM0_T1518
, "MAC tx 1024-1518 byte packets" },
167 { ENETC_PM0_TCNP
, "MAC tx control packets" },
168 { ENETC_PM0_TDFR
, "MAC tx deferred packets" },
169 { ENETC_PM0_TMCOL
, "MAC tx multiple collisions" },
170 { ENETC_PM0_TSCOL
, "MAC tx single collisions" },
171 { ENETC_PM0_TLCOL
, "MAC tx late collisions" },
172 { ENETC_PM0_TECOL
, "MAC tx excessive collisions" },
173 { ENETC_UFDMF
, "SI MAC nomatch u-cast discards" },
174 { ENETC_MFDMF
, "SI MAC nomatch m-cast discards" },
175 { ENETC_PBFDSIR
, "SI MAC nomatch b-cast discards" },
176 { ENETC_PUFDVFR
, "SI VLAN nomatch u-cast discards" },
177 { ENETC_PMFDVFR
, "SI VLAN nomatch m-cast discards" },
178 { ENETC_PBFDVFR
, "SI VLAN nomatch b-cast discards" },
179 { ENETC_PFDMSAPR
, "SI pruning discarded frames" },
180 { ENETC_PICDR(0), "ICM DR0 discarded frames" },
181 { ENETC_PICDR(1), "ICM DR1 discarded frames" },
182 { ENETC_PICDR(2), "ICM DR2 discarded frames" },
183 { ENETC_PICDR(3), "ICM DR3 discarded frames" },
186 static const char rx_ring_stats
[][ETH_GSTRING_LEN
] = {
187 "Rx ring %2d frames",
188 "Rx ring %2d alloc errors",
191 static const char tx_ring_stats
[][ETH_GSTRING_LEN
] = {
192 "Tx ring %2d frames",
195 static int enetc_get_sset_count(struct net_device
*ndev
, int sset
)
197 struct enetc_ndev_priv
*priv
= netdev_priv(ndev
);
199 if (sset
== ETH_SS_STATS
)
200 return ARRAY_SIZE(enetc_si_counters
) +
201 ARRAY_SIZE(tx_ring_stats
) * priv
->num_tx_rings
+
202 ARRAY_SIZE(rx_ring_stats
) * priv
->num_rx_rings
+
203 (enetc_si_is_pf(priv
->si
) ?
204 ARRAY_SIZE(enetc_port_counters
) : 0);
209 static void enetc_get_strings(struct net_device
*ndev
, u32 stringset
, u8
*data
)
211 struct enetc_ndev_priv
*priv
= netdev_priv(ndev
);
217 for (i
= 0; i
< ARRAY_SIZE(enetc_si_counters
); i
++) {
218 strlcpy(p
, enetc_si_counters
[i
].name
, ETH_GSTRING_LEN
);
219 p
+= ETH_GSTRING_LEN
;
221 for (i
= 0; i
< priv
->num_tx_rings
; i
++) {
222 for (j
= 0; j
< ARRAY_SIZE(tx_ring_stats
); j
++) {
223 snprintf(p
, ETH_GSTRING_LEN
, tx_ring_stats
[j
],
225 p
+= ETH_GSTRING_LEN
;
228 for (i
= 0; i
< priv
->num_rx_rings
; i
++) {
229 for (j
= 0; j
< ARRAY_SIZE(rx_ring_stats
); j
++) {
230 snprintf(p
, ETH_GSTRING_LEN
, rx_ring_stats
[j
],
232 p
+= ETH_GSTRING_LEN
;
236 if (!enetc_si_is_pf(priv
->si
))
239 for (i
= 0; i
< ARRAY_SIZE(enetc_port_counters
); i
++) {
240 strlcpy(p
, enetc_port_counters
[i
].name
,
242 p
+= ETH_GSTRING_LEN
;
248 static void enetc_get_ethtool_stats(struct net_device
*ndev
,
249 struct ethtool_stats
*stats
, u64
*data
)
251 struct enetc_ndev_priv
*priv
= netdev_priv(ndev
);
252 struct enetc_hw
*hw
= &priv
->si
->hw
;
255 for (i
= 0; i
< ARRAY_SIZE(enetc_si_counters
); i
++)
256 data
[o
++] = enetc_rd64(hw
, enetc_si_counters
[i
].reg
);
258 for (i
= 0; i
< priv
->num_tx_rings
; i
++)
259 data
[o
++] = priv
->tx_ring
[i
]->stats
.packets
;
261 for (i
= 0; i
< priv
->num_rx_rings
; i
++) {
262 data
[o
++] = priv
->rx_ring
[i
]->stats
.packets
;
263 data
[o
++] = priv
->rx_ring
[i
]->stats
.rx_alloc_errs
;
266 if (!enetc_si_is_pf(priv
->si
))
269 for (i
= 0; i
< ARRAY_SIZE(enetc_port_counters
); i
++)
270 data
[o
++] = enetc_port_rd(hw
, enetc_port_counters
[i
].reg
);
273 #define ENETC_RSSHASH_L3 (RXH_L2DA | RXH_VLAN | RXH_L3_PROTO | RXH_IP_SRC | \
275 #define ENETC_RSSHASH_L4 (ENETC_RSSHASH_L3 | RXH_L4_B_0_1 | RXH_L4_B_2_3)
276 static int enetc_get_rsshash(struct ethtool_rxnfc
*rxnfc
)
278 static const u32 rsshash
[] = {
279 [TCP_V4_FLOW
] = ENETC_RSSHASH_L4
,
280 [UDP_V4_FLOW
] = ENETC_RSSHASH_L4
,
281 [SCTP_V4_FLOW
] = ENETC_RSSHASH_L4
,
282 [AH_ESP_V4_FLOW
] = ENETC_RSSHASH_L3
,
283 [IPV4_FLOW
] = ENETC_RSSHASH_L3
,
284 [TCP_V6_FLOW
] = ENETC_RSSHASH_L4
,
285 [UDP_V6_FLOW
] = ENETC_RSSHASH_L4
,
286 [SCTP_V6_FLOW
] = ENETC_RSSHASH_L4
,
287 [AH_ESP_V6_FLOW
] = ENETC_RSSHASH_L3
,
288 [IPV6_FLOW
] = ENETC_RSSHASH_L3
,
292 if (rxnfc
->flow_type
>= ARRAY_SIZE(rsshash
))
295 rxnfc
->data
= rsshash
[rxnfc
->flow_type
];
300 /* current HW spec does byte reversal on everything including MAC addresses */
301 static void ether_addr_copy_swap(u8
*dst
, const u8
*src
)
305 for (i
= 0; i
< ETH_ALEN
; i
++)
306 dst
[i
] = src
[ETH_ALEN
- i
- 1];
309 static int enetc_set_cls_entry(struct enetc_si
*si
,
310 struct ethtool_rx_flow_spec
*fs
, bool en
)
312 struct ethtool_tcpip4_spec
*l4ip4_h
, *l4ip4_m
;
313 struct ethtool_usrip4_spec
*l3ip4_h
, *l3ip4_m
;
314 struct ethhdr
*eth_h
, *eth_m
;
315 struct enetc_cmd_rfse rfse
= { {0} };
320 switch (fs
->flow_type
& 0xff) {
322 l4ip4_h
= &fs
->h_u
.tcp_ip4_spec
;
323 l4ip4_m
= &fs
->m_u
.tcp_ip4_spec
;
326 l4ip4_h
= &fs
->h_u
.udp_ip4_spec
;
327 l4ip4_m
= &fs
->m_u
.udp_ip4_spec
;
330 l4ip4_h
= &fs
->h_u
.sctp_ip4_spec
;
331 l4ip4_m
= &fs
->m_u
.sctp_ip4_spec
;
333 rfse
.sip_h
[0] = l4ip4_h
->ip4src
;
334 rfse
.sip_m
[0] = l4ip4_m
->ip4src
;
335 rfse
.dip_h
[0] = l4ip4_h
->ip4dst
;
336 rfse
.dip_m
[0] = l4ip4_m
->ip4dst
;
337 rfse
.sport_h
= ntohs(l4ip4_h
->psrc
);
338 rfse
.sport_m
= ntohs(l4ip4_m
->psrc
);
339 rfse
.dport_h
= ntohs(l4ip4_h
->pdst
);
340 rfse
.dport_m
= ntohs(l4ip4_m
->pdst
);
342 netdev_warn(si
->ndev
, "ToS field is not supported and was ignored\n");
343 rfse
.ethtype_h
= ETH_P_IP
; /* IPv4 */
344 rfse
.ethtype_m
= 0xffff;
347 l3ip4_h
= &fs
->h_u
.usr_ip4_spec
;
348 l3ip4_m
= &fs
->m_u
.usr_ip4_spec
;
350 rfse
.sip_h
[0] = l3ip4_h
->ip4src
;
351 rfse
.sip_m
[0] = l3ip4_m
->ip4src
;
352 rfse
.dip_h
[0] = l3ip4_h
->ip4dst
;
353 rfse
.dip_m
[0] = l3ip4_m
->ip4dst
;
355 netdev_warn(si
->ndev
, "ToS field is not supported and was ignored\n");
356 rfse
.ethtype_h
= ETH_P_IP
; /* IPv4 */
357 rfse
.ethtype_m
= 0xffff;
360 eth_h
= &fs
->h_u
.ether_spec
;
361 eth_m
= &fs
->m_u
.ether_spec
;
363 ether_addr_copy_swap(rfse
.smac_h
, eth_h
->h_source
);
364 ether_addr_copy_swap(rfse
.smac_m
, eth_m
->h_source
);
365 ether_addr_copy_swap(rfse
.dmac_h
, eth_h
->h_dest
);
366 ether_addr_copy_swap(rfse
.dmac_m
, eth_m
->h_dest
);
367 rfse
.ethtype_h
= ntohs(eth_h
->h_proto
);
368 rfse
.ethtype_m
= ntohs(eth_m
->h_proto
);
374 rfse
.mode
|= ENETC_RFSE_EN
;
375 if (fs
->ring_cookie
!= RX_CLS_FLOW_DISC
) {
376 rfse
.mode
|= ENETC_RFSE_MODE_BD
;
377 rfse
.result
= fs
->ring_cookie
;
380 return enetc_set_fs_entry(si
, &rfse
, fs
->location
);
383 static int enetc_get_rxnfc(struct net_device
*ndev
, struct ethtool_rxnfc
*rxnfc
,
386 struct enetc_ndev_priv
*priv
= netdev_priv(ndev
);
389 switch (rxnfc
->cmd
) {
390 case ETHTOOL_GRXRINGS
:
391 rxnfc
->data
= priv
->num_rx_rings
;
394 /* get RSS hash config */
395 return enetc_get_rsshash(rxnfc
);
396 case ETHTOOL_GRXCLSRLCNT
:
397 /* total number of entries */
398 rxnfc
->data
= priv
->si
->num_fs_entries
;
399 /* number of entries in use */
401 for (i
= 0; i
< priv
->si
->num_fs_entries
; i
++)
402 if (priv
->cls_rules
[i
].used
)
405 case ETHTOOL_GRXCLSRULE
:
406 if (rxnfc
->fs
.location
>= priv
->si
->num_fs_entries
)
410 rxnfc
->fs
= priv
->cls_rules
[rxnfc
->fs
.location
].fs
;
412 case ETHTOOL_GRXCLSRLALL
:
413 /* total number of entries */
414 rxnfc
->data
= priv
->si
->num_fs_entries
;
415 /* array of indexes of used entries */
417 for (i
= 0; i
< priv
->si
->num_fs_entries
; i
++) {
418 if (!priv
->cls_rules
[i
].used
)
420 if (j
== rxnfc
->rule_cnt
)
424 /* number of entries in use */
434 static int enetc_set_rxnfc(struct net_device
*ndev
, struct ethtool_rxnfc
*rxnfc
)
436 struct enetc_ndev_priv
*priv
= netdev_priv(ndev
);
439 switch (rxnfc
->cmd
) {
440 case ETHTOOL_SRXCLSRLINS
:
441 if (rxnfc
->fs
.location
>= priv
->si
->num_fs_entries
)
444 if (rxnfc
->fs
.ring_cookie
>= priv
->num_rx_rings
&&
445 rxnfc
->fs
.ring_cookie
!= RX_CLS_FLOW_DISC
)
448 err
= enetc_set_cls_entry(priv
->si
, &rxnfc
->fs
, true);
451 priv
->cls_rules
[rxnfc
->fs
.location
].fs
= rxnfc
->fs
;
452 priv
->cls_rules
[rxnfc
->fs
.location
].used
= 1;
454 case ETHTOOL_SRXCLSRLDEL
:
455 if (rxnfc
->fs
.location
>= priv
->si
->num_fs_entries
)
458 err
= enetc_set_cls_entry(priv
->si
, &rxnfc
->fs
, false);
461 priv
->cls_rules
[rxnfc
->fs
.location
].used
= 0;
470 static u32
enetc_get_rxfh_key_size(struct net_device
*ndev
)
472 struct enetc_ndev_priv
*priv
= netdev_priv(ndev
);
474 /* return the size of the RX flow hash key. PF only */
475 return (priv
->si
->hw
.port
) ? ENETC_RSSHASH_KEY_SIZE
: 0;
478 static u32
enetc_get_rxfh_indir_size(struct net_device
*ndev
)
480 struct enetc_ndev_priv
*priv
= netdev_priv(ndev
);
482 /* return the size of the RX flow hash indirection table */
483 return priv
->si
->num_rss
;
486 static int enetc_get_rxfh(struct net_device
*ndev
, u32
*indir
, u8
*key
,
489 struct enetc_ndev_priv
*priv
= netdev_priv(ndev
);
490 struct enetc_hw
*hw
= &priv
->si
->hw
;
493 /* return hash function */
495 *hfunc
= ETH_RSS_HASH_TOP
;
497 /* return hash key */
499 for (i
= 0; i
< ENETC_RSSHASH_KEY_SIZE
/ 4; i
++)
500 ((u32
*)key
)[i
] = enetc_port_rd(hw
, ENETC_PRSSK(i
));
502 /* return RSS table */
504 err
= enetc_get_rss_table(priv
->si
, indir
, priv
->si
->num_rss
);
509 void enetc_set_rss_key(struct enetc_hw
*hw
, const u8
*bytes
)
513 for (i
= 0; i
< ENETC_RSSHASH_KEY_SIZE
/ 4; i
++)
514 enetc_port_wr(hw
, ENETC_PRSSK(i
), ((u32
*)bytes
)[i
]);
517 static int enetc_set_rxfh(struct net_device
*ndev
, const u32
*indir
,
518 const u8
*key
, const u8 hfunc
)
520 struct enetc_ndev_priv
*priv
= netdev_priv(ndev
);
521 struct enetc_hw
*hw
= &priv
->si
->hw
;
524 /* set hash key, if PF */
526 enetc_set_rss_key(hw
, key
);
530 err
= enetc_set_rss_table(priv
->si
, indir
, priv
->si
->num_rss
);
535 static void enetc_get_ringparam(struct net_device
*ndev
,
536 struct ethtool_ringparam
*ring
)
538 struct enetc_ndev_priv
*priv
= netdev_priv(ndev
);
540 ring
->rx_pending
= priv
->rx_bd_count
;
541 ring
->tx_pending
= priv
->tx_bd_count
;
543 /* do some h/w sanity checks for BDR length */
544 if (netif_running(ndev
)) {
545 struct enetc_hw
*hw
= &priv
->si
->hw
;
546 u32 val
= enetc_rxbdr_rd(hw
, 0, ENETC_RBLENR
);
548 if (val
!= priv
->rx_bd_count
)
549 netif_err(priv
, hw
, ndev
, "RxBDR[RBLENR] = %d!\n", val
);
551 val
= enetc_txbdr_rd(hw
, 0, ENETC_TBLENR
);
553 if (val
!= priv
->tx_bd_count
)
554 netif_err(priv
, hw
, ndev
, "TxBDR[TBLENR] = %d!\n", val
);
558 static int enetc_get_ts_info(struct net_device
*ndev
,
559 struct ethtool_ts_info
*info
)
563 phc_idx
= symbol_get(enetc_phc_index
);
565 info
->phc_index
= *phc_idx
;
566 symbol_put(enetc_phc_index
);
568 info
->phc_index
= -1;
571 #ifdef CONFIG_FSL_ENETC_HW_TIMESTAMPING
572 info
->so_timestamping
= SOF_TIMESTAMPING_TX_HARDWARE
|
573 SOF_TIMESTAMPING_RX_HARDWARE
|
574 SOF_TIMESTAMPING_RAW_HARDWARE
;
576 info
->tx_types
= (1 << HWTSTAMP_TX_OFF
) |
577 (1 << HWTSTAMP_TX_ON
);
578 info
->rx_filters
= (1 << HWTSTAMP_FILTER_NONE
) |
579 (1 << HWTSTAMP_FILTER_ALL
);
581 info
->so_timestamping
= SOF_TIMESTAMPING_RX_SOFTWARE
|
582 SOF_TIMESTAMPING_SOFTWARE
;
587 static void enetc_get_wol(struct net_device
*dev
,
588 struct ethtool_wolinfo
*wol
)
594 phy_ethtool_get_wol(dev
->phydev
, wol
);
597 static int enetc_set_wol(struct net_device
*dev
,
598 struct ethtool_wolinfo
*wol
)
605 ret
= phy_ethtool_set_wol(dev
->phydev
, wol
);
607 device_set_wakeup_enable(&dev
->dev
, wol
->wolopts
);
612 static const struct ethtool_ops enetc_pf_ethtool_ops
= {
613 .get_regs_len
= enetc_get_reglen
,
614 .get_regs
= enetc_get_regs
,
615 .get_sset_count
= enetc_get_sset_count
,
616 .get_strings
= enetc_get_strings
,
617 .get_ethtool_stats
= enetc_get_ethtool_stats
,
618 .get_rxnfc
= enetc_get_rxnfc
,
619 .set_rxnfc
= enetc_set_rxnfc
,
620 .get_rxfh_key_size
= enetc_get_rxfh_key_size
,
621 .get_rxfh_indir_size
= enetc_get_rxfh_indir_size
,
622 .get_rxfh
= enetc_get_rxfh
,
623 .set_rxfh
= enetc_set_rxfh
,
624 .get_ringparam
= enetc_get_ringparam
,
625 .get_link_ksettings
= phy_ethtool_get_link_ksettings
,
626 .set_link_ksettings
= phy_ethtool_set_link_ksettings
,
627 .get_link
= ethtool_op_get_link
,
628 .get_ts_info
= enetc_get_ts_info
,
629 .get_wol
= enetc_get_wol
,
630 .set_wol
= enetc_set_wol
,
633 static const struct ethtool_ops enetc_vf_ethtool_ops
= {
634 .get_regs_len
= enetc_get_reglen
,
635 .get_regs
= enetc_get_regs
,
636 .get_sset_count
= enetc_get_sset_count
,
637 .get_strings
= enetc_get_strings
,
638 .get_ethtool_stats
= enetc_get_ethtool_stats
,
639 .get_rxnfc
= enetc_get_rxnfc
,
640 .set_rxnfc
= enetc_set_rxnfc
,
641 .get_rxfh_indir_size
= enetc_get_rxfh_indir_size
,
642 .get_rxfh
= enetc_get_rxfh
,
643 .set_rxfh
= enetc_set_rxfh
,
644 .get_ringparam
= enetc_get_ringparam
,
645 .get_link
= ethtool_op_get_link
,
646 .get_ts_info
= enetc_get_ts_info
,
649 void enetc_set_ethtool_ops(struct net_device
*ndev
)
651 struct enetc_ndev_priv
*priv
= netdev_priv(ndev
);
653 if (enetc_si_is_pf(priv
->si
))
654 ndev
->ethtool_ops
= &enetc_pf_ethtool_ops
;
656 ndev
->ethtool_ops
= &enetc_vf_ethtool_ops
;