From 5deaeae186b4e3b2e2f1dd16f6279873424935aa Mon Sep 17 00:00:00 2001 From: Bhargava Marreddy Date: Thu, 29 Jan 2026 00:26:20 +0530 Subject: [PATCH] bng_en: Add ndo_features_check support Implement ndo_features_check to validate hardware constraints per-packet: - Disable SG if nr_frags exceeds hardware limit. - Disable GSO if packet/fragment length exceeds supported maximum. Signed-off-by: Bhargava Marreddy Reviewed-by: Vikas Gupta Reviewed-by: Ajit Kumar Khaparde Reviewed-by: Rahul Gupta Link: https://patch.msgid.link/20260128185623.26559-6-bhargava.marreddy@broadcom.com Signed-off-by: Jakub Kicinski --- .../net/ethernet/broadcom/bnge/bnge_netdev.c | 1 + .../net/ethernet/broadcom/bnge/bnge_txrx.c | 24 +++++++++++++++++++ .../net/ethernet/broadcom/bnge/bnge_txrx.h | 3 +++ 3 files changed, 28 insertions(+) diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c index 78f04db3c597..fba7f6a73b85 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c @@ -2421,6 +2421,7 @@ static const struct net_device_ops bnge_netdev_ops = { .ndo_open = bnge_open, .ndo_stop = bnge_close, .ndo_start_xmit = bnge_start_xmit, + .ndo_features_check = bnge_features_check, }; static void bnge_init_mac_addr(struct bnge_dev *bd) diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_txrx.c b/drivers/net/ethernet/broadcom/bnge/bnge_txrx.c index 261b071a8bd6..312b5cbea2a5 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_txrx.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_txrx.c @@ -966,3 +966,27 @@ tx_kick_pending: dev_core_stats_tx_dropped_inc(dev); return NETDEV_TX_OK; } + +netdev_features_t bnge_features_check(struct sk_buff *skb, + struct net_device *dev, + netdev_features_t features) +{ + u32 len; + + features = vlan_features_check(skb, features); +#if (MAX_SKB_FRAGS > TX_MAX_FRAGS) + if (skb_shinfo(skb)->nr_frags > TX_MAX_FRAGS) + features &= ~NETIF_F_SG; +#endif + + if (skb_is_gso(skb)) + len = bnge_get_gso_hdr_len(skb) + skb_shinfo(skb)->gso_size; + else + len = skb->len; + + len >>= 9; + if (unlikely(len >= ARRAY_SIZE(bnge_lhint_arr))) + features &= ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK); + + return features; +} diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_txrx.h b/drivers/net/ethernet/broadcom/bnge/bnge_txrx.h index 81a24d8f9689..32be5eb46870 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_txrx.h +++ b/drivers/net/ethernet/broadcom/bnge/bnge_txrx.h @@ -119,4 +119,7 @@ irqreturn_t bnge_msix(int irq, void *dev_instance); netdev_tx_t bnge_start_xmit(struct sk_buff *skb, struct net_device *dev); void bnge_reuse_rx_data(struct bnge_rx_ring_info *rxr, u16 cons, void *data); int bnge_napi_poll(struct napi_struct *napi, int budget); +netdev_features_t bnge_features_check(struct sk_buff *skb, + struct net_device *dev, + netdev_features_t features); #endif /* _BNGE_TXRX_H_ */ -- 2.47.3