From: Bhargava Marreddy <bhargava.marreddy@broadcom.com>
To: davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
pabeni@redhat.com, andrew+netdev@lunn.ch, horms@kernel.org
Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
michael.chan@broadcom.com, pavan.chebbi@broadcom.com,
vsrama-krishna.nemani@broadcom.com, vikas.gupta@broadcom.com,
Bhargava Marreddy <bhargava.marreddy@broadcom.com>,
Rajashekar Hudumula <rajashekar.hudumula@broadcom.com>,
Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
Subject: [PATCH net-next v9 05/10] bng_en: add support for link async events
Date: Wed, 25 Mar 2026 01:37:35 +0530 [thread overview]
Message-ID: <20260324200740.346029-6-bhargava.marreddy@broadcom.com> (raw)
In-Reply-To: <20260324200740.346029-1-bhargava.marreddy@broadcom.com>
Register for firmware asynchronous events, including link-status,
link-speed, and PHY configuration changes. Upon event reception,
re-query the PHY and update ethtool settings accordingly.
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>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
.../ethernet/broadcom/bnge/bnge_hwrm_lib.c | 19 +++++++++-
.../net/ethernet/broadcom/bnge/bnge_link.c | 19 ++++++++++
.../net/ethernet/broadcom/bnge/bnge_link.h | 4 +++
.../net/ethernet/broadcom/bnge/bnge_netdev.c | 23 ++++++++++++
.../net/ethernet/broadcom/bnge/bnge_txrx.c | 35 ++++++++++++++++---
5 files changed, 95 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c b/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c
index 1cc62883d3c7..523b8963b6dc 100644
--- a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c
+++ b/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c
@@ -15,6 +15,13 @@
#include "bnge_rmem.h"
#include "bnge_resc.h"
+static const u16 bnge_async_events_arr[] = {
+ ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE,
+ ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CHANGE,
+ ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE,
+ ASYNC_EVENT_CMPL_EVENT_ID_PORT_PHY_CFG_CHANGE,
+};
+
int bnge_hwrm_ver_get(struct bnge_dev *bd)
{
u32 dev_caps_cfg, hwrm_ver, hwrm_spec_code;
@@ -166,10 +173,12 @@ int bnge_hwrm_fw_set_time(struct bnge_dev *bd)
int bnge_hwrm_func_drv_rgtr(struct bnge_dev *bd)
{
+ DECLARE_BITMAP(async_events_bmap, 256);
+ u32 events[8];
struct hwrm_func_drv_rgtr_output *resp;
struct hwrm_func_drv_rgtr_input *req;
u32 flags;
- int rc;
+ int rc, i;
rc = bnge_hwrm_req_init(bd, req, HWRM_FUNC_DRV_RGTR);
if (rc)
@@ -190,6 +199,14 @@ int bnge_hwrm_func_drv_rgtr(struct bnge_dev *bd)
req->ver_min = cpu_to_le16(DRV_VER_MIN);
req->ver_upd = cpu_to_le16(DRV_VER_UPD);
+ memset(async_events_bmap, 0, sizeof(async_events_bmap));
+ for (i = 0; i < ARRAY_SIZE(bnge_async_events_arr); i++)
+ __set_bit(bnge_async_events_arr[i], async_events_bmap);
+
+ bitmap_to_arr32(events, async_events_bmap, 256);
+ for (i = 0; i < ARRAY_SIZE(req->async_event_fwd); i++)
+ req->async_event_fwd[i] |= cpu_to_le32(events[i]);
+
resp = bnge_hwrm_req_hold(bd, req);
rc = bnge_hwrm_req_send(bd, req);
if (!rc) {
diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_link.c b/drivers/net/ethernet/broadcom/bnge/bnge_link.c
index f924184f715e..3444dd694519 100644
--- a/drivers/net/ethernet/broadcom/bnge/bnge_link.c
+++ b/drivers/net/ethernet/broadcom/bnge/bnge_link.c
@@ -1264,3 +1264,22 @@ int bnge_set_link_ksettings(struct net_device *dev,
set_setting_exit:
return rc;
}
+
+void bnge_link_async_event_process(struct bnge_net *bn,
+ u16 event_id, u32 evt_data)
+{
+ switch (event_id) {
+ case ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE:
+ set_bit(BNGE_LINK_SPEED_CHNG_SP_EVENT, &bn->sp_event);
+ break;
+ case ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CHANGE:
+ case ASYNC_EVENT_CMPL_EVENT_ID_PORT_PHY_CFG_CHANGE:
+ set_bit(BNGE_LINK_CFG_CHANGE_SP_EVENT, &bn->sp_event);
+ break;
+ case ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE:
+ set_bit(BNGE_LINK_CHNG_SP_EVENT, &bn->sp_event);
+ break;
+ default:
+ break;
+ }
+}
diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_link.h b/drivers/net/ethernet/broadcom/bnge/bnge_link.h
index 70d0901b9a32..cadc26cfbcf5 100644
--- a/drivers/net/ethernet/broadcom/bnge/bnge_link.h
+++ b/drivers/net/ethernet/broadcom/bnge/bnge_link.h
@@ -197,4 +197,8 @@ int bnge_set_link_ksettings(struct net_device *dev,
int bnge_get_link_ksettings(struct net_device *dev,
struct ethtool_link_ksettings *lk_ksettings);
u32 bnge_get_link(struct net_device *dev);
+#define BNGE_SPEED_CFG_CHANGE_SP_NOT_SUPP BIT(17)
+
+void bnge_link_async_event_process(struct bnge_net *bn,
+ u16 event_id, u32 evt_data);
#endif /* _BNGE_LINK_H_ */
diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c
index 25f1ba64d026..4ad08a5a933b 100644
--- a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c
+++ b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c
@@ -136,6 +136,7 @@ static void bnge_timer(struct timer_list *t)
static void bnge_sp_task(struct work_struct *work)
{
struct bnge_net *bn = container_of(work, struct bnge_net, sp_task);
+ bool speed_chng, cfg_chng, link_chng;
struct bnge_dev *bd = bn->bd;
netdev_lock(bn->netdev);
@@ -156,6 +157,28 @@ static void bnge_sp_task(struct work_struct *work)
}
}
+ speed_chng = test_and_clear_bit(BNGE_LINK_SPEED_CHNG_SP_EVENT,
+ &bn->sp_event);
+ cfg_chng = test_and_clear_bit(BNGE_LINK_CFG_CHANGE_SP_EVENT,
+ &bn->sp_event);
+ link_chng = test_and_clear_bit(BNGE_LINK_CHNG_SP_EVENT,
+ &bn->sp_event);
+
+ if (speed_chng || cfg_chng || link_chng) {
+ int rc;
+
+ if (speed_chng)
+ bnge_hwrm_phy_qcaps(bd);
+
+ rc = bnge_update_link(bn, true);
+ if (rc)
+ netdev_err(bn->netdev, "SP task cannot update link (rc: %d)\n",
+ rc);
+
+ if (speed_chng || cfg_chng)
+ bnge_init_ethtool_link_settings(bn);
+ }
+
netdev_unlock(bn->netdev);
}
diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_txrx.c b/drivers/net/ethernet/broadcom/bnge/bnge_txrx.c
index a2616f037557..88f9cf1db308 100644
--- a/drivers/net/ethernet/broadcom/bnge/bnge_txrx.c
+++ b/drivers/net/ethernet/broadcom/bnge/bnge_txrx.c
@@ -1128,6 +1128,29 @@ static void __bnge_poll_work_done(struct bnge_net *bn, struct bnge_napi *bnapi,
}
}
+static void bnge_async_event_process(struct bnge_net *bn,
+ struct hwrm_async_event_cmpl *cmpl)
+{
+ u16 event_id = le16_to_cpu(cmpl->event_id);
+ u32 data1 = le32_to_cpu(cmpl->event_data1);
+ u32 data2 = le32_to_cpu(cmpl->event_data2);
+
+ netdev_dbg(bn->netdev, "hwrm event 0x%x {0x%x, 0x%x}\n",
+ event_id, data1, data2);
+
+ switch (event_id) {
+ case ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE:
+ case ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CHANGE:
+ case ASYNC_EVENT_CMPL_EVENT_ID_PORT_PHY_CFG_CHANGE:
+ case ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE:
+ bnge_link_async_event_process(bn, event_id, data1);
+ break;
+ default:
+ return;
+ }
+ __bnge_queue_sp_work(bn);
+}
+
static void
bnge_hwrm_update_token(struct bnge_dev *bd, u16 seq_id,
enum bnge_hwrm_wait_state state)
@@ -1146,7 +1169,7 @@ bnge_hwrm_update_token(struct bnge_dev *bd, u16 seq_id,
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)
+static int bnge_hwrm_handler(struct bnge_net *bn, struct tx_cmp *txcmp)
{
struct hwrm_cmpl *h_cmpl = (struct hwrm_cmpl *)txcmp;
u16 cmpl_type = TX_CMP_TYPE(txcmp), seq_id;
@@ -1154,10 +1177,14 @@ static int bnge_hwrm_handler(struct bnge_dev *bd, struct tx_cmp *txcmp)
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);
+ bnge_hwrm_update_token(bn->bd, seq_id, BNGE_HWRM_COMPLETE);
break;
case CMPL_BASE_TYPE_HWRM_ASYNC_EVENT:
+ bnge_async_event_process(bn,
+ (struct hwrm_async_event_cmpl *)txcmp);
+ break;
+
default:
break;
}
@@ -1235,7 +1262,7 @@ static int __bnge_poll_work(struct bnge_net *bn, struct bnge_cp_ring_info *cpr,
} 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);
+ bnge_hwrm_handler(bn, txcmp);
}
raw_cons = NEXT_RAW_CMP(raw_cons);
@@ -1355,7 +1382,7 @@ int bnge_napi_poll(struct napi_struct *napi, int budget)
budget - work_done);
nqr->has_more_work |= cpr->has_more_work;
} else {
- bnge_hwrm_handler(bn->bd, (struct tx_cmp *)nqcmp);
+ bnge_hwrm_handler(bn, (struct tx_cmp *)nqcmp);
}
raw_cons = NEXT_RAW_CMP(raw_cons);
}
--
2.47.3
next prev parent reply other threads:[~2026-03-24 20:08 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-24 20:07 [PATCH net-next v9 00/10] bng_en: add link management and statistics support Bhargava Marreddy
2026-03-24 20:07 ` [PATCH net-next v9 01/10] bng_en: add per-PF workqueue, timer, and slow-path task Bhargava Marreddy
2026-03-24 20:07 ` [PATCH net-next v9 02/10] bng_en: query PHY capabilities and report link status Bhargava Marreddy
2026-03-24 20:07 ` [PATCH net-next v9 03/10] bng_en: add ethtool link settings, get_link, and nway_reset Bhargava Marreddy
2026-03-25 10:36 ` kernel test robot
2026-03-24 20:07 ` [PATCH net-next v9 04/10] bng_en: implement ethtool pauseparam operations Bhargava Marreddy
2026-03-24 20:07 ` Bhargava Marreddy [this message]
2026-03-24 20:07 ` [PATCH net-next v9 06/10] bng_en: add HW stats infra and structured ethtool ops Bhargava Marreddy
2026-03-24 20:07 ` [PATCH net-next v9 07/10] bng_en: periodically fetch and accumulate hardware statistics Bhargava Marreddy
2026-03-24 20:07 ` [PATCH net-next v9 08/10] bng_en: implement ndo_get_stats64 Bhargava Marreddy
2026-03-24 20:07 ` [PATCH net-next v9 09/10] bng_en: implement netdev_stat_ops Bhargava Marreddy
2026-03-24 20:07 ` [PATCH net-next v9 10/10] bng_en: add support for ethtool -S stats display Bhargava Marreddy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260324200740.346029-6-bhargava.marreddy@broadcom.com \
--to=bhargava.marreddy@broadcom.com \
--cc=ajit.khaparde@broadcom.com \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=michael.chan@broadcom.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=pavan.chebbi@broadcom.com \
--cc=rajashekar.hudumula@broadcom.com \
--cc=vikas.gupta@broadcom.com \
--cc=vsrama-krishna.nemani@broadcom.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox