Skip to content

Commit 79cdf17

Browse files
committed
Merge branch 'ionic-on-chip-desc'
Shannon Nelson says: ==================== ionic: on-chip descriptors We start with a couple of house-keeping patches that were originally presented for 'net', then we add support for on-chip descriptor rings for tx-push, as well as adding support for rx-push. I have a patch for the ethtool userland utility that I can send out once this has been accepted. v4: added rx-push attributes to ethtool netlink converted CMB feature from using a priv-flag to using ethtool tx/rx-push v3: edited commit message to describe interface-down limitation added warn msg if cmb_inuse alloc fails removed unnecessary clearing of phy_cmb_pages and cmb_npages changed cmb_rings_toggle to use cmb_inuse removed unrelated pci_set_drvdata() removed unnecessary (u32) cast added static inline func for writing CMB descriptors v2: dropped the rx buffers patch ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 8024edf + 40bc471 commit 79cdf17

File tree

16 files changed

+438
-35
lines changed

16 files changed

+438
-35
lines changed

Documentation/networking/ethtool-netlink.rst

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -874,6 +874,7 @@ Kernel response contents:
874874
``ETHTOOL_A_RINGS_TCP_DATA_SPLIT`` u8 TCP header / data split
875875
``ETHTOOL_A_RINGS_CQE_SIZE`` u32 Size of TX/RX CQE
876876
``ETHTOOL_A_RINGS_TX_PUSH`` u8 flag of TX Push mode
877+
``ETHTOOL_A_RINGS_RX_PUSH`` u8 flag of RX Push mode
877878
==================================== ====== ===========================
878879

879880
``ETHTOOL_A_RINGS_TCP_DATA_SPLIT`` indicates whether the device is usable with
@@ -883,8 +884,8 @@ separate buffers. The device configuration must make it possible to receive
883884
full memory pages of data, for example because MTU is high enough or through
884885
HW-GRO.
885886

886-
``ETHTOOL_A_RINGS_TX_PUSH`` flag is used to enable descriptor fast
887-
path to send packets. In ordinary path, driver fills descriptors in DRAM and
887+
``ETHTOOL_A_RINGS_[RX|TX]_PUSH`` flag is used to enable descriptor fast
888+
path to send or receive packets. In ordinary path, driver fills descriptors in DRAM and
888889
notifies NIC hardware. In fast path, driver pushes descriptors to the device
889890
through MMIO writes, thus reducing the latency. However, enabling this feature
890891
may increase the CPU cost. Drivers may enforce additional per-packet
@@ -906,6 +907,7 @@ Request contents:
906907
``ETHTOOL_A_RINGS_RX_BUF_LEN`` u32 size of buffers on the ring
907908
``ETHTOOL_A_RINGS_CQE_SIZE`` u32 Size of TX/RX CQE
908909
``ETHTOOL_A_RINGS_TX_PUSH`` u8 flag of TX Push mode
910+
``ETHTOOL_A_RINGS_RX_PUSH`` u8 flag of RX Push mode
909911
==================================== ====== ===========================
910912

911913
Kernel checks that requested ring sizes do not exceed limits reported by

drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ static void ionic_vf_dealloc_locked(struct ionic *ionic)
121121

122122
if (v->stats_pa) {
123123
vfc.stats_pa = 0;
124-
(void)ionic_set_vf_config(ionic, i, &vfc);
124+
ionic_set_vf_config(ionic, i, &vfc);
125125
dma_unmap_single(ionic->dev, v->stats_pa,
126126
sizeof(v->stats), DMA_FROM_DEVICE);
127127
v->stats_pa = 0;
@@ -169,7 +169,7 @@ static int ionic_vf_alloc(struct ionic *ionic, int num_vfs)
169169

170170
/* ignore failures from older FW, we just won't get stats */
171171
vfc.stats_pa = cpu_to_le64(v->stats_pa);
172-
(void)ionic_set_vf_config(ionic, i, &vfc);
172+
ionic_set_vf_config(ionic, i, &vfc);
173173
}
174174

175175
out:
@@ -352,6 +352,7 @@ static int ionic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
352352
err_out_reset:
353353
ionic_reset(ionic);
354354
err_out_teardown:
355+
ionic_dev_teardown(ionic);
355356
pci_clear_master(pdev);
356357
/* Don't fail the probe for these errors, keep
357358
* the hw interface around for inspection
@@ -390,6 +391,7 @@ static void ionic_remove(struct pci_dev *pdev)
390391

391392
ionic_port_reset(ionic);
392393
ionic_reset(ionic);
394+
ionic_dev_teardown(ionic);
393395
pci_clear_master(pdev);
394396
ionic_unmap_bars(ionic);
395397
pci_release_regions(pdev);

drivers/net/ethernet/pensando/ionic/ionic_dev.c

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ int ionic_dev_setup(struct ionic *ionic)
9292
unsigned int num_bars = ionic->num_bars;
9393
struct ionic_dev *idev = &ionic->idev;
9494
struct device *dev = ionic->dev;
95+
int size;
9596
u32 sig;
9697

9798
/* BAR0: dev_cmd and interrupts */
@@ -133,9 +134,36 @@ int ionic_dev_setup(struct ionic *ionic)
133134
idev->db_pages = bar->vaddr;
134135
idev->phy_db_pages = bar->bus_addr;
135136

137+
/* BAR2: optional controller memory mapping */
138+
bar++;
139+
mutex_init(&idev->cmb_inuse_lock);
140+
if (num_bars < 3 || !ionic->bars[IONIC_PCI_BAR_CMB].len) {
141+
idev->cmb_inuse = NULL;
142+
return 0;
143+
}
144+
145+
idev->phy_cmb_pages = bar->bus_addr;
146+
idev->cmb_npages = bar->len / PAGE_SIZE;
147+
size = BITS_TO_LONGS(idev->cmb_npages) * sizeof(long);
148+
idev->cmb_inuse = kzalloc(size, GFP_KERNEL);
149+
if (!idev->cmb_inuse)
150+
dev_warn(dev, "No memory for CMB, disabling\n");
151+
136152
return 0;
137153
}
138154

155+
void ionic_dev_teardown(struct ionic *ionic)
156+
{
157+
struct ionic_dev *idev = &ionic->idev;
158+
159+
kfree(idev->cmb_inuse);
160+
idev->cmb_inuse = NULL;
161+
idev->phy_cmb_pages = 0;
162+
idev->cmb_npages = 0;
163+
164+
mutex_destroy(&idev->cmb_inuse_lock);
165+
}
166+
139167
/* Devcmd Interface */
140168
bool ionic_is_fw_running(struct ionic_dev *idev)
141169
{
@@ -571,6 +599,33 @@ int ionic_db_page_num(struct ionic_lif *lif, int pid)
571599
return (lif->hw_index * lif->dbid_count) + pid;
572600
}
573601

602+
int ionic_get_cmb(struct ionic_lif *lif, u32 *pgid, phys_addr_t *pgaddr, int order)
603+
{
604+
struct ionic_dev *idev = &lif->ionic->idev;
605+
int ret;
606+
607+
mutex_lock(&idev->cmb_inuse_lock);
608+
ret = bitmap_find_free_region(idev->cmb_inuse, idev->cmb_npages, order);
609+
mutex_unlock(&idev->cmb_inuse_lock);
610+
611+
if (ret < 0)
612+
return ret;
613+
614+
*pgid = ret;
615+
*pgaddr = idev->phy_cmb_pages + ret * PAGE_SIZE;
616+
617+
return 0;
618+
}
619+
620+
void ionic_put_cmb(struct ionic_lif *lif, u32 pgid, int order)
621+
{
622+
struct ionic_dev *idev = &lif->ionic->idev;
623+
624+
mutex_lock(&idev->cmb_inuse_lock);
625+
bitmap_release_region(idev->cmb_inuse, pgid, order);
626+
mutex_unlock(&idev->cmb_inuse_lock);
627+
}
628+
574629
int ionic_cq_init(struct ionic_lif *lif, struct ionic_cq *cq,
575630
struct ionic_intr_info *intr,
576631
unsigned int num_descs, size_t desc_size)
@@ -679,6 +734,18 @@ void ionic_q_map(struct ionic_queue *q, void *base, dma_addr_t base_pa)
679734
cur->desc = base + (i * q->desc_size);
680735
}
681736

737+
void ionic_q_cmb_map(struct ionic_queue *q, void __iomem *base, dma_addr_t base_pa)
738+
{
739+
struct ionic_desc_info *cur;
740+
unsigned int i;
741+
742+
q->cmb_base = base;
743+
q->cmb_base_pa = base_pa;
744+
745+
for (i = 0, cur = q->info; i < q->num_descs; i++, cur++)
746+
cur->cmb_desc = base + (i * q->desc_size);
747+
}
748+
682749
void ionic_q_sg_map(struct ionic_queue *q, void *base, dma_addr_t base_pa)
683750
{
684751
struct ionic_desc_info *cur;

drivers/net/ethernet/pensando/ionic/ionic_dev.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,11 @@ struct ionic_dev {
159159
struct ionic_intr __iomem *intr_ctrl;
160160
u64 __iomem *intr_status;
161161

162+
struct mutex cmb_inuse_lock; /* for cmb_inuse */
163+
unsigned long *cmb_inuse;
164+
dma_addr_t phy_cmb_pages;
165+
u32 cmb_npages;
166+
162167
u32 port_info_sz;
163168
struct ionic_port_info *port_info;
164169
dma_addr_t port_info_pa;
@@ -203,6 +208,7 @@ struct ionic_desc_info {
203208
struct ionic_rxq_desc *rxq_desc;
204209
struct ionic_admin_cmd *adminq_desc;
205210
};
211+
void __iomem *cmb_desc;
206212
union {
207213
void *sg_desc;
208214
struct ionic_txq_sg_desc *txq_sg_desc;
@@ -241,12 +247,14 @@ struct ionic_queue {
241247
struct ionic_rxq_desc *rxq;
242248
struct ionic_admin_cmd *adminq;
243249
};
250+
void __iomem *cmb_base;
244251
union {
245252
void *sg_base;
246253
struct ionic_txq_sg_desc *txq_sgl;
247254
struct ionic_rxq_sg_desc *rxq_sgl;
248255
};
249256
dma_addr_t base_pa;
257+
dma_addr_t cmb_base_pa;
250258
dma_addr_t sg_base_pa;
251259
unsigned int desc_size;
252260
unsigned int sg_desc_size;
@@ -309,6 +317,7 @@ static inline bool ionic_q_has_space(struct ionic_queue *q, unsigned int want)
309317

310318
void ionic_init_devinfo(struct ionic *ionic);
311319
int ionic_dev_setup(struct ionic *ionic);
320+
void ionic_dev_teardown(struct ionic *ionic);
312321

313322
void ionic_dev_cmd_go(struct ionic_dev *idev, union ionic_dev_cmd *cmd);
314323
u8 ionic_dev_cmd_status(struct ionic_dev *idev);
@@ -344,6 +353,9 @@ void ionic_dev_cmd_adminq_init(struct ionic_dev *idev, struct ionic_qcq *qcq,
344353

345354
int ionic_db_page_num(struct ionic_lif *lif, int pid);
346355

356+
int ionic_get_cmb(struct ionic_lif *lif, u32 *pgid, phys_addr_t *pgaddr, int order);
357+
void ionic_put_cmb(struct ionic_lif *lif, u32 pgid, int order);
358+
347359
int ionic_cq_init(struct ionic_lif *lif, struct ionic_cq *cq,
348360
struct ionic_intr_info *intr,
349361
unsigned int num_descs, size_t desc_size);
@@ -360,6 +372,7 @@ int ionic_q_init(struct ionic_lif *lif, struct ionic_dev *idev,
360372
unsigned int num_descs, size_t desc_size,
361373
size_t sg_desc_size, unsigned int pid);
362374
void ionic_q_map(struct ionic_queue *q, void *base, dma_addr_t base_pa);
375+
void ionic_q_cmb_map(struct ionic_queue *q, void __iomem *base, dma_addr_t base_pa);
363376
void ionic_q_sg_map(struct ionic_queue *q, void *base, dma_addr_t base_pa);
364377
void ionic_q_post(struct ionic_queue *q, bool ring_doorbell, ionic_desc_cb cb,
365378
void *cb_arg);

drivers/net/ethernet/pensando/ionic/ionic_ethtool.c

Lines changed: 111 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
514595
static 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

527610
static 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

Comments
 (0)