1 // SPDX-License-Identifier: GPL-2.0-only
2 /****************************************************************************
3 * Driver for Solarflare network controllers and boards
4 * Copyright 2019 Solarflare Communications Inc.
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published
8 * by the Free Software Foundation, incorporated herein by reference.
10 #include <linux/module.h>
11 #include <linux/netdevice.h>
12 #include "net_driver.h"
16 #include "rx_common.h"
17 #include "ethtool_common.h"
18 #include "mcdi_port_common.h"
20 struct efx_sw_stat_desc
{
23 EFX_ETHTOOL_STAT_SOURCE_nic
,
24 EFX_ETHTOOL_STAT_SOURCE_channel
,
25 EFX_ETHTOOL_STAT_SOURCE_tx_queue
28 u64 (*get_stat
)(void *field
); /* Reader function */
31 /* Initialiser for a struct efx_sw_stat_desc with type-checking */
32 #define EFX_ETHTOOL_STAT(stat_name, source_name, field, field_type, \
33 get_stat_function) { \
35 .source = EFX_ETHTOOL_STAT_SOURCE_##source_name, \
36 .offset = ((((field_type *) 0) == \
37 &((struct efx_##source_name *)0)->field) ? \
38 offsetof(struct efx_##source_name, field) : \
39 offsetof(struct efx_##source_name, field)), \
40 .get_stat = get_stat_function, \
43 static u64
efx_get_uint_stat(void *field
)
45 return *(unsigned int *)field
;
48 static u64
efx_get_atomic_stat(void *field
)
50 return atomic_read((atomic_t
*) field
);
53 #define EFX_ETHTOOL_ATOMIC_NIC_ERROR_STAT(field) \
54 EFX_ETHTOOL_STAT(field, nic, field, \
55 atomic_t, efx_get_atomic_stat)
57 #define EFX_ETHTOOL_UINT_CHANNEL_STAT(field) \
58 EFX_ETHTOOL_STAT(field, channel, n_##field, \
59 unsigned int, efx_get_uint_stat)
60 #define EFX_ETHTOOL_UINT_CHANNEL_STAT_NO_N(field) \
61 EFX_ETHTOOL_STAT(field, channel, field, \
62 unsigned int, efx_get_uint_stat)
64 #define EFX_ETHTOOL_UINT_TXQ_STAT(field) \
65 EFX_ETHTOOL_STAT(tx_##field, tx_queue, field, \
66 unsigned int, efx_get_uint_stat)
68 static const struct efx_sw_stat_desc efx_sw_stat_desc
[] = {
69 EFX_ETHTOOL_UINT_TXQ_STAT(merge_events
),
70 EFX_ETHTOOL_UINT_TXQ_STAT(tso_bursts
),
71 EFX_ETHTOOL_UINT_TXQ_STAT(tso_long_headers
),
72 EFX_ETHTOOL_UINT_TXQ_STAT(tso_packets
),
73 EFX_ETHTOOL_UINT_TXQ_STAT(tso_fallbacks
),
74 EFX_ETHTOOL_UINT_TXQ_STAT(pushes
),
75 EFX_ETHTOOL_UINT_TXQ_STAT(pio_packets
),
76 EFX_ETHTOOL_UINT_TXQ_STAT(cb_packets
),
77 EFX_ETHTOOL_ATOMIC_NIC_ERROR_STAT(rx_reset
),
78 EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_tobe_disc
),
79 EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_ip_hdr_chksum_err
),
80 EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_tcp_udp_chksum_err
),
81 EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_inner_ip_hdr_chksum_err
),
82 EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_inner_tcp_udp_chksum_err
),
83 EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_outer_ip_hdr_chksum_err
),
84 EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_outer_tcp_udp_chksum_err
),
85 EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_eth_crc_err
),
86 EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_mcast_mismatch
),
87 EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_frm_trunc
),
88 EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_merge_events
),
89 EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_merge_packets
),
90 EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_xdp_drops
),
91 EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_xdp_bad_drops
),
92 EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_xdp_tx
),
93 EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_xdp_redirect
),
94 #ifdef CONFIG_RFS_ACCEL
95 EFX_ETHTOOL_UINT_CHANNEL_STAT_NO_N(rfs_filter_count
),
96 EFX_ETHTOOL_UINT_CHANNEL_STAT(rfs_succeeded
),
97 EFX_ETHTOOL_UINT_CHANNEL_STAT(rfs_failed
),
101 #define EFX_ETHTOOL_SW_STAT_COUNT ARRAY_SIZE(efx_sw_stat_desc)
103 void efx_siena_ethtool_get_drvinfo(struct net_device
*net_dev
,
104 struct ethtool_drvinfo
*info
)
106 struct efx_nic
*efx
= netdev_priv(net_dev
);
108 strscpy(info
->driver
, KBUILD_MODNAME
, sizeof(info
->driver
));
109 efx_siena_mcdi_print_fwver(efx
, info
->fw_version
,
110 sizeof(info
->fw_version
));
111 strscpy(info
->bus_info
, pci_name(efx
->pci_dev
), sizeof(info
->bus_info
));
114 u32
efx_siena_ethtool_get_msglevel(struct net_device
*net_dev
)
116 struct efx_nic
*efx
= netdev_priv(net_dev
);
118 return efx
->msg_enable
;
121 void efx_siena_ethtool_set_msglevel(struct net_device
*net_dev
, u32 msg_enable
)
123 struct efx_nic
*efx
= netdev_priv(net_dev
);
125 efx
->msg_enable
= msg_enable
;
128 void efx_siena_ethtool_get_pauseparam(struct net_device
*net_dev
,
129 struct ethtool_pauseparam
*pause
)
131 struct efx_nic
*efx
= netdev_priv(net_dev
);
133 pause
->rx_pause
= !!(efx
->wanted_fc
& EFX_FC_RX
);
134 pause
->tx_pause
= !!(efx
->wanted_fc
& EFX_FC_TX
);
135 pause
->autoneg
= !!(efx
->wanted_fc
& EFX_FC_AUTO
);
138 int efx_siena_ethtool_set_pauseparam(struct net_device
*net_dev
,
139 struct ethtool_pauseparam
*pause
)
141 struct efx_nic
*efx
= netdev_priv(net_dev
);
142 u8 wanted_fc
, old_fc
;
146 mutex_lock(&efx
->mac_lock
);
148 wanted_fc
= ((pause
->rx_pause
? EFX_FC_RX
: 0) |
149 (pause
->tx_pause
? EFX_FC_TX
: 0) |
150 (pause
->autoneg
? EFX_FC_AUTO
: 0));
152 if ((wanted_fc
& EFX_FC_TX
) && !(wanted_fc
& EFX_FC_RX
)) {
153 netif_dbg(efx
, drv
, efx
->net_dev
,
154 "Flow control unsupported: tx ON rx OFF\n");
159 if ((wanted_fc
& EFX_FC_AUTO
) && !efx
->link_advertising
[0]) {
160 netif_dbg(efx
, drv
, efx
->net_dev
,
161 "Autonegotiation is disabled\n");
166 /* Hook for Falcon bug 11482 workaround */
167 if (efx
->type
->prepare_enable_fc_tx
&&
168 (wanted_fc
& EFX_FC_TX
) && !(efx
->wanted_fc
& EFX_FC_TX
))
169 efx
->type
->prepare_enable_fc_tx(efx
);
171 old_adv
= efx
->link_advertising
[0];
172 old_fc
= efx
->wanted_fc
;
173 efx_siena_link_set_wanted_fc(efx
, wanted_fc
);
174 if (efx
->link_advertising
[0] != old_adv
||
175 (efx
->wanted_fc
^ old_fc
) & EFX_FC_AUTO
) {
176 rc
= efx_siena_mcdi_port_reconfigure(efx
);
178 netif_err(efx
, drv
, efx
->net_dev
,
179 "Unable to advertise requested flow "
180 "control setting\n");
185 /* Reconfigure the MAC. The PHY *may* generate a link state change event
186 * if the user just changed the advertised capabilities, but there's no
187 * harm doing this twice */
188 efx_siena_mac_reconfigure(efx
, false);
191 mutex_unlock(&efx
->mac_lock
);
197 * efx_fill_test - fill in an individual self-test entry
198 * @test_index: Index of the test
199 * @strings: Ethtool strings, or %NULL
200 * @data: Ethtool test results, or %NULL
201 * @test: Pointer to test result (used only if data != %NULL)
202 * @unit_format: Unit name format (e.g. "chan\%d")
203 * @unit_id: Unit id (e.g. 0 for "chan0")
204 * @test_format: Test name format (e.g. "loopback.\%s.tx.sent")
205 * @test_id: Test id (e.g. "PHYXS" for "loopback.PHYXS.tx_sent")
207 * Fill in an individual self-test entry.
209 static void efx_fill_test(unsigned int test_index
, u8
*strings
, u64
*data
,
210 int *test
, const char *unit_format
, int unit_id
,
211 const char *test_format
, const char *test_id
)
213 char unit_str
[ETH_GSTRING_LEN
], test_str
[ETH_GSTRING_LEN
];
215 /* Fill data value, if applicable */
217 data
[test_index
] = *test
;
219 /* Fill string, if applicable */
221 if (strchr(unit_format
, '%'))
222 snprintf(unit_str
, sizeof(unit_str
),
223 unit_format
, unit_id
);
225 strcpy(unit_str
, unit_format
);
226 snprintf(test_str
, sizeof(test_str
), test_format
, test_id
);
227 snprintf(strings
+ test_index
* ETH_GSTRING_LEN
,
229 "%-6s %-24s", unit_str
, test_str
);
233 #define EFX_CHANNEL_NAME(_channel) "chan%d", _channel->channel
234 #define EFX_TX_QUEUE_NAME(_tx_queue) "txq%d", _tx_queue->label
235 #define EFX_LOOPBACK_NAME(_mode, _counter) \
236 "loopback.%s." _counter, STRING_TABLE_LOOKUP(_mode, efx_siena_loopback_mode)
239 * efx_fill_loopback_test - fill in a block of loopback self-test entries
241 * @lb_tests: Efx loopback self-test results structure
242 * @mode: Loopback test mode
243 * @test_index: Starting index of the test
244 * @strings: Ethtool strings, or %NULL
245 * @data: Ethtool test results, or %NULL
247 * Fill in a block of loopback self-test entries. Return new test
250 static int efx_fill_loopback_test(struct efx_nic
*efx
,
251 struct efx_loopback_self_tests
*lb_tests
,
252 enum efx_loopback_mode mode
,
253 unsigned int test_index
,
254 u8
*strings
, u64
*data
)
256 struct efx_channel
*channel
=
257 efx_get_channel(efx
, efx
->tx_channel_offset
);
258 struct efx_tx_queue
*tx_queue
;
260 efx_for_each_channel_tx_queue(tx_queue
, channel
) {
261 efx_fill_test(test_index
++, strings
, data
,
262 &lb_tests
->tx_sent
[tx_queue
->label
],
263 EFX_TX_QUEUE_NAME(tx_queue
),
264 EFX_LOOPBACK_NAME(mode
, "tx_sent"));
265 efx_fill_test(test_index
++, strings
, data
,
266 &lb_tests
->tx_done
[tx_queue
->label
],
267 EFX_TX_QUEUE_NAME(tx_queue
),
268 EFX_LOOPBACK_NAME(mode
, "tx_done"));
270 efx_fill_test(test_index
++, strings
, data
,
273 EFX_LOOPBACK_NAME(mode
, "rx_good"));
274 efx_fill_test(test_index
++, strings
, data
,
277 EFX_LOOPBACK_NAME(mode
, "rx_bad"));
283 * efx_ethtool_fill_self_tests - get self-test details
285 * @tests: Efx self-test results structure, or %NULL
286 * @strings: Ethtool strings, or %NULL
287 * @data: Ethtool test results, or %NULL
289 * Get self-test number of strings, strings, and/or test results.
290 * Return number of strings (== number of test results).
292 * The reason for merging these three functions is to make sure that
293 * they can never be inconsistent.
295 static int efx_ethtool_fill_self_tests(struct efx_nic
*efx
,
296 struct efx_self_tests
*tests
,
297 u8
*strings
, u64
*data
)
299 struct efx_channel
*channel
;
300 unsigned int n
= 0, i
;
301 enum efx_loopback_mode mode
;
303 efx_fill_test(n
++, strings
, data
, &tests
->phy_alive
,
304 "phy", 0, "alive", NULL
);
305 efx_fill_test(n
++, strings
, data
, &tests
->nvram
,
306 "core", 0, "nvram", NULL
);
307 efx_fill_test(n
++, strings
, data
, &tests
->interrupt
,
308 "core", 0, "interrupt", NULL
);
311 efx_for_each_channel(channel
, efx
) {
312 efx_fill_test(n
++, strings
, data
,
313 &tests
->eventq_dma
[channel
->channel
],
314 EFX_CHANNEL_NAME(channel
),
316 efx_fill_test(n
++, strings
, data
,
317 &tests
->eventq_int
[channel
->channel
],
318 EFX_CHANNEL_NAME(channel
),
322 efx_fill_test(n
++, strings
, data
, &tests
->memory
,
323 "core", 0, "memory", NULL
);
324 efx_fill_test(n
++, strings
, data
, &tests
->registers
,
325 "core", 0, "registers", NULL
);
327 for (i
= 0; true; ++i
) {
330 EFX_WARN_ON_PARANOID(i
>= EFX_MAX_PHY_TESTS
);
331 name
= efx_siena_mcdi_phy_test_name(efx
, i
);
335 efx_fill_test(n
++, strings
, data
, &tests
->phy_ext
[i
], "phy", 0, name
, NULL
);
339 for (mode
= LOOPBACK_NONE
; mode
<= LOOPBACK_TEST_MAX
; mode
++) {
340 if (!(efx
->loopback_modes
& (1 << mode
)))
342 n
= efx_fill_loopback_test(efx
,
343 &tests
->loopback
[mode
], mode
, n
,
350 void efx_siena_ethtool_self_test(struct net_device
*net_dev
,
351 struct ethtool_test
*test
, u64
*data
)
353 struct efx_nic
*efx
= netdev_priv(net_dev
);
354 struct efx_self_tests
*efx_tests
;
358 efx_tests
= kzalloc(sizeof(*efx_tests
), GFP_KERNEL
);
362 if (efx
->state
!= STATE_READY
) {
367 netif_info(efx
, drv
, efx
->net_dev
, "starting %sline testing\n",
368 (test
->flags
& ETH_TEST_FL_OFFLINE
) ? "off" : "on");
370 /* We need rx buffers and interrupts. */
371 already_up
= (efx
->net_dev
->flags
& IFF_UP
);
373 rc
= dev_open(efx
->net_dev
, NULL
);
375 netif_err(efx
, drv
, efx
->net_dev
,
376 "failed opening device.\n");
381 rc
= efx_siena_selftest(efx
, efx_tests
, test
->flags
);
384 dev_close(efx
->net_dev
);
386 netif_info(efx
, drv
, efx
->net_dev
, "%s %sline self-tests\n",
387 rc
== 0 ? "passed" : "failed",
388 (test
->flags
& ETH_TEST_FL_OFFLINE
) ? "off" : "on");
391 efx_ethtool_fill_self_tests(efx
, efx_tests
, NULL
, data
);
395 test
->flags
|= ETH_TEST_FL_FAILED
;
398 static size_t efx_describe_per_queue_stats(struct efx_nic
*efx
, u8
**strings
)
401 struct efx_channel
*channel
;
403 efx_for_each_channel(channel
, efx
) {
404 if (efx_channel_has_tx_queues(channel
)) {
409 ethtool_sprintf(strings
, "tx-%u.tx_packets",
410 channel
->tx_queue
[0].queue
/
411 EFX_MAX_TXQ_PER_CHANNEL
);
414 efx_for_each_channel(channel
, efx
) {
415 if (efx_channel_has_rx_queue(channel
)) {
420 ethtool_sprintf(strings
, "rx-%d.rx_packets",
424 if (efx
->xdp_tx_queue_count
&& efx
->xdp_tx_queues
) {
427 for (xdp
= 0; xdp
< efx
->xdp_tx_queue_count
; xdp
++) {
432 ethtool_sprintf(strings
, "tx-xdp-cpu-%hu.tx_packets",
440 int efx_siena_ethtool_get_sset_count(struct net_device
*net_dev
, int string_set
)
442 struct efx_nic
*efx
= netdev_priv(net_dev
);
444 switch (string_set
) {
446 return efx
->type
->describe_stats(efx
, NULL
) +
447 EFX_ETHTOOL_SW_STAT_COUNT
+
448 efx_describe_per_queue_stats(efx
, NULL
) +
449 efx_siena_ptp_describe_stats(efx
, NULL
);
451 return efx_ethtool_fill_self_tests(efx
, NULL
, NULL
, NULL
);
457 void efx_siena_ethtool_get_strings(struct net_device
*net_dev
,
458 u32 string_set
, u8
*strings
)
460 struct efx_nic
*efx
= netdev_priv(net_dev
);
463 switch (string_set
) {
465 efx
->type
->describe_stats(efx
, &strings
);
466 for (i
= 0; i
< EFX_ETHTOOL_SW_STAT_COUNT
; i
++)
467 ethtool_puts(&strings
, efx_sw_stat_desc
[i
].name
);
468 efx_describe_per_queue_stats(efx
, &strings
);
469 efx_siena_ptp_describe_stats(efx
, &strings
);
472 efx_ethtool_fill_self_tests(efx
, NULL
, strings
, NULL
);
475 /* No other string sets */
480 void efx_siena_ethtool_get_stats(struct net_device
*net_dev
,
481 struct ethtool_stats
*stats
,
484 struct efx_nic
*efx
= netdev_priv(net_dev
);
485 const struct efx_sw_stat_desc
*stat
;
486 struct efx_channel
*channel
;
487 struct efx_tx_queue
*tx_queue
;
488 struct efx_rx_queue
*rx_queue
;
491 spin_lock_bh(&efx
->stats_lock
);
493 /* Get NIC statistics */
494 data
+= efx
->type
->update_stats(efx
, data
, NULL
);
496 /* Get software statistics */
497 for (i
= 0; i
< EFX_ETHTOOL_SW_STAT_COUNT
; i
++) {
498 stat
= &efx_sw_stat_desc
[i
];
499 switch (stat
->source
) {
500 case EFX_ETHTOOL_STAT_SOURCE_nic
:
501 data
[i
] = stat
->get_stat((void *)efx
+ stat
->offset
);
503 case EFX_ETHTOOL_STAT_SOURCE_channel
:
505 efx_for_each_channel(channel
, efx
)
506 data
[i
] += stat
->get_stat((void *)channel
+
509 case EFX_ETHTOOL_STAT_SOURCE_tx_queue
:
511 efx_for_each_channel(channel
, efx
) {
512 efx_for_each_channel_tx_queue(tx_queue
, channel
)
514 stat
->get_stat((void *)tx_queue
520 data
+= EFX_ETHTOOL_SW_STAT_COUNT
;
522 spin_unlock_bh(&efx
->stats_lock
);
524 efx_for_each_channel(channel
, efx
) {
525 if (efx_channel_has_tx_queues(channel
)) {
527 efx_for_each_channel_tx_queue(tx_queue
, channel
) {
528 *data
+= tx_queue
->tx_packets
;
533 efx_for_each_channel(channel
, efx
) {
534 if (efx_channel_has_rx_queue(channel
)) {
536 efx_for_each_channel_rx_queue(rx_queue
, channel
) {
537 *data
+= rx_queue
->rx_packets
;
542 if (efx
->xdp_tx_queue_count
&& efx
->xdp_tx_queues
) {
545 for (xdp
= 0; xdp
< efx
->xdp_tx_queue_count
; xdp
++) {
546 data
[0] = efx
->xdp_tx_queues
[xdp
]->tx_packets
;
551 efx_siena_ptp_update_stats(efx
, data
);
554 /* This must be called with rtnl_lock held. */
555 int efx_siena_ethtool_get_link_ksettings(struct net_device
*net_dev
,
556 struct ethtool_link_ksettings
*cmd
)
558 struct efx_nic
*efx
= netdev_priv(net_dev
);
559 struct efx_link_state
*link_state
= &efx
->link_state
;
561 mutex_lock(&efx
->mac_lock
);
562 efx_siena_mcdi_phy_get_link_ksettings(efx
, cmd
);
563 mutex_unlock(&efx
->mac_lock
);
565 /* Both MACs support pause frames (bidirectional and respond-only) */
566 ethtool_link_ksettings_add_link_mode(cmd
, supported
, Pause
);
567 ethtool_link_ksettings_add_link_mode(cmd
, supported
, Asym_Pause
);
569 if (LOOPBACK_INTERNAL(efx
)) {
570 cmd
->base
.speed
= link_state
->speed
;
571 cmd
->base
.duplex
= link_state
->fd
? DUPLEX_FULL
: DUPLEX_HALF
;
577 /* This must be called with rtnl_lock held. */
579 efx_siena_ethtool_set_link_ksettings(struct net_device
*net_dev
,
580 const struct ethtool_link_ksettings
*cmd
)
582 struct efx_nic
*efx
= netdev_priv(net_dev
);
585 /* GMAC does not support 1000Mbps HD */
586 if ((cmd
->base
.speed
== SPEED_1000
) &&
587 (cmd
->base
.duplex
!= DUPLEX_FULL
)) {
588 netif_dbg(efx
, drv
, efx
->net_dev
,
589 "rejecting unsupported 1000Mbps HD setting\n");
593 mutex_lock(&efx
->mac_lock
);
594 rc
= efx_siena_mcdi_phy_set_link_ksettings(efx
, cmd
);
595 mutex_unlock(&efx
->mac_lock
);
599 int efx_siena_ethtool_get_fecparam(struct net_device
*net_dev
,
600 struct ethtool_fecparam
*fecparam
)
602 struct efx_nic
*efx
= netdev_priv(net_dev
);
605 mutex_lock(&efx
->mac_lock
);
606 rc
= efx_siena_mcdi_phy_get_fecparam(efx
, fecparam
);
607 mutex_unlock(&efx
->mac_lock
);
612 int efx_siena_ethtool_set_fecparam(struct net_device
*net_dev
,
613 struct ethtool_fecparam
*fecparam
)
615 struct efx_nic
*efx
= netdev_priv(net_dev
);
618 mutex_lock(&efx
->mac_lock
);
619 rc
= efx_siena_mcdi_phy_set_fecparam(efx
, fecparam
);
620 mutex_unlock(&efx
->mac_lock
);
625 /* MAC address mask including only I/G bit */
626 static const u8 mac_addr_ig_mask
[ETH_ALEN
] __aligned(2) = {0x01, 0, 0, 0, 0, 0};
628 #define IP4_ADDR_FULL_MASK ((__force __be32)~0)
629 #define IP_PROTO_FULL_MASK 0xFF
630 #define PORT_FULL_MASK ((__force __be16)~0)
631 #define ETHER_TYPE_FULL_MASK ((__force __be16)~0)
633 static inline void ip6_fill_mask(__be32
*mask
)
635 mask
[0] = mask
[1] = mask
[2] = mask
[3] = ~(__be32
)0;
638 static int efx_ethtool_get_class_rule(struct efx_nic
*efx
,
639 struct ethtool_rx_flow_spec
*rule
,
642 struct ethtool_tcpip4_spec
*ip_entry
= &rule
->h_u
.tcp_ip4_spec
;
643 struct ethtool_tcpip4_spec
*ip_mask
= &rule
->m_u
.tcp_ip4_spec
;
644 struct ethtool_usrip4_spec
*uip_entry
= &rule
->h_u
.usr_ip4_spec
;
645 struct ethtool_usrip4_spec
*uip_mask
= &rule
->m_u
.usr_ip4_spec
;
646 struct ethtool_tcpip6_spec
*ip6_entry
= &rule
->h_u
.tcp_ip6_spec
;
647 struct ethtool_tcpip6_spec
*ip6_mask
= &rule
->m_u
.tcp_ip6_spec
;
648 struct ethtool_usrip6_spec
*uip6_entry
= &rule
->h_u
.usr_ip6_spec
;
649 struct ethtool_usrip6_spec
*uip6_mask
= &rule
->m_u
.usr_ip6_spec
;
650 struct ethhdr
*mac_entry
= &rule
->h_u
.ether_spec
;
651 struct ethhdr
*mac_mask
= &rule
->m_u
.ether_spec
;
652 struct efx_filter_spec spec
;
655 rc
= efx_filter_get_filter_safe(efx
, EFX_FILTER_PRI_MANUAL
,
656 rule
->location
, &spec
);
660 if (spec
.dmaq_id
== EFX_FILTER_RX_DMAQ_ID_DROP
)
661 rule
->ring_cookie
= RX_CLS_FLOW_DISC
;
663 rule
->ring_cookie
= spec
.dmaq_id
;
665 if ((spec
.match_flags
& EFX_FILTER_MATCH_ETHER_TYPE
) &&
666 spec
.ether_type
== htons(ETH_P_IP
) &&
667 (spec
.match_flags
& EFX_FILTER_MATCH_IP_PROTO
) &&
668 (spec
.ip_proto
== IPPROTO_TCP
|| spec
.ip_proto
== IPPROTO_UDP
) &&
670 ~(EFX_FILTER_MATCH_ETHER_TYPE
| EFX_FILTER_MATCH_OUTER_VID
|
671 EFX_FILTER_MATCH_LOC_HOST
| EFX_FILTER_MATCH_REM_HOST
|
672 EFX_FILTER_MATCH_IP_PROTO
|
673 EFX_FILTER_MATCH_LOC_PORT
| EFX_FILTER_MATCH_REM_PORT
))) {
674 rule
->flow_type
= ((spec
.ip_proto
== IPPROTO_TCP
) ?
675 TCP_V4_FLOW
: UDP_V4_FLOW
);
676 if (spec
.match_flags
& EFX_FILTER_MATCH_LOC_HOST
) {
677 ip_entry
->ip4dst
= spec
.loc_host
[0];
678 ip_mask
->ip4dst
= IP4_ADDR_FULL_MASK
;
680 if (spec
.match_flags
& EFX_FILTER_MATCH_REM_HOST
) {
681 ip_entry
->ip4src
= spec
.rem_host
[0];
682 ip_mask
->ip4src
= IP4_ADDR_FULL_MASK
;
684 if (spec
.match_flags
& EFX_FILTER_MATCH_LOC_PORT
) {
685 ip_entry
->pdst
= spec
.loc_port
;
686 ip_mask
->pdst
= PORT_FULL_MASK
;
688 if (spec
.match_flags
& EFX_FILTER_MATCH_REM_PORT
) {
689 ip_entry
->psrc
= spec
.rem_port
;
690 ip_mask
->psrc
= PORT_FULL_MASK
;
692 } else if ((spec
.match_flags
& EFX_FILTER_MATCH_ETHER_TYPE
) &&
693 spec
.ether_type
== htons(ETH_P_IPV6
) &&
694 (spec
.match_flags
& EFX_FILTER_MATCH_IP_PROTO
) &&
695 (spec
.ip_proto
== IPPROTO_TCP
|| spec
.ip_proto
== IPPROTO_UDP
) &&
697 ~(EFX_FILTER_MATCH_ETHER_TYPE
| EFX_FILTER_MATCH_OUTER_VID
|
698 EFX_FILTER_MATCH_LOC_HOST
| EFX_FILTER_MATCH_REM_HOST
|
699 EFX_FILTER_MATCH_IP_PROTO
|
700 EFX_FILTER_MATCH_LOC_PORT
| EFX_FILTER_MATCH_REM_PORT
))) {
701 rule
->flow_type
= ((spec
.ip_proto
== IPPROTO_TCP
) ?
702 TCP_V6_FLOW
: UDP_V6_FLOW
);
703 if (spec
.match_flags
& EFX_FILTER_MATCH_LOC_HOST
) {
704 memcpy(ip6_entry
->ip6dst
, spec
.loc_host
,
705 sizeof(ip6_entry
->ip6dst
));
706 ip6_fill_mask(ip6_mask
->ip6dst
);
708 if (spec
.match_flags
& EFX_FILTER_MATCH_REM_HOST
) {
709 memcpy(ip6_entry
->ip6src
, spec
.rem_host
,
710 sizeof(ip6_entry
->ip6src
));
711 ip6_fill_mask(ip6_mask
->ip6src
);
713 if (spec
.match_flags
& EFX_FILTER_MATCH_LOC_PORT
) {
714 ip6_entry
->pdst
= spec
.loc_port
;
715 ip6_mask
->pdst
= PORT_FULL_MASK
;
717 if (spec
.match_flags
& EFX_FILTER_MATCH_REM_PORT
) {
718 ip6_entry
->psrc
= spec
.rem_port
;
719 ip6_mask
->psrc
= PORT_FULL_MASK
;
721 } else if (!(spec
.match_flags
&
722 ~(EFX_FILTER_MATCH_LOC_MAC
| EFX_FILTER_MATCH_LOC_MAC_IG
|
723 EFX_FILTER_MATCH_REM_MAC
| EFX_FILTER_MATCH_ETHER_TYPE
|
724 EFX_FILTER_MATCH_OUTER_VID
))) {
725 rule
->flow_type
= ETHER_FLOW
;
726 if (spec
.match_flags
&
727 (EFX_FILTER_MATCH_LOC_MAC
| EFX_FILTER_MATCH_LOC_MAC_IG
)) {
728 ether_addr_copy(mac_entry
->h_dest
, spec
.loc_mac
);
729 if (spec
.match_flags
& EFX_FILTER_MATCH_LOC_MAC
)
730 eth_broadcast_addr(mac_mask
->h_dest
);
732 ether_addr_copy(mac_mask
->h_dest
,
735 if (spec
.match_flags
& EFX_FILTER_MATCH_REM_MAC
) {
736 ether_addr_copy(mac_entry
->h_source
, spec
.rem_mac
);
737 eth_broadcast_addr(mac_mask
->h_source
);
739 if (spec
.match_flags
& EFX_FILTER_MATCH_ETHER_TYPE
) {
740 mac_entry
->h_proto
= spec
.ether_type
;
741 mac_mask
->h_proto
= ETHER_TYPE_FULL_MASK
;
743 } else if (spec
.match_flags
& EFX_FILTER_MATCH_ETHER_TYPE
&&
744 spec
.ether_type
== htons(ETH_P_IP
) &&
746 ~(EFX_FILTER_MATCH_ETHER_TYPE
| EFX_FILTER_MATCH_OUTER_VID
|
747 EFX_FILTER_MATCH_LOC_HOST
| EFX_FILTER_MATCH_REM_HOST
|
748 EFX_FILTER_MATCH_IP_PROTO
))) {
749 rule
->flow_type
= IPV4_USER_FLOW
;
750 uip_entry
->ip_ver
= ETH_RX_NFC_IP4
;
751 if (spec
.match_flags
& EFX_FILTER_MATCH_IP_PROTO
) {
752 uip_mask
->proto
= IP_PROTO_FULL_MASK
;
753 uip_entry
->proto
= spec
.ip_proto
;
755 if (spec
.match_flags
& EFX_FILTER_MATCH_LOC_HOST
) {
756 uip_entry
->ip4dst
= spec
.loc_host
[0];
757 uip_mask
->ip4dst
= IP4_ADDR_FULL_MASK
;
759 if (spec
.match_flags
& EFX_FILTER_MATCH_REM_HOST
) {
760 uip_entry
->ip4src
= spec
.rem_host
[0];
761 uip_mask
->ip4src
= IP4_ADDR_FULL_MASK
;
763 } else if (spec
.match_flags
& EFX_FILTER_MATCH_ETHER_TYPE
&&
764 spec
.ether_type
== htons(ETH_P_IPV6
) &&
766 ~(EFX_FILTER_MATCH_ETHER_TYPE
| EFX_FILTER_MATCH_OUTER_VID
|
767 EFX_FILTER_MATCH_LOC_HOST
| EFX_FILTER_MATCH_REM_HOST
|
768 EFX_FILTER_MATCH_IP_PROTO
))) {
769 rule
->flow_type
= IPV6_USER_FLOW
;
770 if (spec
.match_flags
& EFX_FILTER_MATCH_IP_PROTO
) {
771 uip6_mask
->l4_proto
= IP_PROTO_FULL_MASK
;
772 uip6_entry
->l4_proto
= spec
.ip_proto
;
774 if (spec
.match_flags
& EFX_FILTER_MATCH_LOC_HOST
) {
775 memcpy(uip6_entry
->ip6dst
, spec
.loc_host
,
776 sizeof(uip6_entry
->ip6dst
));
777 ip6_fill_mask(uip6_mask
->ip6dst
);
779 if (spec
.match_flags
& EFX_FILTER_MATCH_REM_HOST
) {
780 memcpy(uip6_entry
->ip6src
, spec
.rem_host
,
781 sizeof(uip6_entry
->ip6src
));
782 ip6_fill_mask(uip6_mask
->ip6src
);
785 /* The above should handle all filters that we insert */
790 if (spec
.match_flags
& EFX_FILTER_MATCH_OUTER_VID
) {
791 rule
->flow_type
|= FLOW_EXT
;
792 rule
->h_ext
.vlan_tci
= spec
.outer_vid
;
793 rule
->m_ext
.vlan_tci
= htons(0xfff);
796 if (spec
.flags
& EFX_FILTER_FLAG_RX_RSS
) {
797 rule
->flow_type
|= FLOW_RSS
;
798 *rss_context
= spec
.rss_context
;
804 int efx_siena_ethtool_get_rxnfc(struct net_device
*net_dev
,
805 struct ethtool_rxnfc
*info
, u32
*rule_locs
)
807 struct efx_nic
*efx
= netdev_priv(net_dev
);
812 case ETHTOOL_GRXRINGS
:
813 info
->data
= efx
->n_rx_channels
;
816 case ETHTOOL_GRXFH
: {
820 if (!efx_rss_active(&efx
->rss_context
)) /* No RSS */
823 switch (info
->flow_type
) {
826 if (efx
->rss_context
.rx_hash_udp_4tuple
)
827 data
= (RXH_L4_B_0_1
| RXH_L4_B_2_3
|
828 RXH_IP_SRC
| RXH_IP_DST
);
830 data
= RXH_IP_SRC
| RXH_IP_DST
;
834 data
= (RXH_L4_B_0_1
| RXH_L4_B_2_3
|
835 RXH_IP_SRC
| RXH_IP_DST
);
843 data
= RXH_IP_SRC
| RXH_IP_DST
;
853 case ETHTOOL_GRXCLSRLCNT
:
854 info
->data
= efx_filter_get_rx_id_limit(efx
);
857 info
->data
|= RX_CLS_LOC_SPECIAL
;
859 efx_filter_count_rx_used(efx
, EFX_FILTER_PRI_MANUAL
);
862 case ETHTOOL_GRXCLSRULE
:
863 if (efx_filter_get_rx_id_limit(efx
) == 0)
865 rc
= efx_ethtool_get_class_rule(efx
, &info
->fs
, &rss_context
);
868 if (info
->fs
.flow_type
& FLOW_RSS
)
869 info
->rss_context
= rss_context
;
872 case ETHTOOL_GRXCLSRLALL
:
873 info
->data
= efx_filter_get_rx_id_limit(efx
);
876 rc
= efx_filter_get_rx_ids(efx
, EFX_FILTER_PRI_MANUAL
,
877 rule_locs
, info
->rule_cnt
);
888 static inline bool ip6_mask_is_full(__be32 mask
[4])
890 return !~(mask
[0] & mask
[1] & mask
[2] & mask
[3]);
893 static inline bool ip6_mask_is_empty(__be32 mask
[4])
895 return !(mask
[0] | mask
[1] | mask
[2] | mask
[3]);
898 static int efx_ethtool_set_class_rule(struct efx_nic
*efx
,
899 struct ethtool_rx_flow_spec
*rule
,
902 struct ethtool_tcpip4_spec
*ip_entry
= &rule
->h_u
.tcp_ip4_spec
;
903 struct ethtool_tcpip4_spec
*ip_mask
= &rule
->m_u
.tcp_ip4_spec
;
904 struct ethtool_usrip4_spec
*uip_entry
= &rule
->h_u
.usr_ip4_spec
;
905 struct ethtool_usrip4_spec
*uip_mask
= &rule
->m_u
.usr_ip4_spec
;
906 struct ethtool_tcpip6_spec
*ip6_entry
= &rule
->h_u
.tcp_ip6_spec
;
907 struct ethtool_tcpip6_spec
*ip6_mask
= &rule
->m_u
.tcp_ip6_spec
;
908 struct ethtool_usrip6_spec
*uip6_entry
= &rule
->h_u
.usr_ip6_spec
;
909 struct ethtool_usrip6_spec
*uip6_mask
= &rule
->m_u
.usr_ip6_spec
;
910 u32 flow_type
= rule
->flow_type
& ~(FLOW_EXT
| FLOW_RSS
);
911 struct ethhdr
*mac_entry
= &rule
->h_u
.ether_spec
;
912 struct ethhdr
*mac_mask
= &rule
->m_u
.ether_spec
;
913 enum efx_filter_flags flags
= 0;
914 struct efx_filter_spec spec
;
917 /* Check that user wants us to choose the location */
918 if (rule
->location
!= RX_CLS_LOC_ANY
)
921 /* Range-check ring_cookie */
922 if (rule
->ring_cookie
>= efx
->n_rx_channels
&&
923 rule
->ring_cookie
!= RX_CLS_FLOW_DISC
)
926 /* Check for unsupported extensions */
927 if ((rule
->flow_type
& FLOW_EXT
) &&
928 (rule
->m_ext
.vlan_etype
|| rule
->m_ext
.data
[0] ||
929 rule
->m_ext
.data
[1]))
933 flags
|= EFX_FILTER_FLAG_RX_SCATTER
;
934 if (rule
->flow_type
& FLOW_RSS
)
935 flags
|= EFX_FILTER_FLAG_RX_RSS
;
937 efx_filter_init_rx(&spec
, EFX_FILTER_PRI_MANUAL
, flags
,
938 (rule
->ring_cookie
== RX_CLS_FLOW_DISC
) ?
939 EFX_FILTER_RX_DMAQ_ID_DROP
: rule
->ring_cookie
);
941 if (rule
->flow_type
& FLOW_RSS
)
942 spec
.rss_context
= rss_context
;
947 spec
.match_flags
= (EFX_FILTER_MATCH_ETHER_TYPE
|
948 EFX_FILTER_MATCH_IP_PROTO
);
949 spec
.ether_type
= htons(ETH_P_IP
);
950 spec
.ip_proto
= flow_type
== TCP_V4_FLOW
? IPPROTO_TCP
952 if (ip_mask
->ip4dst
) {
953 if (ip_mask
->ip4dst
!= IP4_ADDR_FULL_MASK
)
955 spec
.match_flags
|= EFX_FILTER_MATCH_LOC_HOST
;
956 spec
.loc_host
[0] = ip_entry
->ip4dst
;
958 if (ip_mask
->ip4src
) {
959 if (ip_mask
->ip4src
!= IP4_ADDR_FULL_MASK
)
961 spec
.match_flags
|= EFX_FILTER_MATCH_REM_HOST
;
962 spec
.rem_host
[0] = ip_entry
->ip4src
;
965 if (ip_mask
->pdst
!= PORT_FULL_MASK
)
967 spec
.match_flags
|= EFX_FILTER_MATCH_LOC_PORT
;
968 spec
.loc_port
= ip_entry
->pdst
;
971 if (ip_mask
->psrc
!= PORT_FULL_MASK
)
973 spec
.match_flags
|= EFX_FILTER_MATCH_REM_PORT
;
974 spec
.rem_port
= ip_entry
->psrc
;
982 spec
.match_flags
= (EFX_FILTER_MATCH_ETHER_TYPE
|
983 EFX_FILTER_MATCH_IP_PROTO
);
984 spec
.ether_type
= htons(ETH_P_IPV6
);
985 spec
.ip_proto
= flow_type
== TCP_V6_FLOW
? IPPROTO_TCP
987 if (!ip6_mask_is_empty(ip6_mask
->ip6dst
)) {
988 if (!ip6_mask_is_full(ip6_mask
->ip6dst
))
990 spec
.match_flags
|= EFX_FILTER_MATCH_LOC_HOST
;
991 memcpy(spec
.loc_host
, ip6_entry
->ip6dst
, sizeof(spec
.loc_host
));
993 if (!ip6_mask_is_empty(ip6_mask
->ip6src
)) {
994 if (!ip6_mask_is_full(ip6_mask
->ip6src
))
996 spec
.match_flags
|= EFX_FILTER_MATCH_REM_HOST
;
997 memcpy(spec
.rem_host
, ip6_entry
->ip6src
, sizeof(spec
.rem_host
));
999 if (ip6_mask
->pdst
) {
1000 if (ip6_mask
->pdst
!= PORT_FULL_MASK
)
1002 spec
.match_flags
|= EFX_FILTER_MATCH_LOC_PORT
;
1003 spec
.loc_port
= ip6_entry
->pdst
;
1005 if (ip6_mask
->psrc
) {
1006 if (ip6_mask
->psrc
!= PORT_FULL_MASK
)
1008 spec
.match_flags
|= EFX_FILTER_MATCH_REM_PORT
;
1009 spec
.rem_port
= ip6_entry
->psrc
;
1011 if (ip6_mask
->tclass
)
1015 case IPV4_USER_FLOW
:
1016 if (uip_mask
->l4_4_bytes
|| uip_mask
->tos
|| uip_mask
->ip_ver
||
1017 uip_entry
->ip_ver
!= ETH_RX_NFC_IP4
)
1019 spec
.match_flags
= EFX_FILTER_MATCH_ETHER_TYPE
;
1020 spec
.ether_type
= htons(ETH_P_IP
);
1021 if (uip_mask
->ip4dst
) {
1022 if (uip_mask
->ip4dst
!= IP4_ADDR_FULL_MASK
)
1024 spec
.match_flags
|= EFX_FILTER_MATCH_LOC_HOST
;
1025 spec
.loc_host
[0] = uip_entry
->ip4dst
;
1027 if (uip_mask
->ip4src
) {
1028 if (uip_mask
->ip4src
!= IP4_ADDR_FULL_MASK
)
1030 spec
.match_flags
|= EFX_FILTER_MATCH_REM_HOST
;
1031 spec
.rem_host
[0] = uip_entry
->ip4src
;
1033 if (uip_mask
->proto
) {
1034 if (uip_mask
->proto
!= IP_PROTO_FULL_MASK
)
1036 spec
.match_flags
|= EFX_FILTER_MATCH_IP_PROTO
;
1037 spec
.ip_proto
= uip_entry
->proto
;
1041 case IPV6_USER_FLOW
:
1042 if (uip6_mask
->l4_4_bytes
|| uip6_mask
->tclass
)
1044 spec
.match_flags
= EFX_FILTER_MATCH_ETHER_TYPE
;
1045 spec
.ether_type
= htons(ETH_P_IPV6
);
1046 if (!ip6_mask_is_empty(uip6_mask
->ip6dst
)) {
1047 if (!ip6_mask_is_full(uip6_mask
->ip6dst
))
1049 spec
.match_flags
|= EFX_FILTER_MATCH_LOC_HOST
;
1050 memcpy(spec
.loc_host
, uip6_entry
->ip6dst
, sizeof(spec
.loc_host
));
1052 if (!ip6_mask_is_empty(uip6_mask
->ip6src
)) {
1053 if (!ip6_mask_is_full(uip6_mask
->ip6src
))
1055 spec
.match_flags
|= EFX_FILTER_MATCH_REM_HOST
;
1056 memcpy(spec
.rem_host
, uip6_entry
->ip6src
, sizeof(spec
.rem_host
));
1058 if (uip6_mask
->l4_proto
) {
1059 if (uip6_mask
->l4_proto
!= IP_PROTO_FULL_MASK
)
1061 spec
.match_flags
|= EFX_FILTER_MATCH_IP_PROTO
;
1062 spec
.ip_proto
= uip6_entry
->l4_proto
;
1067 if (!is_zero_ether_addr(mac_mask
->h_dest
)) {
1068 if (ether_addr_equal(mac_mask
->h_dest
,
1070 spec
.match_flags
|= EFX_FILTER_MATCH_LOC_MAC_IG
;
1071 else if (is_broadcast_ether_addr(mac_mask
->h_dest
))
1072 spec
.match_flags
|= EFX_FILTER_MATCH_LOC_MAC
;
1075 ether_addr_copy(spec
.loc_mac
, mac_entry
->h_dest
);
1077 if (!is_zero_ether_addr(mac_mask
->h_source
)) {
1078 if (!is_broadcast_ether_addr(mac_mask
->h_source
))
1080 spec
.match_flags
|= EFX_FILTER_MATCH_REM_MAC
;
1081 ether_addr_copy(spec
.rem_mac
, mac_entry
->h_source
);
1083 if (mac_mask
->h_proto
) {
1084 if (mac_mask
->h_proto
!= ETHER_TYPE_FULL_MASK
)
1086 spec
.match_flags
|= EFX_FILTER_MATCH_ETHER_TYPE
;
1087 spec
.ether_type
= mac_entry
->h_proto
;
1095 if ((rule
->flow_type
& FLOW_EXT
) && rule
->m_ext
.vlan_tci
) {
1096 if (rule
->m_ext
.vlan_tci
!= htons(0xfff))
1098 spec
.match_flags
|= EFX_FILTER_MATCH_OUTER_VID
;
1099 spec
.outer_vid
= rule
->h_ext
.vlan_tci
;
1102 rc
= efx_filter_insert_filter(efx
, &spec
, true);
1106 rule
->location
= rc
;
1110 int efx_siena_ethtool_set_rxnfc(struct net_device
*net_dev
,
1111 struct ethtool_rxnfc
*info
)
1113 struct efx_nic
*efx
= netdev_priv(net_dev
);
1115 if (efx_filter_get_rx_id_limit(efx
) == 0)
1118 switch (info
->cmd
) {
1119 case ETHTOOL_SRXCLSRLINS
:
1120 return efx_ethtool_set_class_rule(efx
, &info
->fs
,
1123 case ETHTOOL_SRXCLSRLDEL
:
1124 return efx_filter_remove_id_safe(efx
, EFX_FILTER_PRI_MANUAL
,
1132 u32
efx_siena_ethtool_get_rxfh_indir_size(struct net_device
*net_dev
)
1134 struct efx_nic
*efx
= netdev_priv(net_dev
);
1136 if (efx
->n_rx_channels
== 1)
1138 return ARRAY_SIZE(efx
->rss_context
.rx_indir_table
);
1141 u32
efx_siena_ethtool_get_rxfh_key_size(struct net_device
*net_dev
)
1143 struct efx_nic
*efx
= netdev_priv(net_dev
);
1145 return efx
->type
->rx_hash_key_size
;
1148 int efx_siena_ethtool_get_rxfh(struct net_device
*net_dev
,
1149 struct ethtool_rxfh_param
*rxfh
)
1151 struct efx_nic
*efx
= netdev_priv(net_dev
);
1154 rc
= efx
->type
->rx_pull_rss_config(efx
);
1158 rxfh
->hfunc
= ETH_RSS_HASH_TOP
;
1160 memcpy(rxfh
->indir
, efx
->rss_context
.rx_indir_table
,
1161 sizeof(efx
->rss_context
.rx_indir_table
));
1163 memcpy(rxfh
->key
, efx
->rss_context
.rx_hash_key
,
1164 efx
->type
->rx_hash_key_size
);
1168 int efx_siena_ethtool_set_rxfh(struct net_device
*net_dev
,
1169 struct ethtool_rxfh_param
*rxfh
,
1170 struct netlink_ext_ack
*extack
)
1172 struct efx_nic
*efx
= netdev_priv(net_dev
);
1173 u32
*indir
= rxfh
->indir
;
1174 u8
*key
= rxfh
->key
;
1176 /* Hash function is Toeplitz, cannot be changed */
1177 if (rxfh
->hfunc
!= ETH_RSS_HASH_NO_CHANGE
&&
1178 rxfh
->hfunc
!= ETH_RSS_HASH_TOP
)
1185 key
= efx
->rss_context
.rx_hash_key
;
1187 indir
= efx
->rss_context
.rx_indir_table
;
1189 return efx
->type
->rx_push_rss_config(efx
, true, indir
, key
);
1192 int efx_siena_ethtool_reset(struct net_device
*net_dev
, u32
*flags
)
1194 struct efx_nic
*efx
= netdev_priv(net_dev
);
1197 rc
= efx
->type
->map_reset_flags(flags
);
1201 return efx_siena_reset(efx
, rc
);
1204 int efx_siena_ethtool_get_module_eeprom(struct net_device
*net_dev
,
1205 struct ethtool_eeprom
*ee
,
1208 struct efx_nic
*efx
= netdev_priv(net_dev
);
1211 mutex_lock(&efx
->mac_lock
);
1212 ret
= efx_siena_mcdi_phy_get_module_eeprom(efx
, ee
, data
);
1213 mutex_unlock(&efx
->mac_lock
);
1218 int efx_siena_ethtool_get_module_info(struct net_device
*net_dev
,
1219 struct ethtool_modinfo
*modinfo
)
1221 struct efx_nic
*efx
= netdev_priv(net_dev
);
1224 mutex_lock(&efx
->mac_lock
);
1225 ret
= efx_siena_mcdi_phy_get_module_info(efx
, modinfo
);
1226 mutex_unlock(&efx
->mac_lock
);