Commit 10ef7321 authored by Hante Meuleman's avatar Hante Meuleman Committed by John W. Linville

brcmfmac: Track pending 8021x frames per ifp.

Pending 8021x frames were tracked per dongle. This should be
done per ifp.
Reviewed-by: default avatarArend Van Spriel <arend@broadcom.com>
Reviewed-by: default avatarPieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: default avatarHante Meuleman <meuleman@broadcom.com>
Signed-off-by: default avatarArend van Spriel <arend@broadcom.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 1f170110
...@@ -489,9 +489,6 @@ struct brcmf_pub { ...@@ -489,9 +489,6 @@ struct brcmf_pub {
struct mutex proto_block; struct mutex proto_block;
unsigned char proto_buf[BRCMF_DCMD_MAXLEN]; unsigned char proto_buf[BRCMF_DCMD_MAXLEN];
atomic_t pend_8021x_cnt;
wait_queue_head_t pend_8021x_wait;
struct brcmf_fweh_info fweh; struct brcmf_fweh_info fweh;
#ifdef DEBUG #ifdef DEBUG
struct dentry *dbgfs_dir; struct dentry *dbgfs_dir;
...@@ -518,6 +515,8 @@ struct brcmf_cfg80211_vif; ...@@ -518,6 +515,8 @@ struct brcmf_cfg80211_vif;
* @idx: interface index in device firmware. * @idx: 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.
* @pend_8021x_cnt: tracks outstanding number of 802.1x frames.
* @pend_8021x_wait: used for signalling change in count.
*/ */
struct brcmf_if { struct brcmf_if {
struct brcmf_pub *drvr; struct brcmf_pub *drvr;
...@@ -529,6 +528,8 @@ struct brcmf_if { ...@@ -529,6 +528,8 @@ struct brcmf_if {
int idx; int idx;
s32 bssidx; s32 bssidx;
u8 mac_addr[ETH_ALEN]; u8 mac_addr[ETH_ALEN];
atomic_t pend_8021x_cnt;
wait_queue_head_t pend_8021x_wait;
}; };
......
...@@ -217,7 +217,7 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb, ...@@ -217,7 +217,7 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
if (is_multicast_ether_addr(eh->h_dest)) if (is_multicast_ether_addr(eh->h_dest))
drvr->tx_multicast++; drvr->tx_multicast++;
if (ntohs(eh->h_proto) == ETH_P_PAE) if (ntohs(eh->h_proto) == ETH_P_PAE)
atomic_inc(&drvr->pend_8021x_cnt); atomic_inc(&ifp->pend_8021x_cnt);
/* If the protocol uses a data header, apply it */ /* If the protocol uses a data header, apply it */
brcmf_proto_hdrpush(drvr, ifp->idx, skb); brcmf_proto_hdrpush(drvr, ifp->idx, skb);
...@@ -348,6 +348,7 @@ void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success) ...@@ -348,6 +348,7 @@ void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success)
u16 type; u16 type;
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;
struct brcmf_if *ifp;
brcmf_proto_hdrpull(drvr, &ifidx, txp); brcmf_proto_hdrpull(drvr, &ifidx, txp);
...@@ -355,9 +356,10 @@ void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success) ...@@ -355,9 +356,10 @@ void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success)
type = ntohs(eh->h_proto); type = ntohs(eh->h_proto);
if (type == ETH_P_PAE) { if (type == ETH_P_PAE) {
atomic_dec(&drvr->pend_8021x_cnt); ifp = drvr->iflist[ifidx];
if (waitqueue_active(&drvr->pend_8021x_wait)) atomic_dec(&ifp->pend_8021x_cnt);
wake_up(&drvr->pend_8021x_wait); if (waitqueue_active(&ifp->pend_8021x_wait))
wake_up(&ifp->pend_8021x_wait);
} }
} }
...@@ -565,7 +567,7 @@ static int brcmf_netdev_open(struct net_device *ndev) ...@@ -565,7 +567,7 @@ static int brcmf_netdev_open(struct net_device *ndev)
return -EAGAIN; return -EAGAIN;
} }
atomic_set(&drvr->pend_8021x_cnt, 0); atomic_set(&ifp->pend_8021x_cnt, 0);
/* Get current TOE mode from dongle */ /* Get current TOE mode from dongle */
if (brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_ol) >= 0 if (brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_ol) >= 0
...@@ -686,6 +688,8 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, int ifidx, s32 bssidx, ...@@ -686,6 +688,8 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, int ifidx, s32 bssidx,
INIT_WORK(&ifp->setmacaddr_work, _brcmf_set_mac_address); INIT_WORK(&ifp->setmacaddr_work, _brcmf_set_mac_address);
INIT_WORK(&ifp->multicast_work, _brcmf_set_multicast_list); INIT_WORK(&ifp->multicast_work, _brcmf_set_multicast_list);
init_waitqueue_head(&ifp->pend_8021x_wait);
if (addr_mask != NULL) if (addr_mask != NULL)
for (i = 0; i < ETH_ALEN; i++) for (i = 0; i < ETH_ALEN; i++)
ifp->mac_addr[i] = drvr->mac[i] ^ addr_mask[i]; ifp->mac_addr[i] = drvr->mac[i] ^ addr_mask[i];
...@@ -763,8 +767,6 @@ int brcmf_attach(uint bus_hdrlen, struct device *dev) ...@@ -763,8 +767,6 @@ int brcmf_attach(uint bus_hdrlen, struct device *dev)
INIT_LIST_HEAD(&drvr->bus_if->dcmd_list); INIT_LIST_HEAD(&drvr->bus_if->dcmd_list);
init_waitqueue_head(&drvr->pend_8021x_wait);
return ret; return ret;
fail: fail:
...@@ -879,19 +881,18 @@ void brcmf_detach(struct device *dev) ...@@ -879,19 +881,18 @@ void brcmf_detach(struct device *dev)
kfree(drvr); kfree(drvr);
} }
static int brcmf_get_pend_8021x_cnt(struct brcmf_pub *drvr) static int brcmf_get_pend_8021x_cnt(struct brcmf_if *ifp)
{ {
return atomic_read(&drvr->pend_8021x_cnt); return atomic_read(&ifp->pend_8021x_cnt);
} }
int brcmf_netdev_wait_pend8021x(struct net_device *ndev) int brcmf_netdev_wait_pend8021x(struct net_device *ndev)
{ {
struct brcmf_if *ifp = netdev_priv(ndev); struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_pub *drvr = ifp->drvr;
int err; int err;
err = wait_event_timeout(drvr->pend_8021x_wait, err = wait_event_timeout(ifp->pend_8021x_wait,
!brcmf_get_pend_8021x_cnt(drvr), !brcmf_get_pend_8021x_cnt(ifp),
msecs_to_jiffies(MAX_WAIT_FOR_8021X_TX)); msecs_to_jiffies(MAX_WAIT_FOR_8021X_TX));
WARN_ON(!err); WARN_ON(!err);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment