diff options
author | Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com> | 2013-06-09 02:12:54 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-06-12 15:06:51 -0400 |
commit | d58db4e49f58152a28dd598ebbec56f1fe92aa80 (patch) | |
tree | 1a23627c8bd3ac4db079b6600e3c04c9d1819c2d | |
parent | 92646c9f1f8fa2a31a3c12b026c2a8cd0e168341 (diff) |
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: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/ath/wil6210/txrx.c | 20 | ||||
-rw-r--r-- | drivers/net/wireless/ath/wil6210/wil6210.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/wil6210/wmi.c | 34 |
3 files changed, 9 insertions, 46 deletions
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c index 00dffeda983e..e1c492b9dfef 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.c +++ b/drivers/net/wireless/ath/wil6210/txrx.c | |||
@@ -768,18 +768,16 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
768 | wil_err(wil, "Xmit in monitor mode not supported\n"); | 768 | wil_err(wil, "Xmit in monitor mode not supported\n"); |
769 | goto drop; | 769 | goto drop; |
770 | } | 770 | } |
771 | if (skb->protocol == cpu_to_be16(ETH_P_PAE)) { | 771 | |
772 | rc = wmi_tx_eapol(wil, skb); | 772 | /* find vring */ |
773 | } else { | 773 | vring = wil_find_tx_vring(wil, skb); |
774 | /* find vring */ | 774 | if (!vring) { |
775 | vring = wil_find_tx_vring(wil, skb); | 775 | wil_err(wil, "No Tx VRING available\n"); |
776 | if (!vring) { | 776 | goto drop; |
777 | wil_err(wil, "No Tx VRING available\n"); | ||
778 | goto drop; | ||
779 | } | ||
780 | /* set up vring entry */ | ||
781 | rc = wil_tx_vring(wil, vring, skb); | ||
782 | } | 777 | } |
778 | /* set up vring entry */ | ||
779 | rc = wil_tx_vring(wil, vring, skb); | ||
780 | |||
783 | switch (rc) { | 781 | switch (rc) { |
784 | case 0: | 782 | case 0: |
785 | /* statistics will be updated on the tx_complete */ | 783 | /* statistics will be updated on the tx_complete */ |
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index 373cf656f5b0..44fdab51de7e 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h | |||
@@ -329,7 +329,6 @@ int wmi_set_ssid(struct wil6210_priv *wil, u8 ssid_len, const void *ssid); | |||
329 | int wmi_get_ssid(struct wil6210_priv *wil, u8 *ssid_len, void *ssid); | 329 | int wmi_get_ssid(struct wil6210_priv *wil, u8 *ssid_len, void *ssid); |
330 | int wmi_set_channel(struct wil6210_priv *wil, int channel); | 330 | int wmi_set_channel(struct wil6210_priv *wil, int channel); |
331 | int wmi_get_channel(struct wil6210_priv *wil, int *channel); | 331 | int wmi_get_channel(struct wil6210_priv *wil, int *channel); |
332 | int wmi_tx_eapol(struct wil6210_priv *wil, struct sk_buff *skb); | ||
333 | int wmi_del_cipher_key(struct wil6210_priv *wil, u8 key_index, | 332 | int wmi_del_cipher_key(struct wil6210_priv *wil, u8 key_index, |
334 | const void *mac_addr); | 333 | const void *mac_addr); |
335 | int wmi_add_cipher_key(struct wil6210_priv *wil, u8 key_index, | 334 | int wmi_add_cipher_key(struct wil6210_priv *wil, u8 key_index, |
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index ac4d26b34097..dc8059ad4bab 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c | |||
@@ -839,40 +839,6 @@ int wmi_p2p_cfg(struct wil6210_priv *wil, int channel) | |||
839 | return wmi_send(wil, WMI_P2P_CFG_CMDID, &cmd, sizeof(cmd)); | 839 | return wmi_send(wil, WMI_P2P_CFG_CMDID, &cmd, sizeof(cmd)); |
840 | } | 840 | } |
841 | 841 | ||
842 | int wmi_tx_eapol(struct wil6210_priv *wil, struct sk_buff *skb) | ||
843 | { | ||
844 | struct wmi_eapol_tx_cmd *cmd; | ||
845 | struct ethhdr *eth; | ||
846 | u16 eapol_len = skb->len - ETH_HLEN; | ||
847 | void *eapol = skb->data + ETH_HLEN; | ||
848 | uint i; | ||
849 | int rc; | ||
850 | |||
851 | skb_set_mac_header(skb, 0); | ||
852 | eth = eth_hdr(skb); | ||
853 | wil_dbg_wmi(wil, "EAPOL %d bytes to %pM\n", eapol_len, eth->h_dest); | ||
854 | for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) { | ||
855 | if (memcmp(wil->dst_addr[i], eth->h_dest, ETH_ALEN) == 0) | ||
856 | goto found_dest; | ||
857 | } | ||
858 | |||
859 | return -EINVAL; | ||
860 | |||
861 | found_dest: | ||
862 | /* find out eapol data & len */ | ||
863 | cmd = kzalloc(sizeof(*cmd) + eapol_len, GFP_KERNEL); | ||
864 | if (!cmd) | ||
865 | return -EINVAL; | ||
866 | |||
867 | memcpy(cmd->dst_mac, eth->h_dest, ETH_ALEN); | ||
868 | cmd->eapol_len = cpu_to_le16(eapol_len); | ||
869 | memcpy(cmd->eapol, eapol, eapol_len); | ||
870 | rc = wmi_send(wil, WMI_EAPOL_TX_CMDID, cmd, sizeof(*cmd) + eapol_len); | ||
871 | kfree(cmd); | ||
872 | |||
873 | return rc; | ||
874 | } | ||
875 | |||
876 | int wmi_del_cipher_key(struct wil6210_priv *wil, u8 key_index, | 842 | int wmi_del_cipher_key(struct wil6210_priv *wil, u8 key_index, |
877 | const void *mac_addr) | 843 | const void *mac_addr) |
878 | { | 844 | { |