diff options
author | John W. Linville <linville@tuxdriver.com> | 2010-12-08 16:23:31 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-12-08 16:23:31 -0500 |
commit | 393934c6b5c8d00f9d1ae20670d4a770f07a418a (patch) | |
tree | dad33cd2e4fc0e3d3b28dcbc36cfb44178cb046c | |
parent | 69f4aab1157d2a386e7ea4de77cc253629d1b4f2 (diff) | |
parent | 0a54917c3fc295cb61f3fb52373c173fd3b69f48 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6
Conflicts:
drivers/net/wireless/ath/ath9k/ath9k.h
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/ath9k/xmit.c
-rw-r--r-- | drivers/net/wireless/ath/ath5k/base.c | 13 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ath9k.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/eeprom_def.c | 12 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hif_usb.c | 7 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/htc.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/htc_drv_init.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/htc_drv_main.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/mac.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 26 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/recv.c | 9 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/xmit.c | 19 | ||||
-rw-r--r-- | drivers/net/wireless/orinoco/main.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/orinoco/orinoco_cs.c | 14 | ||||
-rw-r--r-- | drivers/net/wireless/orinoco/spectrum_cs.c | 14 | ||||
-rw-r--r-- | drivers/net/wireless/orinoco/wext.c | 4 | ||||
-rw-r--r-- | net/mac80211/tx.c | 21 |
16 files changed, 100 insertions, 63 deletions
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index bccea7450c38..4e3b97c3d7c2 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -1879,7 +1879,8 @@ ath5k_beacon_send(struct ath5k_softc *sc) | |||
1879 | sc->bmisscount = 0; | 1879 | sc->bmisscount = 0; |
1880 | } | 1880 | } |
1881 | 1881 | ||
1882 | if (sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) { | 1882 | if ((sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) || |
1883 | sc->opmode == NL80211_IFTYPE_MESH_POINT) { | ||
1883 | u64 tsf = ath5k_hw_get_tsf64(ah); | 1884 | u64 tsf = ath5k_hw_get_tsf64(ah); |
1884 | u32 tsftu = TSF_TO_TU(tsf); | 1885 | u32 tsftu = TSF_TO_TU(tsf); |
1885 | int slot = ((tsftu % sc->bintval) * ATH_BCBUF) / sc->bintval; | 1886 | int slot = ((tsftu % sc->bintval) * ATH_BCBUF) / sc->bintval; |
@@ -1911,8 +1912,9 @@ ath5k_beacon_send(struct ath5k_softc *sc) | |||
1911 | /* NB: hw still stops DMA, so proceed */ | 1912 | /* NB: hw still stops DMA, so proceed */ |
1912 | } | 1913 | } |
1913 | 1914 | ||
1914 | /* refresh the beacon for AP mode */ | 1915 | /* refresh the beacon for AP or MESH mode */ |
1915 | if (sc->opmode == NL80211_IFTYPE_AP) | 1916 | if (sc->opmode == NL80211_IFTYPE_AP || |
1917 | sc->opmode == NL80211_IFTYPE_MESH_POINT) | ||
1916 | ath5k_beacon_update(sc->hw, vif); | 1918 | ath5k_beacon_update(sc->hw, vif); |
1917 | 1919 | ||
1918 | ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr); | 1920 | ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr); |
@@ -2997,7 +2999,8 @@ static int ath5k_add_interface(struct ieee80211_hw *hw, | |||
2997 | 2999 | ||
2998 | /* Assign the vap/adhoc to a beacon xmit slot. */ | 3000 | /* Assign the vap/adhoc to a beacon xmit slot. */ |
2999 | if ((avf->opmode == NL80211_IFTYPE_AP) || | 3001 | if ((avf->opmode == NL80211_IFTYPE_AP) || |
3000 | (avf->opmode == NL80211_IFTYPE_ADHOC)) { | 3002 | (avf->opmode == NL80211_IFTYPE_ADHOC) || |
3003 | (avf->opmode == NL80211_IFTYPE_MESH_POINT)) { | ||
3001 | int slot; | 3004 | int slot; |
3002 | 3005 | ||
3003 | WARN_ON(list_empty(&sc->bcbuf)); | 3006 | WARN_ON(list_empty(&sc->bcbuf)); |
@@ -3016,7 +3019,7 @@ static int ath5k_add_interface(struct ieee80211_hw *hw, | |||
3016 | sc->bslot[avf->bslot] = vif; | 3019 | sc->bslot[avf->bslot] = vif; |
3017 | if (avf->opmode == NL80211_IFTYPE_AP) | 3020 | if (avf->opmode == NL80211_IFTYPE_AP) |
3018 | sc->num_ap_vifs++; | 3021 | sc->num_ap_vifs++; |
3019 | else | 3022 | else if (avf->opmode == NL80211_IFTYPE_ADHOC) |
3020 | sc->num_adhoc_vifs++; | 3023 | sc->num_adhoc_vifs++; |
3021 | } | 3024 | } |
3022 | 3025 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 4210a9306955..9b5501f90010 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -311,7 +311,7 @@ void ath_rx_cleanup(struct ath_softc *sc); | |||
311 | int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp); | 311 | int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp); |
312 | struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype); | 312 | struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype); |
313 | void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq); | 313 | void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq); |
314 | void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx); | 314 | bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx); |
315 | void ath_draintxq(struct ath_softc *sc, | 315 | void ath_draintxq(struct ath_softc *sc, |
316 | struct ath_txq *txq, bool retry_tx); | 316 | struct ath_txq *txq, bool retry_tx); |
317 | void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an); | 317 | void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an); |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index c2b4bba7410c..5bfa031545f4 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c | |||
@@ -1063,15 +1063,19 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah, | |||
1063 | case 1: | 1063 | case 1: |
1064 | break; | 1064 | break; |
1065 | case 2: | 1065 | case 2: |
1066 | scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN; | 1066 | if (scaledPower > REDUCE_SCALED_POWER_BY_TWO_CHAIN) |
1067 | scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN; | ||
1068 | else | ||
1069 | scaledPower = 0; | ||
1067 | break; | 1070 | break; |
1068 | case 3: | 1071 | case 3: |
1069 | scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; | 1072 | if (scaledPower > REDUCE_SCALED_POWER_BY_THREE_CHAIN) |
1073 | scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; | ||
1074 | else | ||
1075 | scaledPower = 0; | ||
1070 | break; | 1076 | break; |
1071 | } | 1077 | } |
1072 | 1078 | ||
1073 | scaledPower = max((u16)0, scaledPower); | ||
1074 | |||
1075 | if (IS_CHAN_2GHZ(chan)) { | 1079 | if (IS_CHAN_2GHZ(chan)) { |
1076 | numCtlModes = ARRAY_SIZE(ctlModesFor11g) - | 1080 | numCtlModes = ARRAY_SIZE(ctlModesFor11g) - |
1077 | SUB_NUM_CTL_MODES_AT_2G_40; | 1081 | SUB_NUM_CTL_MODES_AT_2G_40; |
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 45d4b2403a52..d0918bd23b8e 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c | |||
@@ -1015,6 +1015,13 @@ static int ath9k_hif_usb_suspend(struct usb_interface *interface, | |||
1015 | { | 1015 | { |
1016 | struct hif_device_usb *hif_dev = usb_get_intfdata(interface); | 1016 | struct hif_device_usb *hif_dev = usb_get_intfdata(interface); |
1017 | 1017 | ||
1018 | /* | ||
1019 | * The device has to be set to FULLSLEEP mode in case no | ||
1020 | * interface is up. | ||
1021 | */ | ||
1022 | if (!(hif_dev->flags & HIF_USB_START)) | ||
1023 | ath9k_htc_suspend(hif_dev->htc_handle); | ||
1024 | |||
1018 | ath9k_hif_usb_dealloc_urbs(hif_dev); | 1025 | ath9k_hif_usb_dealloc_urbs(hif_dev); |
1019 | 1026 | ||
1020 | return 0; | 1027 | return 0; |
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index afe39a911906..fdf9d5fe8cc0 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h | |||
@@ -455,6 +455,8 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv); | |||
455 | void ath9k_htc_ps_wakeup(struct ath9k_htc_priv *priv); | 455 | void ath9k_htc_ps_wakeup(struct ath9k_htc_priv *priv); |
456 | void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv); | 456 | void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv); |
457 | void ath9k_ps_work(struct work_struct *work); | 457 | void ath9k_ps_work(struct work_struct *work); |
458 | bool ath9k_htc_setpower(struct ath9k_htc_priv *priv, | ||
459 | enum ath9k_power_mode mode); | ||
458 | 460 | ||
459 | void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv); | 461 | void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv); |
460 | void ath9k_init_leds(struct ath9k_htc_priv *priv); | 462 | void ath9k_init_leds(struct ath9k_htc_priv *priv); |
@@ -464,6 +466,7 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, | |||
464 | u16 devid, char *product, u32 drv_info); | 466 | u16 devid, char *product, u32 drv_info); |
465 | void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug); | 467 | void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug); |
466 | #ifdef CONFIG_PM | 468 | #ifdef CONFIG_PM |
469 | void ath9k_htc_suspend(struct htc_target *htc_handle); | ||
467 | int ath9k_htc_resume(struct htc_target *htc_handle); | 470 | int ath9k_htc_resume(struct htc_target *htc_handle); |
468 | #endif | 471 | #endif |
469 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS | 472 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 93f3f615218b..0f6be350fd3c 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
@@ -882,6 +882,12 @@ void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug) | |||
882 | } | 882 | } |
883 | 883 | ||
884 | #ifdef CONFIG_PM | 884 | #ifdef CONFIG_PM |
885 | |||
886 | void ath9k_htc_suspend(struct htc_target *htc_handle) | ||
887 | { | ||
888 | ath9k_htc_setpower(htc_handle->drv_priv, ATH9K_PM_FULL_SLEEP); | ||
889 | } | ||
890 | |||
885 | int ath9k_htc_resume(struct htc_target *htc_handle) | 891 | int ath9k_htc_resume(struct htc_target *htc_handle) |
886 | { | 892 | { |
887 | struct ath9k_htc_priv *priv = htc_handle->drv_priv; | 893 | struct ath9k_htc_priv *priv = htc_handle->drv_priv; |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index fe82e5e30d82..20ea75a44e52 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
@@ -63,8 +63,8 @@ static enum htc_phymode ath9k_htc_get_curmode(struct ath9k_htc_priv *priv, | |||
63 | return mode; | 63 | return mode; |
64 | } | 64 | } |
65 | 65 | ||
66 | static bool ath9k_htc_setpower(struct ath9k_htc_priv *priv, | 66 | bool ath9k_htc_setpower(struct ath9k_htc_priv *priv, |
67 | enum ath9k_power_mode mode) | 67 | enum ath9k_power_mode mode) |
68 | { | 68 | { |
69 | bool ret; | 69 | bool ret; |
70 | 70 | ||
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index f05462ace4e8..e3d2ebf00e2e 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c | |||
@@ -698,8 +698,7 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, | |||
698 | rs->rs_phyerr = phyerr; | 698 | rs->rs_phyerr = phyerr; |
699 | } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr) | 699 | } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr) |
700 | rs->rs_status |= ATH9K_RXERR_DECRYPT; | 700 | rs->rs_status |= ATH9K_RXERR_DECRYPT; |
701 | else if ((ads.ds_rxstatus8 & AR_MichaelErr) && | 701 | else if (ads.ds_rxstatus8 & AR_MichaelErr) |
702 | rs->rs_keyix != ATH9K_RXKEYIX_INVALID) | ||
703 | rs->rs_status |= ATH9K_RXERR_MIC; | 702 | rs->rs_status |= ATH9K_RXERR_MIC; |
704 | else if (ads.ds_rxstatus8 & AR_KeyMiss) | 703 | else if (ads.ds_rxstatus8 & AR_KeyMiss) |
705 | rs->rs_status |= ATH9K_RXERR_DECRYPT; | 704 | rs->rs_status |= ATH9K_RXERR_DECRYPT; |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 41a312a3d401..daa3c9feca66 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -246,9 +246,10 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
246 | * the relevant bits of the h/w. | 246 | * the relevant bits of the h/w. |
247 | */ | 247 | */ |
248 | ath9k_hw_disable_interrupts(ah); | 248 | ath9k_hw_disable_interrupts(ah); |
249 | ath_drain_all_txq(sc, false); | 249 | stopped = ath_drain_all_txq(sc, false); |
250 | 250 | ||
251 | stopped = ath_stoprecv(sc); | 251 | if (!ath_stoprecv(sc)) |
252 | stopped = false; | ||
252 | 253 | ||
253 | /* XXX: do not flush receive queue here. We don't want | 254 | /* XXX: do not flush receive queue here. We don't want |
254 | * to flush data frames already in queue because of | 255 | * to flush data frames already in queue because of |
@@ -1434,8 +1435,6 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, | |||
1434 | struct ath_softc *sc = aphy->sc; | 1435 | struct ath_softc *sc = aphy->sc; |
1435 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1436 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1436 | struct ath_vif *avp = (void *)vif->drv_priv; | 1437 | struct ath_vif *avp = (void *)vif->drv_priv; |
1437 | bool bs_valid = false; | ||
1438 | int i; | ||
1439 | 1438 | ||
1440 | ath_dbg(common, ATH_DBG_CONFIG, "Detach Interface\n"); | 1439 | ath_dbg(common, ATH_DBG_CONFIG, "Detach Interface\n"); |
1441 | 1440 | ||
@@ -1449,26 +1448,21 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, | |||
1449 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || | 1448 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || |
1450 | (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) || | 1449 | (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) || |
1451 | (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) { | 1450 | (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) { |
1451 | /* Disable SWBA interrupt */ | ||
1452 | sc->sc_ah->imask &= ~ATH9K_INT_SWBA; | ||
1452 | ath9k_ps_wakeup(sc); | 1453 | ath9k_ps_wakeup(sc); |
1454 | ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask); | ||
1453 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | 1455 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); |
1454 | ath9k_ps_restore(sc); | 1456 | ath9k_ps_restore(sc); |
1457 | tasklet_kill(&sc->bcon_tasklet); | ||
1455 | } | 1458 | } |
1456 | 1459 | ||
1457 | ath_beacon_return(sc, avp); | 1460 | ath_beacon_return(sc, avp); |
1458 | sc->sc_flags &= ~SC_OP_BEACONS; | 1461 | sc->sc_flags &= ~SC_OP_BEACONS; |
1459 | 1462 | ||
1460 | for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) { | 1463 | if (sc->nbcnvifs) { |
1461 | if (sc->beacon.bslot[i] == vif) { | 1464 | /* Re-enable SWBA interrupt */ |
1462 | printk(KERN_DEBUG "%s: vif had allocated beacon " | 1465 | sc->sc_ah->imask |= ATH9K_INT_SWBA; |
1463 | "slot\n", __func__); | ||
1464 | sc->beacon.bslot[i] = NULL; | ||
1465 | sc->beacon.bslot_aphy[i] = NULL; | ||
1466 | } else if (sc->beacon.bslot[i]) | ||
1467 | bs_valid = true; | ||
1468 | } | ||
1469 | if (!bs_valid && (sc->sc_ah->imask & ATH9K_INT_SWBA)) { | ||
1470 | /* Disable SWBA interrupt */ | ||
1471 | sc->sc_ah->imask &= ~ATH9K_INT_SWBA; | ||
1472 | ath9k_ps_wakeup(sc); | 1466 | ath9k_ps_wakeup(sc); |
1473 | ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask); | 1467 | ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask); |
1474 | ath9k_ps_restore(sc); | 1468 | ath9k_ps_restore(sc); |
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index c3129db7828f..00ebed3f9158 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -841,6 +841,10 @@ static bool ath9k_rx_accept(struct ath_common *common, | |||
841 | struct ath_rx_status *rx_stats, | 841 | struct ath_rx_status *rx_stats, |
842 | bool *decrypt_error) | 842 | bool *decrypt_error) |
843 | { | 843 | { |
844 | #define is_mc_or_valid_tkip_keyix ((is_mc || \ | ||
845 | (rx_stats->rs_keyix != ATH9K_RXKEYIX_INVALID && \ | ||
846 | test_bit(rx_stats->rs_keyix, common->tkip_keymap)))) | ||
847 | |||
844 | struct ath_hw *ah = common->ah; | 848 | struct ath_hw *ah = common->ah; |
845 | __le16 fc; | 849 | __le16 fc; |
846 | u8 rx_status_len = ah->caps.rx_status_len; | 850 | u8 rx_status_len = ah->caps.rx_status_len; |
@@ -882,15 +886,18 @@ static bool ath9k_rx_accept(struct ath_common *common, | |||
882 | if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) { | 886 | if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) { |
883 | *decrypt_error = true; | 887 | *decrypt_error = true; |
884 | } else if (rx_stats->rs_status & ATH9K_RXERR_MIC) { | 888 | } else if (rx_stats->rs_status & ATH9K_RXERR_MIC) { |
889 | bool is_mc; | ||
885 | /* | 890 | /* |
886 | * The MIC error bit is only valid if the frame | 891 | * The MIC error bit is only valid if the frame |
887 | * is not a control frame or fragment, and it was | 892 | * is not a control frame or fragment, and it was |
888 | * decrypted using a valid TKIP key. | 893 | * decrypted using a valid TKIP key. |
889 | */ | 894 | */ |
895 | is_mc = !!is_multicast_ether_addr(hdr->addr1); | ||
896 | |||
890 | if (!ieee80211_is_ctl(fc) && | 897 | if (!ieee80211_is_ctl(fc) && |
891 | !ieee80211_has_morefrags(fc) && | 898 | !ieee80211_has_morefrags(fc) && |
892 | !(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) && | 899 | !(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) && |
893 | test_bit(rx_stats->rs_keyix, common->tkip_keymap)) | 900 | is_mc_or_valid_tkip_keyix) |
894 | rxs->flag |= RX_FLAG_MMIC_ERROR; | 901 | rxs->flag |= RX_FLAG_MMIC_ERROR; |
895 | else | 902 | else |
896 | rx_stats->rs_status &= ~ATH9K_RXERR_MIC; | 903 | rx_stats->rs_status &= ~ATH9K_RXERR_MIC; |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index bce313e85cff..43c0109f202c 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -1171,7 +1171,7 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) | |||
1171 | } | 1171 | } |
1172 | } | 1172 | } |
1173 | 1173 | ||
1174 | void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) | 1174 | bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) |
1175 | { | 1175 | { |
1176 | struct ath_hw *ah = sc->sc_ah; | 1176 | struct ath_hw *ah = sc->sc_ah; |
1177 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1177 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
@@ -1179,7 +1179,7 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) | |||
1179 | int i, npend = 0; | 1179 | int i, npend = 0; |
1180 | 1180 | ||
1181 | if (sc->sc_flags & SC_OP_INVALID) | 1181 | if (sc->sc_flags & SC_OP_INVALID) |
1182 | return; | 1182 | return true; |
1183 | 1183 | ||
1184 | /* Stop beacon queue */ | 1184 | /* Stop beacon queue */ |
1185 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | 1185 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); |
@@ -1193,22 +1193,15 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) | |||
1193 | } | 1193 | } |
1194 | } | 1194 | } |
1195 | 1195 | ||
1196 | if (npend) { | 1196 | if (npend) |
1197 | int r; | 1197 | ath_err(common, "Failed to stop TX DMA!\n"); |
1198 | |||
1199 | ath_err(common, "Failed to stop TX DMA. Resetting hardware!\n"); | ||
1200 | |||
1201 | r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false); | ||
1202 | if (r) | ||
1203 | ath_err(common, | ||
1204 | "Unable to reset hardware; reset status %d\n", | ||
1205 | r); | ||
1206 | } | ||
1207 | 1198 | ||
1208 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { | 1199 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { |
1209 | if (ATH_TXQ_SETUP(sc, i)) | 1200 | if (ATH_TXQ_SETUP(sc, i)) |
1210 | ath_draintxq(sc, &sc->tx.txq[i], retry_tx); | 1201 | ath_draintxq(sc, &sc->tx.txq[i], retry_tx); |
1211 | } | 1202 | } |
1203 | |||
1204 | return !npend; | ||
1212 | } | 1205 | } |
1213 | 1206 | ||
1214 | void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq) | 1207 | void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq) |
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c index fa0cf744958f..f3d396e7544b 100644 --- a/drivers/net/wireless/orinoco/main.c +++ b/drivers/net/wireless/orinoco/main.c | |||
@@ -1811,6 +1811,12 @@ static int __orinoco_commit(struct orinoco_private *priv) | |||
1811 | struct net_device *dev = priv->ndev; | 1811 | struct net_device *dev = priv->ndev; |
1812 | int err = 0; | 1812 | int err = 0; |
1813 | 1813 | ||
1814 | /* If we've called commit, we are reconfiguring or bringing the | ||
1815 | * interface up. Maintaining countermeasures across this would | ||
1816 | * be confusing, so note that we've disabled them. The port will | ||
1817 | * be enabled later in orinoco_commit or __orinoco_up. */ | ||
1818 | priv->tkip_cm_active = 0; | ||
1819 | |||
1814 | err = orinoco_hw_program_rids(priv); | 1820 | err = orinoco_hw_program_rids(priv); |
1815 | 1821 | ||
1816 | /* FIXME: what about netif_tx_lock */ | 1822 | /* FIXME: what about netif_tx_lock */ |
diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c index 71b3d68b9403..32954c4b243a 100644 --- a/drivers/net/wireless/orinoco/orinoco_cs.c +++ b/drivers/net/wireless/orinoco/orinoco_cs.c | |||
@@ -151,20 +151,20 @@ orinoco_cs_config(struct pcmcia_device *link) | |||
151 | goto failed; | 151 | goto failed; |
152 | } | 152 | } |
153 | 153 | ||
154 | ret = pcmcia_request_irq(link, orinoco_interrupt); | ||
155 | if (ret) | ||
156 | goto failed; | ||
157 | |||
158 | /* We initialize the hermes structure before completing PCMCIA | ||
159 | * configuration just in case the interrupt handler gets | ||
160 | * called. */ | ||
161 | mem = ioport_map(link->resource[0]->start, | 154 | mem = ioport_map(link->resource[0]->start, |
162 | resource_size(link->resource[0])); | 155 | resource_size(link->resource[0])); |
163 | if (!mem) | 156 | if (!mem) |
164 | goto failed; | 157 | goto failed; |
165 | 158 | ||
159 | /* We initialize the hermes structure before completing PCMCIA | ||
160 | * configuration just in case the interrupt handler gets | ||
161 | * called. */ | ||
166 | hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING); | 162 | hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING); |
167 | 163 | ||
164 | ret = pcmcia_request_irq(link, orinoco_interrupt); | ||
165 | if (ret) | ||
166 | goto failed; | ||
167 | |||
168 | ret = pcmcia_enable_device(link); | 168 | ret = pcmcia_enable_device(link); |
169 | if (ret) | 169 | if (ret) |
170 | goto failed; | 170 | goto failed; |
diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c index fb859a5ad2eb..db34c282e59b 100644 --- a/drivers/net/wireless/orinoco/spectrum_cs.c +++ b/drivers/net/wireless/orinoco/spectrum_cs.c | |||
@@ -214,21 +214,21 @@ spectrum_cs_config(struct pcmcia_device *link) | |||
214 | goto failed; | 214 | goto failed; |
215 | } | 215 | } |
216 | 216 | ||
217 | ret = pcmcia_request_irq(link, orinoco_interrupt); | ||
218 | if (ret) | ||
219 | goto failed; | ||
220 | |||
221 | /* We initialize the hermes structure before completing PCMCIA | ||
222 | * configuration just in case the interrupt handler gets | ||
223 | * called. */ | ||
224 | mem = ioport_map(link->resource[0]->start, | 217 | mem = ioport_map(link->resource[0]->start, |
225 | resource_size(link->resource[0])); | 218 | resource_size(link->resource[0])); |
226 | if (!mem) | 219 | if (!mem) |
227 | goto failed; | 220 | goto failed; |
228 | 221 | ||
222 | /* We initialize the hermes structure before completing PCMCIA | ||
223 | * configuration just in case the interrupt handler gets | ||
224 | * called. */ | ||
229 | hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING); | 225 | hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING); |
230 | hw->eeprom_pda = true; | 226 | hw->eeprom_pda = true; |
231 | 227 | ||
228 | ret = pcmcia_request_irq(link, orinoco_interrupt); | ||
229 | if (ret) | ||
230 | goto failed; | ||
231 | |||
232 | ret = pcmcia_enable_device(link); | 232 | ret = pcmcia_enable_device(link); |
233 | if (ret) | 233 | if (ret) |
234 | goto failed; | 234 | goto failed; |
diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c index 8e65ffc4cb0a..e793679e2e19 100644 --- a/drivers/net/wireless/orinoco/wext.c +++ b/drivers/net/wireless/orinoco/wext.c | |||
@@ -919,10 +919,10 @@ static int orinoco_ioctl_set_auth(struct net_device *dev, | |||
919 | */ | 919 | */ |
920 | if (param->value) { | 920 | if (param->value) { |
921 | priv->tkip_cm_active = 1; | 921 | priv->tkip_cm_active = 1; |
922 | ret = hermes_enable_port(hw, 0); | 922 | ret = hermes_disable_port(hw, 0); |
923 | } else { | 923 | } else { |
924 | priv->tkip_cm_active = 0; | 924 | priv->tkip_cm_active = 0; |
925 | ret = hermes_disable_port(hw, 0); | 925 | ret = hermes_enable_port(hw, 0); |
926 | } | 926 | } |
927 | break; | 927 | break; |
928 | 928 | ||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 5d6b0759d18c..0ee56bb0ea7e 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1746,15 +1746,13 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1746 | int nh_pos, h_pos; | 1746 | int nh_pos, h_pos; |
1747 | struct sta_info *sta = NULL; | 1747 | struct sta_info *sta = NULL; |
1748 | u32 sta_flags = 0; | 1748 | u32 sta_flags = 0; |
1749 | struct sk_buff *tmp_skb; | ||
1749 | 1750 | ||
1750 | if (unlikely(skb->len < ETH_HLEN)) { | 1751 | if (unlikely(skb->len < ETH_HLEN)) { |
1751 | ret = NETDEV_TX_OK; | 1752 | ret = NETDEV_TX_OK; |
1752 | goto fail; | 1753 | goto fail; |
1753 | } | 1754 | } |
1754 | 1755 | ||
1755 | nh_pos = skb_network_header(skb) - skb->data; | ||
1756 | h_pos = skb_transport_header(skb) - skb->data; | ||
1757 | |||
1758 | /* convert Ethernet header to proper 802.11 header (based on | 1756 | /* convert Ethernet header to proper 802.11 header (based on |
1759 | * operation mode) */ | 1757 | * operation mode) */ |
1760 | ethertype = (skb->data[12] << 8) | skb->data[13]; | 1758 | ethertype = (skb->data[12] << 8) | skb->data[13]; |
@@ -1927,6 +1925,20 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1927 | goto fail; | 1925 | goto fail; |
1928 | } | 1926 | } |
1929 | 1927 | ||
1928 | /* | ||
1929 | * If the skb is shared we need to obtain our own copy. | ||
1930 | */ | ||
1931 | if (skb_shared(skb)) { | ||
1932 | tmp_skb = skb; | ||
1933 | skb = skb_copy(skb, GFP_ATOMIC); | ||
1934 | kfree_skb(tmp_skb); | ||
1935 | |||
1936 | if (!skb) { | ||
1937 | ret = NETDEV_TX_OK; | ||
1938 | goto fail; | ||
1939 | } | ||
1940 | } | ||
1941 | |||
1930 | hdr.frame_control = fc; | 1942 | hdr.frame_control = fc; |
1931 | hdr.duration_id = 0; | 1943 | hdr.duration_id = 0; |
1932 | hdr.seq_ctrl = 0; | 1944 | hdr.seq_ctrl = 0; |
@@ -1945,6 +1957,9 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1945 | encaps_len = 0; | 1957 | encaps_len = 0; |
1946 | } | 1958 | } |
1947 | 1959 | ||
1960 | nh_pos = skb_network_header(skb) - skb->data; | ||
1961 | h_pos = skb_transport_header(skb) - skb->data; | ||
1962 | |||
1948 | skb_pull(skb, skip_header_bytes); | 1963 | skb_pull(skb, skip_header_bytes); |
1949 | nh_pos -= skip_header_bytes; | 1964 | nh_pos -= skip_header_bytes; |
1950 | h_pos -= skip_header_bytes; | 1965 | h_pos -= skip_header_bytes; |