aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath9k
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath9k')
-rw-r--r--drivers/net/wireless/ath9k/beacon.c13
-rw-r--r--drivers/net/wireless/ath9k/core.h1
-rw-r--r--drivers/net/wireless/ath9k/hw.c8
-rw-r--r--drivers/net/wireless/ath9k/main.c32
-rw-r--r--drivers/net/wireless/ath9k/recv.c5
-rw-r--r--drivers/net/wireless/ath9k/xmit.c4
6 files changed, 51 insertions, 12 deletions
diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c
index caf569401a3..00a0eaa0886 100644
--- a/drivers/net/wireless/ath9k/beacon.c
+++ b/drivers/net/wireless/ath9k/beacon.c
@@ -209,6 +209,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
209 unsigned int curlen; 209 unsigned int curlen;
210 struct ath_txq *cabq; 210 struct ath_txq *cabq;
211 struct ath_txq *mcastq; 211 struct ath_txq *mcastq;
212 struct ieee80211_tx_info *info;
212 avp = sc->sc_vaps[if_id]; 213 avp = sc->sc_vaps[if_id];
213 214
214 mcastq = &avp->av_mcastq; 215 mcastq = &avp->av_mcastq;
@@ -232,6 +233,18 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
232 */ 233 */
233 curlen = skb->len; 234 curlen = skb->len;
234 235
236 info = IEEE80211_SKB_CB(skb);
237 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
238 /*
239 * TODO: make sure the seq# gets assigned properly (vs. other
240 * TX frames)
241 */
242 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
243 sc->seq_no += 0x10;
244 hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
245 hdr->seq_ctrl |= cpu_to_le16(sc->seq_no);
246 }
247
235 /* XXX: spin_lock_bh should not be used here, but sparse bitches 248 /* XXX: spin_lock_bh should not be used here, but sparse bitches
236 * otherwise. We should fix sparse :) */ 249 * otherwise. We should fix sparse :) */
237 spin_lock_bh(&mcastq->axq_lock); 250 spin_lock_bh(&mcastq->axq_lock);
diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h
index 673b3d81133..4ee695b76b8 100644
--- a/drivers/net/wireless/ath9k/core.h
+++ b/drivers/net/wireless/ath9k/core.h
@@ -992,6 +992,7 @@ struct ath_softc {
992 u32 sc_txintrperiod; /* tx interrupt batching */ 992 u32 sc_txintrperiod; /* tx interrupt batching */
993 int sc_haltype2q[ATH9K_WME_AC_VO+1]; /* HAL WME AC -> h/w qnum */ 993 int sc_haltype2q[ATH9K_WME_AC_VO+1]; /* HAL WME AC -> h/w qnum */
994 u32 sc_ant_tx[8]; /* recent tx frames/antenna */ 994 u32 sc_ant_tx[8]; /* recent tx frames/antenna */
995 u16 seq_no; /* TX sequence number */
995 996
996 /* Beacon */ 997 /* Beacon */
997 struct ath9k_tx_queue_info sc_beacon_qi; 998 struct ath9k_tx_queue_info sc_beacon_qi;
diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c
index a17eb130f57..6dbfed0b414 100644
--- a/drivers/net/wireless/ath9k/hw.c
+++ b/drivers/net/wireless/ath9k/hw.c
@@ -7285,15 +7285,15 @@ ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry,
7285 } 7285 }
7286 break; 7286 break;
7287 case ATH9K_CIPHER_WEP: 7287 case ATH9K_CIPHER_WEP:
7288 if (k->kv_len < 40 / NBBY) { 7288 if (k->kv_len < LEN_WEP40) {
7289 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE, 7289 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7290 "%s: WEP key length %u too small\n", 7290 "%s: WEP key length %u too small\n",
7291 __func__, k->kv_len); 7291 __func__, k->kv_len);
7292 return false; 7292 return false;
7293 } 7293 }
7294 if (k->kv_len <= 40 / NBBY) 7294 if (k->kv_len <= LEN_WEP40)
7295 keyType = AR_KEYTABLE_TYPE_40; 7295 keyType = AR_KEYTABLE_TYPE_40;
7296 else if (k->kv_len <= 104 / NBBY) 7296 else if (k->kv_len <= LEN_WEP104)
7297 keyType = AR_KEYTABLE_TYPE_104; 7297 keyType = AR_KEYTABLE_TYPE_104;
7298 else 7298 else
7299 keyType = AR_KEYTABLE_TYPE_128; 7299 keyType = AR_KEYTABLE_TYPE_128;
@@ -7313,7 +7313,7 @@ ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry,
7313 key2 = get_unaligned_le32(k->kv_val + 6) ^ xorMask; 7313 key2 = get_unaligned_le32(k->kv_val + 6) ^ xorMask;
7314 key3 = (get_unaligned_le16(k->kv_val + 10) ^ xorMask) & 0xffff; 7314 key3 = (get_unaligned_le16(k->kv_val + 10) ^ xorMask) & 0xffff;
7315 key4 = get_unaligned_le32(k->kv_val + 12) ^ xorMask; 7315 key4 = get_unaligned_le32(k->kv_val + 12) ^ xorMask;
7316 if (k->kv_len <= 104 / NBBY) 7316 if (k->kv_len <= LEN_WEP104)
7317 key4 &= 0xff; 7317 key4 &= 0xff;
7318 7318
7319 if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) { 7319 if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
index 2888778040e..99badf1404c 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -206,7 +206,8 @@ static int ath_key_config(struct ath_softc *sc,
206 if (!ret) 206 if (!ret)
207 return -EIO; 207 return -EIO;
208 208
209 sc->sc_keytype = hk.kv_type; 209 if (mac)
210 sc->sc_keytype = hk.kv_type;
210 return 0; 211 return 0;
211} 212}
212 213
@@ -368,6 +369,20 @@ static int ath9k_tx(struct ieee80211_hw *hw,
368{ 369{
369 struct ath_softc *sc = hw->priv; 370 struct ath_softc *sc = hw->priv;
370 int hdrlen, padsize; 371 int hdrlen, padsize;
372 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
373
374 /*
375 * As a temporary workaround, assign seq# here; this will likely need
376 * to be cleaned up to work better with Beacon transmission and virtual
377 * BSSes.
378 */
379 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
380 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
381 if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
382 sc->seq_no += 0x10;
383 hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
384 hdr->seq_ctrl |= cpu_to_le16(sc->seq_no);
385 }
371 386
372 /* Add the padding after the header if this is not already done */ 387 /* Add the padding after the header if this is not already done */
373 hdrlen = ieee80211_get_hdrlen_from_skb(skb); 388 hdrlen = ieee80211_get_hdrlen_from_skb(skb);
@@ -756,7 +771,8 @@ static int ath9k_set_key(struct ieee80211_hw *hw,
756 key->hw_key_idx = key->keyidx; 771 key->hw_key_idx = key->keyidx;
757 /* push IV and Michael MIC generation to stack */ 772 /* push IV and Michael MIC generation to stack */
758 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; 773 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
759 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; 774 if (key->alg == ALG_TKIP)
775 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
760 } 776 }
761 break; 777 break;
762 case DISABLE_KEY: 778 case DISABLE_KEY:
@@ -1065,8 +1081,16 @@ void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
1065 tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; 1081 tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
1066 tx_status->flags &= ~ATH_TX_BAR; 1082 tx_status->flags &= ~ATH_TX_BAR;
1067 } 1083 }
1068 if (tx_status->flags) 1084
1069 tx_info->status.excessive_retries = 1; 1085 if (tx_status->flags & (ATH_TX_ERROR | ATH_TX_XRETRY)) {
1086 if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) {
1087 /* Frame was not ACKed, but an ACK was expected */
1088 tx_info->status.excessive_retries = 1;
1089 }
1090 } else {
1091 /* Frame was ACKed */
1092 tx_info->flags |= IEEE80211_TX_STAT_ACK;
1093 }
1070 1094
1071 tx_info->status.retry_count = tx_status->retries; 1095 tx_info->status.retry_count = tx_status->retries;
1072 1096
diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c
index 2fe806175c0..20ddb7acdb9 100644
--- a/drivers/net/wireless/ath9k/recv.c
+++ b/drivers/net/wireless/ath9k/recv.c
@@ -360,8 +360,9 @@ static void ath_rx_flush_tid(struct ath_softc *sc,
360 struct ath_arx_tid *rxtid, int drop) 360 struct ath_arx_tid *rxtid, int drop)
361{ 361{
362 struct ath_rxbuf *rxbuf; 362 struct ath_rxbuf *rxbuf;
363 unsigned long flag;
363 364
364 spin_lock_bh(&rxtid->tidlock); 365 spin_lock_irqsave(&rxtid->tidlock, flag);
365 while (rxtid->baw_head != rxtid->baw_tail) { 366 while (rxtid->baw_head != rxtid->baw_tail) {
366 rxbuf = rxtid->rxbuf + rxtid->baw_head; 367 rxbuf = rxtid->rxbuf + rxtid->baw_head;
367 if (!rxbuf->rx_wbuf) { 368 if (!rxbuf->rx_wbuf) {
@@ -382,7 +383,7 @@ static void ath_rx_flush_tid(struct ath_softc *sc,
382 INCR(rxtid->baw_head, ATH_TID_MAX_BUFS); 383 INCR(rxtid->baw_head, ATH_TID_MAX_BUFS);
383 INCR(rxtid->seq_next, IEEE80211_SEQ_MAX); 384 INCR(rxtid->seq_next, IEEE80211_SEQ_MAX);
384 } 385 }
385 spin_unlock_bh(&rxtid->tidlock); 386 spin_unlock_irqrestore(&rxtid->tidlock, flag);
386} 387}
387 388
388static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, 389static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc,
diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c
index 157f830ee6b..550129f717e 100644
--- a/drivers/net/wireless/ath9k/xmit.c
+++ b/drivers/net/wireless/ath9k/xmit.c
@@ -357,9 +357,9 @@ static int ath_tx_prepare(struct ath_softc *sc,
357 txctl->flags = ATH9K_TXDESC_CLRDMASK; /* needed for crypto errors */ 357 txctl->flags = ATH9K_TXDESC_CLRDMASK; /* needed for crypto errors */
358 358
359 if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) 359 if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
360 tx_info->flags |= ATH9K_TXDESC_NOACK; 360 txctl->flags |= ATH9K_TXDESC_NOACK;
361 if (tx_info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) 361 if (tx_info->flags & IEEE80211_TX_CTL_USE_RTS_CTS)
362 tx_info->flags |= ATH9K_TXDESC_RTSENA; 362 txctl->flags |= ATH9K_TXDESC_RTSENA;
363 363
364 /* 364 /*
365 * Setup for rate calculations. 365 * Setup for rate calculations.