Skip to content

Commit

Permalink
bnxt_en: introduce new firmware message API based on DMA pools
Browse files Browse the repository at this point in the history
This change constitutes a major step towards supporting multiple
firmware commands in flight by maintaining a separate response buffer
for the duration of each request. These firmware commands are also
known as Hardware Resource Manager (HWRM) commands.  Using separate
response buffers requires an API change in order for callers to be
able to free the buffer when done.

It is impossible to keep the existing APIs unchanged.  The existing
usage for a simple HWRM message request such as the following:

        struct input req = {0};
        bnxt_hwrm_cmd_hdr_init(bp, &req, REQ_TYPE, -1, -1);
        rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
        if (rc)
                /* error */

changes to:

         struct input *req;
         rc = hwrm_req_init(bp, req, REQ_TYPE);
         if (rc)
                 /* error */
         rc = hwrm_req_send(bp, req); /* consumes req */
         if (rc)
                 /* error */

The key changes are:

1. The req is no longer allocated on the stack.
2. The caller must call hwrm_req_init() to allocate a req buffer and
   check for a valid buffer.
3. The req buffer is automatically released when hwrm_req_send() returns.
4. If the caller wants to check the firmware response, the caller must
   call hwrm_req_hold() to take ownership of the response buffer and
   release it afterwards using hwrm_req_drop().  The caller is no longer
   required to explicitly hold the hwrm_cmd_lock mutex to read the
   response.
5. Because the firmware commands and responses all have different sizes,
   some safeguards are added to the code.

This patch maintains legacy API compatibiltiy, implementing the old
API in terms of the new.  The follow-on patches will convert all
callers to use the new APIs.

v2: Fix redefined writeq with parisc .config
    Fix "cast from pointer to integer of different size" warning in
hwrm_calc_sentinel()

Signed-off-by: Edwin Peer <edwin.peer@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Edwin Peer authored and David S. Miller committed Aug 30, 2021
1 parent 3c8c20d commit f9ff578
Show file tree
Hide file tree
Showing 4 changed files with 442 additions and 121 deletions.
42 changes: 7 additions & 35 deletions drivers/net/ethernet/broadcom/bnxt/bnxt.c
Original file line number Diff line number Diff line change
Expand Up @@ -3963,6 +3963,9 @@ static void bnxt_free_hwrm_resources(struct bnxt *bp)
bp->hwrm_cmd_resp_dma_addr);
bp->hwrm_cmd_resp_addr = NULL;
}

dma_pool_destroy(bp->hwrm_dma_pool);
bp->hwrm_dma_pool = NULL;
}

static int bnxt_alloc_hwrm_resources(struct bnxt *bp)
Expand All @@ -3975,33 +3978,10 @@ static int bnxt_alloc_hwrm_resources(struct bnxt *bp)
if (!bp->hwrm_cmd_resp_addr)
return -ENOMEM;

return 0;
}

static void bnxt_free_hwrm_short_cmd_req(struct bnxt *bp)
{
if (bp->hwrm_short_cmd_req_addr) {
struct pci_dev *pdev = bp->pdev;

dma_free_coherent(&pdev->dev, bp->hwrm_max_ext_req_len,
bp->hwrm_short_cmd_req_addr,
bp->hwrm_short_cmd_req_dma_addr);
bp->hwrm_short_cmd_req_addr = NULL;
}
}

static int bnxt_alloc_hwrm_short_cmd_req(struct bnxt *bp)
{
struct pci_dev *pdev = bp->pdev;

if (bp->hwrm_short_cmd_req_addr)
return 0;

bp->hwrm_short_cmd_req_addr =
dma_alloc_coherent(&pdev->dev, bp->hwrm_max_ext_req_len,
&bp->hwrm_short_cmd_req_dma_addr,
GFP_KERNEL);
if (!bp->hwrm_short_cmd_req_addr)
bp->hwrm_dma_pool = dma_pool_create("bnxt_hwrm", &pdev->dev,
BNXT_HWRM_DMA_SIZE,
BNXT_HWRM_DMA_ALIGN, 0);
if (!bp->hwrm_dma_pool)
return -ENOMEM;

return 0;
Expand Down Expand Up @@ -11654,12 +11634,6 @@ static int bnxt_fw_init_one_p1(struct bnxt *bp)
return rc;
}

if ((bp->fw_cap & BNXT_FW_CAP_SHORT_CMD) ||
bp->hwrm_max_ext_req_len > BNXT_HWRM_MAX_REQ_LEN) {
rc = bnxt_alloc_hwrm_short_cmd_req(bp);
if (rc)
return rc;
}
bnxt_nvm_cfg_ver_get(bp);

rc = bnxt_hwrm_func_reset(bp);
Expand Down Expand Up @@ -12588,7 +12562,6 @@ static void bnxt_remove_one(struct pci_dev *pdev)
bnxt_clear_int_mode(bp);
bnxt_hwrm_func_drv_unrgtr(bp);
bnxt_free_hwrm_resources(bp);
bnxt_free_hwrm_short_cmd_req(bp);
bnxt_ethtool_free(bp);
bnxt_dcb_free(bp);
kfree(bp->edev);
Expand Down Expand Up @@ -13188,7 +13161,6 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)

init_err_pci_clean:
bnxt_hwrm_func_drv_unrgtr(bp);
bnxt_free_hwrm_short_cmd_req(bp);
bnxt_free_hwrm_resources(bp);
bnxt_ethtool_free(bp);
bnxt_ptp_clear(bp);
Expand Down
7 changes: 3 additions & 4 deletions drivers/net/ethernet/broadcom/bnxt/bnxt.h
Original file line number Diff line number Diff line change
Expand Up @@ -1881,10 +1881,9 @@ struct bnxt {
u16 hwrm_cmd_seq;
u16 hwrm_cmd_kong_seq;
u16 hwrm_intr_seq_id;
void *hwrm_short_cmd_req_addr;
dma_addr_t hwrm_short_cmd_req_dma_addr;
void *hwrm_cmd_resp_addr;
dma_addr_t hwrm_cmd_resp_dma_addr;
struct dma_pool *hwrm_dma_pool;

struct rtnl_link_stats64 net_stats_prev;
struct bnxt_stats_mem port_stats;
Expand Down Expand Up @@ -1984,7 +1983,7 @@ struct bnxt {
struct mutex sriov_lock;
#endif

#if BITS_PER_LONG == 32
#ifndef writeq
/* ensure atomic 64-bit doorbell writes on 32-bit systems. */
spinlock_t db_lock;
#endif
Expand Down Expand Up @@ -2113,7 +2112,7 @@ static inline u32 bnxt_tx_avail(struct bnxt *bp, struct bnxt_tx_ring_info *txr)
((txr->tx_prod - txr->tx_cons) & bp->tx_ring_mask);
}

#if BITS_PER_LONG == 32
#ifndef writeq
#define writeq(val64, db) \
do { \
spin_lock(&bp->db_lock); \
Expand Down
Loading

0 comments on commit f9ff578

Please sign in to comment.