aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/tx.c
diff options
context:
space:
mode:
authorYogesh Ashok Powar <yogeshp@marvell.com>2011-06-28 09:11:37 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-07-05 15:26:50 -0400
commit3bff1865186c6bb97855f0c13e3850543dce9cef (patch)
tree4a9150f82cbb83a01f8fb82b3bf2d69028230928 /net/mac80211/tx.c
parent252e735d64880b011f6cdeb41ebcac2eaeb58fd3 (diff)
mac80211: Skip tailroom reservation for full HW-crypto devices with race fix
Based on inputs from Johannes Berg <johannes@sipsolutions.net> from http://article.gmane.org/gmane.linux.kernel.wireless.general/68193 and http://article.gmane.org/gmane.linux.kernel.wireless.general/71702 In xmit path, devices that do full hardware crypto (including MMIC and ICV) need no tailroom. For such devices, tailroom reservation can be skipped if all the keys are programmed into the hardware (i.e software crypto is not used for any of the keys) and none of the keys wants software to generate Michael MIC and IV. v2: Added check for IV along with MMIC. Reported-by: Fabio Rossi <rossi.f@inwind.it> Tested-by: Fabio Rossi <rossi.f@inwind.it> Signed-off-by: Mohammed Shafi Shajakhan <mshajakhan@atheros.com> Cc: Mohammed Shafi Shajakhan <mshajakhan@atheros.com> v3: Fixing races to avoid WARNING: at net/mac80211/wpa.c:397 ccmp_encrypt_skb+0xc4/0x1f0 Reported-by: Andreas Hartmann <andihartmann@01019freenet.de> Tested-by: Andreas Hartmann <andihartmann@01019freenet.de> v4: Added links with message ID Signed-off-by: Yogesh Ashok Powar <yogeshp@marvell.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/tx.c')
-rw-r--r--net/mac80211/tx.c14
1 files changed, 5 insertions, 9 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 3104c844b544..e8d0d2d22665 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1474,18 +1474,14 @@ static bool ieee80211_tx(struct ieee80211_sub_if_data *sdata,
1474 1474
1475/* device xmit handlers */ 1475/* device xmit handlers */
1476 1476
1477static int ieee80211_skb_resize(struct ieee80211_local *local, 1477static int ieee80211_skb_resize(struct ieee80211_sub_if_data *sdata,
1478 struct sk_buff *skb, 1478 struct sk_buff *skb,
1479 int head_need, bool may_encrypt) 1479 int head_need, bool may_encrypt)
1480{ 1480{
1481 struct ieee80211_local *local = sdata->local;
1481 int tail_need = 0; 1482 int tail_need = 0;
1482 1483
1483 /* 1484 if (may_encrypt && sdata->crypto_tx_tailroom_needed_cnt) {
1484 * This could be optimised, devices that do full hardware
1485 * crypto (including TKIP MMIC) need no tailroom... But we
1486 * have no drivers for such devices currently.
1487 */
1488 if (may_encrypt) {
1489 tail_need = IEEE80211_ENCRYPT_TAILROOM; 1485 tail_need = IEEE80211_ENCRYPT_TAILROOM;
1490 tail_need -= skb_tailroom(skb); 1486 tail_need -= skb_tailroom(skb);
1491 tail_need = max_t(int, tail_need, 0); 1487 tail_need = max_t(int, tail_need, 0);
@@ -1578,7 +1574,7 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
1578 headroom -= skb_headroom(skb); 1574 headroom -= skb_headroom(skb);
1579 headroom = max_t(int, 0, headroom); 1575 headroom = max_t(int, 0, headroom);
1580 1576
1581 if (ieee80211_skb_resize(local, skb, headroom, may_encrypt)) { 1577 if (ieee80211_skb_resize(sdata, skb, headroom, may_encrypt)) {
1582 dev_kfree_skb(skb); 1578 dev_kfree_skb(skb);
1583 rcu_read_unlock(); 1579 rcu_read_unlock();
1584 return; 1580 return;
@@ -1945,7 +1941,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1945 head_need += IEEE80211_ENCRYPT_HEADROOM; 1941 head_need += IEEE80211_ENCRYPT_HEADROOM;
1946 head_need += local->tx_headroom; 1942 head_need += local->tx_headroom;
1947 head_need = max_t(int, 0, head_need); 1943 head_need = max_t(int, 0, head_need);
1948 if (ieee80211_skb_resize(local, skb, head_need, true)) 1944 if (ieee80211_skb_resize(sdata, skb, head_need, true))
1949 goto fail; 1945 goto fail;
1950 } 1946 }
1951 1947