diff options
Diffstat (limited to 'drivers/net/wireless')
30 files changed, 234 insertions, 170 deletions
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index b20a45aa8680..0676c6d84383 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c | |||
| @@ -251,7 +251,7 @@ static inline void ath5k_txbuf_free(struct ath5k_softc *sc, | |||
| 251 | return; | 251 | return; |
| 252 | pci_unmap_single(sc->pdev, bf->skbaddr, bf->skb->len, | 252 | pci_unmap_single(sc->pdev, bf->skbaddr, bf->skb->len, |
| 253 | PCI_DMA_TODEVICE); | 253 | PCI_DMA_TODEVICE); |
| 254 | dev_kfree_skb(bf->skb); | 254 | dev_kfree_skb_any(bf->skb); |
| 255 | bf->skb = NULL; | 255 | bf->skb = NULL; |
| 256 | } | 256 | } |
| 257 | 257 | ||
| @@ -466,6 +466,7 @@ ath5k_pci_probe(struct pci_dev *pdev, | |||
| 466 | mutex_init(&sc->lock); | 466 | mutex_init(&sc->lock); |
| 467 | spin_lock_init(&sc->rxbuflock); | 467 | spin_lock_init(&sc->rxbuflock); |
| 468 | spin_lock_init(&sc->txbuflock); | 468 | spin_lock_init(&sc->txbuflock); |
| 469 | spin_lock_init(&sc->block); | ||
| 469 | 470 | ||
| 470 | /* Set private data */ | 471 | /* Set private data */ |
| 471 | pci_set_drvdata(pdev, hw); | 472 | pci_set_drvdata(pdev, hw); |
| @@ -2179,8 +2180,11 @@ ath5k_beacon_config(struct ath5k_softc *sc) | |||
| 2179 | 2180 | ||
| 2180 | sc->imask |= AR5K_INT_SWBA; | 2181 | sc->imask |= AR5K_INT_SWBA; |
| 2181 | 2182 | ||
| 2182 | if (ath5k_hw_hasveol(ah)) | 2183 | if (ath5k_hw_hasveol(ah)) { |
| 2184 | spin_lock(&sc->block); | ||
| 2183 | ath5k_beacon_send(sc); | 2185 | ath5k_beacon_send(sc); |
| 2186 | spin_unlock(&sc->block); | ||
| 2187 | } | ||
| 2184 | } | 2188 | } |
| 2185 | /* TODO else AP */ | 2189 | /* TODO else AP */ |
| 2186 | 2190 | ||
| @@ -2403,7 +2407,9 @@ ath5k_intr(int irq, void *dev_id) | |||
| 2403 | TSF_TO_TU(tsf), | 2407 | TSF_TO_TU(tsf), |
| 2404 | (unsigned long long) tsf); | 2408 | (unsigned long long) tsf); |
| 2405 | } else { | 2409 | } else { |
| 2410 | spin_lock(&sc->block); | ||
| 2406 | ath5k_beacon_send(sc); | 2411 | ath5k_beacon_send(sc); |
| 2412 | spin_unlock(&sc->block); | ||
| 2407 | } | 2413 | } |
| 2408 | } | 2414 | } |
| 2409 | if (status & AR5K_INT_RXEOL) { | 2415 | if (status & AR5K_INT_RXEOL) { |
| @@ -2745,6 +2751,11 @@ static int ath5k_add_interface(struct ieee80211_hw *hw, | |||
| 2745 | ret = -EOPNOTSUPP; | 2751 | ret = -EOPNOTSUPP; |
| 2746 | goto end; | 2752 | goto end; |
| 2747 | } | 2753 | } |
| 2754 | |||
| 2755 | /* Set to a reasonable value. Note that this will | ||
| 2756 | * be set to mac80211's value at ath5k_config(). */ | ||
| 2757 | sc->bintval = 1000; | ||
| 2758 | |||
| 2748 | ret = 0; | 2759 | ret = 0; |
| 2749 | end: | 2760 | end: |
| 2750 | mutex_unlock(&sc->lock); | 2761 | mutex_unlock(&sc->lock); |
| @@ -2789,9 +2800,6 @@ ath5k_config_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
| 2789 | struct ath5k_hw *ah = sc->ah; | 2800 | struct ath5k_hw *ah = sc->ah; |
| 2790 | int ret; | 2801 | int ret; |
| 2791 | 2802 | ||
| 2792 | /* Set to a reasonable value. Note that this will | ||
| 2793 | * be set to mac80211's value at ath5k_config(). */ | ||
| 2794 | sc->bintval = 1000; | ||
| 2795 | mutex_lock(&sc->lock); | 2803 | mutex_lock(&sc->lock); |
| 2796 | if (sc->vif != vif) { | 2804 | if (sc->vif != vif) { |
| 2797 | ret = -EIO; | 2805 | ret = -EIO; |
| @@ -3050,6 +3058,7 @@ static int | |||
| 3050 | ath5k_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | 3058 | ath5k_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) |
| 3051 | { | 3059 | { |
| 3052 | struct ath5k_softc *sc = hw->priv; | 3060 | struct ath5k_softc *sc = hw->priv; |
| 3061 | unsigned long flags; | ||
| 3053 | int ret; | 3062 | int ret; |
| 3054 | 3063 | ||
| 3055 | ath5k_debug_dump_skb(sc, skb, "BC ", 1); | 3064 | ath5k_debug_dump_skb(sc, skb, "BC ", 1); |
| @@ -3059,12 +3068,14 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
| 3059 | goto end; | 3068 | goto end; |
| 3060 | } | 3069 | } |
| 3061 | 3070 | ||
| 3071 | spin_lock_irqsave(&sc->block, flags); | ||
| 3062 | ath5k_txbuf_free(sc, sc->bbuf); | 3072 | ath5k_txbuf_free(sc, sc->bbuf); |
| 3063 | sc->bbuf->skb = skb; | 3073 | sc->bbuf->skb = skb; |
| 3064 | ret = ath5k_beacon_setup(sc, sc->bbuf); | 3074 | ret = ath5k_beacon_setup(sc, sc->bbuf); |
| 3065 | if (ret) | 3075 | if (ret) |
| 3066 | sc->bbuf->skb = NULL; | 3076 | sc->bbuf->skb = NULL; |
| 3067 | else { | 3077 | spin_unlock_irqrestore(&sc->block, flags); |
| 3078 | if (!ret) { | ||
| 3068 | ath5k_beacon_config(sc); | 3079 | ath5k_beacon_config(sc); |
| 3069 | mmiowb(); | 3080 | mmiowb(); |
| 3070 | } | 3081 | } |
diff --git a/drivers/net/wireless/ath5k/base.h b/drivers/net/wireless/ath5k/base.h index d7e03e6b8271..7ec2f377d5c7 100644 --- a/drivers/net/wireless/ath5k/base.h +++ b/drivers/net/wireless/ath5k/base.h | |||
| @@ -172,6 +172,7 @@ struct ath5k_softc { | |||
| 172 | struct tasklet_struct txtq; /* tx intr tasklet */ | 172 | struct tasklet_struct txtq; /* tx intr tasklet */ |
| 173 | struct ath5k_led tx_led; /* tx led */ | 173 | struct ath5k_led tx_led; /* tx led */ |
| 174 | 174 | ||
| 175 | spinlock_t block; /* protects beacon */ | ||
| 175 | struct ath5k_buf *bbuf; /* beacon buffer */ | 176 | struct ath5k_buf *bbuf; /* beacon buffer */ |
| 176 | unsigned int bhalq, /* SW q for outgoing beacons */ | 177 | unsigned int bhalq, /* SW q for outgoing beacons */ |
| 177 | bmisscount, /* missed beacon transmits */ | 178 | bmisscount, /* missed beacon transmits */ |
diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c index caf569401a34..00a0eaa08866 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.c b/drivers/net/wireless/ath9k/core.c index f6c45288d0e7..87e37bc39145 100644 --- a/drivers/net/wireless/ath9k/core.c +++ b/drivers/net/wireless/ath9k/core.c | |||
| @@ -294,8 +294,6 @@ static int ath_stop(struct ath_softc *sc) | |||
| 294 | * hardware is gone (invalid). | 294 | * hardware is gone (invalid). |
| 295 | */ | 295 | */ |
| 296 | 296 | ||
| 297 | if (!sc->sc_invalid) | ||
| 298 | ath9k_hw_set_interrupts(ah, 0); | ||
| 299 | ath_draintxq(sc, false); | 297 | ath_draintxq(sc, false); |
| 300 | if (!sc->sc_invalid) { | 298 | if (!sc->sc_invalid) { |
| 301 | ath_stoprecv(sc); | 299 | ath_stoprecv(sc); |
| @@ -797,6 +795,12 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan) | |||
| 797 | if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) | 795 | if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) |
| 798 | sc->sc_imask |= ATH9K_INT_CST; | 796 | sc->sc_imask |= ATH9K_INT_CST; |
| 799 | 797 | ||
| 798 | /* Note: We disable MIB interrupts for now as we don't yet | ||
| 799 | * handle processing ANI, otherwise you will get an interrupt | ||
| 800 | * storm after about 7 hours of usage making the system unusable | ||
| 801 | * with huge latency. Once we do have ANI processing included | ||
| 802 | * we can re-enable this interrupt. */ | ||
| 803 | #if 0 | ||
| 800 | /* | 804 | /* |
| 801 | * Enable MIB interrupts when there are hardware phy counters. | 805 | * Enable MIB interrupts when there are hardware phy counters. |
| 802 | * Note we only do this (at the moment) for station mode. | 806 | * Note we only do this (at the moment) for station mode. |
| @@ -804,6 +808,7 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan) | |||
| 804 | if (ath9k_hw_phycounters(ah) && | 808 | if (ath9k_hw_phycounters(ah) && |
| 805 | ((sc->sc_opmode == ATH9K_M_STA) || (sc->sc_opmode == ATH9K_M_IBSS))) | 809 | ((sc->sc_opmode == ATH9K_M_STA) || (sc->sc_opmode == ATH9K_M_IBSS))) |
| 806 | sc->sc_imask |= ATH9K_INT_MIB; | 810 | sc->sc_imask |= ATH9K_INT_MIB; |
| 811 | #endif | ||
| 807 | /* | 812 | /* |
| 808 | * Some hardware processes the TIM IE and fires an | 813 | * Some hardware processes the TIM IE and fires an |
| 809 | * interrupt when the TIM bit is set. For hardware | 814 | * interrupt when the TIM bit is set. For hardware |
| @@ -1336,6 +1341,8 @@ void ath_deinit(struct ath_softc *sc) | |||
| 1336 | 1341 | ||
| 1337 | DPRINTF(sc, ATH_DBG_CONFIG, "%s\n", __func__); | 1342 | DPRINTF(sc, ATH_DBG_CONFIG, "%s\n", __func__); |
| 1338 | 1343 | ||
| 1344 | tasklet_kill(&sc->intr_tq); | ||
| 1345 | tasklet_kill(&sc->bcon_tasklet); | ||
| 1339 | ath_stop(sc); | 1346 | ath_stop(sc); |
| 1340 | if (!sc->sc_invalid) | 1347 | if (!sc->sc_invalid) |
| 1341 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); | 1348 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); |
diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index 673b3d81133a..2f84093331ee 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h | |||
| @@ -974,7 +974,6 @@ struct ath_softc { | |||
| 974 | u32 sc_keymax; /* size of key cache */ | 974 | u32 sc_keymax; /* size of key cache */ |
| 975 | DECLARE_BITMAP(sc_keymap, ATH_KEYMAX); /* key use bit map */ | 975 | DECLARE_BITMAP(sc_keymap, ATH_KEYMAX); /* key use bit map */ |
| 976 | u8 sc_splitmic; /* split TKIP MIC keys */ | 976 | u8 sc_splitmic; /* split TKIP MIC keys */ |
| 977 | int sc_keytype; | ||
| 978 | 977 | ||
| 979 | /* RX */ | 978 | /* RX */ |
| 980 | struct list_head sc_rxbuf; | 979 | struct list_head sc_rxbuf; |
| @@ -992,6 +991,7 @@ struct ath_softc { | |||
| 992 | u32 sc_txintrperiod; /* tx interrupt batching */ | 991 | u32 sc_txintrperiod; /* tx interrupt batching */ |
| 993 | int sc_haltype2q[ATH9K_WME_AC_VO+1]; /* HAL WME AC -> h/w qnum */ | 992 | int sc_haltype2q[ATH9K_WME_AC_VO+1]; /* HAL WME AC -> h/w qnum */ |
| 994 | u32 sc_ant_tx[8]; /* recent tx frames/antenna */ | 993 | u32 sc_ant_tx[8]; /* recent tx frames/antenna */ |
| 994 | u16 seq_no; /* TX sequence number */ | ||
| 995 | 995 | ||
| 996 | /* Beacon */ | 996 | /* Beacon */ |
| 997 | struct ath9k_tx_queue_info sc_beacon_qi; | 997 | 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 a17eb130f574..6dbfed0b4149 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 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); |
diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 2fe806175c01..20ddb7acdb94 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 | ||
| 388 | static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, | 389 | static 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 157f830ee6b8..8b332e11a656 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c | |||
| @@ -315,11 +315,11 @@ static int ath_tx_prepare(struct ath_softc *sc, | |||
| 315 | txctl->keyix = tx_info->control.hw_key->hw_key_idx; | 315 | txctl->keyix = tx_info->control.hw_key->hw_key_idx; |
| 316 | txctl->frmlen += tx_info->control.icv_len; | 316 | txctl->frmlen += tx_info->control.icv_len; |
| 317 | 317 | ||
| 318 | if (sc->sc_keytype == ATH9K_CIPHER_WEP) | 318 | if (tx_info->control.hw_key->alg == ALG_WEP) |
| 319 | txctl->keytype = ATH9K_KEY_TYPE_WEP; | 319 | txctl->keytype = ATH9K_KEY_TYPE_WEP; |
| 320 | else if (sc->sc_keytype == ATH9K_CIPHER_TKIP) | 320 | else if (tx_info->control.hw_key->alg == ALG_TKIP) |
| 321 | txctl->keytype = ATH9K_KEY_TYPE_TKIP; | 321 | txctl->keytype = ATH9K_KEY_TYPE_TKIP; |
| 322 | else if (sc->sc_keytype == ATH9K_CIPHER_AES_CCM) | 322 | else if (tx_info->control.hw_key->alg == ALG_CCMP) |
| 323 | txctl->keytype = ATH9K_KEY_TYPE_AES; | 323 | txctl->keytype = ATH9K_KEY_TYPE_AES; |
| 324 | } | 324 | } |
| 325 | 325 | ||
| @@ -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. |
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index bd35bb0a1480..bd65c485098c 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c | |||
| @@ -1304,7 +1304,7 @@ EXPORT_SYMBOL(atmel_open); | |||
| 1304 | int atmel_open(struct net_device *dev) | 1304 | int atmel_open(struct net_device *dev) |
| 1305 | { | 1305 | { |
| 1306 | struct atmel_private *priv = netdev_priv(dev); | 1306 | struct atmel_private *priv = netdev_priv(dev); |
| 1307 | int i, channel; | 1307 | int i, channel, err; |
| 1308 | 1308 | ||
| 1309 | /* any scheduled timer is no longer needed and might screw things up.. */ | 1309 | /* any scheduled timer is no longer needed and might screw things up.. */ |
| 1310 | del_timer_sync(&priv->management_timer); | 1310 | del_timer_sync(&priv->management_timer); |
| @@ -1328,8 +1328,9 @@ int atmel_open(struct net_device *dev) | |||
| 1328 | priv->site_survey_state = SITE_SURVEY_IDLE; | 1328 | priv->site_survey_state = SITE_SURVEY_IDLE; |
| 1329 | priv->station_is_associated = 0; | 1329 | priv->station_is_associated = 0; |
| 1330 | 1330 | ||
| 1331 | if (!reset_atmel_card(dev)) | 1331 | err = reset_atmel_card(dev); |
| 1332 | return -EAGAIN; | 1332 | if (err) |
| 1333 | return err; | ||
| 1333 | 1334 | ||
| 1334 | if (priv->config_reg_domain) { | 1335 | if (priv->config_reg_domain) { |
| 1335 | priv->reg_domain = priv->config_reg_domain; | 1336 | priv->reg_domain = priv->config_reg_domain; |
| @@ -3061,12 +3062,20 @@ static void authenticate(struct atmel_private *priv, u16 frame_len) | |||
| 3061 | } | 3062 | } |
| 3062 | 3063 | ||
| 3063 | if (status == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) { | 3064 | if (status == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) { |
| 3064 | /* Do opensystem first, then try sharedkey */ | 3065 | /* Flip back and forth between WEP auth modes until the max |
| 3066 | * authentication tries has been exceeded. | ||
| 3067 | */ | ||
| 3065 | if (system == WLAN_AUTH_OPEN) { | 3068 | if (system == WLAN_AUTH_OPEN) { |
| 3066 | priv->CurrentAuthentTransactionSeqNum = 0x001; | 3069 | priv->CurrentAuthentTransactionSeqNum = 0x001; |
| 3067 | priv->exclude_unencrypted = 1; | 3070 | priv->exclude_unencrypted = 1; |
| 3068 | send_authentication_request(priv, WLAN_AUTH_SHARED_KEY, NULL, 0); | 3071 | send_authentication_request(priv, WLAN_AUTH_SHARED_KEY, NULL, 0); |
| 3069 | return; | 3072 | return; |
| 3073 | } else if ( system == WLAN_AUTH_SHARED_KEY | ||
| 3074 | && priv->wep_is_on) { | ||
| 3075 | priv->CurrentAuthentTransactionSeqNum = 0x001; | ||
| 3076 | priv->exclude_unencrypted = 0; | ||
| 3077 | send_authentication_request(priv, WLAN_AUTH_OPEN, NULL, 0); | ||
| 3078 | return; | ||
| 3070 | } else if (priv->connect_to_any_BSS) { | 3079 | } else if (priv->connect_to_any_BSS) { |
| 3071 | int bss_index; | 3080 | int bss_index; |
| 3072 | 3081 | ||
| @@ -3580,12 +3589,12 @@ static int atmel_wakeup_firmware(struct atmel_private *priv) | |||
| 3580 | 3589 | ||
| 3581 | if (i == 0) { | 3590 | if (i == 0) { |
| 3582 | printk(KERN_ALERT "%s: MAC failed to boot.\n", priv->dev->name); | 3591 | printk(KERN_ALERT "%s: MAC failed to boot.\n", priv->dev->name); |
| 3583 | return 0; | 3592 | return -EIO; |
| 3584 | } | 3593 | } |
| 3585 | 3594 | ||
| 3586 | if ((priv->host_info_base = atmel_read16(priv->dev, MR2)) == 0xffff) { | 3595 | if ((priv->host_info_base = atmel_read16(priv->dev, MR2)) == 0xffff) { |
| 3587 | printk(KERN_ALERT "%s: card missing.\n", priv->dev->name); | 3596 | printk(KERN_ALERT "%s: card missing.\n", priv->dev->name); |
| 3588 | return 0; | 3597 | return -ENODEV; |
| 3589 | } | 3598 | } |
| 3590 | 3599 | ||
| 3591 | /* now check for completion of MAC initialization through | 3600 | /* now check for completion of MAC initialization through |
| @@ -3609,19 +3618,19 @@ static int atmel_wakeup_firmware(struct atmel_private *priv) | |||
| 3609 | if (i == 0) { | 3618 | if (i == 0) { |
| 3610 | printk(KERN_ALERT "%s: MAC failed to initialise.\n", | 3619 | printk(KERN_ALERT "%s: MAC failed to initialise.\n", |
| 3611 | priv->dev->name); | 3620 | priv->dev->name); |
| 3612 | return 0; | 3621 | return -EIO; |
| 3613 | } | 3622 | } |
| 3614 | 3623 | ||
| 3615 | /* Check for MAC_INIT_OK only on the register that the MAC_INIT_OK was set */ | 3624 | /* Check for MAC_INIT_OK only on the register that the MAC_INIT_OK was set */ |
| 3616 | if ((mr3 & MAC_INIT_COMPLETE) && | 3625 | if ((mr3 & MAC_INIT_COMPLETE) && |
| 3617 | !(atmel_read16(priv->dev, MR3) & MAC_INIT_OK)) { | 3626 | !(atmel_read16(priv->dev, MR3) & MAC_INIT_OK)) { |
| 3618 | printk(KERN_ALERT "%s: MAC failed MR3 self-test.\n", priv->dev->name); | 3627 | printk(KERN_ALERT "%s: MAC failed MR3 self-test.\n", priv->dev->name); |
| 3619 | return 0; | 3628 | return -EIO; |
| 3620 | } | 3629 | } |
| 3621 | if ((mr1 & MAC_INIT_COMPLETE) && | 3630 | if ((mr1 & MAC_INIT_COMPLETE) && |
| 3622 | !(atmel_read16(priv->dev, MR1) & MAC_INIT_OK)) { | 3631 | !(atmel_read16(priv->dev, MR1) & MAC_INIT_OK)) { |
| 3623 | printk(KERN_ALERT "%s: MAC failed MR1 self-test.\n", priv->dev->name); | 3632 | printk(KERN_ALERT "%s: MAC failed MR1 self-test.\n", priv->dev->name); |
| 3624 | return 0; | 3633 | return -EIO; |
| 3625 | } | 3634 | } |
| 3626 | 3635 | ||
| 3627 | atmel_copy_to_host(priv->dev, (unsigned char *)iface, | 3636 | atmel_copy_to_host(priv->dev, (unsigned char *)iface, |
| @@ -3642,7 +3651,7 @@ static int atmel_wakeup_firmware(struct atmel_private *priv) | |||
| 3642 | iface->func_ctrl = le16_to_cpu(iface->func_ctrl); | 3651 | iface->func_ctrl = le16_to_cpu(iface->func_ctrl); |
| 3643 | iface->mac_status = le16_to_cpu(iface->mac_status); | 3652 | iface->mac_status = le16_to_cpu(iface->mac_status); |
| 3644 | 3653 | ||
| 3645 | return 1; | 3654 | return 0; |
| 3646 | } | 3655 | } |
| 3647 | 3656 | ||
| 3648 | /* determine type of memory and MAC address */ | 3657 | /* determine type of memory and MAC address */ |
| @@ -3693,7 +3702,7 @@ static int probe_atmel_card(struct net_device *dev) | |||
| 3693 | /* Standard firmware in flash, boot it up and ask | 3702 | /* Standard firmware in flash, boot it up and ask |
| 3694 | for the Mac Address */ | 3703 | for the Mac Address */ |
| 3695 | priv->card_type = CARD_TYPE_SPI_FLASH; | 3704 | priv->card_type = CARD_TYPE_SPI_FLASH; |
| 3696 | if (atmel_wakeup_firmware(priv)) { | 3705 | if (atmel_wakeup_firmware(priv) == 0) { |
| 3697 | atmel_get_mib(priv, Mac_Address_Mib_Type, 0, dev->dev_addr, 6); | 3706 | atmel_get_mib(priv, Mac_Address_Mib_Type, 0, dev->dev_addr, 6); |
| 3698 | 3707 | ||
| 3699 | /* got address, now squash it again until the network | 3708 | /* got address, now squash it again until the network |
| @@ -3835,6 +3844,7 @@ static int reset_atmel_card(struct net_device *dev) | |||
| 3835 | struct atmel_private *priv = netdev_priv(dev); | 3844 | struct atmel_private *priv = netdev_priv(dev); |
| 3836 | u8 configuration; | 3845 | u8 configuration; |
| 3837 | int old_state = priv->station_state; | 3846 | int old_state = priv->station_state; |
| 3847 | int err = 0; | ||
| 3838 | 3848 | ||
| 3839 | /* data to add to the firmware names, in priority order | 3849 | /* data to add to the firmware names, in priority order |
| 3840 | this implemenents firmware versioning */ | 3850 | this implemenents firmware versioning */ |
| @@ -3868,11 +3878,12 @@ static int reset_atmel_card(struct net_device *dev) | |||
| 3868 | dev->name); | 3878 | dev->name); |
| 3869 | strcpy(priv->firmware_id, "atmel_at76c502.bin"); | 3879 | strcpy(priv->firmware_id, "atmel_at76c502.bin"); |
| 3870 | } | 3880 | } |
| 3871 | if (request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev) != 0) { | 3881 | err = request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev); |
| 3882 | if (err != 0) { | ||
| 3872 | printk(KERN_ALERT | 3883 | printk(KERN_ALERT |
| 3873 | "%s: firmware %s is missing, cannot continue.\n", | 3884 | "%s: firmware %s is missing, cannot continue.\n", |
| 3874 | dev->name, priv->firmware_id); | 3885 | dev->name, priv->firmware_id); |
| 3875 | return 0; | 3886 | return err; |
| 3876 | } | 3887 | } |
| 3877 | } else { | 3888 | } else { |
| 3878 | int fw_index = 0; | 3889 | int fw_index = 0; |
| @@ -3901,7 +3912,7 @@ static int reset_atmel_card(struct net_device *dev) | |||
| 3901 | "%s: firmware %s is missing, cannot start.\n", | 3912 | "%s: firmware %s is missing, cannot start.\n", |
| 3902 | dev->name, priv->firmware_id); | 3913 | dev->name, priv->firmware_id); |
| 3903 | priv->firmware_id[0] = '\0'; | 3914 | priv->firmware_id[0] = '\0'; |
| 3904 | return 0; | 3915 | return -ENOENT; |
| 3905 | } | 3916 | } |
| 3906 | } | 3917 | } |
| 3907 | 3918 | ||
| @@ -3926,8 +3937,9 @@ static int reset_atmel_card(struct net_device *dev) | |||
| 3926 | release_firmware(fw_entry); | 3937 | release_firmware(fw_entry); |
| 3927 | } | 3938 | } |
| 3928 | 3939 | ||
| 3929 | if (!atmel_wakeup_firmware(priv)) | 3940 | err = atmel_wakeup_firmware(priv); |
| 3930 | return 0; | 3941 | if (err != 0) |
| 3942 | return err; | ||
| 3931 | 3943 | ||
| 3932 | /* Check the version and set the correct flag for wpa stuff, | 3944 | /* Check the version and set the correct flag for wpa stuff, |
| 3933 | old and new firmware is incompatible. | 3945 | old and new firmware is incompatible. |
| @@ -3968,10 +3980,9 @@ static int reset_atmel_card(struct net_device *dev) | |||
| 3968 | if (!priv->radio_on_broken) { | 3980 | if (!priv->radio_on_broken) { |
| 3969 | if (atmel_send_command_wait(priv, CMD_EnableRadio, NULL, 0) == | 3981 | if (atmel_send_command_wait(priv, CMD_EnableRadio, NULL, 0) == |
| 3970 | CMD_STATUS_REJECTED_RADIO_OFF) { | 3982 | CMD_STATUS_REJECTED_RADIO_OFF) { |
| 3971 | printk(KERN_INFO | 3983 | printk(KERN_INFO "%s: cannot turn the radio on.\n", |
| 3972 | "%s: cannot turn the radio on. (Hey radio, you're beautiful!)\n", | ||
| 3973 | dev->name); | 3984 | dev->name); |
| 3974 | return 0; | 3985 | return -EIO; |
| 3975 | } | 3986 | } |
| 3976 | } | 3987 | } |
| 3977 | 3988 | ||
| @@ -4006,7 +4017,7 @@ static int reset_atmel_card(struct net_device *dev) | |||
| 4006 | wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL); | 4017 | wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL); |
| 4007 | } | 4018 | } |
| 4008 | 4019 | ||
| 4009 | return 1; | 4020 | return 0; |
| 4010 | } | 4021 | } |
| 4011 | 4022 | ||
| 4012 | static void atmel_send_command(struct atmel_private *priv, int command, | 4023 | static void atmel_send_command(struct atmel_private *priv, int command, |
diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c index fec5645944a4..34ae125d5384 100644 --- a/drivers/net/wireless/b43/rfkill.c +++ b/drivers/net/wireless/b43/rfkill.c | |||
| @@ -43,23 +43,6 @@ static bool b43_is_hw_radio_enabled(struct b43_wldev *dev) | |||
| 43 | return 0; | 43 | return 0; |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | /* Update the rfkill state */ | ||
| 47 | static void b43_rfkill_update_state(struct b43_wldev *dev) | ||
| 48 | { | ||
| 49 | struct b43_rfkill *rfk = &(dev->wl->rfkill); | ||
| 50 | |||
| 51 | if (!dev->radio_hw_enable) { | ||
| 52 | rfk->rfkill->state = RFKILL_STATE_HARD_BLOCKED; | ||
| 53 | return; | ||
| 54 | } | ||
| 55 | |||
| 56 | if (!dev->phy.radio_on) | ||
| 57 | rfk->rfkill->state = RFKILL_STATE_SOFT_BLOCKED; | ||
| 58 | else | ||
| 59 | rfk->rfkill->state = RFKILL_STATE_UNBLOCKED; | ||
| 60 | |||
| 61 | } | ||
| 62 | |||
| 63 | /* The poll callback for the hardware button. */ | 46 | /* The poll callback for the hardware button. */ |
| 64 | static void b43_rfkill_poll(struct input_polled_dev *poll_dev) | 47 | static void b43_rfkill_poll(struct input_polled_dev *poll_dev) |
| 65 | { | 48 | { |
| @@ -77,7 +60,6 @@ static void b43_rfkill_poll(struct input_polled_dev *poll_dev) | |||
| 77 | if (unlikely(enabled != dev->radio_hw_enable)) { | 60 | if (unlikely(enabled != dev->radio_hw_enable)) { |
| 78 | dev->radio_hw_enable = enabled; | 61 | dev->radio_hw_enable = enabled; |
| 79 | report_change = 1; | 62 | report_change = 1; |
| 80 | b43_rfkill_update_state(dev); | ||
| 81 | b43info(wl, "Radio hardware status changed to %s\n", | 63 | b43info(wl, "Radio hardware status changed to %s\n", |
| 82 | enabled ? "ENABLED" : "DISABLED"); | 64 | enabled ? "ENABLED" : "DISABLED"); |
| 83 | } | 65 | } |
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 2541c81932f0..1cb77db5c292 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c | |||
| @@ -34,7 +34,6 @@ | |||
| 34 | #include <linux/moduleparam.h> | 34 | #include <linux/moduleparam.h> |
| 35 | #include <linux/if_arp.h> | 35 | #include <linux/if_arp.h> |
| 36 | #include <linux/etherdevice.h> | 36 | #include <linux/etherdevice.h> |
| 37 | #include <linux/version.h> | ||
| 38 | #include <linux/firmware.h> | 37 | #include <linux/firmware.h> |
| 39 | #include <linux/wireless.h> | 38 | #include <linux/wireless.h> |
| 40 | #include <linux/workqueue.h> | 39 | #include <linux/workqueue.h> |
diff --git a/drivers/net/wireless/b43legacy/rfkill.c b/drivers/net/wireless/b43legacy/rfkill.c index 476add97e974..b32bf6a94f19 100644 --- a/drivers/net/wireless/b43legacy/rfkill.c +++ b/drivers/net/wireless/b43legacy/rfkill.c | |||
| @@ -44,23 +44,6 @@ static bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev) | |||
| 44 | return 0; | 44 | return 0; |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | /* Update the rfkill state */ | ||
| 48 | static void b43legacy_rfkill_update_state(struct b43legacy_wldev *dev) | ||
| 49 | { | ||
| 50 | struct b43legacy_rfkill *rfk = &(dev->wl->rfkill); | ||
| 51 | |||
| 52 | if (!dev->radio_hw_enable) { | ||
| 53 | rfk->rfkill->state = RFKILL_STATE_HARD_BLOCKED; | ||
| 54 | return; | ||
| 55 | } | ||
| 56 | |||
| 57 | if (!dev->phy.radio_on) | ||
| 58 | rfk->rfkill->state = RFKILL_STATE_SOFT_BLOCKED; | ||
| 59 | else | ||
| 60 | rfk->rfkill->state = RFKILL_STATE_UNBLOCKED; | ||
| 61 | |||
| 62 | } | ||
| 63 | |||
| 64 | /* The poll callback for the hardware button. */ | 47 | /* The poll callback for the hardware button. */ |
| 65 | static void b43legacy_rfkill_poll(struct input_polled_dev *poll_dev) | 48 | static void b43legacy_rfkill_poll(struct input_polled_dev *poll_dev) |
| 66 | { | 49 | { |
| @@ -78,7 +61,6 @@ static void b43legacy_rfkill_poll(struct input_polled_dev *poll_dev) | |||
| 78 | if (unlikely(enabled != dev->radio_hw_enable)) { | 61 | if (unlikely(enabled != dev->radio_hw_enable)) { |
| 79 | dev->radio_hw_enable = enabled; | 62 | dev->radio_hw_enable = enabled; |
| 80 | report_change = 1; | 63 | report_change = 1; |
| 81 | b43legacy_rfkill_update_state(dev); | ||
| 82 | b43legacyinfo(wl, "Radio hardware status changed to %s\n", | 64 | b43legacyinfo(wl, "Radio hardware status changed to %s\n", |
| 83 | enabled ? "ENABLED" : "DISABLED"); | 65 | enabled ? "ENABLED" : "DISABLED"); |
| 84 | } | 66 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.c b/drivers/net/wireless/iwlwifi/iwl-3945-led.c index d3336966b6b5..705c65bed9fd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.c | |||
| @@ -27,7 +27,6 @@ | |||
| 27 | 27 | ||
| 28 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
| 29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
| 30 | #include <linux/version.h> | ||
| 31 | #include <linux/init.h> | 30 | #include <linux/init.h> |
| 32 | #include <linux/pci.h> | 31 | #include <linux/pci.h> |
| 33 | #include <linux/dma-mapping.h> | 32 | #include <linux/dma-mapping.h> |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index e2581229d8b2..23fed3298962 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
| @@ -474,8 +474,8 @@ static void iwl4965_apm_stop(struct iwl_priv *priv) | |||
| 474 | iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); | 474 | iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); |
| 475 | 475 | ||
| 476 | udelay(10); | 476 | udelay(10); |
| 477 | 477 | /* clear "init complete" move adapter D0A* --> D0U state */ | |
| 478 | iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); | 478 | iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); |
| 479 | spin_unlock_irqrestore(&priv->lock, flags); | 479 | spin_unlock_irqrestore(&priv->lock, flags); |
| 480 | } | 480 | } |
| 481 | 481 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index cbc01a00eaf4..b08036a9d894 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
| @@ -145,7 +145,8 @@ static void iwl5000_apm_stop(struct iwl_priv *priv) | |||
| 145 | 145 | ||
| 146 | udelay(10); | 146 | udelay(10); |
| 147 | 147 | ||
| 148 | iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); | 148 | /* clear "init complete" move adapter D0A* --> D0U state */ |
| 149 | iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); | ||
| 149 | 150 | ||
| 150 | spin_unlock_irqrestore(&priv->lock, flags); | 151 | spin_unlock_irqrestore(&priv->lock, flags); |
| 151 | } | 152 | } |
| @@ -577,14 +578,11 @@ static int iwl5000_load_section(struct iwl_priv *priv, | |||
| 577 | FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL), | 578 | FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL), |
| 578 | phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK); | 579 | phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK); |
| 579 | 580 | ||
| 580 | /* FIME: write the MSB of the phy_addr in CTRL1 | ||
| 581 | * iwl_write_direct32(priv, | ||
| 582 | IWL_FH_TFDIB_CTRL1_REG(IWL_FH_SRVC_CHNL), | ||
| 583 | ((phy_addr & MSB_MSK) | ||
| 584 | << FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_count); | ||
| 585 | */ | ||
| 586 | iwl_write_direct32(priv, | 581 | iwl_write_direct32(priv, |
| 587 | FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL), byte_cnt); | 582 | FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL), |
| 583 | (iwl_get_dma_hi_address(phy_addr) | ||
| 584 | << FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt); | ||
| 585 | |||
| 588 | iwl_write_direct32(priv, | 586 | iwl_write_direct32(priv, |
| 589 | FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL), | 587 | FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL), |
| 590 | 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM | | 588 | 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM | |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 754fef5b592f..90a2b6dee7c0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c | |||
| @@ -1153,7 +1153,8 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv, | |||
| 1153 | !sta->ht_info.ht_supported) | 1153 | !sta->ht_info.ht_supported) |
| 1154 | return -1; | 1154 | return -1; |
| 1155 | 1155 | ||
| 1156 | if (priv->current_ht_config.tx_mimo_ps_mode == IWL_MIMO_PS_STATIC) | 1156 | if (((sta->ht_info.cap & IEEE80211_HT_CAP_MIMO_PS) >> 2) |
| 1157 | == IWL_MIMO_PS_STATIC) | ||
| 1157 | return -1; | 1158 | return -1; |
| 1158 | 1159 | ||
| 1159 | /* Need both Tx chains/antennas to support MIMO */ | 1160 | /* Need both Tx chains/antennas to support MIMO */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 061ffba9c884..e01f048a02dd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
| @@ -181,14 +181,14 @@ static int iwl4965_check_rxon_cmd(struct iwl_rxon_cmd *rxon) | |||
| 181 | } | 181 | } |
| 182 | 182 | ||
| 183 | /** | 183 | /** |
| 184 | * iwl4965_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed | 184 | * iwl_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed |
| 185 | * @priv: staging_rxon is compared to active_rxon | 185 | * @priv: staging_rxon is compared to active_rxon |
| 186 | * | 186 | * |
| 187 | * If the RXON structure is changing enough to require a new tune, | 187 | * If the RXON structure is changing enough to require a new tune, |
| 188 | * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that | 188 | * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that |
| 189 | * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required. | 189 | * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required. |
| 190 | */ | 190 | */ |
| 191 | static int iwl4965_full_rxon_required(struct iwl_priv *priv) | 191 | static int iwl_full_rxon_required(struct iwl_priv *priv) |
| 192 | { | 192 | { |
| 193 | 193 | ||
| 194 | /* These items are only settable from the full RXON command */ | 194 | /* These items are only settable from the full RXON command */ |
| @@ -207,7 +207,6 @@ static int iwl4965_full_rxon_required(struct iwl_priv *priv) | |||
| 207 | priv->active_rxon.ofdm_ht_single_stream_basic_rates) || | 207 | priv->active_rxon.ofdm_ht_single_stream_basic_rates) || |
| 208 | (priv->staging_rxon.ofdm_ht_dual_stream_basic_rates != | 208 | (priv->staging_rxon.ofdm_ht_dual_stream_basic_rates != |
| 209 | priv->active_rxon.ofdm_ht_dual_stream_basic_rates) || | 209 | priv->active_rxon.ofdm_ht_dual_stream_basic_rates) || |
| 210 | (priv->staging_rxon.rx_chain != priv->active_rxon.rx_chain) || | ||
| 211 | (priv->staging_rxon.assoc_id != priv->active_rxon.assoc_id)) | 210 | (priv->staging_rxon.assoc_id != priv->active_rxon.assoc_id)) |
| 212 | return 1; | 211 | return 1; |
| 213 | 212 | ||
| @@ -263,7 +262,7 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv) | |||
| 263 | /* If we don't need to send a full RXON, we can use | 262 | /* If we don't need to send a full RXON, we can use |
| 264 | * iwl4965_rxon_assoc_cmd which is used to reconfigure filter | 263 | * iwl4965_rxon_assoc_cmd which is used to reconfigure filter |
| 265 | * and other flags for the current radio configuration. */ | 264 | * and other flags for the current radio configuration. */ |
| 266 | if (!iwl4965_full_rxon_required(priv)) { | 265 | if (!iwl_full_rxon_required(priv)) { |
| 267 | ret = iwl_send_rxon_assoc(priv); | 266 | ret = iwl_send_rxon_assoc(priv); |
| 268 | if (ret) { | 267 | if (ret) { |
| 269 | IWL_ERROR("Error setting RXON_ASSOC (%d)\n", ret); | 268 | IWL_ERROR("Error setting RXON_ASSOC (%d)\n", ret); |
| @@ -587,8 +586,6 @@ static void iwl4965_ht_conf(struct iwl_priv *priv, | |||
| 587 | iwl_conf->supported_chan_width = 0; | 586 | iwl_conf->supported_chan_width = 0; |
| 588 | } | 587 | } |
| 589 | 588 | ||
| 590 | iwl_conf->tx_mimo_ps_mode = | ||
| 591 | (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2); | ||
| 592 | memcpy(iwl_conf->supp_mcs_set, ht_conf->supp_mcs_set, 16); | 589 | memcpy(iwl_conf->supp_mcs_set, ht_conf->supp_mcs_set, 16); |
| 593 | 590 | ||
| 594 | iwl_conf->control_channel = ht_bss_conf->primary_channel; | 591 | iwl_conf->control_channel = ht_bss_conf->primary_channel; |
| @@ -2190,7 +2187,10 @@ static void __iwl4965_down(struct iwl_priv *priv) | |||
| 2190 | udelay(5); | 2187 | udelay(5); |
| 2191 | 2188 | ||
| 2192 | /* FIXME: apm_ops.suspend(priv) */ | 2189 | /* FIXME: apm_ops.suspend(priv) */ |
| 2193 | priv->cfg->ops->lib->apm_ops.reset(priv); | 2190 | if (exit_pending || test_bit(STATUS_IN_SUSPEND, &priv->status)) |
| 2191 | priv->cfg->ops->lib->apm_ops.stop(priv); | ||
| 2192 | else | ||
| 2193 | priv->cfg->ops->lib->apm_ops.reset(priv); | ||
| 2194 | priv->cfg->ops->lib->free_shared_mem(priv); | 2194 | priv->cfg->ops->lib->free_shared_mem(priv); |
| 2195 | 2195 | ||
| 2196 | exit: | 2196 | exit: |
| @@ -2602,6 +2602,7 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw) | |||
| 2602 | { | 2602 | { |
| 2603 | struct iwl_priv *priv = hw->priv; | 2603 | struct iwl_priv *priv = hw->priv; |
| 2604 | int ret; | 2604 | int ret; |
| 2605 | u16 pci_cmd; | ||
| 2605 | 2606 | ||
| 2606 | IWL_DEBUG_MAC80211("enter\n"); | 2607 | IWL_DEBUG_MAC80211("enter\n"); |
| 2607 | 2608 | ||
| @@ -2612,6 +2613,13 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw) | |||
| 2612 | pci_restore_state(priv->pci_dev); | 2613 | pci_restore_state(priv->pci_dev); |
| 2613 | pci_enable_msi(priv->pci_dev); | 2614 | pci_enable_msi(priv->pci_dev); |
| 2614 | 2615 | ||
| 2616 | /* enable interrupts if needed: hw bug w/a */ | ||
| 2617 | pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd); | ||
| 2618 | if (pci_cmd & PCI_COMMAND_INTX_DISABLE) { | ||
| 2619 | pci_cmd &= ~PCI_COMMAND_INTX_DISABLE; | ||
| 2620 | pci_write_config_word(priv->pci_dev, PCI_COMMAND, pci_cmd); | ||
| 2621 | } | ||
| 2622 | |||
| 2615 | ret = request_irq(priv->pci_dev->irq, iwl4965_isr, IRQF_SHARED, | 2623 | ret = request_irq(priv->pci_dev->irq, iwl4965_isr, IRQF_SHARED, |
| 2616 | DRV_NAME, priv); | 2624 | DRV_NAME, priv); |
| 2617 | if (ret) { | 2625 | if (ret) { |
| @@ -3580,7 +3588,7 @@ static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk | |||
| 3580 | 3588 | ||
| 3581 | priv->assoc_id = 0; | 3589 | priv->assoc_id = 0; |
| 3582 | timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; | 3590 | timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; |
| 3583 | priv->timestamp = le64_to_cpu(timestamp) + (priv->beacon_int * 1000); | 3591 | priv->timestamp = le64_to_cpu(timestamp); |
| 3584 | 3592 | ||
| 3585 | IWL_DEBUG_MAC80211("leave\n"); | 3593 | IWL_DEBUG_MAC80211("leave\n"); |
| 3586 | spin_unlock_irqrestore(&priv->lock, flags); | 3594 | spin_unlock_irqrestore(&priv->lock, flags); |
| @@ -4364,15 +4372,18 @@ static void __devexit iwl4965_pci_remove(struct pci_dev *pdev) | |||
| 4364 | iwl_dbgfs_unregister(priv); | 4372 | iwl_dbgfs_unregister(priv); |
| 4365 | sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group); | 4373 | sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group); |
| 4366 | 4374 | ||
| 4375 | /* ieee80211_unregister_hw call wil cause iwl4965_mac_stop to | ||
| 4376 | * to be called and iwl4965_down since we are removing the device | ||
| 4377 | * we need to set STATUS_EXIT_PENDING bit. | ||
| 4378 | */ | ||
| 4379 | set_bit(STATUS_EXIT_PENDING, &priv->status); | ||
| 4367 | if (priv->mac80211_registered) { | 4380 | if (priv->mac80211_registered) { |
| 4368 | ieee80211_unregister_hw(priv->hw); | 4381 | ieee80211_unregister_hw(priv->hw); |
| 4369 | priv->mac80211_registered = 0; | 4382 | priv->mac80211_registered = 0; |
| 4383 | } else { | ||
| 4384 | iwl4965_down(priv); | ||
| 4370 | } | 4385 | } |
| 4371 | 4386 | ||
| 4372 | set_bit(STATUS_EXIT_PENDING, &priv->status); | ||
| 4373 | |||
| 4374 | iwl4965_down(priv); | ||
| 4375 | |||
| 4376 | /* make sure we flush any pending irq or | 4387 | /* make sure we flush any pending irq or |
| 4377 | * tasklet for the driver | 4388 | * tasklet for the driver |
| 4378 | */ | 4389 | */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index c72f72579bea..80f2f84defa8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
| @@ -592,12 +592,11 @@ static void iwlcore_free_geos(struct iwl_priv *priv) | |||
| 592 | clear_bit(STATUS_GEO_CONFIGURED, &priv->status); | 592 | clear_bit(STATUS_GEO_CONFIGURED, &priv->status); |
| 593 | } | 593 | } |
| 594 | 594 | ||
| 595 | static u8 is_single_rx_stream(struct iwl_priv *priv) | 595 | static bool is_single_rx_stream(struct iwl_priv *priv) |
| 596 | { | 596 | { |
| 597 | return !priv->current_ht_config.is_ht || | 597 | return !priv->current_ht_config.is_ht || |
| 598 | ((priv->current_ht_config.supp_mcs_set[1] == 0) && | 598 | ((priv->current_ht_config.supp_mcs_set[1] == 0) && |
| 599 | (priv->current_ht_config.supp_mcs_set[2] == 0)) || | 599 | (priv->current_ht_config.supp_mcs_set[2] == 0)); |
| 600 | priv->ps_mode == IWL_MIMO_PS_STATIC; | ||
| 601 | } | 600 | } |
| 602 | 601 | ||
| 603 | static u8 iwl_is_channel_extension(struct iwl_priv *priv, | 602 | static u8 iwl_is_channel_extension(struct iwl_priv *priv, |
| @@ -704,33 +703,39 @@ EXPORT_SYMBOL(iwl_set_rxon_ht); | |||
| 704 | * MIMO (dual stream) requires at least 2, but works better with 3. | 703 | * MIMO (dual stream) requires at least 2, but works better with 3. |
| 705 | * This does not determine *which* chains to use, just how many. | 704 | * This does not determine *which* chains to use, just how many. |
| 706 | */ | 705 | */ |
| 707 | static int iwlcore_get_rx_chain_counter(struct iwl_priv *priv, | 706 | static int iwl_get_active_rx_chain_count(struct iwl_priv *priv) |
| 708 | u8 *idle_state, u8 *rx_state) | ||
| 709 | { | 707 | { |
| 710 | u8 is_single = is_single_rx_stream(priv); | 708 | bool is_single = is_single_rx_stream(priv); |
| 711 | u8 is_cam = test_bit(STATUS_POWER_PMI, &priv->status) ? 0 : 1; | 709 | bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status); |
| 712 | 710 | ||
| 713 | /* # of Rx chains to use when expecting MIMO. */ | 711 | /* # of Rx chains to use when expecting MIMO. */ |
| 714 | if (is_single || (!is_cam && (priv->ps_mode == IWL_MIMO_PS_STATIC))) | 712 | if (is_single || (!is_cam && (priv->ps_mode == IWL_MIMO_PS_STATIC))) |
| 715 | *rx_state = 2; | 713 | return 2; |
| 716 | else | 714 | else |
| 717 | *rx_state = 3; | 715 | return 3; |
| 716 | } | ||
| 718 | 717 | ||
| 718 | static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt) | ||
| 719 | { | ||
| 720 | int idle_cnt; | ||
| 721 | bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status); | ||
| 719 | /* # Rx chains when idling and maybe trying to save power */ | 722 | /* # Rx chains when idling and maybe trying to save power */ |
| 720 | switch (priv->ps_mode) { | 723 | switch (priv->ps_mode) { |
| 721 | case IWL_MIMO_PS_STATIC: | 724 | case IWL_MIMO_PS_STATIC: |
| 722 | case IWL_MIMO_PS_DYNAMIC: | 725 | case IWL_MIMO_PS_DYNAMIC: |
| 723 | *idle_state = (is_cam) ? 2 : 1; | 726 | idle_cnt = (is_cam) ? 2 : 1; |
| 724 | break; | 727 | break; |
| 725 | case IWL_MIMO_PS_NONE: | 728 | case IWL_MIMO_PS_NONE: |
| 726 | *idle_state = (is_cam) ? *rx_state : 1; | 729 | idle_cnt = (is_cam) ? active_cnt : 1; |
| 727 | break; | 730 | break; |
| 731 | case IWL_MIMO_PS_INVALID: | ||
| 728 | default: | 732 | default: |
| 729 | *idle_state = 1; | 733 | IWL_ERROR("invalide mimo ps mode %d\n", priv->ps_mode); |
| 734 | WARN_ON(1); | ||
| 735 | idle_cnt = -1; | ||
| 730 | break; | 736 | break; |
| 731 | } | 737 | } |
| 732 | 738 | return idle_cnt; | |
| 733 | return 0; | ||
| 734 | } | 739 | } |
| 735 | 740 | ||
| 736 | /** | 741 | /** |
| @@ -741,34 +746,44 @@ static int iwlcore_get_rx_chain_counter(struct iwl_priv *priv, | |||
| 741 | */ | 746 | */ |
| 742 | void iwl_set_rxon_chain(struct iwl_priv *priv) | 747 | void iwl_set_rxon_chain(struct iwl_priv *priv) |
| 743 | { | 748 | { |
| 744 | u8 is_single = is_single_rx_stream(priv); | 749 | bool is_single = is_single_rx_stream(priv); |
| 745 | u8 idle_state, rx_state; | 750 | bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status); |
| 746 | 751 | u8 idle_rx_cnt, active_rx_cnt; | |
| 747 | priv->staging_rxon.rx_chain = 0; | 752 | u16 rx_chain; |
| 748 | rx_state = idle_state = 3; | ||
| 749 | 753 | ||
| 750 | /* Tell uCode which antennas are actually connected. | 754 | /* Tell uCode which antennas are actually connected. |
| 751 | * Before first association, we assume all antennas are connected. | 755 | * Before first association, we assume all antennas are connected. |
| 752 | * Just after first association, iwl_chain_noise_calibration() | 756 | * Just after first association, iwl_chain_noise_calibration() |
| 753 | * checks which antennas actually *are* connected. */ | 757 | * checks which antennas actually *are* connected. */ |
| 754 | priv->staging_rxon.rx_chain |= | 758 | rx_chain = priv->hw_params.valid_rx_ant << RXON_RX_CHAIN_VALID_POS; |
| 755 | cpu_to_le16(priv->hw_params.valid_rx_ant << | ||
| 756 | RXON_RX_CHAIN_VALID_POS); | ||
| 757 | 759 | ||
| 758 | /* How many receivers should we use? */ | 760 | /* How many receivers should we use? */ |
| 759 | iwlcore_get_rx_chain_counter(priv, &idle_state, &rx_state); | 761 | active_rx_cnt = iwl_get_active_rx_chain_count(priv); |
| 760 | priv->staging_rxon.rx_chain |= | 762 | idle_rx_cnt = iwl_get_idle_rx_chain_count(priv, active_rx_cnt); |
| 761 | cpu_to_le16(rx_state << RXON_RX_CHAIN_MIMO_CNT_POS); | 763 | |
| 762 | priv->staging_rxon.rx_chain |= | 764 | /* correct rx chain count accoridng hw settings */ |
| 763 | cpu_to_le16(idle_state << RXON_RX_CHAIN_CNT_POS); | 765 | if (priv->hw_params.rx_chains_num < active_rx_cnt) |
| 764 | 766 | active_rx_cnt = priv->hw_params.rx_chains_num; | |
| 765 | if (!is_single && (rx_state >= 2) && | 767 | |
| 766 | !test_bit(STATUS_POWER_PMI, &priv->status)) | 768 | if (priv->hw_params.rx_chains_num < idle_rx_cnt) |
| 769 | idle_rx_cnt = priv->hw_params.rx_chains_num; | ||
| 770 | |||
| 771 | rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS; | ||
| 772 | rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS; | ||
| 773 | |||
| 774 | priv->staging_rxon.rx_chain = cpu_to_le16(rx_chain); | ||
| 775 | |||
| 776 | if (!is_single && (active_rx_cnt >= 2) && is_cam) | ||
| 767 | priv->staging_rxon.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK; | 777 | priv->staging_rxon.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK; |
| 768 | else | 778 | else |
| 769 | priv->staging_rxon.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK; | 779 | priv->staging_rxon.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK; |
| 770 | 780 | ||
| 771 | IWL_DEBUG_ASSOC("rx chain %X\n", priv->staging_rxon.rx_chain); | 781 | IWL_DEBUG_ASSOC("rx_chain=0x%Xi active=%d idle=%d\n", |
| 782 | priv->staging_rxon.rx_chain, | ||
| 783 | active_rx_cnt, idle_rx_cnt); | ||
| 784 | |||
| 785 | WARN_ON(active_rx_cnt == 0 || idle_rx_cnt == 0 || | ||
| 786 | active_rx_cnt < idle_rx_cnt); | ||
| 772 | } | 787 | } |
| 773 | EXPORT_SYMBOL(iwl_set_rxon_chain); | 788 | EXPORT_SYMBOL(iwl_set_rxon_chain); |
| 774 | 789 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index c19db438306c..cdfb343c7ec6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
| @@ -412,7 +412,6 @@ struct iwl_ht_info { | |||
| 412 | /* self configuration data */ | 412 | /* self configuration data */ |
| 413 | u8 is_ht; | 413 | u8 is_ht; |
| 414 | u8 supported_chan_width; | 414 | u8 supported_chan_width; |
| 415 | u16 tx_mimo_ps_mode; | ||
| 416 | u8 is_green_field; | 415 | u8 is_green_field; |
| 417 | u8 sgf; /* HT_SHORT_GI_* short guard interval */ | 416 | u8 sgf; /* HT_SHORT_GI_* short guard interval */ |
| 418 | u8 max_amsdu_size; | 417 | u8 max_amsdu_size; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h index 944642450d3d..cd11c0ca2991 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/iwlwifi/iwl-fh.h | |||
| @@ -287,6 +287,7 @@ | |||
| 287 | 287 | ||
| 288 | #define FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE (0x01000000) | 288 | #define FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE (0x01000000) |
| 289 | 289 | ||
| 290 | #define FH_MEM_TFDIB_REG1_ADDR_BITSHIFT 28 | ||
| 290 | 291 | ||
| 291 | /** | 292 | /** |
| 292 | * Transmit DMA Channel Control/Status Registers (TCSR) | 293 | * Transmit DMA Channel Control/Status Registers (TCSR) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index cb11c4a4d691..4eee1b163cd2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c | |||
| @@ -27,7 +27,6 @@ | |||
| 27 | 27 | ||
| 28 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
| 29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
| 30 | #include <linux/version.h> | ||
| 31 | #include <linux/init.h> | 30 | #include <linux/init.h> |
| 32 | #include <linux/pci.h> | 31 | #include <linux/pci.h> |
| 33 | #include <linux/dma-mapping.h> | 32 | #include <linux/dma-mapping.h> |
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.c b/drivers/net/wireless/iwlwifi/iwl-rfkill.c index e5e5846e9f25..5d642298f04c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rfkill.c +++ b/drivers/net/wireless/iwlwifi/iwl-rfkill.c | |||
| @@ -27,7 +27,6 @@ | |||
| 27 | *****************************************************************************/ | 27 | *****************************************************************************/ |
| 28 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
| 29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
| 30 | #include <linux/version.h> | ||
| 31 | #include <linux/init.h> | 30 | #include <linux/init.h> |
| 32 | 31 | ||
| 33 | #include <net/mac80211.h> | 32 | #include <net/mac80211.h> |
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index f3f6ea49fdd2..e81bfc42a7cb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c | |||
| @@ -1173,7 +1173,10 @@ void iwl_rx_reply_rx(struct iwl_priv *priv, | |||
| 1173 | 1173 | ||
| 1174 | rx_status.antenna = 0; | 1174 | rx_status.antenna = 0; |
| 1175 | rx_status.flag = 0; | 1175 | rx_status.flag = 0; |
| 1176 | rx_status.flag |= RX_FLAG_TSFT; | 1176 | |
| 1177 | /* TSF isn't reliable. In order to allow smooth user experience, | ||
| 1178 | * this W/A doesn't propagate it to the mac80211 */ | ||
| 1179 | /*rx_status.flag |= RX_FLAG_TSFT;*/ | ||
| 1177 | 1180 | ||
| 1178 | if ((unlikely(rx_start->cfg_phy_cnt > 20))) { | 1181 | if ((unlikely(rx_start->cfg_phy_cnt > 20))) { |
| 1179 | IWL_DEBUG_DROP("dsp size out of range [0,20]: %d/n", | 1182 | IWL_DEBUG_DROP("dsp size out of range [0,20]: %d/n", |
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 9bb6adb28b73..6c8ac3a87d54 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c | |||
| @@ -421,7 +421,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, | |||
| 421 | else | 421 | else |
| 422 | scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE; | 422 | scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE; |
| 423 | 423 | ||
| 424 | if ((scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) && n_probes) | 424 | if (n_probes) |
| 425 | scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes); | 425 | scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes); |
| 426 | 426 | ||
| 427 | scan_ch->active_dwell = cpu_to_le16(active_dwell); | 427 | scan_ch->active_dwell = cpu_to_le16(active_dwell); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index d82823b5c8ab..78b1a7a4ca40 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
| @@ -402,12 +402,11 @@ static int iwl_hw_tx_queue_init(struct iwl_priv *priv, | |||
| 402 | /** | 402 | /** |
| 403 | * iwl_tx_queue_init - Allocate and initialize one tx/cmd queue | 403 | * iwl_tx_queue_init - Allocate and initialize one tx/cmd queue |
| 404 | */ | 404 | */ |
| 405 | static int iwl_tx_queue_init(struct iwl_priv *priv, | 405 | static int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, |
| 406 | struct iwl_tx_queue *txq, | ||
| 407 | int slots_num, u32 txq_id) | 406 | int slots_num, u32 txq_id) |
| 408 | { | 407 | { |
| 409 | int i, len; | 408 | int i, len; |
| 410 | int rc = 0; | 409 | int ret; |
| 411 | 410 | ||
| 412 | /* | 411 | /* |
| 413 | * Alloc buffer array for commands (Tx or other types of commands). | 412 | * Alloc buffer array for commands (Tx or other types of commands). |
| @@ -426,19 +425,16 @@ static int iwl_tx_queue_init(struct iwl_priv *priv, | |||
| 426 | continue; | 425 | continue; |
| 427 | } | 426 | } |
| 428 | 427 | ||
| 429 | txq->cmd[i] = kmalloc(len, GFP_KERNEL | GFP_DMA); | 428 | txq->cmd[i] = kmalloc(len, GFP_KERNEL); |
| 430 | if (!txq->cmd[i]) | 429 | if (!txq->cmd[i]) |
| 431 | return -ENOMEM; | 430 | goto err; |
| 432 | } | 431 | } |
| 433 | 432 | ||
| 434 | /* Alloc driver data array and TFD circular buffer */ | 433 | /* Alloc driver data array and TFD circular buffer */ |
| 435 | rc = iwl_tx_queue_alloc(priv, txq, txq_id); | 434 | ret = iwl_tx_queue_alloc(priv, txq, txq_id); |
| 436 | if (rc) { | 435 | if (ret) |
| 437 | for (i = 0; i < slots_num; i++) | 436 | goto err; |
| 438 | kfree(txq->cmd[i]); | ||
| 439 | 437 | ||
| 440 | return -ENOMEM; | ||
| 441 | } | ||
| 442 | txq->need_update = 0; | 438 | txq->need_update = 0; |
| 443 | 439 | ||
| 444 | /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise | 440 | /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise |
| @@ -452,6 +448,17 @@ static int iwl_tx_queue_init(struct iwl_priv *priv, | |||
| 452 | iwl_hw_tx_queue_init(priv, txq); | 448 | iwl_hw_tx_queue_init(priv, txq); |
| 453 | 449 | ||
| 454 | return 0; | 450 | return 0; |
| 451 | err: | ||
| 452 | for (i = 0; i < slots_num; i++) { | ||
| 453 | kfree(txq->cmd[i]); | ||
| 454 | txq->cmd[i] = NULL; | ||
| 455 | } | ||
| 456 | |||
| 457 | if (txq_id == IWL_CMD_QUEUE_NUM) { | ||
| 458 | kfree(txq->cmd[slots_num]); | ||
| 459 | txq->cmd[slots_num] = NULL; | ||
| 460 | } | ||
| 461 | return -ENOMEM; | ||
| 455 | } | 462 | } |
| 456 | /** | 463 | /** |
| 457 | * iwl_hw_txq_ctx_free - Free TXQ Context | 464 | * iwl_hw_txq_ctx_free - Free TXQ Context |
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c index 04d7a251e3f0..8941919001bb 100644 --- a/drivers/net/wireless/libertas/if_cs.c +++ b/drivers/net/wireless/libertas/if_cs.c | |||
| @@ -595,7 +595,7 @@ static int if_cs_prog_helper(struct if_cs_card *card) | |||
| 595 | if (ret < 0) { | 595 | if (ret < 0) { |
| 596 | lbs_pr_err("can't download helper at 0x%x, ret %d\n", | 596 | lbs_pr_err("can't download helper at 0x%x, ret %d\n", |
| 597 | sent, ret); | 597 | sent, ret); |
| 598 | goto done; | 598 | goto err_release; |
| 599 | } | 599 | } |
| 600 | 600 | ||
| 601 | if (count == 0) | 601 | if (count == 0) |
| @@ -604,9 +604,8 @@ static int if_cs_prog_helper(struct if_cs_card *card) | |||
| 604 | sent += count; | 604 | sent += count; |
| 605 | } | 605 | } |
| 606 | 606 | ||
| 607 | err_release: | ||
| 607 | release_firmware(fw); | 608 | release_firmware(fw); |
| 608 | ret = 0; | ||
| 609 | |||
| 610 | done: | 609 | done: |
| 611 | lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret); | 610 | lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret); |
| 612 | return ret; | 611 | return ret; |
| @@ -676,14 +675,8 @@ static int if_cs_prog_real(struct if_cs_card *card) | |||
| 676 | } | 675 | } |
| 677 | 676 | ||
| 678 | ret = if_cs_poll_while_fw_download(card, IF_CS_SCRATCH, 0x5a); | 677 | ret = if_cs_poll_while_fw_download(card, IF_CS_SCRATCH, 0x5a); |
| 679 | if (ret < 0) { | 678 | if (ret < 0) |
| 680 | lbs_pr_err("firmware download failed\n"); | 679 | lbs_pr_err("firmware download failed\n"); |
| 681 | goto err_release; | ||
| 682 | } | ||
| 683 | |||
| 684 | ret = 0; | ||
| 685 | goto done; | ||
| 686 | |||
| 687 | 680 | ||
| 688 | err_release: | 681 | err_release: |
| 689 | release_firmware(fw); | 682 | release_firmware(fw); |
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c index 1ebcafe7ca5f..36c004e15602 100644 --- a/drivers/net/wireless/orinoco.c +++ b/drivers/net/wireless/orinoco.c | |||
| @@ -1970,6 +1970,9 @@ __orinoco_set_multicast_list(struct net_device *dev) | |||
| 1970 | priv->promiscuous = promisc; | 1970 | priv->promiscuous = promisc; |
| 1971 | } | 1971 | } |
| 1972 | 1972 | ||
| 1973 | /* If we're not in promiscuous mode, then we need to set the | ||
| 1974 | * group address if either we want to multicast, or if we were | ||
| 1975 | * multicasting and want to stop */ | ||
| 1973 | if (! promisc && (mc_count || priv->mc_count) ) { | 1976 | if (! promisc && (mc_count || priv->mc_count) ) { |
| 1974 | struct dev_mc_list *p = dev->mc_list; | 1977 | struct dev_mc_list *p = dev->mc_list; |
| 1975 | struct hermes_multicast mclist; | 1978 | struct hermes_multicast mclist; |
| @@ -1989,9 +1992,10 @@ __orinoco_set_multicast_list(struct net_device *dev) | |||
| 1989 | printk(KERN_WARNING "%s: Multicast list is " | 1992 | printk(KERN_WARNING "%s: Multicast list is " |
| 1990 | "longer than mc_count\n", dev->name); | 1993 | "longer than mc_count\n", dev->name); |
| 1991 | 1994 | ||
| 1992 | err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFGROUPADDRESSES, | 1995 | err = hermes_write_ltv(hw, USER_BAP, |
| 1993 | HERMES_BYTES_TO_RECLEN(priv->mc_count * ETH_ALEN), | 1996 | HERMES_RID_CNFGROUPADDRESSES, |
| 1994 | &mclist); | 1997 | HERMES_BYTES_TO_RECLEN(mc_count * ETH_ALEN), |
| 1998 | &mclist); | ||
| 1995 | if (err) | 1999 | if (err) |
| 1996 | printk(KERN_ERR "%s: Error %d setting multicast list.\n", | 2000 | printk(KERN_ERR "%s: Error %d setting multicast list.\n", |
| 1997 | dev->name, err); | 2001 | dev->name, err); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00reg.h b/drivers/net/wireless/rt2x00/rt2x00reg.h index 7e88ce5651b9..2ea7866abd5d 100644 --- a/drivers/net/wireless/rt2x00/rt2x00reg.h +++ b/drivers/net/wireless/rt2x00/rt2x00reg.h | |||
| @@ -136,7 +136,7 @@ struct rt2x00_field32 { | |||
| 136 | */ | 136 | */ |
| 137 | #define is_power_of_two(x) ( !((x) & ((x)-1)) ) | 137 | #define is_power_of_two(x) ( !((x) & ((x)-1)) ) |
| 138 | #define low_bit_mask(x) ( ((x)-1) & ~(x) ) | 138 | #define low_bit_mask(x) ( ((x)-1) & ~(x) ) |
| 139 | #define is_valid_mask(x) is_power_of_two(1 + (x) + low_bit_mask(x)) | 139 | #define is_valid_mask(x) is_power_of_two(1LU + (x) + low_bit_mask(x)) |
| 140 | 140 | ||
| 141 | /* | 141 | /* |
| 142 | * Macro's to find first set bit in a variable. | 142 | * Macro's to find first set bit in a variable. |
| @@ -173,8 +173,7 @@ struct rt2x00_field32 { | |||
| 173 | * does not exceed the given typelimit. | 173 | * does not exceed the given typelimit. |
| 174 | */ | 174 | */ |
| 175 | #define FIELD_CHECK(__mask, __type) \ | 175 | #define FIELD_CHECK(__mask, __type) \ |
| 176 | BUILD_BUG_ON(!__builtin_constant_p(__mask) || \ | 176 | BUILD_BUG_ON(!(__mask) || \ |
| 177 | !(__mask) || \ | ||
| 178 | !is_valid_mask(__mask) || \ | 177 | !is_valid_mask(__mask) || \ |
| 179 | (__mask) != (__type)(__mask)) \ | 178 | (__mask) != (__type)(__mask)) \ |
| 180 | 179 | ||
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index da8b7433e3a6..a60ae86bd5c9 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c | |||
| @@ -58,6 +58,7 @@ static struct usb_device_id usb_ids[] = { | |||
| 58 | { USB_DEVICE(0x0586, 0x3407), .driver_info = DEVICE_ZD1211 }, | 58 | { USB_DEVICE(0x0586, 0x3407), .driver_info = DEVICE_ZD1211 }, |
| 59 | { USB_DEVICE(0x129b, 0x1666), .driver_info = DEVICE_ZD1211 }, | 59 | { USB_DEVICE(0x129b, 0x1666), .driver_info = DEVICE_ZD1211 }, |
| 60 | { USB_DEVICE(0x157e, 0x300a), .driver_info = DEVICE_ZD1211 }, | 60 | { USB_DEVICE(0x157e, 0x300a), .driver_info = DEVICE_ZD1211 }, |
| 61 | { USB_DEVICE(0x0105, 0x145f), .driver_info = DEVICE_ZD1211 }, | ||
| 61 | /* ZD1211B */ | 62 | /* ZD1211B */ |
| 62 | { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B }, | 63 | { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B }, |
| 63 | { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B }, | 64 | { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B }, |
