Skip to content

Commit

Permalink
bnxt_en: Add TPH support in BNXT driver
Browse files Browse the repository at this point in the history
Add TPH support to the Broadcom BNXT device driver. This allows the
driver to utilize TPH functions for retrieving and configuring Steering
Tags when changing interrupt affinity. With compatible NIC firmware,
network traffic will be tagged correctly with Steering Tags, resulting
in significant memory bandwidth savings and other advantages as
demonstrated by real network benchmarks on TPH-capable platforms.

Co-developed-by: Somnath Kotur <somnath.kotur@broadcom.com>
Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
Co-developed-by: Wei Huang <wei.huang2@amd.com>
Signed-off-by: Wei Huang <wei.huang2@amd.com>
Signed-off-by: Manoj Panicker <manoj.panicker2@amd.com>
Reviewed-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Link: https://patch.msgid.link/20250213011240.1640031-12-michael.chan@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Manoj Panicker authored and Jakub Kicinski committed Feb 15, 2025
1 parent fe96d71 commit c214410
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 0 deletions.
106 changes: 106 additions & 0 deletions drivers/net/ethernet/broadcom/bnxt/bnxt.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@
#include <net/page_pool/helpers.h>
#include <linux/align.h>
#include <net/netdev_queues.h>
#include <net/netdev_rx_queue.h>
#include <linux/pci-tph.h>

#include "bnxt_hsi.h"
#include "bnxt.h"
Expand All @@ -76,6 +78,7 @@
#define BNXT_DEF_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_HW | \
NETIF_MSG_TX_ERR)

MODULE_IMPORT_NS("NETDEV_INTERNAL");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Broadcom NetXtreme network driver");

Expand Down Expand Up @@ -11351,6 +11354,83 @@ static int bnxt_tx_queue_start(struct bnxt *bp, int idx)
return 0;
}

static void bnxt_irq_affinity_notify(struct irq_affinity_notify *notify,
const cpumask_t *mask)
{
struct bnxt_irq *irq;
u16 tag;
int err;

irq = container_of(notify, struct bnxt_irq, affinity_notify);

if (!irq->bp->tph_mode)
return;

cpumask_copy(irq->cpu_mask, mask);

if (irq->ring_nr >= irq->bp->rx_nr_rings)
return;

if (pcie_tph_get_cpu_st(irq->bp->pdev, TPH_MEM_TYPE_VM,
cpumask_first(irq->cpu_mask), &tag))
return;

if (pcie_tph_set_st_entry(irq->bp->pdev, irq->msix_nr, tag))
return;

rtnl_lock();
if (netif_running(irq->bp->dev)) {
err = netdev_rx_queue_restart(irq->bp->dev, irq->ring_nr);
if (err)
netdev_err(irq->bp->dev,
"RX queue restart failed: err=%d\n", err);
}
rtnl_unlock();
}

static void bnxt_irq_affinity_release(struct kref *ref)
{
struct irq_affinity_notify *notify =
container_of(ref, struct irq_affinity_notify, kref);
struct bnxt_irq *irq;

irq = container_of(notify, struct bnxt_irq, affinity_notify);

if (!irq->bp->tph_mode)
return;

if (pcie_tph_set_st_entry(irq->bp->pdev, irq->msix_nr, 0)) {
netdev_err(irq->bp->dev,
"Setting ST=0 for MSIX entry %d failed\n",
irq->msix_nr);
return;
}
}

static void bnxt_release_irq_notifier(struct bnxt_irq *irq)
{
irq_set_affinity_notifier(irq->vector, NULL);
}

static void bnxt_register_irq_notifier(struct bnxt *bp, struct bnxt_irq *irq)
{
struct irq_affinity_notify *notify;

irq->bp = bp;

/* Nothing to do if TPH is not enabled */
if (!bp->tph_mode)
return;

/* Register IRQ affinity notifier */
notify = &irq->affinity_notify;
notify->irq = irq->vector;
notify->notify = bnxt_irq_affinity_notify;
notify->release = bnxt_irq_affinity_release;

irq_set_affinity_notifier(irq->vector, notify);
}

static void bnxt_free_irq(struct bnxt *bp)
{
struct bnxt_irq *irq;
Expand All @@ -11373,11 +11453,18 @@ static void bnxt_free_irq(struct bnxt *bp)
free_cpumask_var(irq->cpu_mask);
irq->have_cpumask = 0;
}

bnxt_release_irq_notifier(irq);

free_irq(irq->vector, bp->bnapi[i]);
}

irq->requested = 0;
}

/* Disable TPH support */
pcie_disable_tph(bp->pdev);
bp->tph_mode = 0;
}

static int bnxt_request_irq(struct bnxt *bp)
Expand All @@ -11397,6 +11484,12 @@ static int bnxt_request_irq(struct bnxt *bp)
#ifdef CONFIG_RFS_ACCEL
rmap = bp->dev->rx_cpu_rmap;
#endif

/* Enable TPH support as part of IRQ request */
rc = pcie_enable_tph(bp->pdev, PCI_TPH_ST_IV_MODE);
if (!rc)
bp->tph_mode = PCI_TPH_ST_IV_MODE;

for (i = 0, j = 0; i < bp->cp_nr_rings; i++) {
int map_idx = bnxt_cp_num_to_irq_num(bp, i);
struct bnxt_irq *irq = &bp->irq_tbl[map_idx];
Expand All @@ -11420,8 +11513,11 @@ static int bnxt_request_irq(struct bnxt *bp)

if (zalloc_cpumask_var(&irq->cpu_mask, GFP_KERNEL)) {
int numa_node = dev_to_node(&bp->pdev->dev);
u16 tag;

irq->have_cpumask = 1;
irq->msix_nr = map_idx;
irq->ring_nr = i;
cpumask_set_cpu(cpumask_local_spread(i, numa_node),
irq->cpu_mask);
rc = irq_update_affinity_hint(irq->vector, irq->cpu_mask);
Expand All @@ -11431,6 +11527,16 @@ static int bnxt_request_irq(struct bnxt *bp)
irq->vector);
break;
}

bnxt_register_irq_notifier(bp, irq);

/* Init ST table entry */
if (pcie_tph_get_cpu_st(irq->bp->pdev, TPH_MEM_TYPE_VM,
cpumask_first(irq->cpu_mask),
&tag))
continue;

pcie_tph_set_st_entry(irq->bp->pdev, irq->msix_nr, tag);
}
}
return rc;
Expand Down
5 changes: 5 additions & 0 deletions drivers/net/ethernet/broadcom/bnxt/bnxt.h
Original file line number Diff line number Diff line change
Expand Up @@ -1234,6 +1234,11 @@ struct bnxt_irq {
u8 have_cpumask:1;
char name[IFNAMSIZ + BNXT_IRQ_NAME_EXTRA];
cpumask_var_t cpu_mask;

struct bnxt *bp;
int msix_nr;
int ring_nr;
struct irq_affinity_notify affinity_notify;
};

#define HWRM_RING_ALLOC_TX 0x1
Expand Down

0 comments on commit c214410

Please sign in to comment.