Commit 687006e2 authored by Thomas Gleixner's avatar Thomas Gleixner Committed by David S. Miller
Browse files

net: brcmfmac: Convey execution context via argument to brcmf_netif_rx()



bcrmgf_netif_rx() uses in_interrupt to chose between netif_rx() and
netif_rx_ni(). in_interrupt() usage in drivers is phased out.

Convey the execution mode via an 'inirq' argument through the various
callchains leading to brcmf_netif_rx():

brcmf_pcie_isr_thread()		    <- Task context
  brcmf_proto_msgbuf_rx_trigger()
    brcmf_msgbuf_process_rx()
      brcmf_msgbuf_process_msgtype()
        brcmf_msgbuf_process_rx_complete()
	  brcmf_netif_mon_rx()
	     brcmf_netif_rx(isirq = false)
	  brcmf_netif_rx(isirq = false)

brcmf_sdio_readframes()  <- Task context sdio_claim_host() might sleep
  brcmf_rx_frame(isirq = false)

brcmf_sdio_rxglom()      <- Task context sdio_claim_host() might sleep
  brcmf_rx_frame(isirq = false)

brcmf_usb_rx_complete()  <- Interrupt context
  brcmf_rx_frame(isirq = true)

brcmf_rx_frame()
  brcmf_proto_rxreorder()
    brcmf_proto_bcdc_rxreorder()
      brcmf_fws_rxreorder()
        brcmf_netif_rx()
      brcmf_netif_rx()

Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Cc: Arend van Spriel <arend.vanspriel@broadcom.com>
Cc: Kalle Valo <kvalo@codeaurora.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d067c0fa
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -397,9 +397,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
+2 −1
Original line number Diff line number Diff line
@@ -249,7 +249,8 @@ int brcmf_bus_reset(struct brcmf_bus *bus)
 */

/* Receive frame for delivery to OS.  Callee disposes of rxp. */
void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp, bool handle_event);
void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp, bool handle_event,
		    bool inirq);
/* Receive async event packet from firmware. Callee disposes of rxp. */
void brcmf_rx_event(struct device *dev, struct sk_buff *rxp);

+9 −7
Original line number Diff line number Diff line
@@ -395,7 +395,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
@@ -418,15 +418,16 @@ 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 (in_interrupt())
	if (inirq) {
		netif_rx(skb);
	else
	} 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);
	}
}

void brcmf_netif_mon_rx(struct brcmf_if *ifp, struct sk_buff *skb)
{
@@ -474,7 +475,7 @@ void brcmf_netif_mon_rx(struct brcmf_if *ifp, struct sk_buff *skb)
	skb->pkt_type = PACKET_OTHERHOST;
	skb->protocol = htons(ETH_P_802_2);

	brcmf_netif_rx(ifp, skb);
	brcmf_netif_rx(ifp, skb, false);
}

static int brcmf_rx_hdrpull(struct brcmf_pub *drvr, struct sk_buff *skb,
@@ -496,7 +497,8 @@ static int brcmf_rx_hdrpull(struct brcmf_pub *drvr, struct sk_buff *skb,
	return 0;
}

void brcmf_rx_frame(struct device *dev, struct sk_buff *skb, bool handle_event)
void brcmf_rx_frame(struct device *dev, struct sk_buff *skb, bool handle_event,
		    bool inirq)
{
	struct brcmf_if *ifp;
	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
@@ -508,14 +510,14 @@ void brcmf_rx_frame(struct device *dev, struct sk_buff *skb, bool handle_event)
		return;

	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)
			brcmf_fweh_process_skb(ifp->drvr, skb,
					       BCMILCP_SUBTYPE_VENDOR_LONG);

		brcmf_netif_rx(ifp, skb);
		brcmf_netif_rx(ifp, skb, inirq);
	}
}

+1 −1
Original line number Diff line number Diff line
@@ -208,7 +208,7 @@ void brcmf_remove_interface(struct brcmf_if *ifp, bool rtnl_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 rtnl_locked);
int brcmf_net_mon_attach(struct brcmf_if *ifp);
+5 −5
Original line number Diff line number Diff line
@@ -1664,7 +1664,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;
@@ -1682,7 +1682,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;
	}

@@ -1694,7 +1694,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;
		}

@@ -1719,7 +1719,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;
		}

@@ -1833,7 +1833,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);
	}
}

Loading