]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
bng_en: Handle an HWRM completion request
authorBhargava Marreddy <bhargava.marreddy@broadcom.com>
Wed, 28 Jan 2026 18:56:18 +0000 (00:26 +0530)
committerJakub Kicinski <kuba@kernel.org>
Fri, 30 Jan 2026 03:49:56 +0000 (19:49 -0800)
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>
drivers/net/ethernet/broadcom/bnge/bnge_netdev.c
drivers/net/ethernet/broadcom/bnge/bnge_netdev.h
drivers/net/ethernet/broadcom/bnge/bnge_txrx.c

index 70d2fbca2a9563c97c8bece854ea820f64413401..500653f085e645aa9de2f01e94a901e36b536436 100644 (file)
@@ -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;
 }
 
index ce5e93a50ad8e32aee776199b1ed4ac992b9f772..810b1046f794ae827ca2829a5e3b7b1edac88ac5 100644 (file)
@@ -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;
index a8a55e166331255093bcb5c42add551b4cf531f5..99d9ac80647ae53ffd592eb543741f67e4845b8d 100644 (file)
@@ -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);
        }