diff options
Diffstat (limited to 'drivers/net/wireless/ath9k/main.c')
-rw-r--r-- | drivers/net/wireless/ath9k/main.c | 40 |
1 files changed, 34 insertions, 6 deletions
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 2888778040e4..acebdf1d20a8 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c | |||
@@ -206,7 +206,6 @@ 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; | ||
210 | return 0; | 209 | return 0; |
211 | } | 210 | } |
212 | 211 | ||
@@ -368,6 +367,20 @@ static int ath9k_tx(struct ieee80211_hw *hw, | |||
368 | { | 367 | { |
369 | struct ath_softc *sc = hw->priv; | 368 | struct ath_softc *sc = hw->priv; |
370 | int hdrlen, padsize; | 369 | int hdrlen, padsize; |
370 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
371 | |||
372 | /* | ||
373 | * As a temporary workaround, assign seq# here; this will likely need | ||
374 | * to be cleaned up to work better with Beacon transmission and virtual | ||
375 | * BSSes. | ||
376 | */ | ||
377 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { | ||
378 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | ||
379 | if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) | ||
380 | sc->seq_no += 0x10; | ||
381 | hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); | ||
382 | hdr->seq_ctrl |= cpu_to_le16(sc->seq_no); | ||
383 | } | ||
371 | 384 | ||
372 | /* Add the padding after the header if this is not already done */ | 385 | /* Add the padding after the header if this is not already done */ |
373 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 386 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); |
@@ -756,13 +769,13 @@ static int ath9k_set_key(struct ieee80211_hw *hw, | |||
756 | key->hw_key_idx = key->keyidx; | 769 | key->hw_key_idx = key->keyidx; |
757 | /* push IV and Michael MIC generation to stack */ | 770 | /* push IV and Michael MIC generation to stack */ |
758 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; | 771 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; |
759 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; | 772 | if (key->alg == ALG_TKIP) |
773 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; | ||
760 | } | 774 | } |
761 | break; | 775 | break; |
762 | case DISABLE_KEY: | 776 | case DISABLE_KEY: |
763 | ath_key_delete(sc, key); | 777 | ath_key_delete(sc, key); |
764 | clear_bit(key->keyidx, sc->sc_keymap); | 778 | clear_bit(key->keyidx, sc->sc_keymap); |
765 | sc->sc_keytype = ATH9K_CIPHER_CLR; | ||
766 | break; | 779 | break; |
767 | default: | 780 | default: |
768 | ret = -EINVAL; | 781 | ret = -EINVAL; |
@@ -1065,8 +1078,16 @@ void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
1065 | tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; | 1078 | tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; |
1066 | tx_status->flags &= ~ATH_TX_BAR; | 1079 | tx_status->flags &= ~ATH_TX_BAR; |
1067 | } | 1080 | } |
1068 | if (tx_status->flags) | 1081 | |
1069 | tx_info->status.excessive_retries = 1; | 1082 | if (tx_status->flags & (ATH_TX_ERROR | ATH_TX_XRETRY)) { |
1083 | if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) { | ||
1084 | /* Frame was not ACKed, but an ACK was expected */ | ||
1085 | tx_info->status.excessive_retries = 1; | ||
1086 | } | ||
1087 | } else { | ||
1088 | /* Frame was ACKed */ | ||
1089 | tx_info->flags |= IEEE80211_TX_STAT_ACK; | ||
1090 | } | ||
1070 | 1091 | ||
1071 | tx_info->status.retry_count = tx_status->retries; | 1092 | tx_info->status.retry_count = tx_status->retries; |
1072 | 1093 | ||
@@ -1390,10 +1411,17 @@ static void ath_pci_remove(struct pci_dev *pdev) | |||
1390 | { | 1411 | { |
1391 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); | 1412 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); |
1392 | struct ath_softc *sc = hw->priv; | 1413 | struct ath_softc *sc = hw->priv; |
1414 | enum ath9k_int status; | ||
1393 | 1415 | ||
1394 | if (pdev->irq) | 1416 | if (pdev->irq) { |
1417 | ath9k_hw_set_interrupts(sc->sc_ah, 0); | ||
1418 | /* clear the ISR */ | ||
1419 | ath9k_hw_getisr(sc->sc_ah, &status); | ||
1420 | sc->sc_invalid = 1; | ||
1395 | free_irq(pdev->irq, sc); | 1421 | free_irq(pdev->irq, sc); |
1422 | } | ||
1396 | ath_detach(sc); | 1423 | ath_detach(sc); |
1424 | |||
1397 | pci_iounmap(pdev, sc->mem); | 1425 | pci_iounmap(pdev, sc->mem); |
1398 | pci_release_region(pdev, 0); | 1426 | pci_release_region(pdev, 0); |
1399 | pci_disable_device(pdev); | 1427 | pci_disable_device(pdev); |