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

Commit d58db4e4 authored by Vladimir Kondratiev's avatar Vladimir Kondratiev Committed by John W. Linville
Browse files

wil6210: Send EAPOL frames using normal Tx queue



No more need for special processing of EAPOL, FW can now send EAPOL frames
using normal Tx queue for TID 0

This fixes "schedule while atomic" bug - start_xmit called in softirq context;
while WMI mechanism that was used may sleep.

Signed-off-by: default avatarVladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 92646c9f
Loading
Loading
Loading
Loading
+9 −11
Original line number Diff line number Diff line
@@ -768,9 +768,7 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
		wil_err(wil, "Xmit in monitor mode not supported\n");
		goto drop;
	}
	if (skb->protocol == cpu_to_be16(ETH_P_PAE)) {
		rc = wmi_tx_eapol(wil, skb);
	} else {

	/* find vring */
	vring = wil_find_tx_vring(wil, skb);
	if (!vring) {
@@ -779,7 +777,7 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
	}
	/* set up vring entry */
	rc = wil_tx_vring(wil, vring, skb);
	}

	switch (rc) {
	case 0:
		/* statistics will be updated on the tx_complete */
+0 −1
Original line number Diff line number Diff line
@@ -329,7 +329,6 @@ int wmi_set_ssid(struct wil6210_priv *wil, u8 ssid_len, const void *ssid);
int wmi_get_ssid(struct wil6210_priv *wil, u8 *ssid_len, void *ssid);
int wmi_set_channel(struct wil6210_priv *wil, int channel);
int wmi_get_channel(struct wil6210_priv *wil, int *channel);
int wmi_tx_eapol(struct wil6210_priv *wil, struct sk_buff *skb);
int wmi_del_cipher_key(struct wil6210_priv *wil, u8 key_index,
		       const void *mac_addr);
int wmi_add_cipher_key(struct wil6210_priv *wil, u8 key_index,
+0 −34
Original line number Diff line number Diff line
@@ -839,40 +839,6 @@ int wmi_p2p_cfg(struct wil6210_priv *wil, int channel)
	return wmi_send(wil, WMI_P2P_CFG_CMDID, &cmd, sizeof(cmd));
}

int wmi_tx_eapol(struct wil6210_priv *wil, struct sk_buff *skb)
{
	struct wmi_eapol_tx_cmd *cmd;
	struct ethhdr *eth;
	u16 eapol_len = skb->len - ETH_HLEN;
	void *eapol = skb->data + ETH_HLEN;
	uint i;
	int rc;

	skb_set_mac_header(skb, 0);
	eth = eth_hdr(skb);
	wil_dbg_wmi(wil, "EAPOL %d bytes to %pM\n", eapol_len, eth->h_dest);
	for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) {
		if (memcmp(wil->dst_addr[i], eth->h_dest, ETH_ALEN) == 0)
			goto found_dest;
	}

	return -EINVAL;

 found_dest:
	/* find out eapol data & len */
	cmd = kzalloc(sizeof(*cmd) + eapol_len, GFP_KERNEL);
	if (!cmd)
		return -EINVAL;

	memcpy(cmd->dst_mac, eth->h_dest, ETH_ALEN);
	cmd->eapol_len = cpu_to_le16(eapol_len);
	memcpy(cmd->eapol, eapol, eapol_len);
	rc = wmi_send(wil, WMI_EAPOL_TX_CMDID, cmd, sizeof(*cmd) + eapol_len);
	kfree(cmd);

	return rc;
}

int wmi_del_cipher_key(struct wil6210_priv *wil, u8 key_index,
		       const void *mac_addr)
{