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

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

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
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -489,9 +489,6 @@ struct brcmf_pub {
	struct mutex proto_block;
	unsigned char proto_buf[BRCMF_DCMD_MAXLEN];

	atomic_t pend_8021x_cnt;
	wait_queue_head_t pend_8021x_wait;

	struct brcmf_fweh_info fweh;
#ifdef DEBUG
	struct dentry *dbgfs_dir;
@@ -518,6 +515,8 @@ struct brcmf_cfg80211_vif;
 * @idx: interface index in device firmware.
 * @bssidx: index of bss associated with this interface.
 * @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_pub *drvr;
@@ -529,6 +528,8 @@ struct brcmf_if {
	int idx;
	s32 bssidx;
	u8 mac_addr[ETH_ALEN];
	atomic_t pend_8021x_cnt;
	wait_queue_head_t pend_8021x_wait;
};


+13 −12
Original line number Diff line number Diff line
@@ -217,7 +217,7 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
	if (is_multicast_ether_addr(eh->h_dest))
		drvr->tx_multicast++;
	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 */
	brcmf_proto_hdrpush(drvr, ifp->idx, skb);
@@ -348,6 +348,7 @@ void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success)
	u16 type;
	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
	struct brcmf_pub *drvr = bus_if->drvr;
	struct brcmf_if *ifp;

	brcmf_proto_hdrpull(drvr, &ifidx, txp);

@@ -355,9 +356,10 @@ void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success)
	type = ntohs(eh->h_proto);

	if (type == ETH_P_PAE) {
		atomic_dec(&drvr->pend_8021x_cnt);
		if (waitqueue_active(&drvr->pend_8021x_wait))
			wake_up(&drvr->pend_8021x_wait);
		ifp = drvr->iflist[ifidx];
		atomic_dec(&ifp->pend_8021x_cnt);
		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)
		return -EAGAIN;
	}

	atomic_set(&drvr->pend_8021x_cnt, 0);
	atomic_set(&ifp->pend_8021x_cnt, 0);

	/* Get current TOE mode from dongle */
	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,
	INIT_WORK(&ifp->setmacaddr_work, _brcmf_set_mac_address);
	INIT_WORK(&ifp->multicast_work, _brcmf_set_multicast_list);

	init_waitqueue_head(&ifp->pend_8021x_wait);

	if (addr_mask != NULL)
		for (i = 0; i < ETH_ALEN; i++)
			ifp->mac_addr[i] = drvr->mac[i] ^ addr_mask[i];
@@ -763,8 +767,6 @@ int brcmf_attach(uint bus_hdrlen, struct device *dev)

	INIT_LIST_HEAD(&drvr->bus_if->dcmd_list);

	init_waitqueue_head(&drvr->pend_8021x_wait);

	return ret;

fail:
@@ -879,19 +881,18 @@ void brcmf_detach(struct device *dev)
	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)
{
	struct brcmf_if *ifp = netdev_priv(ndev);
	struct brcmf_pub *drvr = ifp->drvr;
	int err;

	err = wait_event_timeout(drvr->pend_8021x_wait,
				 !brcmf_get_pend_8021x_cnt(drvr),
	err = wait_event_timeout(ifp->pend_8021x_wait,
				 !brcmf_get_pend_8021x_cnt(ifp),
				 msecs_to_jiffies(MAX_WAIT_FOR_8021X_TX));

	WARN_ON(!err);