Skip to content

Commit

Permalink
bnxt_en: Add interface to support RDMA driver.
Browse files Browse the repository at this point in the history
Since the network driver and RDMA driver operate on the same PCI function,
we need to create an interface to allow the RDMA driver to share resources
with the network driver.

1. Create a new bnxt_en_dev struct which will be returned by
bnxt_ulp_probe() upon success.  After that, all calls from the RDMA driver
to bnxt_en will pass a pointer to this struct.

2. This struct contains additional function pointers to register, request
msix, send fw messages, register for async events.

3. If the RDMA driver wants to enable RDMA on the function, it needs to
call the function pointer bnxt_register_device().  A ulp_ops structure
is passed for RCU protected upcalls from bnxt_en to the RDMA driver.

4. The RDMA driver can call firmware APIs using the bnxt_send_fw_msg()
function pointer.

5. 1 stats context is reserved when the RDMA driver registers.  MSIX
and completion rings are reserved when the RDMA driver calls
bnxt_request_msix() function pointer.

6. When the RDMA driver calls bnxt_unregister_device(), all RDMA resources
will be cleaned up.

v2: Fixed 2 uninitialized variable warnings.

Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Michael Chan authored and David S. Miller committed Dec 7, 2016
1 parent a1653b1 commit a588e45
Show file tree
Hide file tree
Showing 5 changed files with 483 additions and 5 deletions.
2 changes: 1 addition & 1 deletion drivers/net/ethernet/broadcom/bnxt/Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
obj-$(CONFIG_BNXT) += bnxt_en.o

bnxt_en-y := bnxt.o bnxt_sriov.o bnxt_ethtool.o bnxt_dcb.o
bnxt_en-y := bnxt.o bnxt_sriov.o bnxt_ethtool.o bnxt_dcb.o bnxt_ulp.o
41 changes: 37 additions & 4 deletions drivers/net/ethernet/broadcom/bnxt/bnxt.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@

#include "bnxt_hsi.h"
#include "bnxt.h"
#include "bnxt_ulp.h"
#include "bnxt_sriov.h"
#include "bnxt_ethtool.h"
#include "bnxt_dcb.h"
Expand Down Expand Up @@ -1528,12 +1529,11 @@ static int bnxt_async_event_process(struct bnxt *bp,
set_bit(BNXT_RESET_TASK_SILENT_SP_EVENT, &bp->sp_event);
break;
default:
netdev_err(bp->dev, "unhandled ASYNC event (id 0x%x)\n",
event_id);
goto async_event_process_exit;
}
schedule_work(&bp->sp_task);
async_event_process_exit:
bnxt_ulp_async_events(bp, cmpl);
return 0;
}

Expand Down Expand Up @@ -3547,7 +3547,7 @@ static int bnxt_hwrm_vnic_ctx_alloc(struct bnxt *bp, u16 vnic_id, u16 ctx_idx)
return rc;
}

static int bnxt_hwrm_vnic_cfg(struct bnxt *bp, u16 vnic_id)
int bnxt_hwrm_vnic_cfg(struct bnxt *bp, u16 vnic_id)
{
unsigned int ring = 0, grp_idx;
struct bnxt_vnic_info *vnic = &bp->vnic_info[vnic_id];
Expand Down Expand Up @@ -3595,6 +3595,9 @@ static int bnxt_hwrm_vnic_cfg(struct bnxt *bp, u16 vnic_id)
#endif
if ((bp->flags & BNXT_FLAG_STRIP_VLAN) || def_vlan)
req.flags |= cpu_to_le32(VNIC_CFG_REQ_FLAGS_VLAN_STRIP_MODE);
if (!vnic_id && bnxt_ulp_registered(bp->edev, BNXT_ROCE_ULP))
req.flags |=
cpu_to_le32(VNIC_CFG_REQ_FLAGS_ROCE_DUAL_VNIC_MODE);

return hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
}
Expand Down Expand Up @@ -4842,6 +4845,16 @@ unsigned int bnxt_get_max_func_stat_ctxs(struct bnxt *bp)
return bp->pf.max_stat_ctxs;
}

void bnxt_set_max_func_stat_ctxs(struct bnxt *bp, unsigned int max)
{
#if defined(CONFIG_BNXT_SRIOV)
if (BNXT_VF(bp))
bp->vf.max_stat_ctxs = max;
else
#endif
bp->pf.max_stat_ctxs = max;
}

unsigned int bnxt_get_max_func_cp_rings(struct bnxt *bp)
{
#if defined(CONFIG_BNXT_SRIOV)
Expand All @@ -4851,6 +4864,16 @@ unsigned int bnxt_get_max_func_cp_rings(struct bnxt *bp)
return bp->pf.max_cp_rings;
}

void bnxt_set_max_func_cp_rings(struct bnxt *bp, unsigned int max)
{
#if defined(CONFIG_BNXT_SRIOV)
if (BNXT_VF(bp))
bp->vf.max_cp_rings = max;
else
#endif
bp->pf.max_cp_rings = max;
}

static unsigned int bnxt_get_max_func_irqs(struct bnxt *bp)
{
#if defined(CONFIG_BNXT_SRIOV)
Expand Down Expand Up @@ -6767,6 +6790,8 @@ static void bnxt_remove_one(struct pci_dev *pdev)
pci_iounmap(pdev, bp->bar2);
pci_iounmap(pdev, bp->bar1);
pci_iounmap(pdev, bp->bar0);
kfree(bp->edev);
bp->edev = NULL;
free_netdev(dev);

pci_release_regions(pdev);
Expand Down Expand Up @@ -6936,6 +6961,7 @@ void bnxt_restore_pf_fw_resources(struct bnxt *bp)
{
ASSERT_RTNL();
bnxt_hwrm_func_qcaps(bp);
bnxt_subtract_ulp_resources(bp, BNXT_ROCE_ULP);
}

static void bnxt_parse_log_pcie_link(struct bnxt *bp)
Expand Down Expand Up @@ -7047,6 +7073,8 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (rc)
goto init_err;

bp->ulp_probe = bnxt_ulp_probe;

/* Get the MAX capabilities for this function */
rc = bnxt_hwrm_func_qcaps(bp);
if (rc) {
Expand Down Expand Up @@ -7144,12 +7172,15 @@ static pci_ers_result_t bnxt_io_error_detected(struct pci_dev *pdev,
pci_channel_state_t state)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct bnxt *bp = netdev_priv(netdev);

netdev_info(netdev, "PCI I/O error detected\n");

rtnl_lock();
netif_device_detach(netdev);

bnxt_ulp_stop(bp);

if (state == pci_channel_io_perm_failure) {
rtnl_unlock();
return PCI_ERS_RESULT_DISCONNECT;
Expand Down Expand Up @@ -7195,8 +7226,10 @@ static pci_ers_result_t bnxt_io_slot_reset(struct pci_dev *pdev)
if (!err && netif_running(netdev))
err = bnxt_open(netdev);

if (!err)
if (!err) {
result = PCI_ERS_RESULT_RECOVERED;
bnxt_ulp_start(bp);
}
}

if (result != PCI_ERS_RESULT_RECOVERED && netif_running(netdev))
Expand Down
6 changes: 6 additions & 0 deletions drivers/net/ethernet/broadcom/bnxt/bnxt.h
Original file line number Diff line number Diff line change
Expand Up @@ -972,6 +972,9 @@ struct bnxt {
#define BNXT_SINGLE_PF(bp) (BNXT_PF(bp) && !BNXT_NPAR(bp))
#define BNXT_CHIP_TYPE_NITRO_A0(bp) ((bp)->flags & BNXT_FLAG_CHIP_NITRO_A0)

struct bnxt_en_dev *edev;
struct bnxt_en_dev * (*ulp_probe)(struct net_device *);

struct bnxt_napi **bnapi;

struct bnxt_rx_ring_info *rx_ring;
Expand Down Expand Up @@ -1242,9 +1245,12 @@ int hwrm_send_message(struct bnxt *, void *, u32, int);
int hwrm_send_message_silent(struct bnxt *, void *, u32, int);
int bnxt_hwrm_func_rgtr_async_events(struct bnxt *bp, unsigned long *bmap,
int bmap_size);
int bnxt_hwrm_vnic_cfg(struct bnxt *bp, u16 vnic_id);
int bnxt_hwrm_set_coal(struct bnxt *);
unsigned int bnxt_get_max_func_stat_ctxs(struct bnxt *bp);
void bnxt_set_max_func_stat_ctxs(struct bnxt *bp, unsigned int max);
unsigned int bnxt_get_max_func_cp_rings(struct bnxt *bp);
void bnxt_set_max_func_cp_rings(struct bnxt *bp, unsigned int max);
void bnxt_set_max_func_irqs(struct bnxt *bp, unsigned int max);
void bnxt_tx_disable(struct bnxt *bp);
void bnxt_tx_enable(struct bnxt *bp);
Expand Down
Loading

0 comments on commit a588e45

Please sign in to comment.