1
2
3
4
5
6
7
8#include <linux/netdevice.h>
9#include <linux/ethtool.h>
10#include <linux/rtnetlink.h>
11#include <linux/in.h>
12#include "net_driver.h"
13#include "workarounds.h"
14#include "selftest.h"
15#include "efx.h"
16#include "efx_channels.h"
17#include "rx_common.h"
18#include "tx_common.h"
19#include "ethtool_common.h"
20#include "filter.h"
21#include "nic.h"
22
23#define EFX_ETHTOOL_EEPROM_MAGIC 0xEFAB
24
25
26
27
28
29
30
31
32
33static int efx_ethtool_phys_id(struct net_device *net_dev,
34 enum ethtool_phys_id_state state)
35{
36 struct efx_nic *efx = netdev_priv(net_dev);
37 enum efx_led_mode mode = EFX_LED_DEFAULT;
38
39 switch (state) {
40 case ETHTOOL_ID_ON:
41 mode = EFX_LED_ON;
42 break;
43 case ETHTOOL_ID_OFF:
44 mode = EFX_LED_OFF;
45 break;
46 case ETHTOOL_ID_INACTIVE:
47 mode = EFX_LED_DEFAULT;
48 break;
49 case ETHTOOL_ID_ACTIVE:
50 return 1;
51 }
52
53 efx->type->set_id_led(efx, mode);
54 return 0;
55}
56
57
58static int
59efx_ethtool_get_link_ksettings(struct net_device *net_dev,
60 struct ethtool_link_ksettings *cmd)
61{
62 struct efx_nic *efx = netdev_priv(net_dev);
63 struct efx_link_state *link_state = &efx->link_state;
64 u32 supported;
65
66 mutex_lock(&efx->mac_lock);
67 efx->phy_op->get_link_ksettings(efx, cmd);
68 mutex_unlock(&efx->mac_lock);
69
70
71 ethtool_convert_link_mode_to_legacy_u32(&supported,
72 cmd->link_modes.supported);
73
74 supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
75
76 ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported,
77 supported);
78
79 if (LOOPBACK_INTERNAL(efx)) {
80 cmd->base.speed = link_state->speed;
81 cmd->base.duplex = link_state->fd ? DUPLEX_FULL : DUPLEX_HALF;
82 }
83
84 return 0;
85}
86
87
88static int
89efx_ethtool_set_link_ksettings(struct net_device *net_dev,
90 const struct ethtool_link_ksettings *cmd)
91{
92 struct efx_nic *efx = netdev_priv(net_dev);
93 int rc;
94
95
96 if ((cmd->base.speed == SPEED_1000) &&
97 (cmd->base.duplex != DUPLEX_FULL)) {
98 netif_dbg(efx, drv, efx->net_dev,
99 "rejecting unsupported 1000Mbps HD setting\n");
100 return -EINVAL;
101 }
102
103 mutex_lock(&efx->mac_lock);
104 rc = efx->phy_op->set_link_ksettings(efx, cmd);
105 mutex_unlock(&efx->mac_lock);
106 return rc;
107}
108
109static int efx_ethtool_get_regs_len(struct net_device *net_dev)
110{
111 return efx_nic_get_regs_len(netdev_priv(net_dev));
112}
113
114static void efx_ethtool_get_regs(struct net_device *net_dev,
115 struct ethtool_regs *regs, void *buf)
116{
117 struct efx_nic *efx = netdev_priv(net_dev);
118
119 regs->version = efx->type->revision;
120 efx_nic_get_regs(efx, buf);
121}
122
123static void efx_ethtool_self_test(struct net_device *net_dev,
124 struct ethtool_test *test, u64 *data)
125{
126 struct efx_nic *efx = netdev_priv(net_dev);
127 struct efx_self_tests *efx_tests;
128 bool already_up;
129 int rc = -ENOMEM;
130
131 efx_tests = kzalloc(sizeof(*efx_tests), GFP_KERNEL);
132 if (!efx_tests)
133 goto fail;
134
135 if (efx->state != STATE_READY) {
136 rc = -EBUSY;
137 goto out;
138 }
139
140 netif_info(efx, drv, efx->net_dev, "starting %sline testing\n",
141 (test->flags & ETH_TEST_FL_OFFLINE) ? "off" : "on");
142
143
144 already_up = (efx->net_dev->flags & IFF_UP);
145 if (!already_up) {
146 rc = dev_open(efx->net_dev, NULL);
147 if (rc) {
148 netif_err(efx, drv, efx->net_dev,
149 "failed opening device.\n");
150 goto out;
151 }
152 }
153
154 rc = efx_selftest(efx, efx_tests, test->flags);
155
156 if (!already_up)
157 dev_close(efx->net_dev);
158
159 netif_info(efx, drv, efx->net_dev, "%s %sline self-tests\n",
160 rc == 0 ? "passed" : "failed",
161 (test->flags & ETH_TEST_FL_OFFLINE) ? "off" : "on");
162
163out:
164 efx_ethtool_fill_self_tests(efx, efx_tests, NULL, data);
165 kfree(efx_tests);
166fail:
167 if (rc)
168 test->flags |= ETH_TEST_FL_FAILED;
169}
170
171
172static int efx_ethtool_nway_reset(struct net_device *net_dev)
173{
174 struct efx_nic *efx = netdev_priv(net_dev);
175
176 return mdio45_nway_restart(&efx->mdio);
177}
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208static int efx_ethtool_get_coalesce(struct net_device *net_dev,
209 struct ethtool_coalesce *coalesce)
210{
211 struct efx_nic *efx = netdev_priv(net_dev);
212 unsigned int tx_usecs, rx_usecs;
213 bool rx_adaptive;
214
215 efx_get_irq_moderation(efx, &tx_usecs, &rx_usecs, &rx_adaptive);
216
217 coalesce->tx_coalesce_usecs = tx_usecs;
218 coalesce->tx_coalesce_usecs_irq = tx_usecs;
219 coalesce->rx_coalesce_usecs = rx_usecs;
220 coalesce->rx_coalesce_usecs_irq = rx_usecs;
221 coalesce->use_adaptive_rx_coalesce = rx_adaptive;
222
223 return 0;
224}
225
226static int efx_ethtool_set_coalesce(struct net_device *net_dev,
227 struct ethtool_coalesce *coalesce)
228{
229 struct efx_nic *efx = netdev_priv(net_dev);
230 struct efx_channel *channel;
231 unsigned int tx_usecs, rx_usecs;
232 bool adaptive, rx_may_override_tx;
233 int rc;
234
235 efx_get_irq_moderation(efx, &tx_usecs, &rx_usecs, &adaptive);
236
237 if (coalesce->rx_coalesce_usecs != rx_usecs)
238 rx_usecs = coalesce->rx_coalesce_usecs;
239 else
240 rx_usecs = coalesce->rx_coalesce_usecs_irq;
241
242 adaptive = coalesce->use_adaptive_rx_coalesce;
243
244
245
246
247 rx_may_override_tx = (coalesce->tx_coalesce_usecs == tx_usecs &&
248 coalesce->tx_coalesce_usecs_irq == tx_usecs);
249 if (coalesce->tx_coalesce_usecs != tx_usecs)
250 tx_usecs = coalesce->tx_coalesce_usecs;
251 else
252 tx_usecs = coalesce->tx_coalesce_usecs_irq;
253
254 rc = efx_init_irq_moderation(efx, tx_usecs, rx_usecs, adaptive,
255 rx_may_override_tx);
256 if (rc != 0)
257 return rc;
258
259 efx_for_each_channel(channel, efx)
260 efx->type->push_irq_moderation(channel);
261
262 return 0;
263}
264
265static void efx_ethtool_get_ringparam(struct net_device *net_dev,
266 struct ethtool_ringparam *ring)
267{
268 struct efx_nic *efx = netdev_priv(net_dev);
269
270 ring->rx_max_pending = EFX_MAX_DMAQ_SIZE;
271 ring->tx_max_pending = EFX_TXQ_MAX_ENT(efx);
272 ring->rx_pending = efx->rxq_entries;
273 ring->tx_pending = efx->txq_entries;
274}
275
276static int efx_ethtool_set_ringparam(struct net_device *net_dev,
277 struct ethtool_ringparam *ring)
278{
279 struct efx_nic *efx = netdev_priv(net_dev);
280 u32 txq_entries;
281
282 if (ring->rx_mini_pending || ring->rx_jumbo_pending ||
283 ring->rx_pending > EFX_MAX_DMAQ_SIZE ||
284 ring->tx_pending > EFX_TXQ_MAX_ENT(efx))
285 return -EINVAL;
286
287 if (ring->rx_pending < EFX_RXQ_MIN_ENT) {
288 netif_err(efx, drv, efx->net_dev,
289 "RX queues cannot be smaller than %u\n",
290 EFX_RXQ_MIN_ENT);
291 return -EINVAL;
292 }
293
294 txq_entries = max(ring->tx_pending, EFX_TXQ_MIN_ENT(efx));
295 if (txq_entries != ring->tx_pending)
296 netif_warn(efx, drv, efx->net_dev,
297 "increasing TX queue size to minimum of %u\n",
298 txq_entries);
299
300 return efx_realloc_channels(efx, ring->rx_pending, txq_entries);
301}
302
303static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
304 struct ethtool_pauseparam *pause)
305{
306 struct efx_nic *efx = netdev_priv(net_dev);
307 u8 wanted_fc, old_fc;
308 u32 old_adv;
309 int rc = 0;
310
311 mutex_lock(&efx->mac_lock);
312
313 wanted_fc = ((pause->rx_pause ? EFX_FC_RX : 0) |
314 (pause->tx_pause ? EFX_FC_TX : 0) |
315 (pause->autoneg ? EFX_FC_AUTO : 0));
316
317 if ((wanted_fc & EFX_FC_TX) && !(wanted_fc & EFX_FC_RX)) {
318 netif_dbg(efx, drv, efx->net_dev,
319 "Flow control unsupported: tx ON rx OFF\n");
320 rc = -EINVAL;
321 goto out;
322 }
323
324 if ((wanted_fc & EFX_FC_AUTO) && !efx->link_advertising[0]) {
325 netif_dbg(efx, drv, efx->net_dev,
326 "Autonegotiation is disabled\n");
327 rc = -EINVAL;
328 goto out;
329 }
330
331
332 if (efx->type->prepare_enable_fc_tx &&
333 (wanted_fc & EFX_FC_TX) && !(efx->wanted_fc & EFX_FC_TX))
334 efx->type->prepare_enable_fc_tx(efx);
335
336 old_adv = efx->link_advertising[0];
337 old_fc = efx->wanted_fc;
338 efx_link_set_wanted_fc(efx, wanted_fc);
339 if (efx->link_advertising[0] != old_adv ||
340 (efx->wanted_fc ^ old_fc) & EFX_FC_AUTO) {
341 rc = efx->phy_op->reconfigure(efx);
342 if (rc) {
343 netif_err(efx, drv, efx->net_dev,
344 "Unable to advertise requested flow "
345 "control setting\n");
346 goto out;
347 }
348 }
349
350
351
352
353 efx_mac_reconfigure(efx);
354
355out:
356 mutex_unlock(&efx->mac_lock);
357
358 return rc;
359}
360
361static void efx_ethtool_get_wol(struct net_device *net_dev,
362 struct ethtool_wolinfo *wol)
363{
364 struct efx_nic *efx = netdev_priv(net_dev);
365 return efx->type->get_wol(efx, wol);
366}
367
368
369static int efx_ethtool_set_wol(struct net_device *net_dev,
370 struct ethtool_wolinfo *wol)
371{
372 struct efx_nic *efx = netdev_priv(net_dev);
373 return efx->type->set_wol(efx, wol->wolopts);
374}
375
376static int efx_ethtool_reset(struct net_device *net_dev, u32 *flags)
377{
378 struct efx_nic *efx = netdev_priv(net_dev);
379 int rc;
380
381 rc = efx->type->map_reset_flags(flags);
382 if (rc < 0)
383 return rc;
384
385 return efx_reset(efx, rc);
386}
387
388
389static const u8 mac_addr_ig_mask[ETH_ALEN] __aligned(2) = {0x01, 0, 0, 0, 0, 0};
390
391#define IP4_ADDR_FULL_MASK ((__force __be32)~0)
392#define IP_PROTO_FULL_MASK 0xFF
393#define PORT_FULL_MASK ((__force __be16)~0)
394#define ETHER_TYPE_FULL_MASK ((__force __be16)~0)
395
396static inline void ip6_fill_mask(__be32 *mask)
397{
398 mask[0] = mask[1] = mask[2] = mask[3] = ~(__be32)0;
399}
400
401static int efx_ethtool_get_class_rule(struct efx_nic *efx,
402 struct ethtool_rx_flow_spec *rule,
403 u32 *rss_context)
404{
405 struct ethtool_tcpip4_spec *ip_entry = &rule->h_u.tcp_ip4_spec;
406 struct ethtool_tcpip4_spec *ip_mask = &rule->m_u.tcp_ip4_spec;
407 struct ethtool_usrip4_spec *uip_entry = &rule->h_u.usr_ip4_spec;
408 struct ethtool_usrip4_spec *uip_mask = &rule->m_u.usr_ip4_spec;
409 struct ethtool_tcpip6_spec *ip6_entry = &rule->h_u.tcp_ip6_spec;
410 struct ethtool_tcpip6_spec *ip6_mask = &rule->m_u.tcp_ip6_spec;
411 struct ethtool_usrip6_spec *uip6_entry = &rule->h_u.usr_ip6_spec;
412 struct ethtool_usrip6_spec *uip6_mask = &rule->m_u.usr_ip6_spec;
413 struct ethhdr *mac_entry = &rule->h_u.ether_spec;
414 struct ethhdr *mac_mask = &rule->m_u.ether_spec;
415 struct efx_filter_spec spec;
416 int rc;
417
418 rc = efx_filter_get_filter_safe(efx, EFX_FILTER_PRI_MANUAL,
419 rule->location, &spec);
420 if (rc)
421 return rc;
422
423 if (spec.dmaq_id == EFX_FILTER_RX_DMAQ_ID_DROP)
424 rule->ring_cookie = RX_CLS_FLOW_DISC;
425 else
426 rule->ring_cookie = spec.dmaq_id;
427
428 if ((spec.match_flags & EFX_FILTER_MATCH_ETHER_TYPE) &&
429 spec.ether_type == htons(ETH_P_IP) &&
430 (spec.match_flags & EFX_FILTER_MATCH_IP_PROTO) &&
431 (spec.ip_proto == IPPROTO_TCP || spec.ip_proto == IPPROTO_UDP) &&
432 !(spec.match_flags &
433 ~(EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_OUTER_VID |
434 EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_REM_HOST |
435 EFX_FILTER_MATCH_IP_PROTO |
436 EFX_FILTER_MATCH_LOC_PORT | EFX_FILTER_MATCH_REM_PORT))) {
437 rule->flow_type = ((spec.ip_proto == IPPROTO_TCP) ?
438 TCP_V4_FLOW : UDP_V4_FLOW);
439 if (spec.match_flags & EFX_FILTER_MATCH_LOC_HOST) {
440 ip_entry->ip4dst = spec.loc_host[0];
441 ip_mask->ip4dst = IP4_ADDR_FULL_MASK;
442 }
443 if (spec.match_flags & EFX_FILTER_MATCH_REM_HOST) {
444 ip_entry->ip4src = spec.rem_host[0];
445 ip_mask->ip4src = IP4_ADDR_FULL_MASK;
446 }
447 if (spec.match_flags & EFX_FILTER_MATCH_LOC_PORT) {
448 ip_entry->pdst = spec.loc_port;
449 ip_mask->pdst = PORT_FULL_MASK;
450 }
451 if (spec.match_flags & EFX_FILTER_MATCH_REM_PORT) {
452 ip_entry->psrc = spec.rem_port;
453 ip_mask->psrc = PORT_FULL_MASK;
454 }
455 } else if ((spec.match_flags & EFX_FILTER_MATCH_ETHER_TYPE) &&
456 spec.ether_type == htons(ETH_P_IPV6) &&
457 (spec.match_flags & EFX_FILTER_MATCH_IP_PROTO) &&
458 (spec.ip_proto == IPPROTO_TCP || spec.ip_proto == IPPROTO_UDP) &&
459 !(spec.match_flags &
460 ~(EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_OUTER_VID |
461 EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_REM_HOST |
462 EFX_FILTER_MATCH_IP_PROTO |
463 EFX_FILTER_MATCH_LOC_PORT | EFX_FILTER_MATCH_REM_PORT))) {
464 rule->flow_type = ((spec.ip_proto == IPPROTO_TCP) ?
465 TCP_V6_FLOW : UDP_V6_FLOW);
466 if (spec.match_flags & EFX_FILTER_MATCH_LOC_HOST) {
467 memcpy(ip6_entry->ip6dst, spec.loc_host,
468 sizeof(ip6_entry->ip6dst));
469 ip6_fill_mask(ip6_mask->ip6dst);
470 }
471 if (spec.match_flags & EFX_FILTER_MATCH_REM_HOST) {
472 memcpy(ip6_entry->ip6src, spec.rem_host,
473 sizeof(ip6_entry->ip6src));
474 ip6_fill_mask(ip6_mask->ip6src);
475 }
476 if (spec.match_flags & EFX_FILTER_MATCH_LOC_PORT) {
477 ip6_entry->pdst = spec.loc_port;
478 ip6_mask->pdst = PORT_FULL_MASK;
479 }
480 if (spec.match_flags & EFX_FILTER_MATCH_REM_PORT) {
481 ip6_entry->psrc = spec.rem_port;
482 ip6_mask->psrc = PORT_FULL_MASK;
483 }
484 } else if (!(spec.match_flags &
485 ~(EFX_FILTER_MATCH_LOC_MAC | EFX_FILTER_MATCH_LOC_MAC_IG |
486 EFX_FILTER_MATCH_REM_MAC | EFX_FILTER_MATCH_ETHER_TYPE |
487 EFX_FILTER_MATCH_OUTER_VID))) {
488 rule->flow_type = ETHER_FLOW;
489 if (spec.match_flags &
490 (EFX_FILTER_MATCH_LOC_MAC | EFX_FILTER_MATCH_LOC_MAC_IG)) {
491 ether_addr_copy(mac_entry->h_dest, spec.loc_mac);
492 if (spec.match_flags & EFX_FILTER_MATCH_LOC_MAC)
493 eth_broadcast_addr(mac_mask->h_dest);
494 else
495 ether_addr_copy(mac_mask->h_dest,
496 mac_addr_ig_mask);
497 }
498 if (spec.match_flags & EFX_FILTER_MATCH_REM_MAC) {
499 ether_addr_copy(mac_entry->h_source, spec.rem_mac);
500 eth_broadcast_addr(mac_mask->h_source);
501 }
502 if (spec.match_flags & EFX_FILTER_MATCH_ETHER_TYPE) {
503 mac_entry->h_proto = spec.ether_type;
504 mac_mask->h_proto = ETHER_TYPE_FULL_MASK;
505 }
506 } else if (spec.match_flags & EFX_FILTER_MATCH_ETHER_TYPE &&
507 spec.ether_type == htons(ETH_P_IP) &&
508 !(spec.match_flags &
509 ~(EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_OUTER_VID |
510 EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_REM_HOST |
511 EFX_FILTER_MATCH_IP_PROTO))) {
512 rule->flow_type = IPV4_USER_FLOW;
513 uip_entry->ip_ver = ETH_RX_NFC_IP4;
514 if (spec.match_flags & EFX_FILTER_MATCH_IP_PROTO) {
515 uip_mask->proto = IP_PROTO_FULL_MASK;
516 uip_entry->proto = spec.ip_proto;
517 }
518 if (spec.match_flags & EFX_FILTER_MATCH_LOC_HOST) {
519 uip_entry->ip4dst = spec.loc_host[0];
520 uip_mask->ip4dst = IP4_ADDR_FULL_MASK;
521 }
522 if (spec.match_flags & EFX_FILTER_MATCH_REM_HOST) {
523 uip_entry->ip4src = spec.rem_host[0];
524 uip_mask->ip4src = IP4_ADDR_FULL_MASK;
525 }
526 } else if (spec.match_flags & EFX_FILTER_MATCH_ETHER_TYPE &&
527 spec.ether_type == htons(ETH_P_IPV6) &&
528 !(spec.match_flags &
529 ~(EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_OUTER_VID |
530 EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_REM_HOST |
531 EFX_FILTER_MATCH_IP_PROTO))) {
532 rule->flow_type = IPV6_USER_FLOW;
533 if (spec.match_flags & EFX_FILTER_MATCH_IP_PROTO) {
534 uip6_mask->l4_proto = IP_PROTO_FULL_MASK;
535 uip6_entry->l4_proto = spec.ip_proto;
536 }
537 if (spec.match_flags & EFX_FILTER_MATCH_LOC_HOST) {
538 memcpy(uip6_entry->ip6dst, spec.loc_host,
539 sizeof(uip6_entry->ip6dst));
540 ip6_fill_mask(uip6_mask->ip6dst);
541 }
542 if (spec.match_flags & EFX_FILTER_MATCH_REM_HOST) {
543 memcpy(uip6_entry->ip6src, spec.rem_host,
544 sizeof(uip6_entry->ip6src));
545 ip6_fill_mask(uip6_mask->ip6src);
546 }
547 } else {
548
549 WARN_ON(1);
550 return -EINVAL;
551 }
552
553 if (spec.match_flags & EFX_FILTER_MATCH_OUTER_VID) {
554 rule->flow_type |= FLOW_EXT;
555 rule->h_ext.vlan_tci = spec.outer_vid;
556 rule->m_ext.vlan_tci = htons(0xfff);
557 }
558
559 if (spec.flags & EFX_FILTER_FLAG_RX_RSS) {
560 rule->flow_type |= FLOW_RSS;
561 *rss_context = spec.rss_context;
562 }
563
564 return rc;
565}
566
567static int
568efx_ethtool_get_rxnfc(struct net_device *net_dev,
569 struct ethtool_rxnfc *info, u32 *rule_locs)
570{
571 struct efx_nic *efx = netdev_priv(net_dev);
572 u32 rss_context = 0;
573 s32 rc = 0;
574
575 switch (info->cmd) {
576 case ETHTOOL_GRXRINGS:
577 info->data = efx->n_rx_channels;
578 return 0;
579
580 case ETHTOOL_GRXFH: {
581 struct efx_rss_context *ctx = &efx->rss_context;
582 __u64 data;
583
584 mutex_lock(&efx->rss_lock);
585 if (info->flow_type & FLOW_RSS && info->rss_context) {
586 ctx = efx_find_rss_context_entry(efx, info->rss_context);
587 if (!ctx) {
588 rc = -ENOENT;
589 goto out_unlock;
590 }
591 }
592
593 data = 0;
594 if (!efx_rss_active(ctx))
595 goto out_setdata_unlock;
596
597 switch (info->flow_type & ~FLOW_RSS) {
598 case UDP_V4_FLOW:
599 case UDP_V6_FLOW:
600 if (ctx->rx_hash_udp_4tuple)
601 data = (RXH_L4_B_0_1 | RXH_L4_B_2_3 |
602 RXH_IP_SRC | RXH_IP_DST);
603 else
604 data = RXH_IP_SRC | RXH_IP_DST;
605 break;
606 case TCP_V4_FLOW:
607 case TCP_V6_FLOW:
608 data = (RXH_L4_B_0_1 | RXH_L4_B_2_3 |
609 RXH_IP_SRC | RXH_IP_DST);
610 break;
611 case SCTP_V4_FLOW:
612 case SCTP_V6_FLOW:
613 case AH_ESP_V4_FLOW:
614 case AH_ESP_V6_FLOW:
615 case IPV4_FLOW:
616 case IPV6_FLOW:
617 data = RXH_IP_SRC | RXH_IP_DST;
618 break;
619 default:
620 break;
621 }
622out_setdata_unlock:
623 info->data = data;
624out_unlock:
625 mutex_unlock(&efx->rss_lock);
626 return rc;
627 }
628
629 case ETHTOOL_GRXCLSRLCNT:
630 info->data = efx_filter_get_rx_id_limit(efx);
631 if (info->data == 0)
632 return -EOPNOTSUPP;
633 info->data |= RX_CLS_LOC_SPECIAL;
634 info->rule_cnt =
635 efx_filter_count_rx_used(efx, EFX_FILTER_PRI_MANUAL);
636 return 0;
637
638 case ETHTOOL_GRXCLSRULE:
639 if (efx_filter_get_rx_id_limit(efx) == 0)
640 return -EOPNOTSUPP;
641 rc = efx_ethtool_get_class_rule(efx, &info->fs, &rss_context);
642 if (rc < 0)
643 return rc;
644 if (info->fs.flow_type & FLOW_RSS)
645 info->rss_context = rss_context;
646 return 0;
647
648 case ETHTOOL_GRXCLSRLALL:
649 info->data = efx_filter_get_rx_id_limit(efx);
650 if (info->data == 0)
651 return -EOPNOTSUPP;
652 rc = efx_filter_get_rx_ids(efx, EFX_FILTER_PRI_MANUAL,
653 rule_locs, info->rule_cnt);
654 if (rc < 0)
655 return rc;
656 info->rule_cnt = rc;
657 return 0;
658
659 default:
660 return -EOPNOTSUPP;
661 }
662}
663
664static inline bool ip6_mask_is_full(__be32 mask[4])
665{
666 return !~(mask[0] & mask[1] & mask[2] & mask[3]);
667}
668
669static inline bool ip6_mask_is_empty(__be32 mask[4])
670{
671 return !(mask[0] | mask[1] | mask[2] | mask[3]);
672}
673
674static int efx_ethtool_set_class_rule(struct efx_nic *efx,
675 struct ethtool_rx_flow_spec *rule,
676 u32 rss_context)
677{
678 struct ethtool_tcpip4_spec *ip_entry = &rule->h_u.tcp_ip4_spec;
679 struct ethtool_tcpip4_spec *ip_mask = &rule->m_u.tcp_ip4_spec;
680 struct ethtool_usrip4_spec *uip_entry = &rule->h_u.usr_ip4_spec;
681 struct ethtool_usrip4_spec *uip_mask = &rule->m_u.usr_ip4_spec;
682 struct ethtool_tcpip6_spec *ip6_entry = &rule->h_u.tcp_ip6_spec;
683 struct ethtool_tcpip6_spec *ip6_mask = &rule->m_u.tcp_ip6_spec;
684 struct ethtool_usrip6_spec *uip6_entry = &rule->h_u.usr_ip6_spec;
685 struct ethtool_usrip6_spec *uip6_mask = &rule->m_u.usr_ip6_spec;
686 u32 flow_type = rule->flow_type & ~(FLOW_EXT | FLOW_RSS);
687 struct ethhdr *mac_entry = &rule->h_u.ether_spec;
688 struct ethhdr *mac_mask = &rule->m_u.ether_spec;
689 enum efx_filter_flags flags = 0;
690 struct efx_filter_spec spec;
691 int rc;
692
693
694 if (rule->location != RX_CLS_LOC_ANY)
695 return -EINVAL;
696
697
698 if (rule->ring_cookie >= efx->n_rx_channels &&
699 rule->ring_cookie != RX_CLS_FLOW_DISC)
700 return -EINVAL;
701
702
703 if ((rule->flow_type & FLOW_EXT) &&
704 (rule->m_ext.vlan_etype || rule->m_ext.data[0] ||
705 rule->m_ext.data[1]))
706 return -EINVAL;
707
708 if (efx->rx_scatter)
709 flags |= EFX_FILTER_FLAG_RX_SCATTER;
710 if (rule->flow_type & FLOW_RSS)
711 flags |= EFX_FILTER_FLAG_RX_RSS;
712
713 efx_filter_init_rx(&spec, EFX_FILTER_PRI_MANUAL, flags,
714 (rule->ring_cookie == RX_CLS_FLOW_DISC) ?
715 EFX_FILTER_RX_DMAQ_ID_DROP : rule->ring_cookie);
716
717 if (rule->flow_type & FLOW_RSS)
718 spec.rss_context = rss_context;
719
720 switch (flow_type) {
721 case TCP_V4_FLOW:
722 case UDP_V4_FLOW:
723 spec.match_flags = (EFX_FILTER_MATCH_ETHER_TYPE |
724 EFX_FILTER_MATCH_IP_PROTO);
725 spec.ether_type = htons(ETH_P_IP);
726 spec.ip_proto = flow_type == TCP_V4_FLOW ? IPPROTO_TCP
727 : IPPROTO_UDP;
728 if (ip_mask->ip4dst) {
729 if (ip_mask->ip4dst != IP4_ADDR_FULL_MASK)
730 return -EINVAL;
731 spec.match_flags |= EFX_FILTER_MATCH_LOC_HOST;
732 spec.loc_host[0] = ip_entry->ip4dst;
733 }
734 if (ip_mask->ip4src) {
735 if (ip_mask->ip4src != IP4_ADDR_FULL_MASK)
736 return -EINVAL;
737 spec.match_flags |= EFX_FILTER_MATCH_REM_HOST;
738 spec.rem_host[0] = ip_entry->ip4src;
739 }
740 if (ip_mask->pdst) {
741 if (ip_mask->pdst != PORT_FULL_MASK)
742 return -EINVAL;
743 spec.match_flags |= EFX_FILTER_MATCH_LOC_PORT;
744 spec.loc_port = ip_entry->pdst;
745 }
746 if (ip_mask->psrc) {
747 if (ip_mask->psrc != PORT_FULL_MASK)
748 return -EINVAL;
749 spec.match_flags |= EFX_FILTER_MATCH_REM_PORT;
750 spec.rem_port = ip_entry->psrc;
751 }
752 if (ip_mask->tos)
753 return -EINVAL;
754 break;
755
756 case TCP_V6_FLOW:
757 case UDP_V6_FLOW:
758 spec.match_flags = (EFX_FILTER_MATCH_ETHER_TYPE |
759 EFX_FILTER_MATCH_IP_PROTO);
760 spec.ether_type = htons(ETH_P_IPV6);
761 spec.ip_proto = flow_type == TCP_V6_FLOW ? IPPROTO_TCP
762 : IPPROTO_UDP;
763 if (!ip6_mask_is_empty(ip6_mask->ip6dst)) {
764 if (!ip6_mask_is_full(ip6_mask->ip6dst))
765 return -EINVAL;
766 spec.match_flags |= EFX_FILTER_MATCH_LOC_HOST;
767 memcpy(spec.loc_host, ip6_entry->ip6dst, sizeof(spec.loc_host));
768 }
769 if (!ip6_mask_is_empty(ip6_mask->ip6src)) {
770 if (!ip6_mask_is_full(ip6_mask->ip6src))
771 return -EINVAL;
772 spec.match_flags |= EFX_FILTER_MATCH_REM_HOST;
773 memcpy(spec.rem_host, ip6_entry->ip6src, sizeof(spec.rem_host));
774 }
775 if (ip6_mask->pdst) {
776 if (ip6_mask->pdst != PORT_FULL_MASK)
777 return -EINVAL;
778 spec.match_flags |= EFX_FILTER_MATCH_LOC_PORT;
779 spec.loc_port = ip6_entry->pdst;
780 }
781 if (ip6_mask->psrc) {
782 if (ip6_mask->psrc != PORT_FULL_MASK)
783 return -EINVAL;
784 spec.match_flags |= EFX_FILTER_MATCH_REM_PORT;
785 spec.rem_port = ip6_entry->psrc;
786 }
787 if (ip6_mask->tclass)
788 return -EINVAL;
789 break;
790
791 case IPV4_USER_FLOW:
792 if (uip_mask->l4_4_bytes || uip_mask->tos || uip_mask->ip_ver ||
793 uip_entry->ip_ver != ETH_RX_NFC_IP4)
794 return -EINVAL;
795 spec.match_flags = EFX_FILTER_MATCH_ETHER_TYPE;
796 spec.ether_type = htons(ETH_P_IP);
797 if (uip_mask->ip4dst) {
798 if (uip_mask->ip4dst != IP4_ADDR_FULL_MASK)
799 return -EINVAL;
800 spec.match_flags |= EFX_FILTER_MATCH_LOC_HOST;
801 spec.loc_host[0] = uip_entry->ip4dst;
802 }
803 if (uip_mask->ip4src) {
804 if (uip_mask->ip4src != IP4_ADDR_FULL_MASK)
805 return -EINVAL;
806 spec.match_flags |= EFX_FILTER_MATCH_REM_HOST;
807 spec.rem_host[0] = uip_entry->ip4src;
808 }
809 if (uip_mask->proto) {
810 if (uip_mask->proto != IP_PROTO_FULL_MASK)
811 return -EINVAL;
812 spec.match_flags |= EFX_FILTER_MATCH_IP_PROTO;
813 spec.ip_proto = uip_entry->proto;
814 }
815 break;
816
817 case IPV6_USER_FLOW:
818 if (uip6_mask->l4_4_bytes || uip6_mask->tclass)
819 return -EINVAL;
820 spec.match_flags = EFX_FILTER_MATCH_ETHER_TYPE;
821 spec.ether_type = htons(ETH_P_IPV6);
822 if (!ip6_mask_is_empty(uip6_mask->ip6dst)) {
823 if (!ip6_mask_is_full(uip6_mask->ip6dst))
824 return -EINVAL;
825 spec.match_flags |= EFX_FILTER_MATCH_LOC_HOST;
826 memcpy(spec.loc_host, uip6_entry->ip6dst, sizeof(spec.loc_host));
827 }
828 if (!ip6_mask_is_empty(uip6_mask->ip6src)) {
829 if (!ip6_mask_is_full(uip6_mask->ip6src))
830 return -EINVAL;
831 spec.match_flags |= EFX_FILTER_MATCH_REM_HOST;
832 memcpy(spec.rem_host, uip6_entry->ip6src, sizeof(spec.rem_host));
833 }
834 if (uip6_mask->l4_proto) {
835 if (uip6_mask->l4_proto != IP_PROTO_FULL_MASK)
836 return -EINVAL;
837 spec.match_flags |= EFX_FILTER_MATCH_IP_PROTO;
838 spec.ip_proto = uip6_entry->l4_proto;
839 }
840 break;
841
842 case ETHER_FLOW:
843 if (!is_zero_ether_addr(mac_mask->h_dest)) {
844 if (ether_addr_equal(mac_mask->h_dest,
845 mac_addr_ig_mask))
846 spec.match_flags |= EFX_FILTER_MATCH_LOC_MAC_IG;
847 else if (is_broadcast_ether_addr(mac_mask->h_dest))
848 spec.match_flags |= EFX_FILTER_MATCH_LOC_MAC;
849 else
850 return -EINVAL;
851 ether_addr_copy(spec.loc_mac, mac_entry->h_dest);
852 }
853 if (!is_zero_ether_addr(mac_mask->h_source)) {
854 if (!is_broadcast_ether_addr(mac_mask->h_source))
855 return -EINVAL;
856 spec.match_flags |= EFX_FILTER_MATCH_REM_MAC;
857 ether_addr_copy(spec.rem_mac, mac_entry->h_source);
858 }
859 if (mac_mask->h_proto) {
860 if (mac_mask->h_proto != ETHER_TYPE_FULL_MASK)
861 return -EINVAL;
862 spec.match_flags |= EFX_FILTER_MATCH_ETHER_TYPE;
863 spec.ether_type = mac_entry->h_proto;
864 }
865 break;
866
867 default:
868 return -EINVAL;
869 }
870
871 if ((rule->flow_type & FLOW_EXT) && rule->m_ext.vlan_tci) {
872 if (rule->m_ext.vlan_tci != htons(0xfff))
873 return -EINVAL;
874 spec.match_flags |= EFX_FILTER_MATCH_OUTER_VID;
875 spec.outer_vid = rule->h_ext.vlan_tci;
876 }
877
878 rc = efx_filter_insert_filter(efx, &spec, true);
879 if (rc < 0)
880 return rc;
881
882 rule->location = rc;
883 return 0;
884}
885
886static int efx_ethtool_set_rxnfc(struct net_device *net_dev,
887 struct ethtool_rxnfc *info)
888{
889 struct efx_nic *efx = netdev_priv(net_dev);
890
891 if (efx_filter_get_rx_id_limit(efx) == 0)
892 return -EOPNOTSUPP;
893
894 switch (info->cmd) {
895 case ETHTOOL_SRXCLSRLINS:
896 return efx_ethtool_set_class_rule(efx, &info->fs,
897 info->rss_context);
898
899 case ETHTOOL_SRXCLSRLDEL:
900 return efx_filter_remove_id_safe(efx, EFX_FILTER_PRI_MANUAL,
901 info->fs.location);
902
903 default:
904 return -EOPNOTSUPP;
905 }
906}
907
908static u32 efx_ethtool_get_rxfh_indir_size(struct net_device *net_dev)
909{
910 struct efx_nic *efx = netdev_priv(net_dev);
911
912 if (efx->n_rx_channels == 1)
913 return 0;
914 return ARRAY_SIZE(efx->rss_context.rx_indir_table);
915}
916
917static u32 efx_ethtool_get_rxfh_key_size(struct net_device *net_dev)
918{
919 struct efx_nic *efx = netdev_priv(net_dev);
920
921 return efx->type->rx_hash_key_size;
922}
923
924static int efx_ethtool_get_rxfh(struct net_device *net_dev, u32 *indir, u8 *key,
925 u8 *hfunc)
926{
927 struct efx_nic *efx = netdev_priv(net_dev);
928 int rc;
929
930 rc = efx->type->rx_pull_rss_config(efx);
931 if (rc)
932 return rc;
933
934 if (hfunc)
935 *hfunc = ETH_RSS_HASH_TOP;
936 if (indir)
937 memcpy(indir, efx->rss_context.rx_indir_table,
938 sizeof(efx->rss_context.rx_indir_table));
939 if (key)
940 memcpy(key, efx->rss_context.rx_hash_key,
941 efx->type->rx_hash_key_size);
942 return 0;
943}
944
945static int efx_ethtool_set_rxfh(struct net_device *net_dev, const u32 *indir,
946 const u8 *key, const u8 hfunc)
947{
948 struct efx_nic *efx = netdev_priv(net_dev);
949
950
951 if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
952 return -EOPNOTSUPP;
953 if (!indir && !key)
954 return 0;
955
956 if (!key)
957 key = efx->rss_context.rx_hash_key;
958 if (!indir)
959 indir = efx->rss_context.rx_indir_table;
960
961 return efx->type->rx_push_rss_config(efx, true, indir, key);
962}
963
964static int efx_ethtool_get_rxfh_context(struct net_device *net_dev, u32 *indir,
965 u8 *key, u8 *hfunc, u32 rss_context)
966{
967 struct efx_nic *efx = netdev_priv(net_dev);
968 struct efx_rss_context *ctx;
969 int rc = 0;
970
971 if (!efx->type->rx_pull_rss_context_config)
972 return -EOPNOTSUPP;
973
974 mutex_lock(&efx->rss_lock);
975 ctx = efx_find_rss_context_entry(efx, rss_context);
976 if (!ctx) {
977 rc = -ENOENT;
978 goto out_unlock;
979 }
980 rc = efx->type->rx_pull_rss_context_config(efx, ctx);
981 if (rc)
982 goto out_unlock;
983
984 if (hfunc)
985 *hfunc = ETH_RSS_HASH_TOP;
986 if (indir)
987 memcpy(indir, ctx->rx_indir_table, sizeof(ctx->rx_indir_table));
988 if (key)
989 memcpy(key, ctx->rx_hash_key, efx->type->rx_hash_key_size);
990out_unlock:
991 mutex_unlock(&efx->rss_lock);
992 return rc;
993}
994
995static int efx_ethtool_set_rxfh_context(struct net_device *net_dev,
996 const u32 *indir, const u8 *key,
997 const u8 hfunc, u32 *rss_context,
998 bool delete)
999{
1000 struct efx_nic *efx = netdev_priv(net_dev);
1001 struct efx_rss_context *ctx;
1002 bool allocated = false;
1003 int rc;
1004
1005 if (!efx->type->rx_push_rss_context_config)
1006 return -EOPNOTSUPP;
1007
1008 if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
1009 return -EOPNOTSUPP;
1010
1011 mutex_lock(&efx->rss_lock);
1012
1013 if (*rss_context == ETH_RXFH_CONTEXT_ALLOC) {
1014 if (delete) {
1015
1016 rc = -EINVAL;
1017 goto out_unlock;
1018 }
1019 ctx = efx_alloc_rss_context_entry(efx);
1020 if (!ctx) {
1021 rc = -ENOMEM;
1022 goto out_unlock;
1023 }
1024 ctx->context_id = EFX_MCDI_RSS_CONTEXT_INVALID;
1025
1026 efx_set_default_rx_indir_table(efx, ctx);
1027 netdev_rss_key_fill(ctx->rx_hash_key, sizeof(ctx->rx_hash_key));
1028 allocated = true;
1029 } else {
1030 ctx = efx_find_rss_context_entry(efx, *rss_context);
1031 if (!ctx) {
1032 rc = -ENOENT;
1033 goto out_unlock;
1034 }
1035 }
1036
1037 if (delete) {
1038
1039 rc = efx->type->rx_push_rss_context_config(efx, ctx, NULL, NULL);
1040 if (!rc)
1041 efx_free_rss_context_entry(ctx);
1042 goto out_unlock;
1043 }
1044
1045 if (!key)
1046 key = ctx->rx_hash_key;
1047 if (!indir)
1048 indir = ctx->rx_indir_table;
1049
1050 rc = efx->type->rx_push_rss_context_config(efx, ctx, indir, key);
1051 if (rc && allocated)
1052 efx_free_rss_context_entry(ctx);
1053 else
1054 *rss_context = ctx->user_id;
1055out_unlock:
1056 mutex_unlock(&efx->rss_lock);
1057 return rc;
1058}
1059
1060static int efx_ethtool_get_ts_info(struct net_device *net_dev,
1061 struct ethtool_ts_info *ts_info)
1062{
1063 struct efx_nic *efx = netdev_priv(net_dev);
1064
1065
1066 ts_info->so_timestamping = (SOF_TIMESTAMPING_RX_SOFTWARE |
1067 SOF_TIMESTAMPING_SOFTWARE);
1068 ts_info->phc_index = -1;
1069
1070 efx_ptp_get_ts_info(efx, ts_info);
1071 return 0;
1072}
1073
1074static int efx_ethtool_get_module_eeprom(struct net_device *net_dev,
1075 struct ethtool_eeprom *ee,
1076 u8 *data)
1077{
1078 struct efx_nic *efx = netdev_priv(net_dev);
1079 int ret;
1080
1081 if (!efx->phy_op || !efx->phy_op->get_module_eeprom)
1082 return -EOPNOTSUPP;
1083
1084 mutex_lock(&efx->mac_lock);
1085 ret = efx->phy_op->get_module_eeprom(efx, ee, data);
1086 mutex_unlock(&efx->mac_lock);
1087
1088 return ret;
1089}
1090
1091static int efx_ethtool_get_module_info(struct net_device *net_dev,
1092 struct ethtool_modinfo *modinfo)
1093{
1094 struct efx_nic *efx = netdev_priv(net_dev);
1095 int ret;
1096
1097 if (!efx->phy_op || !efx->phy_op->get_module_info)
1098 return -EOPNOTSUPP;
1099
1100 mutex_lock(&efx->mac_lock);
1101 ret = efx->phy_op->get_module_info(efx, modinfo);
1102 mutex_unlock(&efx->mac_lock);
1103
1104 return ret;
1105}
1106
1107static int efx_ethtool_get_fecparam(struct net_device *net_dev,
1108 struct ethtool_fecparam *fecparam)
1109{
1110 struct efx_nic *efx = netdev_priv(net_dev);
1111 int rc;
1112
1113 if (!efx->phy_op || !efx->phy_op->get_fecparam)
1114 return -EOPNOTSUPP;
1115 mutex_lock(&efx->mac_lock);
1116 rc = efx->phy_op->get_fecparam(efx, fecparam);
1117 mutex_unlock(&efx->mac_lock);
1118
1119 return rc;
1120}
1121
1122static int efx_ethtool_set_fecparam(struct net_device *net_dev,
1123 struct ethtool_fecparam *fecparam)
1124{
1125 struct efx_nic *efx = netdev_priv(net_dev);
1126 int rc;
1127
1128 if (!efx->phy_op || !efx->phy_op->get_fecparam)
1129 return -EOPNOTSUPP;
1130 mutex_lock(&efx->mac_lock);
1131 rc = efx->phy_op->set_fecparam(efx, fecparam);
1132 mutex_unlock(&efx->mac_lock);
1133
1134 return rc;
1135}
1136
1137const struct ethtool_ops efx_ethtool_ops = {
1138 .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
1139 ETHTOOL_COALESCE_USECS_IRQ |
1140 ETHTOOL_COALESCE_USE_ADAPTIVE_RX,
1141 .get_drvinfo = efx_ethtool_get_drvinfo,
1142 .get_regs_len = efx_ethtool_get_regs_len,
1143 .get_regs = efx_ethtool_get_regs,
1144 .get_msglevel = efx_ethtool_get_msglevel,
1145 .set_msglevel = efx_ethtool_set_msglevel,
1146 .nway_reset = efx_ethtool_nway_reset,
1147 .get_link = ethtool_op_get_link,
1148 .get_coalesce = efx_ethtool_get_coalesce,
1149 .set_coalesce = efx_ethtool_set_coalesce,
1150 .get_ringparam = efx_ethtool_get_ringparam,
1151 .set_ringparam = efx_ethtool_set_ringparam,
1152 .get_pauseparam = efx_ethtool_get_pauseparam,
1153 .set_pauseparam = efx_ethtool_set_pauseparam,
1154 .get_sset_count = efx_ethtool_get_sset_count,
1155 .self_test = efx_ethtool_self_test,
1156 .get_strings = efx_ethtool_get_strings,
1157 .set_phys_id = efx_ethtool_phys_id,
1158 .get_ethtool_stats = efx_ethtool_get_stats,
1159 .get_wol = efx_ethtool_get_wol,
1160 .set_wol = efx_ethtool_set_wol,
1161 .reset = efx_ethtool_reset,
1162 .get_rxnfc = efx_ethtool_get_rxnfc,
1163 .set_rxnfc = efx_ethtool_set_rxnfc,
1164 .get_rxfh_indir_size = efx_ethtool_get_rxfh_indir_size,
1165 .get_rxfh_key_size = efx_ethtool_get_rxfh_key_size,
1166 .get_rxfh = efx_ethtool_get_rxfh,
1167 .set_rxfh = efx_ethtool_set_rxfh,
1168 .get_rxfh_context = efx_ethtool_get_rxfh_context,
1169 .set_rxfh_context = efx_ethtool_set_rxfh_context,
1170 .get_ts_info = efx_ethtool_get_ts_info,
1171 .get_module_info = efx_ethtool_get_module_info,
1172 .get_module_eeprom = efx_ethtool_get_module_eeprom,
1173 .get_link_ksettings = efx_ethtool_get_link_ksettings,
1174 .set_link_ksettings = efx_ethtool_set_link_ksettings,
1175 .get_fecparam = efx_ethtool_get_fecparam,
1176 .set_fecparam = efx_ethtool_set_fecparam,
1177};
1178