mirror of
https://github.com/torvalds/linux.git
synced 2026-09-24 06:24:02 +02:00
bnge: add ndo_set_rx_mode_async support
Register bnge_set_rx_mode() as ndo_set_rx_mode_async to handle unicast, multicast, broadcast, and promiscuous filter updates via CFA_L2_SET_RX_MASK. The async variant receives pre-snapshotted address lists from the kernel, allowing the driver to issue sleepable HWRM firmware commands without holding the addr lock. Move uc_update detection to the caller so the async path can compute it directly from the snapshotted UC list before calling bnge_cfg_rx_mode(). Handle -EAGAIN from bnge_hwrm_set_vnic_filter() and bnge_hwrm_cfa_l2_set_rx_mask() on the open path by scheduling a retry via netif_rx_mode_schedule_retry() rather than failing the open. Signed-off-by: Vikas Gupta <vikas.gupta@broadcom.com> Reviewed-by: Dharmender Garg <dharmender.garg@broadcom.com> Reviewed-by: Rahul Gupta <rahul-rg.gupta@broadcom.com> Link: https://patch.msgid.link/20260731163712.3463362-3-vikas.gupta@broadcom.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
d5d7b17b3f
commit
fbe3647fd4
|
|
@ -2202,18 +2202,13 @@ static bool bnge_promisc_ok(struct bnge_net *bn)
|
|||
}
|
||||
|
||||
static int bnge_cfg_rx_mode(struct bnge_net *bn, struct netdev_hw_addr_list *uc,
|
||||
bool snapshot)
|
||||
bool uc_update, bool snapshot)
|
||||
{
|
||||
struct bnge_vnic_info *vnic = &bn->vnic_info[BNGE_VNIC_DEFAULT];
|
||||
struct net_device *dev = bn->netdev;
|
||||
struct bnge_dev *bd = bn->bd;
|
||||
struct netdev_hw_addr *ha;
|
||||
int i, off = 0, rc;
|
||||
bool uc_update;
|
||||
|
||||
netif_addr_lock_bh(dev);
|
||||
uc_update = bnge_uc_list_updated(bn, uc);
|
||||
netif_addr_unlock_bh(dev);
|
||||
|
||||
if (!uc_update)
|
||||
goto skip_uc;
|
||||
|
|
@ -2267,13 +2262,58 @@ static int bnge_cfg_rx_mode(struct bnge_net *bn, struct netdev_hw_addr_list *uc,
|
|||
vnic->mc_list_count = 0;
|
||||
rc = bnge_hwrm_cfa_l2_set_rx_mask(bd, vnic);
|
||||
}
|
||||
if (rc)
|
||||
netdev_err(dev, "HWRM cfa l2 rx mask failure rc: %d\n",
|
||||
rc);
|
||||
if (rc) {
|
||||
if (rc == -EAGAIN) {
|
||||
netdev_warn(dev, "FW busy while setting l2 rx mask in CFA, will retry\n");
|
||||
vnic->rx_mask &= ~BNGE_RX_MASK_CFG_FLAGS;
|
||||
} else {
|
||||
netdev_err(dev, "HWRM CFA L2 rx mask failure rc: %d\n",
|
||||
rc);
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int bnge_set_rx_mode(struct net_device *dev,
|
||||
struct netdev_hw_addr_list *uc,
|
||||
struct netdev_hw_addr_list *mc)
|
||||
{
|
||||
struct bnge_net *bn = netdev_priv(dev);
|
||||
struct bnge_vnic_info *vnic;
|
||||
bool mc_update = false;
|
||||
bool uc_update;
|
||||
u32 mask;
|
||||
|
||||
if (!test_bit(BNGE_STATE_OPEN, &bn->bd->state))
|
||||
return 0;
|
||||
|
||||
vnic = &bn->vnic_info[BNGE_VNIC_DEFAULT];
|
||||
mask = vnic->rx_mask;
|
||||
mask &= ~BNGE_RX_MASK_CFG_FLAGS;
|
||||
|
||||
if (dev->flags & IFF_PROMISC)
|
||||
mask |= CFA_L2_SET_RX_MASK_REQ_MASK_PROMISCUOUS;
|
||||
|
||||
uc_update = bnge_uc_list_updated(bn, uc);
|
||||
|
||||
if (dev->flags & IFF_BROADCAST)
|
||||
mask |= CFA_L2_SET_RX_MASK_REQ_MASK_BCAST;
|
||||
if (dev->flags & IFF_ALLMULTI) {
|
||||
mask |= CFA_L2_SET_RX_MASK_REQ_MASK_ALL_MCAST;
|
||||
vnic->mc_list_count = 0;
|
||||
} else if (dev->flags & IFF_MULTICAST) {
|
||||
mc_update = bnge_mc_list_updated(bn, &mask, mc);
|
||||
}
|
||||
|
||||
if (mask != vnic->rx_mask || uc_update || mc_update) {
|
||||
vnic->rx_mask = mask;
|
||||
return bnge_cfg_rx_mode(bn, uc, uc_update, true);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bnge_disable_int(struct bnge_net *bn)
|
||||
{
|
||||
struct bnge_dev *bd = bn->bd;
|
||||
|
|
@ -2706,9 +2746,13 @@ static int bnge_init_chip(struct bnge_net *bn)
|
|||
vnic->rx_mask |= mask;
|
||||
}
|
||||
|
||||
rc = bnge_cfg_rx_mode(bn, &bn->netdev->uc, false);
|
||||
if (rc)
|
||||
rc = bnge_cfg_rx_mode(bn, &bn->netdev->uc, true, false);
|
||||
if (rc == -EAGAIN) {
|
||||
netif_rx_mode_schedule_retry(bn->netdev);
|
||||
rc = 0;
|
||||
} else if (rc) {
|
||||
goto err_out;
|
||||
}
|
||||
return 0;
|
||||
|
||||
err_out:
|
||||
|
|
@ -3202,6 +3246,7 @@ static const struct net_device_ops bnge_netdev_ops = {
|
|||
.ndo_stop = bnge_close,
|
||||
.ndo_start_xmit = bnge_start_xmit,
|
||||
.ndo_get_stats64 = bnge_get_stats64,
|
||||
.ndo_set_rx_mode_async = bnge_set_rx_mode,
|
||||
.ndo_features_check = bnge_features_check,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -561,6 +561,12 @@ struct bnge_napi {
|
|||
#define BNGE_VNIC_DEFAULT 0
|
||||
#define BNGE_MAX_UC_ADDRS 4
|
||||
|
||||
#define BNGE_RX_MASK_CFG_FLAGS \
|
||||
(CFA_L2_SET_RX_MASK_REQ_MASK_PROMISCUOUS | \
|
||||
CFA_L2_SET_RX_MASK_REQ_MASK_MCAST | \
|
||||
CFA_L2_SET_RX_MASK_REQ_MASK_ALL_MCAST | \
|
||||
CFA_L2_SET_RX_MASK_REQ_MASK_BCAST)
|
||||
|
||||
struct bnge_vnic_info {
|
||||
u16 fw_vnic_id;
|
||||
#define BNGE_MAX_CTX_PER_VNIC 8
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user