@@ -511,6 +511,87 @@ static int ionic_set_coalesce(struct net_device *netdev,
511511 return 0 ;
512512}
513513
514+ static int ionic_validate_cmb_config (struct ionic_lif * lif ,
515+ struct ionic_queue_params * qparam )
516+ {
517+ int pages_have , pages_required = 0 ;
518+ unsigned long sz ;
519+
520+ if (!lif -> ionic -> idev .cmb_inuse &&
521+ (qparam -> cmb_tx || qparam -> cmb_rx )) {
522+ netdev_info (lif -> netdev , "CMB rings are not supported on this device\n" );
523+ return - EOPNOTSUPP ;
524+ }
525+
526+ if (qparam -> cmb_tx ) {
527+ if (!(lif -> qtype_info [IONIC_QTYPE_TXQ ].features & IONIC_QIDENT_F_CMB )) {
528+ netdev_info (lif -> netdev ,
529+ "CMB rings for tx-push are not supported on this device\n" );
530+ return - EOPNOTSUPP ;
531+ }
532+
533+ sz = sizeof (struct ionic_txq_desc ) * qparam -> ntxq_descs * qparam -> nxqs ;
534+ pages_required += ALIGN (sz , PAGE_SIZE ) / PAGE_SIZE ;
535+ }
536+
537+ if (qparam -> cmb_rx ) {
538+ if (!(lif -> qtype_info [IONIC_QTYPE_RXQ ].features & IONIC_QIDENT_F_CMB )) {
539+ netdev_info (lif -> netdev ,
540+ "CMB rings for rx-push are not supported on this device\n" );
541+ return - EOPNOTSUPP ;
542+ }
543+
544+ sz = sizeof (struct ionic_rxq_desc ) * qparam -> nrxq_descs * qparam -> nxqs ;
545+ pages_required += ALIGN (sz , PAGE_SIZE ) / PAGE_SIZE ;
546+ }
547+
548+ pages_have = lif -> ionic -> bars [IONIC_PCI_BAR_CMB ].len / PAGE_SIZE ;
549+ if (pages_required > pages_have ) {
550+ netdev_info (lif -> netdev ,
551+ "Not enough CMB pages for number of queues and size of descriptor rings, need %d have %d" ,
552+ pages_required , pages_have );
553+ return - ENOMEM ;
554+ }
555+
556+ return pages_required ;
557+ }
558+
559+ static int ionic_cmb_rings_toggle (struct ionic_lif * lif , bool cmb_tx , bool cmb_rx )
560+ {
561+ struct ionic_queue_params qparam ;
562+ int pages_used ;
563+
564+ if (netif_running (lif -> netdev )) {
565+ netdev_info (lif -> netdev , "Please stop device to toggle CMB for tx/rx-push\n" );
566+ return - EBUSY ;
567+ }
568+
569+ ionic_init_queue_params (lif , & qparam );
570+ qparam .cmb_tx = cmb_tx ;
571+ qparam .cmb_rx = cmb_rx ;
572+ pages_used = ionic_validate_cmb_config (lif , & qparam );
573+ if (pages_used < 0 )
574+ return pages_used ;
575+
576+ if (cmb_tx )
577+ set_bit (IONIC_LIF_F_CMB_TX_RINGS , lif -> state );
578+ else
579+ clear_bit (IONIC_LIF_F_CMB_TX_RINGS , lif -> state );
580+
581+ if (cmb_rx )
582+ set_bit (IONIC_LIF_F_CMB_RX_RINGS , lif -> state );
583+ else
584+ clear_bit (IONIC_LIF_F_CMB_RX_RINGS , lif -> state );
585+
586+ if (cmb_tx || cmb_rx )
587+ netdev_info (lif -> netdev , "Enabling CMB %s %s rings - %d pages\n" ,
588+ cmb_tx ? "TX" : "" , cmb_rx ? "RX" : "" , pages_used );
589+ else
590+ netdev_info (lif -> netdev , "Disabling CMB rings\n" );
591+
592+ return 0 ;
593+ }
594+
514595static void ionic_get_ringparam (struct net_device * netdev ,
515596 struct ethtool_ringparam * ring ,
516597 struct kernel_ethtool_ringparam * kernel_ring ,
@@ -522,6 +603,8 @@ static void ionic_get_ringparam(struct net_device *netdev,
522603 ring -> tx_pending = lif -> ntxq_descs ;
523604 ring -> rx_max_pending = IONIC_MAX_RX_DESC ;
524605 ring -> rx_pending = lif -> nrxq_descs ;
606+ kernel_ring -> tx_push = test_bit (IONIC_LIF_F_CMB_TX_RINGS , lif -> state );
607+ kernel_ring -> rx_push = test_bit (IONIC_LIF_F_CMB_RX_RINGS , lif -> state );
525608}
526609
527610static int ionic_set_ringparam (struct net_device * netdev ,
@@ -551,9 +634,28 @@ static int ionic_set_ringparam(struct net_device *netdev,
551634
552635 /* if nothing to do return success */
553636 if (ring -> tx_pending == lif -> ntxq_descs &&
554- ring -> rx_pending == lif -> nrxq_descs )
637+ ring -> rx_pending == lif -> nrxq_descs &&
638+ kernel_ring -> tx_push == test_bit (IONIC_LIF_F_CMB_TX_RINGS , lif -> state ) &&
639+ kernel_ring -> rx_push == test_bit (IONIC_LIF_F_CMB_RX_RINGS , lif -> state ))
555640 return 0 ;
556641
642+ qparam .ntxq_descs = ring -> tx_pending ;
643+ qparam .nrxq_descs = ring -> rx_pending ;
644+ qparam .cmb_tx = kernel_ring -> tx_push ;
645+ qparam .cmb_rx = kernel_ring -> rx_push ;
646+
647+ err = ionic_validate_cmb_config (lif , & qparam );
648+ if (err < 0 )
649+ return err ;
650+
651+ if (kernel_ring -> tx_push != test_bit (IONIC_LIF_F_CMB_TX_RINGS , lif -> state ) ||
652+ kernel_ring -> rx_push != test_bit (IONIC_LIF_F_CMB_RX_RINGS , lif -> state )) {
653+ err = ionic_cmb_rings_toggle (lif , kernel_ring -> tx_push ,
654+ kernel_ring -> rx_push );
655+ if (err < 0 )
656+ return err ;
657+ }
658+
557659 if (ring -> tx_pending != lif -> ntxq_descs )
558660 netdev_info (netdev , "Changing Tx ring size from %d to %d\n" ,
559661 lif -> ntxq_descs , ring -> tx_pending );
@@ -569,9 +671,6 @@ static int ionic_set_ringparam(struct net_device *netdev,
569671 return 0 ;
570672 }
571673
572- qparam .ntxq_descs = ring -> tx_pending ;
573- qparam .nrxq_descs = ring -> rx_pending ;
574-
575674 mutex_lock (& lif -> queue_lock );
576675 err = ionic_reconfigure_queues (lif , & qparam );
577676 mutex_unlock (& lif -> queue_lock );
@@ -638,7 +737,7 @@ static int ionic_set_channels(struct net_device *netdev,
638737 lif -> nxqs , ch -> combined_count );
639738
640739 qparam .nxqs = ch -> combined_count ;
641- qparam .intr_split = 0 ;
740+ qparam .intr_split = false ;
642741 } else {
643742 max_cnt /= 2 ;
644743 if (ch -> rx_count > max_cnt )
@@ -654,9 +753,13 @@ static int ionic_set_channels(struct net_device *netdev,
654753 lif -> nxqs , ch -> rx_count );
655754
656755 qparam .nxqs = ch -> rx_count ;
657- qparam .intr_split = 1 ;
756+ qparam .intr_split = true ;
658757 }
659758
759+ err = ionic_validate_cmb_config (lif , & qparam );
760+ if (err < 0 )
761+ return err ;
762+
660763 /* if we're not running, just set the values and return */
661764 if (!netif_running (lif -> netdev )) {
662765 lif -> nxqs = qparam .nxqs ;
@@ -965,6 +1068,8 @@ static const struct ethtool_ops ionic_ethtool_ops = {
9651068 .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
9661069 ETHTOOL_COALESCE_USE_ADAPTIVE_RX |
9671070 ETHTOOL_COALESCE_USE_ADAPTIVE_TX ,
1071+ .supported_ring_params = ETHTOOL_RING_USE_TX_PUSH |
1072+ ETHTOOL_RING_USE_RX_PUSH ,
9681073 .get_drvinfo = ionic_get_drvinfo ,
9691074 .get_regs_len = ionic_get_regs_len ,
9701075 .get_regs = ionic_get_regs ,
0 commit comments