From dca3ac00963456c75e4a0de748e9d6a14d5a48d0 Mon Sep 17 00:00:00 2001 From: Owen Huang Date: Wed, 3 Jul 2024 22:07:34 -0500 Subject: [PATCH 265/296] brcmfmac: refine netif_rx() for different kernel version netif_rx can be used under any context, it's part of kernel from kernel v5.18. 1. Revert "wireless: brcmfmac: Use netif_rx()." This reverts commit 04368b849ac3c0f2b867dfeaf68a5f6e408f3d36. 2. Add Linux version checking to use new approach Signed-off-by: Owen Huang --- .../broadcom/brcm80211/brcmfmac/bcdc.c | 4 ++-- .../broadcom/brcm80211/brcmfmac/core.c | 18 +++++++++++++++--- .../broadcom/brcm80211/brcmfmac/core.h | 2 +- .../broadcom/brcm80211/brcmfmac/fwsignal.c | 10 +++++----- .../broadcom/brcm80211/brcmfmac/fwsignal.h | 2 +- .../broadcom/brcm80211/brcmfmac/msgbuf.c | 5 +++-- .../broadcom/brcm80211/brcmfmac/proto.h | 6 +++--- 7 files changed, 30 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c index 9ec0c60b6da1..4fefd8587e5c 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c @@ -398,9 +398,9 @@ brcmf_proto_bcdc_add_tdls_peer(struct brcmf_pub *drvr, int ifidx, } static void brcmf_proto_bcdc_rxreorder(struct brcmf_if *ifp, - struct sk_buff *skb) + struct sk_buff *skb, bool inirq) { - brcmf_fws_rxreorder(ifp, skb); + brcmf_fws_rxreorder(ifp, skb, inirq); } static void diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c index ad18635d6eb6..d4c5aafc9c11 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c @@ -594,7 +594,7 @@ void brcmf_txflowblock_if(struct brcmf_if *ifp, spin_unlock_irqrestore(&ifp->netif_stop_lock, flags); } -void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb) +void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb, bool inirq) { /* Most of Broadcom's firmwares send 802.11f ADD frame every time a new * STA connects to the AP interface. This is an obsoleted standard most @@ -617,7 +617,19 @@ void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb) ifp->ndev->stats.rx_packets++; brcmf_dbg(DATA, "rx proto=0x%X\n", ntohs(skb->protocol)); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0)) netif_rx(skb); +#else + if (inirq) { + netif_rx(skb); + } else { + /* If the receive is not processed inside an ISR, + * the softirqd must be woken explicitly to service + * the NET_RX_SOFTIRQ. This is handled by netif_rx_ni(). + */ + netif_rx_ni(skb); + } +#endif /* kernel 5.18.0 */ } void brcmf_netif_mon_rx(struct brcmf_if *ifp, struct sk_buff *skb) @@ -701,7 +713,7 @@ struct sk_buff *brcmf_rx_frame(struct device *dev, struct sk_buff *skb, bool han return NULL; if (brcmf_proto_is_reorder_skb(skb)) { - brcmf_proto_rxreorder(ifp, skb); + brcmf_proto_rxreorder(ifp, skb, inirq); } else { /* Process special event packets */ if (handle_event) { @@ -715,7 +727,7 @@ struct sk_buff *brcmf_rx_frame(struct device *dev, struct sk_buff *skb, bool han if (brcmf_feat_is_sdio_rxf_in_kthread(drvr)) return skb; else - brcmf_netif_rx(ifp, skb); + brcmf_netif_rx(ifp, skb, inirq); } return NULL; } diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h index c78bd67412f8..e75bb806a4ac 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h @@ -249,7 +249,7 @@ void brcmf_remove_interface(struct brcmf_if *ifp, bool locked); void brcmf_txflowblock_if(struct brcmf_if *ifp, enum brcmf_netif_stop_reason reason, bool state); void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success); -void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb); +void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb, bool inirq); void brcmf_netif_mon_rx(struct brcmf_if *ifp, struct sk_buff *skb); void brcmf_net_detach(struct net_device *ndev, bool locked); int brcmf_net_mon_attach(struct brcmf_if *ifp); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c index ad38dff09d00..5040f6bf99e0 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c @@ -1667,7 +1667,7 @@ static void brcmf_rxreorder_get_skb_list(struct brcmf_ampdu_rx_reorder *rfi, rfi->pend_pkts -= skb_queue_len(skb_list); } -void brcmf_fws_rxreorder(struct brcmf_if *ifp, struct sk_buff *pkt) +void brcmf_fws_rxreorder(struct brcmf_if *ifp, struct sk_buff *pkt, bool inirq) { struct brcmf_pub *drvr = ifp->drvr; u8 *reorder_data; @@ -1685,7 +1685,7 @@ void brcmf_fws_rxreorder(struct brcmf_if *ifp, struct sk_buff *pkt) /* validate flags and flow id */ if (flags == 0xFF) { bphy_err(drvr, "invalid flags...so ignore this packet\n"); - brcmf_netif_rx(ifp, pkt); + brcmf_netif_rx(ifp, pkt, inirq); return; } @@ -1697,7 +1697,7 @@ void brcmf_fws_rxreorder(struct brcmf_if *ifp, struct sk_buff *pkt) if (rfi == NULL) { brcmf_dbg(INFO, "received flags to cleanup, but no flow (%d) yet\n", flow_id); - brcmf_netif_rx(ifp, pkt); + brcmf_netif_rx(ifp, pkt, inirq); return; } @@ -1722,7 +1722,7 @@ void brcmf_fws_rxreorder(struct brcmf_if *ifp, struct sk_buff *pkt) rfi = kzalloc(buf_size, GFP_ATOMIC); if (rfi == NULL) { bphy_err(drvr, "failed to alloc buffer\n"); - brcmf_netif_rx(ifp, pkt); + brcmf_netif_rx(ifp, pkt, inirq); return; } @@ -1836,7 +1836,7 @@ void brcmf_fws_rxreorder(struct brcmf_if *ifp, struct sk_buff *pkt) netif_rx: skb_queue_walk_safe(&reorder_list, pkt, pnext) { __skb_unlink(pkt, &reorder_list); - brcmf_netif_rx(ifp, pkt); + brcmf_netif_rx(ifp, pkt, inirq); } } diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h index f9c36cd8f1de..c3b2d3691c43 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h @@ -43,6 +43,6 @@ void brcmf_fws_del_interface(struct brcmf_if *ifp); void brcmf_fws_bustxcomplete(struct brcmf_fws_info *fws, struct sk_buff *skb, bool success); void brcmf_fws_bus_blocked(struct brcmf_pub *drvr, bool flow_blocked); -void brcmf_fws_rxreorder(struct brcmf_if *ifp, struct sk_buff *skb); +void brcmf_fws_rxreorder(struct brcmf_if *ifp, struct sk_buff *skb, bool inirq); #endif /* FWSIGNAL_H_ */ diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c index de4b2c9c6129..4308ab1e9288 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c @@ -590,7 +590,8 @@ static int brcmf_msgbuf_hdrpull(struct brcmf_pub *drvr, bool do_fws, return -ENODEV; } -static void brcmf_msgbuf_rxreorder(struct brcmf_if *ifp, struct sk_buff *skb) +static void brcmf_msgbuf_rxreorder(struct brcmf_if *ifp, struct sk_buff *skb, + bool inirq) { } @@ -827,7 +828,7 @@ static void brcmf_msgbuf_rx(struct brcmf_msgbuf *msgbuf) while ((skb = skb_dequeue(&msgbuf->rx_data_q))) { ifp = netdev_priv(skb->dev); if (ifp) - brcmf_netif_rx(ifp, skb); + brcmf_netif_rx(ifp, skb, false); } } diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h index bd08d3aaa8f4..f4a79e217da5 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h @@ -32,7 +32,7 @@ struct brcmf_proto { u8 peer[ETH_ALEN]); void (*add_tdls_peer)(struct brcmf_pub *drvr, int ifidx, u8 peer[ETH_ALEN]); - void (*rxreorder)(struct brcmf_if *ifp, struct sk_buff *skb); + void (*rxreorder)(struct brcmf_if *ifp, struct sk_buff *skb, bool inirq); void (*add_if)(struct brcmf_if *ifp); void (*del_if)(struct brcmf_if *ifp); void (*reset_if)(struct brcmf_if *ifp); @@ -109,9 +109,9 @@ static inline bool brcmf_proto_is_reorder_skb(struct sk_buff *skb) } static inline void -brcmf_proto_rxreorder(struct brcmf_if *ifp, struct sk_buff *skb) +brcmf_proto_rxreorder(struct brcmf_if *ifp, struct sk_buff *skb, bool inirq) { - ifp->drvr->proto->rxreorder(ifp, skb); + ifp->drvr->proto->rxreorder(ifp, skb, inirq); } static inline void -- 2.25.1