diff options
| author | Bhargava Marreddy <bhargava.marreddy@broadcom.com> | 2026-01-29 00:26:18 +0530 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2026-01-29 19:49:56 -0800 |
| commit | 23cfc4e8e149012a137aba13f25667f311d4e670 (patch) | |
| tree | 76e5d29e747674b03ec934962da1d32a0e98c9bb | |
| parent | 4d6a60057c34b7db611905d5a65ef2e6a36ec731 (diff) | |
bng_en: Handle an HWRM completion request
Since the HWRM completion for a sent request lands on the NQ,
add functions to handle the HWRM completion event.
Signed-off-by: Bhargava Marreddy <bhargava.marreddy@broadcom.com>
Reviewed-by: Vikas Gupta <vikas.gupta@broadcom.com>
Reviewed-by: Rajashekar Hudumula <rajashekar.hudumula@broadcom.com>
Link: https://patch.msgid.link/20260128185623.26559-4-bhargava.marreddy@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
| -rw-r--r-- | drivers/net/ethernet/broadcom/bnge/bnge_netdev.c | 3 | ||||
| -rw-r--r-- | drivers/net/ethernet/broadcom/bnge/bnge_netdev.h | 1 | ||||
| -rw-r--r-- | drivers/net/ethernet/broadcom/bnge/bnge_txrx.c | 44 |
3 files changed, 45 insertions, 3 deletions
diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c index 70d2fbca2a95..500653f085e6 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c @@ -2305,8 +2305,7 @@ static int bnge_open(struct net_device *dev) static int bnge_shutdown_nic(struct bnge_net *bn) { - /* TODO: close_path = 0 until we make NAPI functional */ - bnge_hwrm_resource_free(bn, 0); + bnge_hwrm_resource_free(bn, 1); return 0; } diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.h b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.h index ce5e93a50ad8..810b1046f794 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.h +++ b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.h @@ -77,6 +77,7 @@ struct tx_cmp { #define CMPL_BASE_TYPE_HWRM_FWD_REQ 0x22UL #define CMPL_BASE_TYPE_HWRM_FWD_RESP 0x24UL #define CMPL_BASE_TYPE_HWRM_ASYNC_EVENT 0x2eUL + #define CMPL_BA_TY_HWRM_ASY_EVT CMPL_BASE_TYPE_HWRM_ASYNC_EVENT #define TX_CMP_FLAGS_ERROR (1 << 6) #define TX_CMP_FLAGS_PUSH (1 << 7) u32 tx_cmp_opaque; diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_txrx.c b/drivers/net/ethernet/broadcom/bnge/bnge_txrx.c index a8a55e166331..99d9ac80647a 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_txrx.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_txrx.c @@ -383,6 +383,43 @@ static void __bnge_poll_work_done(struct bnge_net *bn, struct bnge_napi *bnapi, } } +static void +bnge_hwrm_update_token(struct bnge_dev *bd, u16 seq_id, + enum bnge_hwrm_wait_state state) +{ + struct bnge_hwrm_wait_token *token; + + rcu_read_lock(); + hlist_for_each_entry_rcu(token, &bd->hwrm_pending_list, node) { + if (token->seq_id == seq_id) { + WRITE_ONCE(token->state, state); + rcu_read_unlock(); + return; + } + } + rcu_read_unlock(); + dev_err(bd->dev, "Invalid hwrm seq id %d\n", seq_id); +} + +static int bnge_hwrm_handler(struct bnge_dev *bd, struct tx_cmp *txcmp) +{ + struct hwrm_cmpl *h_cmpl = (struct hwrm_cmpl *)txcmp; + u16 cmpl_type = TX_CMP_TYPE(txcmp), seq_id; + + switch (cmpl_type) { + case CMPL_BASE_TYPE_HWRM_DONE: + seq_id = le16_to_cpu(h_cmpl->sequence_id); + bnge_hwrm_update_token(bd, seq_id, BNGE_HWRM_COMPLETE); + break; + + case CMPL_BASE_TYPE_HWRM_ASYNC_EVENT: + default: + break; + } + + return 0; +} + static int __bnge_poll_work(struct bnge_net *bn, struct bnge_cp_ring_info *cpr, int budget) { @@ -433,8 +470,11 @@ static int __bnge_poll_work(struct bnge_net *bn, struct bnge_cp_ring_info *cpr, rx_pkts++; else if (rc == -EBUSY) /* partial completion */ break; + } else if (unlikely(cmp_type == CMPL_BASE_TYPE_HWRM_DONE || + cmp_type == CMPL_BASE_TYPE_HWRM_FWD_REQ || + cmp_type == CMPL_BA_TY_HWRM_ASY_EVT)) { + bnge_hwrm_handler(bn->bd, txcmp); } - raw_cons = NEXT_RAW_CMP(raw_cons); if (rx_pkts && rx_pkts == budget) { @@ -552,6 +592,8 @@ int bnge_napi_poll(struct napi_struct *napi, int budget) work_done += __bnge_poll_work(bn, cpr, budget - work_done); nqr->has_more_work |= cpr->has_more_work; + } else { + bnge_hwrm_handler(bn->bd, (struct tx_cmp *)nqcmp); } raw_cons = NEXT_RAW_CMP(raw_cons); } |
