31
31
#include "cn23xx_pf_device.h"
32
32
#include "cn23xx_vf_device.h"
33
33
34
+ static int lio_reset_queues (struct net_device * netdev , uint32_t num_qs );
34
35
static int octnet_get_link_stats (struct net_device * netdev );
35
36
36
37
struct oct_intrmod_context {
@@ -300,13 +301,43 @@ lio_get_vf_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
300
301
strncpy (drvinfo -> bus_info , pci_name (oct -> pci_dev ), 32 );
301
302
}
302
303
304
+ static int
305
+ lio_send_queue_count_update (struct net_device * netdev , uint32_t num_queues )
306
+ {
307
+ struct lio * lio = GET_LIO (netdev );
308
+ struct octeon_device * oct = lio -> oct_dev ;
309
+ struct octnic_ctrl_pkt nctrl ;
310
+ int ret = 0 ;
311
+
312
+ memset (& nctrl , 0 , sizeof (struct octnic_ctrl_pkt ));
313
+
314
+ nctrl .ncmd .u64 = 0 ;
315
+ nctrl .ncmd .s .cmd = OCTNET_CMD_QUEUE_COUNT_CTL ;
316
+ nctrl .ncmd .s .param1 = num_queues ;
317
+ nctrl .ncmd .s .param2 = num_queues ;
318
+ nctrl .iq_no = lio -> linfo .txpciq [0 ].s .q_no ;
319
+ nctrl .wait_time = 100 ;
320
+ nctrl .netpndev = (u64 )netdev ;
321
+ nctrl .cb_fn = liquidio_link_ctrl_cmd_completion ;
322
+
323
+ ret = octnet_send_nic_ctrl_pkt (lio -> oct_dev , & nctrl );
324
+ if (ret < 0 ) {
325
+ dev_err (& oct -> pci_dev -> dev , "Failed to send Queue reset command (ret: 0x%x)\n" ,
326
+ ret );
327
+ return -1 ;
328
+ }
329
+
330
+ return 0 ;
331
+ }
332
+
303
333
static void
304
334
lio_ethtool_get_channels (struct net_device * dev ,
305
335
struct ethtool_channels * channel )
306
336
{
307
337
struct lio * lio = GET_LIO (dev );
308
338
struct octeon_device * oct = lio -> oct_dev ;
309
339
u32 max_rx = 0 , max_tx = 0 , tx_count = 0 , rx_count = 0 ;
340
+ u32 combined_count = 0 , max_combined = 0 ;
310
341
311
342
if (OCTEON_CN6XXX (oct )) {
312
343
struct octeon_config * conf6x = CHIP_CONF (oct , cn6xxx );
@@ -316,22 +347,137 @@ lio_ethtool_get_channels(struct net_device *dev,
316
347
rx_count = CFG_GET_NUM_RXQS_NIC_IF (conf6x , lio -> ifidx );
317
348
tx_count = CFG_GET_NUM_TXQS_NIC_IF (conf6x , lio -> ifidx );
318
349
} else if (OCTEON_CN23XX_PF (oct )) {
319
-
320
- max_rx = oct -> sriov_info .num_pf_rings ;
321
- max_tx = oct -> sriov_info .num_pf_rings ;
322
- rx_count = lio -> linfo .num_rxpciq ;
323
- tx_count = lio -> linfo .num_txpciq ;
350
+ max_combined = lio -> linfo .num_txpciq ;
351
+ combined_count = oct -> num_iqs ;
324
352
} else if (OCTEON_CN23XX_VF (oct )) {
325
- max_tx = oct -> sriov_info .rings_per_vf ;
326
- max_rx = oct -> sriov_info .rings_per_vf ;
327
- rx_count = lio -> linfo .num_rxpciq ;
328
- tx_count = lio -> linfo .num_txpciq ;
353
+ u64 reg_val = 0ULL ;
354
+ u64 ctrl = CN23XX_VF_SLI_IQ_PKT_CONTROL64 (0 );
355
+
356
+ reg_val = octeon_read_csr64 (oct , ctrl );
357
+ reg_val = reg_val >> CN23XX_PKT_INPUT_CTL_RPVF_POS ;
358
+ max_combined = reg_val & CN23XX_PKT_INPUT_CTL_RPVF_MASK ;
359
+ combined_count = oct -> num_iqs ;
329
360
}
330
361
331
362
channel -> max_rx = max_rx ;
332
363
channel -> max_tx = max_tx ;
364
+ channel -> max_combined = max_combined ;
333
365
channel -> rx_count = rx_count ;
334
366
channel -> tx_count = tx_count ;
367
+ channel -> combined_count = combined_count ;
368
+ }
369
+
370
+ static int
371
+ lio_irq_reallocate_irqs (struct octeon_device * oct , uint32_t num_ioqs )
372
+ {
373
+ struct msix_entry * msix_entries ;
374
+ int num_msix_irqs = 0 ;
375
+ int i ;
376
+
377
+ if (!oct -> msix_on )
378
+ return 0 ;
379
+
380
+ /* Disable the input and output queues now. No more packets will
381
+ * arrive from Octeon.
382
+ */
383
+ oct -> fn_list .disable_interrupt (oct , OCTEON_ALL_INTR );
384
+
385
+ if (oct -> msix_on ) {
386
+ if (OCTEON_CN23XX_PF (oct ))
387
+ num_msix_irqs = oct -> num_msix_irqs - 1 ;
388
+ else if (OCTEON_CN23XX_VF (oct ))
389
+ num_msix_irqs = oct -> num_msix_irqs ;
390
+
391
+ msix_entries = (struct msix_entry * )oct -> msix_entries ;
392
+ for (i = 0 ; i < num_msix_irqs ; i ++ ) {
393
+ if (oct -> ioq_vector [i ].vector ) {
394
+ /* clear the affinity_cpumask */
395
+ irq_set_affinity_hint (msix_entries [i ].vector ,
396
+ NULL );
397
+ free_irq (msix_entries [i ].vector ,
398
+ & oct -> ioq_vector [i ]);
399
+ oct -> ioq_vector [i ].vector = 0 ;
400
+ }
401
+ }
402
+
403
+ /* non-iov vector's argument is oct struct */
404
+ if (OCTEON_CN23XX_PF (oct ))
405
+ free_irq (msix_entries [i ].vector , oct );
406
+
407
+ pci_disable_msix (oct -> pci_dev );
408
+ kfree (oct -> msix_entries );
409
+ oct -> msix_entries = NULL ;
410
+ }
411
+
412
+ kfree (oct -> irq_name_storage );
413
+ oct -> irq_name_storage = NULL ;
414
+ if (octeon_setup_interrupt (oct , num_ioqs )) {
415
+ dev_info (& oct -> pci_dev -> dev , "Setup interuupt failed\n" );
416
+ return 1 ;
417
+ }
418
+
419
+ /* Enable Octeon device interrupts */
420
+ oct -> fn_list .enable_interrupt (oct , OCTEON_ALL_INTR );
421
+
422
+ return 0 ;
423
+ }
424
+
425
+ static int
426
+ lio_ethtool_set_channels (struct net_device * dev ,
427
+ struct ethtool_channels * channel )
428
+ {
429
+ u32 combined_count , max_combined ;
430
+ struct lio * lio = GET_LIO (dev );
431
+ struct octeon_device * oct = lio -> oct_dev ;
432
+ int stopped = 0 ;
433
+
434
+ if (strcmp (oct -> fw_info .liquidio_firmware_version , "1.6.1" ) < 0 ) {
435
+ dev_err (& oct -> pci_dev -> dev , "Minimum firmware version required is 1.6.1\n" );
436
+ return - EINVAL ;
437
+ }
438
+
439
+ if (!channel -> combined_count || channel -> other_count ||
440
+ channel -> rx_count || channel -> tx_count )
441
+ return - EINVAL ;
442
+
443
+ combined_count = channel -> combined_count ;
444
+
445
+ if (OCTEON_CN23XX_PF (oct )) {
446
+ max_combined = channel -> max_combined ;
447
+ } else if (OCTEON_CN23XX_VF (oct )) {
448
+ u64 reg_val = 0ULL ;
449
+ u64 ctrl = CN23XX_VF_SLI_IQ_PKT_CONTROL64 (0 );
450
+
451
+ reg_val = octeon_read_csr64 (oct , ctrl );
452
+ reg_val = reg_val >> CN23XX_PKT_INPUT_CTL_RPVF_POS ;
453
+ max_combined = reg_val & CN23XX_PKT_INPUT_CTL_RPVF_MASK ;
454
+ } else {
455
+ return - EINVAL ;
456
+ }
457
+
458
+ if (combined_count > max_combined || combined_count < 1 )
459
+ return - EINVAL ;
460
+
461
+ if (combined_count == oct -> num_iqs )
462
+ return 0 ;
463
+
464
+ ifstate_set (lio , LIO_IFSTATE_RESETTING );
465
+
466
+ if (netif_running (dev )) {
467
+ dev -> netdev_ops -> ndo_stop (dev );
468
+ stopped = 1 ;
469
+ }
470
+
471
+ if (lio_reset_queues (dev , combined_count ))
472
+ return - EINVAL ;
473
+
474
+ lio_irq_reallocate_irqs (oct , combined_count );
475
+ if (stopped )
476
+ dev -> netdev_ops -> ndo_open (dev );
477
+
478
+ ifstate_reset (lio , LIO_IFSTATE_RESETTING );
479
+
480
+ return 0 ;
335
481
}
336
482
337
483
static int lio_get_eeprom_len (struct net_device * netdev )
@@ -664,15 +810,12 @@ lio_ethtool_get_ringparam(struct net_device *netdev,
664
810
ering -> rx_jumbo_max_pending = 0 ;
665
811
}
666
812
667
- static int lio_reset_queues (struct net_device * netdev )
813
+ static int lio_reset_queues (struct net_device * netdev , uint32_t num_qs )
668
814
{
669
815
struct lio * lio = GET_LIO (netdev );
670
816
struct octeon_device * oct = lio -> oct_dev ;
671
817
struct napi_struct * napi , * n ;
672
- int i ;
673
-
674
- dev_dbg (& oct -> pci_dev -> dev , "%s:%d ifidx %d\n" ,
675
- __func__ , __LINE__ , lio -> ifidx );
818
+ int i , update = 0 ;
676
819
677
820
if (wait_for_pending_requests (oct ))
678
821
dev_err (& oct -> pci_dev -> dev , "There were pending requests\n" );
@@ -693,6 +836,12 @@ static int lio_reset_queues(struct net_device *netdev)
693
836
list_for_each_entry_safe (napi , n , & netdev -> napi_list , dev_list )
694
837
netif_napi_del (napi );
695
838
839
+ if (num_qs != oct -> num_iqs ) {
840
+ netif_set_real_num_rx_queues (netdev , num_qs );
841
+ netif_set_real_num_tx_queues (netdev , num_qs );
842
+ update = 1 ;
843
+ }
844
+
696
845
for (i = 0 ; i < MAX_OCTEON_OUTPUT_QUEUES (oct ); i ++ ) {
697
846
if (!(oct -> io_qmask .oq & BIT_ULL (i )))
698
847
continue ;
@@ -710,7 +859,7 @@ static int lio_reset_queues(struct net_device *netdev)
710
859
return -1 ;
711
860
}
712
861
713
- if (liquidio_setup_io_queues (oct , 0 )) {
862
+ if (liquidio_setup_io_queues (oct , 0 , num_qs , num_qs )) {
714
863
dev_err (& oct -> pci_dev -> dev , "IO queues initialization failed\n" );
715
864
return -1 ;
716
865
}
@@ -721,6 +870,9 @@ static int lio_reset_queues(struct net_device *netdev)
721
870
return -1 ;
722
871
}
723
872
873
+ if (update && lio_send_queue_count_update (netdev , num_qs ))
874
+ return -1 ;
875
+
724
876
return 0 ;
725
877
}
726
878
@@ -764,7 +916,7 @@ static int lio_ethtool_set_ringparam(struct net_device *netdev,
764
916
CFG_SET_NUM_RX_DESCS_NIC_IF (octeon_get_conf (oct ), lio -> ifidx ,
765
917
rx_count );
766
918
767
- if (lio_reset_queues (netdev ))
919
+ if (lio_reset_queues (netdev , lio -> linfo . num_txpciq ))
768
920
goto err_lio_reset_queues ;
769
921
770
922
if (stopped )
@@ -1194,7 +1346,7 @@ static void lio_vf_get_ethtool_stats(struct net_device *netdev,
1194
1346
/* lio->link_changes */
1195
1347
data [i ++ ] = CVM_CAST64 (lio -> link_changes );
1196
1348
1197
- for (vj = 0 ; vj < lio -> linfo . num_txpciq ; vj ++ ) {
1349
+ for (vj = 0 ; vj < oct_dev -> num_iqs ; vj ++ ) {
1198
1350
j = lio -> linfo .txpciq [vj ].s .q_no ;
1199
1351
1200
1352
/* packets to network port */
@@ -1236,7 +1388,7 @@ static void lio_vf_get_ethtool_stats(struct net_device *netdev,
1236
1388
}
1237
1389
1238
1390
/* RX */
1239
- for (vj = 0 ; vj < lio -> linfo . num_rxpciq ; vj ++ ) {
1391
+ for (vj = 0 ; vj < oct_dev -> num_oqs ; vj ++ ) {
1240
1392
j = lio -> linfo .rxpciq [vj ].s .q_no ;
1241
1393
1242
1394
/* packets send to TCP/IP network stack */
@@ -2705,6 +2857,7 @@ static const struct ethtool_ops lio_ethtool_ops = {
2705
2857
.get_ringparam = lio_ethtool_get_ringparam ,
2706
2858
.set_ringparam = lio_ethtool_set_ringparam ,
2707
2859
.get_channels = lio_ethtool_get_channels ,
2860
+ .set_channels = lio_ethtool_set_channels ,
2708
2861
.set_phys_id = lio_set_phys_id ,
2709
2862
.get_eeprom_len = lio_get_eeprom_len ,
2710
2863
.get_eeprom = lio_get_eeprom ,
@@ -2731,6 +2884,7 @@ static const struct ethtool_ops lio_vf_ethtool_ops = {
2731
2884
.get_ringparam = lio_ethtool_get_ringparam ,
2732
2885
.set_ringparam = lio_ethtool_set_ringparam ,
2733
2886
.get_channels = lio_ethtool_get_channels ,
2887
+ .set_channels = lio_ethtool_set_channels ,
2734
2888
.get_strings = lio_vf_get_strings ,
2735
2889
.get_ethtool_stats = lio_vf_get_ethtool_stats ,
2736
2890
.get_regs_len = lio_get_regs_len ,
0 commit comments