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: Pieter-Paul Giesberts <pieterpg@broadcom.com> Reviewed-by: Hante Meuleman <meuleman@broadcom.com> Reviewed-by: Piotr Haber <phaber@broadcom.com> Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
fba1400a9b
commit
29e04ae31d
@ -554,6 +554,19 @@ struct brcmf_if_event {
|
|||||||
struct brcmf_cfg80211_vif;
|
struct brcmf_cfg80211_vif;
|
||||||
struct brcmf_fws_mac_descriptor;
|
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.
|
* struct brcmf_if - interface control information.
|
||||||
*
|
*
|
||||||
@ -567,6 +580,7 @@ struct brcmf_fws_mac_descriptor;
|
|||||||
* @ifidx: interface index in device firmware.
|
* @ifidx: interface index in device firmware.
|
||||||
* @bssidx: index of bss associated with this interface.
|
* @bssidx: index of bss associated with this interface.
|
||||||
* @mac_addr: assigned mac address.
|
* @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_cnt: tracks outstanding number of 802.1x frames.
|
||||||
* @pend_8021x_wait: used for signalling change in count.
|
* @pend_8021x_wait: used for signalling change in count.
|
||||||
*/
|
*/
|
||||||
@ -581,6 +595,7 @@ struct brcmf_if {
|
|||||||
int ifidx;
|
int ifidx;
|
||||||
s32 bssidx;
|
s32 bssidx;
|
||||||
u8 mac_addr[ETH_ALEN];
|
u8 mac_addr[ETH_ALEN];
|
||||||
|
u8 netif_stop;
|
||||||
atomic_t pend_8021x_cnt;
|
atomic_t pend_8021x_cnt;
|
||||||
wait_queue_head_t pend_8021x_wait;
|
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,
|
extern struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx,
|
||||||
s32 ifidx, char *name, u8 *mac_addr);
|
s32 ifidx, char *name, u8 *mac_addr);
|
||||||
extern void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx);
|
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);
|
extern u32 brcmf_get_chip_info(struct brcmf_if *ifp);
|
||||||
|
|
||||||
#endif /* _BRCMF_H_ */
|
#endif /* _BRCMF_H_ */
|
||||||
|
@ -248,9 +248,27 @@ done:
|
|||||||
return NETDEV_TX_OK;
|
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)
|
void brcmf_txflowblock(struct device *dev, bool state)
|
||||||
{
|
{
|
||||||
struct net_device *ndev;
|
|
||||||
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
|
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
|
||||||
struct brcmf_pub *drvr = bus_if->drvr;
|
struct brcmf_pub *drvr = bus_if->drvr;
|
||||||
int i;
|
int i;
|
||||||
@ -258,13 +276,8 @@ void brcmf_txflowblock(struct device *dev, bool state)
|
|||||||
brcmf_dbg(TRACE, "Enter\n");
|
brcmf_dbg(TRACE, "Enter\n");
|
||||||
|
|
||||||
for (i = 0; i < BRCMF_MAX_IFS; i++)
|
for (i = 0; i < BRCMF_MAX_IFS; i++)
|
||||||
if (drvr->iflist[i]) {
|
brcmf_txflowblock_if(drvr->iflist[i],
|
||||||
ndev = drvr->iflist[i]->ndev;
|
BRCMF_NETIF_STOP_REASON_BLOCK_BUS, state);
|
||||||
if (state)
|
|
||||||
netif_stop_queue(ndev);
|
|
||||||
else
|
|
||||||
netif_wake_queue(ndev);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)
|
void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)
|
||||||
|
Loading…
Reference in New Issue
Block a user