1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28#include "i40evf.h"
29
30#include <linux/uaccess.h>
31
32struct i40evf_stats {
33 char stat_string[ETH_GSTRING_LEN];
34 int stat_offset;
35};
36
37#define I40EVF_STAT(_name, _stat) { \
38 .stat_string = _name, \
39 .stat_offset = offsetof(struct i40evf_adapter, _stat) \
40}
41
42
43static 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),
56};
57
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))
65
66
67
68
69
70
71
72
73
74static int i40evf_get_settings(struct net_device *netdev,
75 struct ethtool_cmd *ecmd)
76{
77 struct i40evf_adapter *adapter = netdev_priv(netdev);
78
79 ecmd->supported = 0;
80 ecmd->autoneg = AUTONEG_DISABLE;
81 ecmd->transceiver = XCVR_DUMMY1;
82 ecmd->port = PORT_NONE;
83
84 switch (adapter->link_speed) {
85 case I40E_LINK_SPEED_40GB:
86 ethtool_cmd_speed_set(ecmd, SPEED_40000);
87 break;
88 case I40E_LINK_SPEED_20GB:
89 ethtool_cmd_speed_set(ecmd, SPEED_20000);
90 break;
91 case I40E_LINK_SPEED_10GB:
92 ethtool_cmd_speed_set(ecmd, SPEED_10000);
93 break;
94 case I40E_LINK_SPEED_1GB:
95 ethtool_cmd_speed_set(ecmd, SPEED_1000);
96 break;
97 case I40E_LINK_SPEED_100MB:
98 ethtool_cmd_speed_set(ecmd, SPEED_100);
99 break;
100 default:
101 break;
102 }
103 ecmd->duplex = DUPLEX_FULL;
104
105 return 0;
106}
107
108
109
110
111
112
113
114
115
116static int i40evf_get_sset_count(struct net_device *netdev, int sset)
117{
118 if (sset == ETH_SS_STATS)
119 return I40EVF_STATS_LEN(netdev);
120 else
121 return -EINVAL;
122}
123
124
125
126
127
128
129
130
131
132static void i40evf_get_ethtool_stats(struct net_device *netdev,
133 struct ethtool_stats *stats, u64 *data)
134{
135 struct i40evf_adapter *adapter = netdev_priv(netdev);
136 int i, j;
137 char *p;
138
139 for (i = 0; i < I40EVF_GLOBAL_STATS_LEN; i++) {
140 p = (char *)adapter + i40evf_gstrings_stats[i].stat_offset;
141 data[i] = *(u64 *)p;
142 }
143 for (j = 0; j < adapter->num_active_queues; j++) {
144 data[i++] = adapter->tx_rings[j].stats.packets;
145 data[i++] = adapter->tx_rings[j].stats.bytes;
146 }
147 for (j = 0; j < adapter->num_active_queues; j++) {
148 data[i++] = adapter->rx_rings[j].stats.packets;
149 data[i++] = adapter->rx_rings[j].stats.bytes;
150 }
151}
152
153
154
155
156
157
158
159
160
161static void i40evf_get_strings(struct net_device *netdev, u32 sset, u8 *data)
162{
163 struct i40evf_adapter *adapter = netdev_priv(netdev);
164 u8 *p = data;
165 int i;
166
167 if (sset == ETH_SS_STATS) {
168 for (i = 0; i < I40EVF_GLOBAL_STATS_LEN; i++) {
169 memcpy(p, i40evf_gstrings_stats[i].stat_string,
170 ETH_GSTRING_LEN);
171 p += ETH_GSTRING_LEN;
172 }
173 for (i = 0; i < adapter->num_active_queues; i++) {
174 snprintf(p, ETH_GSTRING_LEN, "tx-%u.packets", i);
175 p += ETH_GSTRING_LEN;
176 snprintf(p, ETH_GSTRING_LEN, "tx-%u.bytes", i);
177 p += ETH_GSTRING_LEN;
178 }
179 for (i = 0; i < adapter->num_active_queues; i++) {
180 snprintf(p, ETH_GSTRING_LEN, "rx-%u.packets", i);
181 p += ETH_GSTRING_LEN;
182 snprintf(p, ETH_GSTRING_LEN, "rx-%u.bytes", i);
183 p += ETH_GSTRING_LEN;
184 }
185 }
186}
187
188
189
190
191
192
193
194static u32 i40evf_get_msglevel(struct net_device *netdev)
195{
196 struct i40evf_adapter *adapter = netdev_priv(netdev);
197
198 return adapter->msg_enable;
199}
200
201
202
203
204
205
206
207
208
209static void i40evf_set_msglevel(struct net_device *netdev, u32 data)
210{
211 struct i40evf_adapter *adapter = netdev_priv(netdev);
212
213 if (I40E_DEBUG_USER & data)
214 adapter->hw.debug_mask = data;
215 adapter->msg_enable = data;
216}
217
218
219
220
221
222
223
224
225static void i40evf_get_drvinfo(struct net_device *netdev,
226 struct ethtool_drvinfo *drvinfo)
227{
228 struct i40evf_adapter *adapter = netdev_priv(netdev);
229
230 strlcpy(drvinfo->driver, i40evf_driver_name, 32);
231 strlcpy(drvinfo->version, i40evf_driver_version, 32);
232 strlcpy(drvinfo->fw_version, "N/A", 4);
233 strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
234}
235
236
237
238
239
240
241
242
243
244static void i40evf_get_ringparam(struct net_device *netdev,
245 struct ethtool_ringparam *ring)
246{
247 struct i40evf_adapter *adapter = netdev_priv(netdev);
248
249 ring->rx_max_pending = I40EVF_MAX_RXD;
250 ring->tx_max_pending = I40EVF_MAX_TXD;
251 ring->rx_pending = adapter->rx_desc_count;
252 ring->tx_pending = adapter->tx_desc_count;
253}
254
255
256
257
258
259
260
261
262
263static int i40evf_set_ringparam(struct net_device *netdev,
264 struct ethtool_ringparam *ring)
265{
266 struct i40evf_adapter *adapter = netdev_priv(netdev);
267 u32 new_rx_count, new_tx_count;
268
269 if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
270 return -EINVAL;
271
272 new_tx_count = clamp_t(u32, ring->tx_pending,
273 I40EVF_MIN_TXD,
274 I40EVF_MAX_TXD);
275 new_tx_count = ALIGN(new_tx_count, I40EVF_REQ_DESCRIPTOR_MULTIPLE);
276
277 new_rx_count = clamp_t(u32, ring->rx_pending,
278 I40EVF_MIN_RXD,
279 I40EVF_MAX_RXD);
280 new_rx_count = ALIGN(new_rx_count, I40EVF_REQ_DESCRIPTOR_MULTIPLE);
281
282
283 if ((new_tx_count == adapter->tx_desc_count) &&
284 (new_rx_count == adapter->rx_desc_count))
285 return 0;
286
287 adapter->tx_desc_count = new_tx_count;
288 adapter->rx_desc_count = new_rx_count;
289
290 if (netif_running(netdev)) {
291 adapter->flags |= I40EVF_FLAG_RESET_NEEDED;
292 schedule_work(&adapter->reset_task);
293 }
294
295 return 0;
296}
297
298
299
300
301
302
303
304
305
306
307
308static int __i40evf_get_coalesce(struct net_device *netdev,
309 struct ethtool_coalesce *ec,
310 int queue)
311{
312 struct i40evf_adapter *adapter = netdev_priv(netdev);
313 struct i40e_vsi *vsi = &adapter->vsi;
314 struct i40e_ring *rx_ring, *tx_ring;
315
316 ec->tx_max_coalesced_frames = vsi->work_limit;
317 ec->rx_max_coalesced_frames = vsi->work_limit;
318
319
320
321
322 if (queue < 0)
323 queue = 0;
324 else if (queue >= adapter->num_active_queues)
325 return -EINVAL;
326
327 rx_ring = &adapter->rx_rings[queue];
328 tx_ring = &adapter->tx_rings[queue];
329
330 if (ITR_IS_DYNAMIC(rx_ring->rx_itr_setting))
331 ec->use_adaptive_rx_coalesce = 1;
332
333 if (ITR_IS_DYNAMIC(tx_ring->tx_itr_setting))
334 ec->use_adaptive_tx_coalesce = 1;
335
336 ec->rx_coalesce_usecs = rx_ring->rx_itr_setting & ~I40E_ITR_DYNAMIC;
337 ec->tx_coalesce_usecs = tx_ring->tx_itr_setting & ~I40E_ITR_DYNAMIC;
338
339 return 0;
340}
341
342
343
344
345
346
347
348
349
350
351
352static int i40evf_get_coalesce(struct net_device *netdev,
353 struct ethtool_coalesce *ec)
354{
355 return __i40evf_get_coalesce(netdev, ec, -1);
356}
357
358
359
360
361
362
363
364
365
366static int i40evf_get_per_queue_coalesce(struct net_device *netdev,
367 u32 queue,
368 struct ethtool_coalesce *ec)
369{
370 return __i40evf_get_coalesce(netdev, ec, queue);
371}
372
373
374
375
376
377
378
379
380
381static void i40evf_set_itr_per_queue(struct i40evf_adapter *adapter,
382 struct ethtool_coalesce *ec,
383 int queue)
384{
385 struct i40e_vsi *vsi = &adapter->vsi;
386 struct i40e_hw *hw = &adapter->hw;
387 struct i40e_q_vector *q_vector;
388 u16 vector;
389
390 adapter->rx_rings[queue].rx_itr_setting = ec->rx_coalesce_usecs;
391 adapter->tx_rings[queue].tx_itr_setting = ec->tx_coalesce_usecs;
392
393 if (ec->use_adaptive_rx_coalesce)
394 adapter->rx_rings[queue].rx_itr_setting |= I40E_ITR_DYNAMIC;
395 else
396 adapter->rx_rings[queue].rx_itr_setting &= ~I40E_ITR_DYNAMIC;
397
398 if (ec->use_adaptive_tx_coalesce)
399 adapter->tx_rings[queue].tx_itr_setting |= I40E_ITR_DYNAMIC;
400 else
401 adapter->tx_rings[queue].tx_itr_setting &= ~I40E_ITR_DYNAMIC;
402
403 q_vector = adapter->rx_rings[queue].q_vector;
404 q_vector->rx.itr = ITR_TO_REG(adapter->rx_rings[queue].rx_itr_setting);
405 vector = vsi->base_vector + q_vector->v_idx;
406 wr32(hw, I40E_VFINT_ITRN1(I40E_RX_ITR, vector - 1), q_vector->rx.itr);
407
408 q_vector = adapter->tx_rings[queue].q_vector;
409 q_vector->tx.itr = ITR_TO_REG(adapter->tx_rings[queue].tx_itr_setting);
410 vector = vsi->base_vector + q_vector->v_idx;
411 wr32(hw, I40E_VFINT_ITRN1(I40E_TX_ITR, vector - 1), q_vector->tx.itr);
412
413 i40e_flush(hw);
414}
415
416
417
418
419
420
421
422
423
424static int __i40evf_set_coalesce(struct net_device *netdev,
425 struct ethtool_coalesce *ec,
426 int queue)
427{
428 struct i40evf_adapter *adapter = netdev_priv(netdev);
429 struct i40e_vsi *vsi = &adapter->vsi;
430 int i;
431
432 if (ec->tx_max_coalesced_frames_irq || ec->rx_max_coalesced_frames_irq)
433 vsi->work_limit = ec->tx_max_coalesced_frames_irq;
434
435 if (ec->rx_coalesce_usecs == 0) {
436 if (ec->use_adaptive_rx_coalesce)
437 netif_info(adapter, drv, netdev, "rx-usecs=0, need to disable adaptive-rx for a complete disable\n");
438 } else if ((ec->rx_coalesce_usecs < (I40E_MIN_ITR << 1)) ||
439 (ec->rx_coalesce_usecs > (I40E_MAX_ITR << 1))) {
440 netif_info(adapter, drv, netdev, "Invalid value, rx-usecs range is 0-8160\n");
441 return -EINVAL;
442 }
443
444 else
445 if (ec->tx_coalesce_usecs == 0) {
446 if (ec->use_adaptive_tx_coalesce)
447 netif_info(adapter, drv, netdev, "tx-usecs=0, need to disable adaptive-tx for a complete disable\n");
448 } else if ((ec->tx_coalesce_usecs < (I40E_MIN_ITR << 1)) ||
449 (ec->tx_coalesce_usecs > (I40E_MAX_ITR << 1))) {
450 netif_info(adapter, drv, netdev, "Invalid value, tx-usecs range is 0-8160\n");
451 return -EINVAL;
452 }
453
454
455
456
457 if (queue < 0) {
458 for (i = 0; i < adapter->num_active_queues; i++)
459 i40evf_set_itr_per_queue(adapter, ec, i);
460 } else if (queue < adapter->num_active_queues) {
461 i40evf_set_itr_per_queue(adapter, ec, queue);
462 } else {
463 netif_info(adapter, drv, netdev, "Invalid queue value, queue range is 0 - %d\n",
464 adapter->num_active_queues - 1);
465 return -EINVAL;
466 }
467
468 return 0;
469}
470
471
472
473
474
475
476
477
478static int i40evf_set_coalesce(struct net_device *netdev,
479 struct ethtool_coalesce *ec)
480{
481 return __i40evf_set_coalesce(netdev, ec, -1);
482}
483
484
485
486
487
488
489
490
491
492static int i40evf_set_per_queue_coalesce(struct net_device *netdev,
493 u32 queue,
494 struct ethtool_coalesce *ec)
495{
496 return __i40evf_set_coalesce(netdev, ec, queue);
497}
498
499
500
501
502
503
504
505
506static int i40evf_get_rxnfc(struct net_device *netdev,
507 struct ethtool_rxnfc *cmd,
508 u32 *rule_locs)
509{
510 struct i40evf_adapter *adapter = netdev_priv(netdev);
511 int ret = -EOPNOTSUPP;
512
513 switch (cmd->cmd) {
514 case ETHTOOL_GRXRINGS:
515 cmd->data = adapter->num_active_queues;
516 ret = 0;
517 break;
518 case ETHTOOL_GRXFH:
519 netdev_info(netdev,
520 "RSS hash info is not available to vf, use pf.\n");
521 break;
522 default:
523 break;
524 }
525
526 return ret;
527}
528
529
530
531
532
533
534
535
536static void i40evf_get_channels(struct net_device *netdev,
537 struct ethtool_channels *ch)
538{
539 struct i40evf_adapter *adapter = netdev_priv(netdev);
540
541
542 ch->max_combined = adapter->num_active_queues;
543
544 ch->max_other = NONQ_VECS;
545 ch->other_count = NONQ_VECS;
546
547 ch->combined_count = adapter->num_active_queues;
548}
549
550
551
552
553
554
555
556static u32 i40evf_get_rxfh_key_size(struct net_device *netdev)
557{
558 struct i40evf_adapter *adapter = netdev_priv(netdev);
559
560 return adapter->rss_key_size;
561}
562
563
564
565
566
567
568
569static u32 i40evf_get_rxfh_indir_size(struct net_device *netdev)
570{
571 struct i40evf_adapter *adapter = netdev_priv(netdev);
572
573 return adapter->rss_lut_size;
574}
575
576
577
578
579
580
581
582
583
584static int i40evf_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
585 u8 *hfunc)
586{
587 struct i40evf_adapter *adapter = netdev_priv(netdev);
588 u16 i;
589
590 if (hfunc)
591 *hfunc = ETH_RSS_HASH_TOP;
592 if (!indir)
593 return 0;
594
595 memcpy(key, adapter->rss_key, adapter->rss_key_size);
596
597
598 for (i = 0; i < adapter->rss_lut_size; i++)
599 indir[i] = (u32)adapter->rss_lut[i];
600
601 return 0;
602}
603
604
605
606
607
608
609
610
611
612
613static int i40evf_set_rxfh(struct net_device *netdev, const u32 *indir,
614 const u8 *key, const u8 hfunc)
615{
616 struct i40evf_adapter *adapter = netdev_priv(netdev);
617 u16 i;
618
619
620 if (key ||
621 (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP))
622 return -EOPNOTSUPP;
623 if (!indir)
624 return 0;
625
626 if (key) {
627 memcpy(adapter->rss_key, key, adapter->rss_key_size);
628 }
629
630
631 for (i = 0; i < adapter->rss_lut_size; i++)
632 adapter->rss_lut[i] = (u8)(indir[i]);
633
634 return i40evf_config_rss(adapter);
635}
636
637static const struct ethtool_ops i40evf_ethtool_ops = {
638 .get_settings = i40evf_get_settings,
639 .get_drvinfo = i40evf_get_drvinfo,
640 .get_link = ethtool_op_get_link,
641 .get_ringparam = i40evf_get_ringparam,
642 .set_ringparam = i40evf_set_ringparam,
643 .get_strings = i40evf_get_strings,
644 .get_ethtool_stats = i40evf_get_ethtool_stats,
645 .get_sset_count = i40evf_get_sset_count,
646 .get_msglevel = i40evf_get_msglevel,
647 .set_msglevel = i40evf_set_msglevel,
648 .get_coalesce = i40evf_get_coalesce,
649 .set_coalesce = i40evf_set_coalesce,
650 .get_per_queue_coalesce = i40evf_get_per_queue_coalesce,
651 .set_per_queue_coalesce = i40evf_set_per_queue_coalesce,
652 .get_rxnfc = i40evf_get_rxnfc,
653 .get_rxfh_indir_size = i40evf_get_rxfh_indir_size,
654 .get_rxfh = i40evf_get_rxfh,
655 .set_rxfh = i40evf_set_rxfh,
656 .get_channels = i40evf_get_channels,
657 .get_rxfh_key_size = i40evf_get_rxfh_key_size,
658};
659
660
661
662
663
664
665
666
667void i40evf_set_ethtool_ops(struct net_device *netdev)
668{
669 netdev->ethtool_ops = &i40evf_ethtool_ops;
670}
671