1 /*******************************************************************************
3 * Intel Ethernet Controller XL710 Family Linux Virtual Function Driver
4 * Copyright(c) 2013 - 2016 Intel Corporation.
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * You should have received a copy of the GNU General Public License along
16 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
21 * Contact Information:
22 * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
23 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
25 ******************************************************************************/
27 /* ethtool support for i40evf */
30 #include <linux/uaccess.h>
33 char stat_string
[ETH_GSTRING_LEN
];
37 #define I40EVF_STAT(_name, _stat) { \
38 .stat_string = _name, \
39 .stat_offset = offsetof(struct i40evf_adapter, _stat) \
42 /* All stats are u64, so we don't need to track the size of the field. */
43 static const struct i40evf_stats i40evf_gstrings_stats
[] = {
44 I40EVF_STAT("rx_bytes", current_stats
.rx_bytes
),
45 I40EVF_STAT("rx_unicast", current_stats
.rx_unicast
),
46 I40EVF_STAT("rx_multicast", current_stats
.rx_multicast
),
47 I40EVF_STAT("rx_broadcast", current_stats
.rx_broadcast
),
48 I40EVF_STAT("rx_discards", current_stats
.rx_discards
),
49 I40EVF_STAT("rx_unknown_protocol", current_stats
.rx_unknown_protocol
),
50 I40EVF_STAT("tx_bytes", current_stats
.tx_bytes
),
51 I40EVF_STAT("tx_unicast", current_stats
.tx_unicast
),
52 I40EVF_STAT("tx_multicast", current_stats
.tx_multicast
),
53 I40EVF_STAT("tx_broadcast", current_stats
.tx_broadcast
),
54 I40EVF_STAT("tx_discards", current_stats
.tx_discards
),
55 I40EVF_STAT("tx_errors", current_stats
.tx_errors
),
58 #define I40EVF_GLOBAL_STATS_LEN ARRAY_SIZE(i40evf_gstrings_stats)
59 #define I40EVF_QUEUE_STATS_LEN(_dev) \
60 (((struct i40evf_adapter *)\
61 netdev_priv(_dev))->num_active_queues \
62 * 2 * (sizeof(struct i40e_queue_stats) / sizeof(u64)))
63 #define I40EVF_STATS_LEN(_dev) \
64 (I40EVF_GLOBAL_STATS_LEN + I40EVF_QUEUE_STATS_LEN(_dev))
66 static const char i40evf_priv_flags_strings
[][ETH_GSTRING_LEN
] = {
70 #define I40EVF_PRIV_FLAGS_STR_LEN ARRAY_SIZE(i40evf_priv_flags_strings)
73 * i40evf_get_settings - Get Link Speed and Duplex settings
74 * @netdev: network interface device structure
75 * @ecmd: ethtool command
77 * Reports speed/duplex settings. Because this is a VF, we don't know what
78 * kind of link we really have, so we fake it.
80 static int i40evf_get_settings(struct net_device
*netdev
,
81 struct ethtool_cmd
*ecmd
)
83 /* In the future the VF will be able to query the PF for
84 * some information - for now use a dummy value
87 ecmd
->autoneg
= AUTONEG_DISABLE
;
88 ecmd
->transceiver
= XCVR_DUMMY1
;
89 ecmd
->port
= PORT_NONE
;
95 * i40evf_get_sset_count - Get length of string set
96 * @netdev: network interface device structure
97 * @sset: id of string set
99 * Reports size of string table. This driver only supports
100 * strings for statistics.
102 static int i40evf_get_sset_count(struct net_device
*netdev
, int sset
)
104 if (sset
== ETH_SS_STATS
)
105 return I40EVF_STATS_LEN(netdev
);
106 else if (sset
== ETH_SS_PRIV_FLAGS
)
107 return I40EVF_PRIV_FLAGS_STR_LEN
;
113 * i40evf_get_ethtool_stats - report device statistics
114 * @netdev: network interface device structure
115 * @stats: ethtool statistics structure
116 * @data: pointer to data buffer
118 * All statistics are added to the data buffer as an array of u64.
120 static void i40evf_get_ethtool_stats(struct net_device
*netdev
,
121 struct ethtool_stats
*stats
, u64
*data
)
123 struct i40evf_adapter
*adapter
= netdev_priv(netdev
);
127 for (i
= 0; i
< I40EVF_GLOBAL_STATS_LEN
; i
++) {
128 p
= (char *)adapter
+ i40evf_gstrings_stats
[i
].stat_offset
;
131 for (j
= 0; j
< adapter
->num_active_queues
; j
++) {
132 data
[i
++] = adapter
->tx_rings
[j
].stats
.packets
;
133 data
[i
++] = adapter
->tx_rings
[j
].stats
.bytes
;
135 for (j
= 0; j
< adapter
->num_active_queues
; j
++) {
136 data
[i
++] = adapter
->rx_rings
[j
].stats
.packets
;
137 data
[i
++] = adapter
->rx_rings
[j
].stats
.bytes
;
142 * i40evf_get_strings - Get string set
143 * @netdev: network interface device structure
144 * @sset: id of string set
145 * @data: buffer for string data
147 * Builds stats string table.
149 static void i40evf_get_strings(struct net_device
*netdev
, u32 sset
, u8
*data
)
151 struct i40evf_adapter
*adapter
= netdev_priv(netdev
);
155 if (sset
== ETH_SS_STATS
) {
156 for (i
= 0; i
< I40EVF_GLOBAL_STATS_LEN
; i
++) {
157 memcpy(p
, i40evf_gstrings_stats
[i
].stat_string
,
159 p
+= ETH_GSTRING_LEN
;
161 for (i
= 0; i
< adapter
->num_active_queues
; i
++) {
162 snprintf(p
, ETH_GSTRING_LEN
, "tx-%u.packets", i
);
163 p
+= ETH_GSTRING_LEN
;
164 snprintf(p
, ETH_GSTRING_LEN
, "tx-%u.bytes", i
);
165 p
+= ETH_GSTRING_LEN
;
167 for (i
= 0; i
< adapter
->num_active_queues
; i
++) {
168 snprintf(p
, ETH_GSTRING_LEN
, "rx-%u.packets", i
);
169 p
+= ETH_GSTRING_LEN
;
170 snprintf(p
, ETH_GSTRING_LEN
, "rx-%u.bytes", i
);
171 p
+= ETH_GSTRING_LEN
;
173 } else if (sset
== ETH_SS_PRIV_FLAGS
) {
174 for (i
= 0; i
< I40EVF_PRIV_FLAGS_STR_LEN
; i
++) {
175 memcpy(data
, i40evf_priv_flags_strings
[i
],
177 data
+= ETH_GSTRING_LEN
;
183 * i40evf_get_msglevel - Get debug message level
184 * @netdev: network interface device structure
186 * Returns current debug message level.
188 static u32
i40evf_get_msglevel(struct net_device
*netdev
)
190 struct i40evf_adapter
*adapter
= netdev_priv(netdev
);
192 return adapter
->msg_enable
;
196 * i40evf_set_msglevel - Set debug message level
197 * @netdev: network interface device structure
198 * @data: message level
200 * Set current debug message level. Higher values cause the driver to
203 static void i40evf_set_msglevel(struct net_device
*netdev
, u32 data
)
205 struct i40evf_adapter
*adapter
= netdev_priv(netdev
);
207 if (I40E_DEBUG_USER
& data
)
208 adapter
->hw
.debug_mask
= data
;
209 adapter
->msg_enable
= data
;
213 * i40evf_get_drvinfo - Get driver info
214 * @netdev: network interface device structure
215 * @drvinfo: ethool driver info structure
217 * Returns information about the driver and device for display to the user.
219 static void i40evf_get_drvinfo(struct net_device
*netdev
,
220 struct ethtool_drvinfo
*drvinfo
)
222 struct i40evf_adapter
*adapter
= netdev_priv(netdev
);
224 strlcpy(drvinfo
->driver
, i40evf_driver_name
, 32);
225 strlcpy(drvinfo
->version
, i40evf_driver_version
, 32);
226 strlcpy(drvinfo
->fw_version
, "N/A", 4);
227 strlcpy(drvinfo
->bus_info
, pci_name(adapter
->pdev
), 32);
228 drvinfo
->n_priv_flags
= I40EVF_PRIV_FLAGS_STR_LEN
;
232 * i40evf_get_ringparam - Get ring parameters
233 * @netdev: network interface device structure
234 * @ring: ethtool ringparam structure
236 * Returns current ring parameters. TX and RX rings are reported separately,
237 * but the number of rings is not reported.
239 static void i40evf_get_ringparam(struct net_device
*netdev
,
240 struct ethtool_ringparam
*ring
)
242 struct i40evf_adapter
*adapter
= netdev_priv(netdev
);
244 ring
->rx_max_pending
= I40EVF_MAX_RXD
;
245 ring
->tx_max_pending
= I40EVF_MAX_TXD
;
246 ring
->rx_pending
= adapter
->rx_desc_count
;
247 ring
->tx_pending
= adapter
->tx_desc_count
;
251 * i40evf_set_ringparam - Set ring parameters
252 * @netdev: network interface device structure
253 * @ring: ethtool ringparam structure
255 * Sets ring parameters. TX and RX rings are controlled separately, but the
256 * number of rings is not specified, so all rings get the same settings.
258 static int i40evf_set_ringparam(struct net_device
*netdev
,
259 struct ethtool_ringparam
*ring
)
261 struct i40evf_adapter
*adapter
= netdev_priv(netdev
);
262 u32 new_rx_count
, new_tx_count
;
264 if ((ring
->rx_mini_pending
) || (ring
->rx_jumbo_pending
))
267 new_tx_count
= clamp_t(u32
, ring
->tx_pending
,
270 new_tx_count
= ALIGN(new_tx_count
, I40EVF_REQ_DESCRIPTOR_MULTIPLE
);
272 new_rx_count
= clamp_t(u32
, ring
->rx_pending
,
275 new_rx_count
= ALIGN(new_rx_count
, I40EVF_REQ_DESCRIPTOR_MULTIPLE
);
277 /* if nothing to do return success */
278 if ((new_tx_count
== adapter
->tx_desc_count
) &&
279 (new_rx_count
== adapter
->rx_desc_count
))
282 adapter
->tx_desc_count
= new_tx_count
;
283 adapter
->rx_desc_count
= new_rx_count
;
285 if (netif_running(netdev
)) {
286 adapter
->flags
|= I40EVF_FLAG_RESET_NEEDED
;
287 schedule_work(&adapter
->reset_task
);
294 * i40evf_get_coalesce - Get interrupt coalescing settings
295 * @netdev: network interface device structure
296 * @ec: ethtool coalesce structure
298 * Returns current coalescing settings. This is referred to elsewhere in the
299 * driver as Interrupt Throttle Rate, as this is how the hardware describes
300 * this functionality.
302 static int i40evf_get_coalesce(struct net_device
*netdev
,
303 struct ethtool_coalesce
*ec
)
305 struct i40evf_adapter
*adapter
= netdev_priv(netdev
);
306 struct i40e_vsi
*vsi
= &adapter
->vsi
;
308 ec
->tx_max_coalesced_frames
= vsi
->work_limit
;
309 ec
->rx_max_coalesced_frames
= vsi
->work_limit
;
311 if (ITR_IS_DYNAMIC(vsi
->rx_itr_setting
))
312 ec
->use_adaptive_rx_coalesce
= 1;
314 if (ITR_IS_DYNAMIC(vsi
->tx_itr_setting
))
315 ec
->use_adaptive_tx_coalesce
= 1;
317 ec
->rx_coalesce_usecs
= vsi
->rx_itr_setting
& ~I40E_ITR_DYNAMIC
;
318 ec
->tx_coalesce_usecs
= vsi
->tx_itr_setting
& ~I40E_ITR_DYNAMIC
;
324 * i40evf_set_coalesce - Set interrupt coalescing settings
325 * @netdev: network interface device structure
326 * @ec: ethtool coalesce structure
328 * Change current coalescing settings.
330 static int i40evf_set_coalesce(struct net_device
*netdev
,
331 struct ethtool_coalesce
*ec
)
333 struct i40evf_adapter
*adapter
= netdev_priv(netdev
);
334 struct i40e_hw
*hw
= &adapter
->hw
;
335 struct i40e_vsi
*vsi
= &adapter
->vsi
;
336 struct i40e_q_vector
*q_vector
;
339 if (ec
->tx_max_coalesced_frames_irq
|| ec
->rx_max_coalesced_frames_irq
)
340 vsi
->work_limit
= ec
->tx_max_coalesced_frames_irq
;
342 if ((ec
->rx_coalesce_usecs
>= (I40E_MIN_ITR
<< 1)) &&
343 (ec
->rx_coalesce_usecs
<= (I40E_MAX_ITR
<< 1)))
344 vsi
->rx_itr_setting
= ec
->rx_coalesce_usecs
;
349 if ((ec
->tx_coalesce_usecs
>= (I40E_MIN_ITR
<< 1)) &&
350 (ec
->tx_coalesce_usecs
<= (I40E_MAX_ITR
<< 1)))
351 vsi
->tx_itr_setting
= ec
->tx_coalesce_usecs
;
352 else if (ec
->use_adaptive_tx_coalesce
)
353 vsi
->tx_itr_setting
= (I40E_ITR_DYNAMIC
|
354 ITR_REG_TO_USEC(I40E_ITR_RX_DEF
));
358 if (ec
->use_adaptive_rx_coalesce
)
359 vsi
->rx_itr_setting
|= I40E_ITR_DYNAMIC
;
361 vsi
->rx_itr_setting
&= ~I40E_ITR_DYNAMIC
;
363 if (ec
->use_adaptive_tx_coalesce
)
364 vsi
->tx_itr_setting
|= I40E_ITR_DYNAMIC
;
366 vsi
->tx_itr_setting
&= ~I40E_ITR_DYNAMIC
;
368 for (i
= 0; i
< adapter
->num_msix_vectors
- NONQ_VECS
; i
++) {
369 q_vector
= &adapter
->q_vectors
[i
];
370 q_vector
->rx
.itr
= ITR_TO_REG(vsi
->rx_itr_setting
);
371 wr32(hw
, I40E_VFINT_ITRN1(0, i
), q_vector
->rx
.itr
);
372 q_vector
->tx
.itr
= ITR_TO_REG(vsi
->tx_itr_setting
);
373 wr32(hw
, I40E_VFINT_ITRN1(1, i
), q_vector
->tx
.itr
);
381 * i40e_get_rss_hash_opts - Get RSS hash Input Set for each flow type
382 * @adapter: board private structure
383 * @cmd: ethtool rxnfc command
385 * Returns Success if the flow is supported, else Invalid Input.
387 static int i40evf_get_rss_hash_opts(struct i40evf_adapter
*adapter
,
388 struct ethtool_rxnfc
*cmd
)
390 struct i40e_hw
*hw
= &adapter
->hw
;
391 u64 hena
= (u64
)rd32(hw
, I40E_VFQF_HENA(0)) |
392 ((u64
)rd32(hw
, I40E_VFQF_HENA(1)) << 32);
394 /* We always hash on IP src and dest addresses */
395 cmd
->data
= RXH_IP_SRC
| RXH_IP_DST
;
397 switch (cmd
->flow_type
) {
399 if (hena
& BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP
))
400 cmd
->data
|= RXH_L4_B_0_1
| RXH_L4_B_2_3
;
403 if (hena
& BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_UDP
))
404 cmd
->data
|= RXH_L4_B_0_1
| RXH_L4_B_2_3
;
415 if (hena
& BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP
))
416 cmd
->data
|= RXH_L4_B_0_1
| RXH_L4_B_2_3
;
419 if (hena
& BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_UDP
))
420 cmd
->data
|= RXH_L4_B_0_1
| RXH_L4_B_2_3
;
438 * i40evf_get_rxnfc - command to get RX flow classification rules
439 * @netdev: network interface device structure
440 * @cmd: ethtool rxnfc command
442 * Returns Success if the command is supported.
444 static int i40evf_get_rxnfc(struct net_device
*netdev
,
445 struct ethtool_rxnfc
*cmd
,
448 struct i40evf_adapter
*adapter
= netdev_priv(netdev
);
449 int ret
= -EOPNOTSUPP
;
452 case ETHTOOL_GRXRINGS
:
453 cmd
->data
= adapter
->num_active_queues
;
457 ret
= i40evf_get_rss_hash_opts(adapter
, cmd
);
467 * i40evf_set_rss_hash_opt - Enable/Disable flow types for RSS hash
468 * @adapter: board private structure
469 * @cmd: ethtool rxnfc command
471 * Returns Success if the flow input set is supported.
473 static int i40evf_set_rss_hash_opt(struct i40evf_adapter
*adapter
,
474 struct ethtool_rxnfc
*nfc
)
476 struct i40e_hw
*hw
= &adapter
->hw
;
477 u32 flags
= adapter
->vf_res
->vf_offload_flags
;
479 u64 hena
= (u64
)rd32(hw
, I40E_VFQF_HENA(0)) |
480 ((u64
)rd32(hw
, I40E_VFQF_HENA(1)) << 32);
482 /* RSS does not support anything other than hashing
483 * to queues on src and dst IPs and ports
485 if (nfc
->data
& ~(RXH_IP_SRC
| RXH_IP_DST
|
486 RXH_L4_B_0_1
| RXH_L4_B_2_3
))
489 /* We need at least the IP SRC and DEST fields for hashing */
490 if (!(nfc
->data
& RXH_IP_SRC
) ||
491 !(nfc
->data
& RXH_IP_DST
))
494 switch (nfc
->flow_type
) {
496 if (nfc
->data
& (RXH_L4_B_0_1
| RXH_L4_B_2_3
)) {
497 if (flags
& I40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2
)
499 BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK
);
501 hena
|= BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP
);
507 if (nfc
->data
& (RXH_L4_B_0_1
| RXH_L4_B_2_3
)) {
508 if (flags
& I40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2
)
510 BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK
);
512 hena
|= BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP
);
518 if (nfc
->data
& (RXH_L4_B_0_1
| RXH_L4_B_2_3
)) {
519 if (flags
& I40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2
)
521 BIT_ULL(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP
) |
522 BIT_ULL(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP
);
524 hena
|= (BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_UDP
) |
525 BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV4
));
531 if (nfc
->data
& (RXH_L4_B_0_1
| RXH_L4_B_2_3
)) {
532 if (flags
& I40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2
)
534 BIT_ULL(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP
) |
535 BIT_ULL(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP
);
537 hena
|= (BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_UDP
) |
538 BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV6
));
547 if ((nfc
->data
& RXH_L4_B_0_1
) ||
548 (nfc
->data
& RXH_L4_B_2_3
))
550 hena
|= BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_OTHER
);
556 if ((nfc
->data
& RXH_L4_B_0_1
) ||
557 (nfc
->data
& RXH_L4_B_2_3
))
559 hena
|= BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_OTHER
);
562 hena
|= (BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_OTHER
) |
563 BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV4
));
566 hena
|= (BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_OTHER
) |
567 BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV6
));
573 wr32(hw
, I40E_VFQF_HENA(0), (u32
)hena
);
574 wr32(hw
, I40E_VFQF_HENA(1), (u32
)(hena
>> 32));
581 * i40evf_set_rxnfc - command to set RX flow classification rules
582 * @netdev: network interface device structure
583 * @cmd: ethtool rxnfc command
585 * Returns Success if the command is supported.
587 static int i40evf_set_rxnfc(struct net_device
*netdev
,
588 struct ethtool_rxnfc
*cmd
)
590 struct i40evf_adapter
*adapter
= netdev_priv(netdev
);
591 int ret
= -EOPNOTSUPP
;
595 ret
= i40evf_set_rss_hash_opt(adapter
, cmd
);
605 * i40evf_get_channels: get the number of channels supported by the device
606 * @netdev: network interface device structure
607 * @ch: channel information structure
609 * For the purposes of our device, we only use combined channels, i.e. a tx/rx
610 * queue pair. Report one extra channel to match our "other" MSI-X vector.
612 static void i40evf_get_channels(struct net_device
*netdev
,
613 struct ethtool_channels
*ch
)
615 struct i40evf_adapter
*adapter
= netdev_priv(netdev
);
617 /* Report maximum channels */
618 ch
->max_combined
= adapter
->num_active_queues
;
620 ch
->max_other
= NONQ_VECS
;
621 ch
->other_count
= NONQ_VECS
;
623 ch
->combined_count
= adapter
->num_active_queues
;
627 * i40evf_get_rxfh_indir_size - get the rx flow hash indirection table size
628 * @netdev: network interface device structure
630 * Returns the table size.
632 static u32
i40evf_get_rxfh_indir_size(struct net_device
*netdev
)
634 return (I40E_VFQF_HLUT_MAX_INDEX
+ 1) * 4;
638 * i40evf_get_rxfh - get the rx flow hash indirection table
639 * @netdev: network interface device structure
640 * @indir: indirection table
643 * Reads the indirection table directly from the hardware. Always returns 0.
645 static int i40evf_get_rxfh(struct net_device
*netdev
, u32
*indir
, u8
*key
,
648 struct i40evf_adapter
*adapter
= netdev_priv(netdev
);
649 struct i40e_vsi
*vsi
= &adapter
->vsi
;
650 u8
*seed
= NULL
, *lut
;
655 *hfunc
= ETH_RSS_HASH_TOP
;
661 lut
= kzalloc(I40EVF_HLUT_ARRAY_SIZE
, GFP_KERNEL
);
665 ret
= i40evf_get_rss(vsi
, seed
, lut
, I40EVF_HLUT_ARRAY_SIZE
);
669 /* Each 32 bits pointed by 'indir' is stored with a lut entry */
670 for (i
= 0; i
< I40EVF_HLUT_ARRAY_SIZE
; i
++)
671 indir
[i
] = (u32
)lut
[i
];
680 * i40evf_set_rxfh - set the rx flow hash indirection table
681 * @netdev: network interface device structure
682 * @indir: indirection table
685 * Returns -EINVAL if the table specifies an inavlid queue id, otherwise
686 * returns 0 after programming the table.
688 static int i40evf_set_rxfh(struct net_device
*netdev
, const u32
*indir
,
689 const u8
*key
, const u8 hfunc
)
691 struct i40evf_adapter
*adapter
= netdev_priv(netdev
);
692 struct i40e_vsi
*vsi
= &adapter
->vsi
;
696 /* We do not allow change in unsupported parameters */
698 (hfunc
!= ETH_RSS_HASH_NO_CHANGE
&& hfunc
!= ETH_RSS_HASH_TOP
))
704 if (!vsi
->rss_hkey_user
) {
705 vsi
->rss_hkey_user
= kzalloc(I40EVF_HKEY_ARRAY_SIZE
,
707 if (!vsi
->rss_hkey_user
)
710 memcpy(vsi
->rss_hkey_user
, key
, I40EVF_HKEY_ARRAY_SIZE
);
711 seed
= vsi
->rss_hkey_user
;
713 if (!vsi
->rss_lut_user
) {
714 vsi
->rss_lut_user
= kzalloc(I40EVF_HLUT_ARRAY_SIZE
,
716 if (!vsi
->rss_lut_user
)
720 /* Each 32 bits pointed by 'indir' is stored with a lut entry */
721 for (i
= 0; i
< I40EVF_HLUT_ARRAY_SIZE
; i
++)
722 vsi
->rss_lut_user
[i
] = (u8
)(indir
[i
]);
724 return i40evf_config_rss(vsi
, seed
, vsi
->rss_lut_user
,
725 I40EVF_HLUT_ARRAY_SIZE
);
729 * i40evf_get_priv_flags - report device private flags
730 * @dev: network interface device structure
732 * The get string set count and the string set should be matched for each
733 * flag returned. Add new strings for each flag to the i40e_priv_flags_strings
736 * Returns a u32 bitmap of flags.
738 static u32
i40evf_get_priv_flags(struct net_device
*dev
)
740 struct i40evf_adapter
*adapter
= netdev_priv(dev
);
743 ret_flags
|= adapter
->flags
& I40EVF_FLAG_RX_PS_ENABLED
?
744 I40EVF_PRIV_FLAGS_PS
: 0;
750 * i40evf_set_priv_flags - set private flags
751 * @dev: network interface device structure
752 * @flags: bit flags to be set
754 static int i40evf_set_priv_flags(struct net_device
*dev
, u32 flags
)
756 struct i40evf_adapter
*adapter
= netdev_priv(dev
);
757 bool reset_required
= false;
759 if ((flags
& I40EVF_PRIV_FLAGS_PS
) &&
760 !(adapter
->flags
& I40EVF_FLAG_RX_PS_ENABLED
)) {
761 adapter
->flags
|= I40EVF_FLAG_RX_PS_ENABLED
;
762 reset_required
= true;
763 } else if (!(flags
& I40EVF_PRIV_FLAGS_PS
) &&
764 (adapter
->flags
& I40EVF_FLAG_RX_PS_ENABLED
)) {
765 adapter
->flags
&= ~I40EVF_FLAG_RX_PS_ENABLED
;
766 reset_required
= true;
769 /* if needed, issue reset to cause things to take effect */
771 i40evf_schedule_reset(adapter
);
776 static const struct ethtool_ops i40evf_ethtool_ops
= {
777 .get_settings
= i40evf_get_settings
,
778 .get_drvinfo
= i40evf_get_drvinfo
,
779 .get_link
= ethtool_op_get_link
,
780 .get_ringparam
= i40evf_get_ringparam
,
781 .set_ringparam
= i40evf_set_ringparam
,
782 .get_strings
= i40evf_get_strings
,
783 .get_ethtool_stats
= i40evf_get_ethtool_stats
,
784 .get_sset_count
= i40evf_get_sset_count
,
785 .get_priv_flags
= i40evf_get_priv_flags
,
786 .set_priv_flags
= i40evf_set_priv_flags
,
787 .get_msglevel
= i40evf_get_msglevel
,
788 .set_msglevel
= i40evf_set_msglevel
,
789 .get_coalesce
= i40evf_get_coalesce
,
790 .set_coalesce
= i40evf_set_coalesce
,
791 .get_rxnfc
= i40evf_get_rxnfc
,
792 .set_rxnfc
= i40evf_set_rxnfc
,
793 .get_rxfh_indir_size
= i40evf_get_rxfh_indir_size
,
794 .get_rxfh
= i40evf_get_rxfh
,
795 .set_rxfh
= i40evf_set_rxfh
,
796 .get_channels
= i40evf_get_channels
,
800 * i40evf_set_ethtool_ops - Initialize ethtool ops struct
801 * @netdev: network interface device structure
803 * Sets ethtool ops struct in our netdev so that ethtool can call
806 void i40evf_set_ethtool_ops(struct net_device
*netdev
)
808 netdev
->ethtool_ops
= &i40evf_ethtool_ops
;