Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 29e04ae3 authored by Arend van Spriel's avatar Arend van Spriel Committed by John W. Linville
Browse files

brcmfmac: allow stopping netif queue for different reasons



Currently, the netif queue is only stopped when the bus interface is
giving a push back. This will change soon so prepare the driver by
adding a stop reason and stop/resume the queue accordingly.

Reviewed-by: default avatarPieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: default avatarHante Meuleman <meuleman@broadcom.com>
Reviewed-by: default avatarPiotr Haber <phaber@broadcom.com>
Signed-off-by: default avatarArend van Spriel <arend@broadcom.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent fba1400a
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -554,6 +554,19 @@ struct brcmf_if_event {
struct brcmf_cfg80211_vif;
struct brcmf_fws_mac_descriptor;

/**
 * enum brcmf_netif_stop_reason - reason for stopping netif queue.
 *
 * @BRCMF_NETIF_STOP_REASON_FWS_FC:
 *	netif stopped due to firmware signalling flow control.
 * @BRCMF_NETIF_STOP_REASON_BLOCK_BUS:
 *	netif stopped due to bus blocking.
 */
enum brcmf_netif_stop_reason {
	BRCMF_NETIF_STOP_REASON_FWS_FC = 1,
	BRCMF_NETIF_STOP_REASON_BLOCK_BUS = 2
};

/**
 * struct brcmf_if - interface control information.
 *
@@ -567,6 +580,7 @@ struct brcmf_fws_mac_descriptor;
 * @ifidx: interface index in device firmware.
 * @bssidx: index of bss associated with this interface.
 * @mac_addr: assigned mac address.
 * @netif_stop: bitmap indicates reason why netif queues are stopped.
 * @pend_8021x_cnt: tracks outstanding number of 802.1x frames.
 * @pend_8021x_wait: used for signalling change in count.
 */
@@ -581,6 +595,7 @@ struct brcmf_if {
	int ifidx;
	s32 bssidx;
	u8 mac_addr[ETH_ALEN];
	u8 netif_stop;
	atomic_t pend_8021x_cnt;
	wait_queue_head_t pend_8021x_wait;
};
@@ -605,6 +620,8 @@ extern int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked);
extern struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx,
				     s32 ifidx, char *name, u8 *mac_addr);
extern void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx);
void brcmf_txflowblock_if(struct brcmf_if *ifp,
			  enum brcmf_netif_stop_reason reason, bool state);
extern u32 brcmf_get_chip_info(struct brcmf_if *ifp);

#endif				/* _BRCMF_H_ */
+21 −8
Original line number Diff line number Diff line
@@ -248,9 +248,27 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
	return NETDEV_TX_OK;
}

void brcmf_txflowblock_if(struct brcmf_if *ifp,
			  enum brcmf_netif_stop_reason reason, bool state)
{
	if (!ifp)
		return;

	brcmf_dbg(TRACE, "enter: idx=%d stop=0x%X reason=%d state=%d\n",
		  ifp->bssidx, ifp->netif_stop, reason, state);
	if (state) {
		if (!ifp->netif_stop)
			netif_stop_queue(ifp->ndev);
		ifp->netif_stop |= reason;
	} else {
		ifp->netif_stop &= ~reason;
		if (!ifp->netif_stop)
			netif_wake_queue(ifp->ndev);
	}
}

void brcmf_txflowblock(struct device *dev, bool state)
{
	struct net_device *ndev;
	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
	struct brcmf_pub *drvr = bus_if->drvr;
	int i;
@@ -258,13 +276,8 @@ void brcmf_txflowblock(struct device *dev, bool state)
	brcmf_dbg(TRACE, "Enter\n");

	for (i = 0; i < BRCMF_MAX_IFS; i++)
		if (drvr->iflist[i]) {
			ndev = drvr->iflist[i]->ndev;
			if (state)
				netif_stop_queue(ndev);
			else
				netif_wake_queue(ndev);
		}
		brcmf_txflowblock_if(drvr->iflist[i],
				     BRCMF_NETIF_STOP_REASON_BLOCK_BUS, state);
}

void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)