diff options
Diffstat (limited to 'drivers/net/wireless/ath')
39 files changed, 539 insertions, 1492 deletions
diff --git a/drivers/net/wireless/ath/ath5k/Kconfig b/drivers/net/wireless/ath/ath5k/Kconfig index e0793319389d..e18a9aa7b6ca 100644 --- a/drivers/net/wireless/ath/ath5k/Kconfig +++ b/drivers/net/wireless/ath/ath5k/Kconfig | |||
@@ -40,6 +40,17 @@ config ATH5K_DEBUG | |||
40 | 40 | ||
41 | modprobe ath5k debug=0x00000400 | 41 | modprobe ath5k debug=0x00000400 |
42 | 42 | ||
43 | config ATH5K_TRACER | ||
44 | bool "Atheros 5xxx tracer" | ||
45 | depends on ATH5K | ||
46 | depends on EVENT_TRACING | ||
47 | ---help--- | ||
48 | Say Y here to enable tracepoints for the ath5k driver | ||
49 | using the kernel tracing infrastructure. Select this | ||
50 | option if you are interested in debugging the driver. | ||
51 | |||
52 | If unsure, say N. | ||
53 | |||
43 | config ATH5K_AHB | 54 | config ATH5K_AHB |
44 | bool "Atheros 5xxx AHB bus support" | 55 | bool "Atheros 5xxx AHB bus support" |
45 | depends on (ATHEROS_AR231X && !PCI) | 56 | depends on (ATHEROS_AR231X && !PCI) |
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 407e39c2b10b..e43175a89d67 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h | |||
@@ -210,14 +210,9 @@ | |||
210 | /* Initial values */ | 210 | /* Initial values */ |
211 | #define AR5K_INIT_CYCRSSI_THR1 2 | 211 | #define AR5K_INIT_CYCRSSI_THR1 2 |
212 | 212 | ||
213 | /* Tx retry limits */ | 213 | /* Tx retry limit defaults from standard */ |
214 | #define AR5K_INIT_SH_RETRY 10 | 214 | #define AR5K_INIT_RETRY_SHORT 7 |
215 | #define AR5K_INIT_LG_RETRY AR5K_INIT_SH_RETRY | 215 | #define AR5K_INIT_RETRY_LONG 4 |
216 | /* For station mode */ | ||
217 | #define AR5K_INIT_SSH_RETRY 32 | ||
218 | #define AR5K_INIT_SLG_RETRY AR5K_INIT_SSH_RETRY | ||
219 | #define AR5K_INIT_TX_RETRY 10 | ||
220 | |||
221 | 216 | ||
222 | /* Slot time */ | 217 | /* Slot time */ |
223 | #define AR5K_INIT_SLOT_TIME_TURBO 6 | 218 | #define AR5K_INIT_SLOT_TIME_TURBO 6 |
@@ -1057,7 +1052,9 @@ struct ath5k_hw { | |||
1057 | #define ah_modes ah_capabilities.cap_mode | 1052 | #define ah_modes ah_capabilities.cap_mode |
1058 | #define ah_ee_version ah_capabilities.cap_eeprom.ee_version | 1053 | #define ah_ee_version ah_capabilities.cap_eeprom.ee_version |
1059 | 1054 | ||
1060 | u32 ah_limit_tx_retries; | 1055 | u8 ah_retry_long; |
1056 | u8 ah_retry_short; | ||
1057 | |||
1061 | u8 ah_coverage_class; | 1058 | u8 ah_coverage_class; |
1062 | bool ah_ack_bitrate_high; | 1059 | bool ah_ack_bitrate_high; |
1063 | u8 ah_bwmode; | 1060 | u8 ah_bwmode; |
@@ -1067,7 +1064,6 @@ struct ath5k_hw { | |||
1067 | u8 ah_ant_mode; | 1064 | u8 ah_ant_mode; |
1068 | u8 ah_tx_ant; | 1065 | u8 ah_tx_ant; |
1069 | u8 ah_def_ant; | 1066 | u8 ah_def_ant; |
1070 | bool ah_software_retry; | ||
1071 | 1067 | ||
1072 | struct ath5k_capabilities ah_capabilities; | 1068 | struct ath5k_capabilities ah_capabilities; |
1073 | 1069 | ||
@@ -1250,6 +1246,8 @@ int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue, | |||
1250 | int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, | 1246 | int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, |
1251 | enum ath5k_tx_queue queue_type, | 1247 | enum ath5k_tx_queue queue_type, |
1252 | struct ath5k_txq_info *queue_info); | 1248 | struct ath5k_txq_info *queue_info); |
1249 | void ath5k_hw_set_tx_retry_limits(struct ath5k_hw *ah, | ||
1250 | unsigned int queue); | ||
1253 | u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue); | 1251 | u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue); |
1254 | void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue); | 1252 | void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue); |
1255 | int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue); | 1253 | int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue); |
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index cdac5cff0177..c71fdbb4c439 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c | |||
@@ -118,8 +118,8 @@ int ath5k_hw_init(struct ath5k_softc *sc) | |||
118 | ah->ah_bwmode = AR5K_BWMODE_DEFAULT; | 118 | ah->ah_bwmode = AR5K_BWMODE_DEFAULT; |
119 | ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER; | 119 | ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER; |
120 | ah->ah_imr = 0; | 120 | ah->ah_imr = 0; |
121 | ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY; | 121 | ah->ah_retry_short = AR5K_INIT_RETRY_SHORT; |
122 | ah->ah_software_retry = false; | 122 | ah->ah_retry_long = AR5K_INIT_RETRY_LONG; |
123 | ah->ah_ant_mode = AR5K_ANTMODE_DEFAULT; | 123 | ah->ah_ant_mode = AR5K_ANTMODE_DEFAULT; |
124 | ah->ah_noise_floor = -95; /* until first NF calibration is run */ | 124 | ah->ah_noise_floor = -95; /* until first NF calibration is run */ |
125 | sc->ani_state.ani_mode = ATH5K_ANI_MODE_AUTO; | 125 | sc->ani_state.ani_mode = ATH5K_ANI_MODE_AUTO; |
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index dae0bdcef257..dbc45e085434 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -61,6 +61,9 @@ | |||
61 | #include "debug.h" | 61 | #include "debug.h" |
62 | #include "ani.h" | 62 | #include "ani.h" |
63 | 63 | ||
64 | #define CREATE_TRACE_POINTS | ||
65 | #include "trace.h" | ||
66 | |||
64 | int ath5k_modparam_nohwcrypt; | 67 | int ath5k_modparam_nohwcrypt; |
65 | module_param_named(nohwcrypt, ath5k_modparam_nohwcrypt, bool, S_IRUGO); | 68 | module_param_named(nohwcrypt, ath5k_modparam_nohwcrypt, bool, S_IRUGO); |
66 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); | 69 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); |
@@ -1379,7 +1382,7 @@ ath5k_receive_frame(struct ath5k_softc *sc, struct sk_buff *skb, | |||
1379 | sc->sbands[sc->curchan->band].bitrates[rxs->rate_idx].hw_value_short) | 1382 | sc->sbands[sc->curchan->band].bitrates[rxs->rate_idx].hw_value_short) |
1380 | rxs->flag |= RX_FLAG_SHORTPRE; | 1383 | rxs->flag |= RX_FLAG_SHORTPRE; |
1381 | 1384 | ||
1382 | ath5k_debug_dump_skb(sc, skb, "RX ", 0); | 1385 | trace_ath5k_rx(sc, skb); |
1383 | 1386 | ||
1384 | ath5k_update_beacon_rssi(sc, skb, rs->rs_rssi); | 1387 | ath5k_update_beacon_rssi(sc, skb, rs->rs_rssi); |
1385 | 1388 | ||
@@ -1524,7 +1527,7 @@ ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1524 | unsigned long flags; | 1527 | unsigned long flags; |
1525 | int padsize; | 1528 | int padsize; |
1526 | 1529 | ||
1527 | ath5k_debug_dump_skb(sc, skb, "TX ", 1); | 1530 | trace_ath5k_tx(sc, skb, txq); |
1528 | 1531 | ||
1529 | /* | 1532 | /* |
1530 | * The hardware expects the header padded to 4 byte boundaries. | 1533 | * The hardware expects the header padded to 4 byte boundaries. |
@@ -1573,7 +1576,7 @@ drop_packet: | |||
1573 | 1576 | ||
1574 | static void | 1577 | static void |
1575 | ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb, | 1578 | ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb, |
1576 | struct ath5k_tx_status *ts) | 1579 | struct ath5k_txq *txq, struct ath5k_tx_status *ts) |
1577 | { | 1580 | { |
1578 | struct ieee80211_tx_info *info; | 1581 | struct ieee80211_tx_info *info; |
1579 | int i; | 1582 | int i; |
@@ -1625,6 +1628,7 @@ ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb, | |||
1625 | else | 1628 | else |
1626 | sc->stats.antenna_tx[0]++; /* invalid */ | 1629 | sc->stats.antenna_tx[0]++; /* invalid */ |
1627 | 1630 | ||
1631 | trace_ath5k_tx_complete(sc, skb, txq, ts); | ||
1628 | ieee80211_tx_status(sc->hw, skb); | 1632 | ieee80211_tx_status(sc->hw, skb); |
1629 | } | 1633 | } |
1630 | 1634 | ||
@@ -1661,7 +1665,7 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) | |||
1661 | 1665 | ||
1662 | dma_unmap_single(sc->dev, bf->skbaddr, skb->len, | 1666 | dma_unmap_single(sc->dev, bf->skbaddr, skb->len, |
1663 | DMA_TO_DEVICE); | 1667 | DMA_TO_DEVICE); |
1664 | ath5k_tx_frame_completed(sc, skb, &ts); | 1668 | ath5k_tx_frame_completed(sc, skb, txq, &ts); |
1665 | } | 1669 | } |
1666 | 1670 | ||
1667 | /* | 1671 | /* |
@@ -1803,8 +1807,6 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | |||
1803 | goto out; | 1807 | goto out; |
1804 | } | 1808 | } |
1805 | 1809 | ||
1806 | ath5k_debug_dump_skb(sc, skb, "BC ", 1); | ||
1807 | |||
1808 | ath5k_txbuf_free_skb(sc, avf->bbuf); | 1810 | ath5k_txbuf_free_skb(sc, avf->bbuf); |
1809 | avf->bbuf->skb = skb; | 1811 | avf->bbuf->skb = skb; |
1810 | ret = ath5k_beacon_setup(sc, avf->bbuf); | 1812 | ret = ath5k_beacon_setup(sc, avf->bbuf); |
@@ -1899,6 +1901,8 @@ ath5k_beacon_send(struct ath5k_softc *sc) | |||
1899 | sc->opmode == NL80211_IFTYPE_MESH_POINT) | 1901 | sc->opmode == NL80211_IFTYPE_MESH_POINT) |
1900 | ath5k_beacon_update(sc->hw, vif); | 1902 | ath5k_beacon_update(sc->hw, vif); |
1901 | 1903 | ||
1904 | trace_ath5k_tx(sc, bf->skb, &sc->txqs[sc->bhalq]); | ||
1905 | |||
1902 | ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr); | 1906 | ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr); |
1903 | ath5k_hw_start_tx_dma(ah, sc->bhalq); | 1907 | ath5k_hw_start_tx_dma(ah, sc->bhalq); |
1904 | ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n", | 1908 | ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n", |
@@ -2399,7 +2403,8 @@ ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops) | |||
2399 | /* set up multi-rate retry capabilities */ | 2403 | /* set up multi-rate retry capabilities */ |
2400 | if (sc->ah->ah_version == AR5K_AR5212) { | 2404 | if (sc->ah->ah_version == AR5K_AR5212) { |
2401 | hw->max_rates = 4; | 2405 | hw->max_rates = 4; |
2402 | hw->max_rate_tries = 11; | 2406 | hw->max_rate_tries = max(AR5K_INIT_RETRY_SHORT, |
2407 | AR5K_INIT_RETRY_LONG); | ||
2403 | } | 2408 | } |
2404 | 2409 | ||
2405 | hw->vif_data_size = sizeof(struct ath5k_vif); | 2410 | hw->vif_data_size = sizeof(struct ath5k_vif); |
diff --git a/drivers/net/wireless/ath/ath5k/caps.c b/drivers/net/wireless/ath/ath5k/caps.c index 31cad80e9b01..f77e8a703c5c 100644 --- a/drivers/net/wireless/ath/ath5k/caps.c +++ b/drivers/net/wireless/ath/ath5k/caps.c | |||
@@ -32,23 +32,24 @@ | |||
32 | */ | 32 | */ |
33 | int ath5k_hw_set_capabilities(struct ath5k_hw *ah) | 33 | int ath5k_hw_set_capabilities(struct ath5k_hw *ah) |
34 | { | 34 | { |
35 | struct ath5k_capabilities *caps = &ah->ah_capabilities; | ||
35 | u16 ee_header; | 36 | u16 ee_header; |
36 | 37 | ||
37 | /* Capabilities stored in the EEPROM */ | 38 | /* Capabilities stored in the EEPROM */ |
38 | ee_header = ah->ah_capabilities.cap_eeprom.ee_header; | 39 | ee_header = caps->cap_eeprom.ee_header; |
39 | 40 | ||
40 | if (ah->ah_version == AR5K_AR5210) { | 41 | if (ah->ah_version == AR5K_AR5210) { |
41 | /* | 42 | /* |
42 | * Set radio capabilities | 43 | * Set radio capabilities |
43 | * (The AR5110 only supports the middle 5GHz band) | 44 | * (The AR5110 only supports the middle 5GHz band) |
44 | */ | 45 | */ |
45 | ah->ah_capabilities.cap_range.range_5ghz_min = 5120; | 46 | caps->cap_range.range_5ghz_min = 5120; |
46 | ah->ah_capabilities.cap_range.range_5ghz_max = 5430; | 47 | caps->cap_range.range_5ghz_max = 5430; |
47 | ah->ah_capabilities.cap_range.range_2ghz_min = 0; | 48 | caps->cap_range.range_2ghz_min = 0; |
48 | ah->ah_capabilities.cap_range.range_2ghz_max = 0; | 49 | caps->cap_range.range_2ghz_max = 0; |
49 | 50 | ||
50 | /* Set supported modes */ | 51 | /* Set supported modes */ |
51 | __set_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode); | 52 | __set_bit(AR5K_MODE_11A, caps->cap_mode); |
52 | } else { | 53 | } else { |
53 | /* | 54 | /* |
54 | * XXX The tranceiver supports frequencies from 4920 to 6100GHz | 55 | * XXX The tranceiver supports frequencies from 4920 to 6100GHz |
@@ -56,9 +57,8 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah) | |||
56 | * XXX current ieee80211 implementation because the IEEE | 57 | * XXX current ieee80211 implementation because the IEEE |
57 | * XXX channel mapping does not support negative channel | 58 | * XXX channel mapping does not support negative channel |
58 | * XXX numbers (2312MHz is channel -19). Of course, this | 59 | * XXX numbers (2312MHz is channel -19). Of course, this |
59 | * XXX doesn't matter because these channels are out of range | 60 | * XXX doesn't matter because these channels are out of the |
60 | * XXX but some regulation domains like MKK (Japan) will | 61 | * XXX legal range. |
61 | * XXX support frequencies somewhere around 4.8GHz. | ||
62 | */ | 62 | */ |
63 | 63 | ||
64 | /* | 64 | /* |
@@ -66,13 +66,14 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah) | |||
66 | */ | 66 | */ |
67 | 67 | ||
68 | if (AR5K_EEPROM_HDR_11A(ee_header)) { | 68 | if (AR5K_EEPROM_HDR_11A(ee_header)) { |
69 | /* 4920 */ | 69 | if (ath_is_49ghz_allowed(caps->cap_eeprom.ee_regdomain)) |
70 | ah->ah_capabilities.cap_range.range_5ghz_min = 5005; | 70 | caps->cap_range.range_5ghz_min = 4920; |
71 | ah->ah_capabilities.cap_range.range_5ghz_max = 6100; | 71 | else |
72 | caps->cap_range.range_5ghz_min = 5005; | ||
73 | caps->cap_range.range_5ghz_max = 6100; | ||
72 | 74 | ||
73 | /* Set supported modes */ | 75 | /* Set supported modes */ |
74 | __set_bit(AR5K_MODE_11A, | 76 | __set_bit(AR5K_MODE_11A, caps->cap_mode); |
75 | ah->ah_capabilities.cap_mode); | ||
76 | } | 77 | } |
77 | 78 | ||
78 | /* Enable 802.11b if a 2GHz capable radio (2111/5112) is | 79 | /* Enable 802.11b if a 2GHz capable radio (2111/5112) is |
@@ -81,32 +82,29 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah) | |||
81 | (AR5K_EEPROM_HDR_11G(ee_header) && | 82 | (AR5K_EEPROM_HDR_11G(ee_header) && |
82 | ah->ah_version != AR5K_AR5211)) { | 83 | ah->ah_version != AR5K_AR5211)) { |
83 | /* 2312 */ | 84 | /* 2312 */ |
84 | ah->ah_capabilities.cap_range.range_2ghz_min = 2412; | 85 | caps->cap_range.range_2ghz_min = 2412; |
85 | ah->ah_capabilities.cap_range.range_2ghz_max = 2732; | 86 | caps->cap_range.range_2ghz_max = 2732; |
86 | 87 | ||
87 | if (AR5K_EEPROM_HDR_11B(ee_header)) | 88 | if (AR5K_EEPROM_HDR_11B(ee_header)) |
88 | __set_bit(AR5K_MODE_11B, | 89 | __set_bit(AR5K_MODE_11B, caps->cap_mode); |
89 | ah->ah_capabilities.cap_mode); | ||
90 | 90 | ||
91 | if (AR5K_EEPROM_HDR_11G(ee_header) && | 91 | if (AR5K_EEPROM_HDR_11G(ee_header) && |
92 | ah->ah_version != AR5K_AR5211) | 92 | ah->ah_version != AR5K_AR5211) |
93 | __set_bit(AR5K_MODE_11G, | 93 | __set_bit(AR5K_MODE_11G, caps->cap_mode); |
94 | ah->ah_capabilities.cap_mode); | ||
95 | } | 94 | } |
96 | } | 95 | } |
97 | 96 | ||
98 | /* Set number of supported TX queues */ | 97 | /* Set number of supported TX queues */ |
99 | if (ah->ah_version == AR5K_AR5210) | 98 | if (ah->ah_version == AR5K_AR5210) |
100 | ah->ah_capabilities.cap_queues.q_tx_num = | 99 | caps->cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES_NOQCU; |
101 | AR5K_NUM_TX_QUEUES_NOQCU; | ||
102 | else | 100 | else |
103 | ah->ah_capabilities.cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES; | 101 | caps->cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES; |
104 | 102 | ||
105 | /* newer hardware has PHY error counters */ | 103 | /* newer hardware has PHY error counters */ |
106 | if (ah->ah_mac_srev >= AR5K_SREV_AR5213A) | 104 | if (ah->ah_mac_srev >= AR5K_SREV_AR5213A) |
107 | ah->ah_capabilities.cap_has_phyerr_counters = true; | 105 | caps->cap_has_phyerr_counters = true; |
108 | else | 106 | else |
109 | ah->ah_capabilities.cap_has_phyerr_counters = false; | 107 | caps->cap_has_phyerr_counters = false; |
110 | 108 | ||
111 | return 0; | 109 | return 0; |
112 | } | 110 | } |
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c index d2f84d76bb07..0230f30e9e9a 100644 --- a/drivers/net/wireless/ath/ath5k/debug.c +++ b/drivers/net/wireless/ath/ath5k/debug.c | |||
@@ -308,8 +308,6 @@ static const struct { | |||
308 | { ATH5K_DEBUG_CALIBRATE, "calib", "periodic calibration" }, | 308 | { ATH5K_DEBUG_CALIBRATE, "calib", "periodic calibration" }, |
309 | { ATH5K_DEBUG_TXPOWER, "txpower", "transmit power setting" }, | 309 | { ATH5K_DEBUG_TXPOWER, "txpower", "transmit power setting" }, |
310 | { ATH5K_DEBUG_LED, "led", "LED management" }, | 310 | { ATH5K_DEBUG_LED, "led", "LED management" }, |
311 | { ATH5K_DEBUG_DUMP_RX, "dumprx", "print received skb content" }, | ||
312 | { ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" }, | ||
313 | { ATH5K_DEBUG_DUMPBANDS, "dumpbands", "dump bands" }, | 311 | { ATH5K_DEBUG_DUMPBANDS, "dumpbands", "dump bands" }, |
314 | { ATH5K_DEBUG_DMA, "dma", "dma start/stop" }, | 312 | { ATH5K_DEBUG_DMA, "dma", "dma start/stop" }, |
315 | { ATH5K_DEBUG_ANI, "ani", "adaptive noise immunity" }, | 313 | { ATH5K_DEBUG_ANI, "ani", "adaptive noise immunity" }, |
@@ -1036,24 +1034,6 @@ ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) | |||
1036 | } | 1034 | } |
1037 | 1035 | ||
1038 | void | 1036 | void |
1039 | ath5k_debug_dump_skb(struct ath5k_softc *sc, | ||
1040 | struct sk_buff *skb, const char *prefix, int tx) | ||
1041 | { | ||
1042 | char buf[16]; | ||
1043 | |||
1044 | if (likely(!((tx && (sc->debug.level & ATH5K_DEBUG_DUMP_TX)) || | ||
1045 | (!tx && (sc->debug.level & ATH5K_DEBUG_DUMP_RX))))) | ||
1046 | return; | ||
1047 | |||
1048 | snprintf(buf, sizeof(buf), "%s %s", wiphy_name(sc->hw->wiphy), prefix); | ||
1049 | |||
1050 | print_hex_dump_bytes(buf, DUMP_PREFIX_NONE, skb->data, | ||
1051 | min(200U, skb->len)); | ||
1052 | |||
1053 | printk(KERN_DEBUG "\n"); | ||
1054 | } | ||
1055 | |||
1056 | void | ||
1057 | ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf) | 1037 | ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf) |
1058 | { | 1038 | { |
1059 | struct ath5k_desc *ds = bf->desc; | 1039 | struct ath5k_desc *ds = bf->desc; |
diff --git a/drivers/net/wireless/ath/ath5k/debug.h b/drivers/net/wireless/ath/ath5k/debug.h index 3e34428d5126..b0355aef68d3 100644 --- a/drivers/net/wireless/ath/ath5k/debug.h +++ b/drivers/net/wireless/ath/ath5k/debug.h | |||
@@ -116,8 +116,6 @@ enum ath5k_debug_level { | |||
116 | ATH5K_DEBUG_CALIBRATE = 0x00000020, | 116 | ATH5K_DEBUG_CALIBRATE = 0x00000020, |
117 | ATH5K_DEBUG_TXPOWER = 0x00000040, | 117 | ATH5K_DEBUG_TXPOWER = 0x00000040, |
118 | ATH5K_DEBUG_LED = 0x00000080, | 118 | ATH5K_DEBUG_LED = 0x00000080, |
119 | ATH5K_DEBUG_DUMP_RX = 0x00000100, | ||
120 | ATH5K_DEBUG_DUMP_TX = 0x00000200, | ||
121 | ATH5K_DEBUG_DUMPBANDS = 0x00000400, | 119 | ATH5K_DEBUG_DUMPBANDS = 0x00000400, |
122 | ATH5K_DEBUG_DMA = 0x00000800, | 120 | ATH5K_DEBUG_DMA = 0x00000800, |
123 | ATH5K_DEBUG_ANI = 0x00002000, | 121 | ATH5K_DEBUG_ANI = 0x00002000, |
@@ -152,10 +150,6 @@ void | |||
152 | ath5k_debug_dump_bands(struct ath5k_softc *sc); | 150 | ath5k_debug_dump_bands(struct ath5k_softc *sc); |
153 | 151 | ||
154 | void | 152 | void |
155 | ath5k_debug_dump_skb(struct ath5k_softc *sc, | ||
156 | struct sk_buff *skb, const char *prefix, int tx); | ||
157 | |||
158 | void | ||
159 | ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf); | 153 | ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf); |
160 | 154 | ||
161 | #else /* no debugging */ | 155 | #else /* no debugging */ |
@@ -182,10 +176,6 @@ static inline void | |||
182 | ath5k_debug_dump_bands(struct ath5k_softc *sc) {} | 176 | ath5k_debug_dump_bands(struct ath5k_softc *sc) {} |
183 | 177 | ||
184 | static inline void | 178 | static inline void |
185 | ath5k_debug_dump_skb(struct ath5k_softc *sc, | ||
186 | struct sk_buff *skb, const char *prefix, int tx) {} | ||
187 | |||
188 | static inline void | ||
189 | ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf) {} | 179 | ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf) {} |
190 | 180 | ||
191 | #endif /* ifdef CONFIG_ATH5K_DEBUG */ | 181 | #endif /* ifdef CONFIG_ATH5K_DEBUG */ |
diff --git a/drivers/net/wireless/ath/ath5k/dma.c b/drivers/net/wireless/ath/ath5k/dma.c index 0064be7ce5c9..21091c26a9a5 100644 --- a/drivers/net/wireless/ath/ath5k/dma.c +++ b/drivers/net/wireless/ath/ath5k/dma.c | |||
@@ -838,9 +838,9 @@ int ath5k_hw_dma_stop(struct ath5k_hw *ah) | |||
838 | for (i = 0; i < qmax; i++) { | 838 | for (i = 0; i < qmax; i++) { |
839 | err = ath5k_hw_stop_tx_dma(ah, i); | 839 | err = ath5k_hw_stop_tx_dma(ah, i); |
840 | /* -EINVAL -> queue inactive */ | 840 | /* -EINVAL -> queue inactive */ |
841 | if (err != -EINVAL) | 841 | if (err && err != -EINVAL) |
842 | return err; | 842 | return err; |
843 | } | 843 | } |
844 | 844 | ||
845 | return err; | 845 | return 0; |
846 | } | 846 | } |
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index d76d68c99f72..36a51995a7bc 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c | |||
@@ -226,6 +226,7 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed) | |||
226 | struct ath5k_hw *ah = sc->ah; | 226 | struct ath5k_hw *ah = sc->ah; |
227 | struct ieee80211_conf *conf = &hw->conf; | 227 | struct ieee80211_conf *conf = &hw->conf; |
228 | int ret = 0; | 228 | int ret = 0; |
229 | int i; | ||
229 | 230 | ||
230 | mutex_lock(&sc->lock); | 231 | mutex_lock(&sc->lock); |
231 | 232 | ||
@@ -243,6 +244,14 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed) | |||
243 | ath5k_hw_set_txpower_limit(ah, (conf->power_level * 2)); | 244 | ath5k_hw_set_txpower_limit(ah, (conf->power_level * 2)); |
244 | } | 245 | } |
245 | 246 | ||
247 | if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) { | ||
248 | ah->ah_retry_long = conf->long_frame_max_tx_count; | ||
249 | ah->ah_retry_short = conf->short_frame_max_tx_count; | ||
250 | |||
251 | for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) | ||
252 | ath5k_hw_set_tx_retry_limits(ah, i); | ||
253 | } | ||
254 | |||
246 | /* TODO: | 255 | /* TODO: |
247 | * 1) Move this on config_interface and handle each case | 256 | * 1) Move this on config_interface and handle each case |
248 | * separately eg. when we have only one STA vif, use | 257 | * separately eg. when we have only one STA vif, use |
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index e5f2b96a4c63..a702817daf72 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c | |||
@@ -86,7 +86,7 @@ int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, | |||
86 | if (!ah->ah_bwmode) { | 86 | if (!ah->ah_bwmode) { |
87 | dur = ieee80211_generic_frame_duration(sc->hw, | 87 | dur = ieee80211_generic_frame_duration(sc->hw, |
88 | NULL, len, rate); | 88 | NULL, len, rate); |
89 | return dur; | 89 | return le16_to_cpu(dur); |
90 | } | 90 | } |
91 | 91 | ||
92 | bitrate = rate->bitrate; | 92 | bitrate = rate->bitrate; |
@@ -265,8 +265,6 @@ static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah) | |||
265 | * what rate we should choose to TX ACKs. */ | 265 | * what rate we should choose to TX ACKs. */ |
266 | tx_time = ath5k_hw_get_frame_duration(ah, 10, rate); | 266 | tx_time = ath5k_hw_get_frame_duration(ah, 10, rate); |
267 | 267 | ||
268 | tx_time = le16_to_cpu(tx_time); | ||
269 | |||
270 | ath5k_hw_reg_write(ah, tx_time, reg); | 268 | ath5k_hw_reg_write(ah, tx_time, reg); |
271 | 269 | ||
272 | if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)) | 270 | if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)) |
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c index 2c9c9e793d4e..3343fb9e4940 100644 --- a/drivers/net/wireless/ath/ath5k/qcu.c +++ b/drivers/net/wireless/ath/ath5k/qcu.c | |||
@@ -228,24 +228,9 @@ int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type, | |||
228 | /* | 228 | /* |
229 | * Set tx retry limits on DCU | 229 | * Set tx retry limits on DCU |
230 | */ | 230 | */ |
231 | static void ath5k_hw_set_tx_retry_limits(struct ath5k_hw *ah, | 231 | void ath5k_hw_set_tx_retry_limits(struct ath5k_hw *ah, |
232 | unsigned int queue) | 232 | unsigned int queue) |
233 | { | 233 | { |
234 | u32 retry_lg, retry_sh; | ||
235 | |||
236 | /* | ||
237 | * Calculate and set retry limits | ||
238 | */ | ||
239 | if (ah->ah_software_retry) { | ||
240 | /* XXX Need to test this */ | ||
241 | retry_lg = ah->ah_limit_tx_retries; | ||
242 | retry_sh = retry_lg = retry_lg > AR5K_DCU_RETRY_LMT_SH_RETRY ? | ||
243 | AR5K_DCU_RETRY_LMT_SH_RETRY : retry_lg; | ||
244 | } else { | ||
245 | retry_lg = AR5K_INIT_LG_RETRY; | ||
246 | retry_sh = AR5K_INIT_SH_RETRY; | ||
247 | } | ||
248 | |||
249 | /* Single data queue on AR5210 */ | 234 | /* Single data queue on AR5210 */ |
250 | if (ah->ah_version == AR5K_AR5210) { | 235 | if (ah->ah_version == AR5K_AR5210) { |
251 | struct ath5k_txq_info *tq = &ah->ah_txq[queue]; | 236 | struct ath5k_txq_info *tq = &ah->ah_txq[queue]; |
@@ -255,25 +240,26 @@ static void ath5k_hw_set_tx_retry_limits(struct ath5k_hw *ah, | |||
255 | 240 | ||
256 | ath5k_hw_reg_write(ah, | 241 | ath5k_hw_reg_write(ah, |
257 | (tq->tqi_cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S) | 242 | (tq->tqi_cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S) |
258 | | AR5K_REG_SM(AR5K_INIT_SLG_RETRY, | 243 | | AR5K_REG_SM(ah->ah_retry_long, |
259 | AR5K_NODCU_RETRY_LMT_SLG_RETRY) | 244 | AR5K_NODCU_RETRY_LMT_SLG_RETRY) |
260 | | AR5K_REG_SM(AR5K_INIT_SSH_RETRY, | 245 | | AR5K_REG_SM(ah->ah_retry_short, |
261 | AR5K_NODCU_RETRY_LMT_SSH_RETRY) | 246 | AR5K_NODCU_RETRY_LMT_SSH_RETRY) |
262 | | AR5K_REG_SM(retry_lg, AR5K_NODCU_RETRY_LMT_LG_RETRY) | 247 | | AR5K_REG_SM(ah->ah_retry_long, |
263 | | AR5K_REG_SM(retry_sh, AR5K_NODCU_RETRY_LMT_SH_RETRY), | 248 | AR5K_NODCU_RETRY_LMT_LG_RETRY) |
249 | | AR5K_REG_SM(ah->ah_retry_short, | ||
250 | AR5K_NODCU_RETRY_LMT_SH_RETRY), | ||
264 | AR5K_NODCU_RETRY_LMT); | 251 | AR5K_NODCU_RETRY_LMT); |
265 | /* DCU on AR5211+ */ | 252 | /* DCU on AR5211+ */ |
266 | } else { | 253 | } else { |
267 | ath5k_hw_reg_write(ah, | 254 | ath5k_hw_reg_write(ah, |
268 | AR5K_REG_SM(AR5K_INIT_SLG_RETRY, | 255 | AR5K_REG_SM(ah->ah_retry_long, |
269 | AR5K_DCU_RETRY_LMT_SLG_RETRY) | | 256 | AR5K_DCU_RETRY_LMT_RTS) |
270 | AR5K_REG_SM(AR5K_INIT_SSH_RETRY, | 257 | | AR5K_REG_SM(ah->ah_retry_long, |
271 | AR5K_DCU_RETRY_LMT_SSH_RETRY) | | 258 | AR5K_DCU_RETRY_LMT_STA_RTS) |
272 | AR5K_REG_SM(retry_lg, AR5K_DCU_RETRY_LMT_LG_RETRY) | | 259 | | AR5K_REG_SM(max(ah->ah_retry_long, ah->ah_retry_short), |
273 | AR5K_REG_SM(retry_sh, AR5K_DCU_RETRY_LMT_SH_RETRY), | 260 | AR5K_DCU_RETRY_LMT_STA_DATA), |
274 | AR5K_QUEUE_DFS_RETRY_LIMIT(queue)); | 261 | AR5K_QUEUE_DFS_RETRY_LIMIT(queue)); |
275 | } | 262 | } |
276 | return; | ||
277 | } | 263 | } |
278 | 264 | ||
279 | /** | 265 | /** |
diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h index fd14b9103951..e1c9abd8c879 100644 --- a/drivers/net/wireless/ath/ath5k/reg.h +++ b/drivers/net/wireless/ath/ath5k/reg.h | |||
@@ -686,16 +686,15 @@ | |||
686 | 686 | ||
687 | /* | 687 | /* |
688 | * DCU retry limit registers | 688 | * DCU retry limit registers |
689 | * all these fields don't allow zero values | ||
689 | */ | 690 | */ |
690 | #define AR5K_DCU_RETRY_LMT_BASE 0x1080 /* Register Address -Queue0 DCU_RETRY_LMT */ | 691 | #define AR5K_DCU_RETRY_LMT_BASE 0x1080 /* Register Address -Queue0 DCU_RETRY_LMT */ |
691 | #define AR5K_DCU_RETRY_LMT_SH_RETRY 0x0000000f /* Short retry limit mask */ | 692 | #define AR5K_DCU_RETRY_LMT_RTS 0x0000000f /* RTS failure limit. Transmission fails if no CTS is received for this number of times */ |
692 | #define AR5K_DCU_RETRY_LMT_SH_RETRY_S 0 | 693 | #define AR5K_DCU_RETRY_LMT_RTS_S 0 |
693 | #define AR5K_DCU_RETRY_LMT_LG_RETRY 0x000000f0 /* Long retry limit mask */ | 694 | #define AR5K_DCU_RETRY_LMT_STA_RTS 0x00003f00 /* STA RTS failure limit. If exceeded CW reset */ |
694 | #define AR5K_DCU_RETRY_LMT_LG_RETRY_S 4 | 695 | #define AR5K_DCU_RETRY_LMT_STA_RTS_S 8 |
695 | #define AR5K_DCU_RETRY_LMT_SSH_RETRY 0x00003f00 /* Station short retry limit mask (?) */ | 696 | #define AR5K_DCU_RETRY_LMT_STA_DATA 0x000fc000 /* STA data failure limit. If exceeded CW reset. */ |
696 | #define AR5K_DCU_RETRY_LMT_SSH_RETRY_S 8 | 697 | #define AR5K_DCU_RETRY_LMT_STA_DATA_S 14 |
697 | #define AR5K_DCU_RETRY_LMT_SLG_RETRY 0x000fc000 /* Station long retry limit mask (?) */ | ||
698 | #define AR5K_DCU_RETRY_LMT_SLG_RETRY_S 14 | ||
699 | #define AR5K_QUEUE_DFS_RETRY_LIMIT(_q) AR5K_QUEUE_REG(AR5K_DCU_RETRY_LMT_BASE, _q) | 698 | #define AR5K_QUEUE_DFS_RETRY_LIMIT(_q) AR5K_QUEUE_REG(AR5K_DCU_RETRY_LMT_BASE, _q) |
700 | 699 | ||
701 | /* | 700 | /* |
diff --git a/drivers/net/wireless/ath/ath5k/trace.h b/drivers/net/wireless/ath/ath5k/trace.h new file mode 100644 index 000000000000..2de68adb6240 --- /dev/null +++ b/drivers/net/wireless/ath/ath5k/trace.h | |||
@@ -0,0 +1,107 @@ | |||
1 | #if !defined(__TRACE_ATH5K_H) || defined(TRACE_HEADER_MULTI_READ) | ||
2 | #define __TRACE_ATH5K_H | ||
3 | |||
4 | #include <linux/tracepoint.h> | ||
5 | #include "base.h" | ||
6 | |||
7 | #ifndef CONFIG_ATH5K_TRACER | ||
8 | #undef TRACE_EVENT | ||
9 | #define TRACE_EVENT(name, proto, ...) \ | ||
10 | static inline void trace_ ## name(proto) {} | ||
11 | #endif | ||
12 | |||
13 | struct sk_buff; | ||
14 | |||
15 | #define PRIV_ENTRY __field(struct ath5k_softc *, priv) | ||
16 | #define PRIV_ASSIGN __entry->priv = priv | ||
17 | |||
18 | #undef TRACE_SYSTEM | ||
19 | #define TRACE_SYSTEM ath5k | ||
20 | |||
21 | TRACE_EVENT(ath5k_rx, | ||
22 | TP_PROTO(struct ath5k_softc *priv, struct sk_buff *skb), | ||
23 | TP_ARGS(priv, skb), | ||
24 | TP_STRUCT__entry( | ||
25 | PRIV_ENTRY | ||
26 | __field(unsigned long, skbaddr) | ||
27 | __dynamic_array(u8, frame, skb->len) | ||
28 | ), | ||
29 | TP_fast_assign( | ||
30 | PRIV_ASSIGN; | ||
31 | __entry->skbaddr = (unsigned long) skb; | ||
32 | memcpy(__get_dynamic_array(frame), skb->data, skb->len); | ||
33 | ), | ||
34 | TP_printk( | ||
35 | "[%p] RX skb=%lx", __entry->priv, __entry->skbaddr | ||
36 | ) | ||
37 | ); | ||
38 | |||
39 | TRACE_EVENT(ath5k_tx, | ||
40 | TP_PROTO(struct ath5k_softc *priv, struct sk_buff *skb, | ||
41 | struct ath5k_txq *q), | ||
42 | |||
43 | TP_ARGS(priv, skb, q), | ||
44 | |||
45 | TP_STRUCT__entry( | ||
46 | PRIV_ENTRY | ||
47 | __field(unsigned long, skbaddr) | ||
48 | __field(u8, qnum) | ||
49 | __dynamic_array(u8, frame, skb->len) | ||
50 | ), | ||
51 | |||
52 | TP_fast_assign( | ||
53 | PRIV_ASSIGN; | ||
54 | __entry->skbaddr = (unsigned long) skb; | ||
55 | __entry->qnum = (u8) q->qnum; | ||
56 | memcpy(__get_dynamic_array(frame), skb->data, skb->len); | ||
57 | ), | ||
58 | |||
59 | TP_printk( | ||
60 | "[%p] TX skb=%lx q=%d", __entry->priv, __entry->skbaddr, | ||
61 | __entry->qnum | ||
62 | ) | ||
63 | ); | ||
64 | |||
65 | TRACE_EVENT(ath5k_tx_complete, | ||
66 | TP_PROTO(struct ath5k_softc *priv, struct sk_buff *skb, | ||
67 | struct ath5k_txq *q, struct ath5k_tx_status *ts), | ||
68 | |||
69 | TP_ARGS(priv, skb, q, ts), | ||
70 | |||
71 | TP_STRUCT__entry( | ||
72 | PRIV_ENTRY | ||
73 | __field(unsigned long, skbaddr) | ||
74 | __field(u8, qnum) | ||
75 | __field(u8, ts_status) | ||
76 | __field(s8, ts_rssi) | ||
77 | __field(u8, ts_antenna) | ||
78 | ), | ||
79 | |||
80 | TP_fast_assign( | ||
81 | PRIV_ASSIGN; | ||
82 | __entry->skbaddr = (unsigned long) skb; | ||
83 | __entry->qnum = (u8) q->qnum; | ||
84 | __entry->ts_status = ts->ts_status; | ||
85 | __entry->ts_rssi = ts->ts_rssi; | ||
86 | __entry->ts_antenna = ts->ts_antenna; | ||
87 | ), | ||
88 | |||
89 | TP_printk( | ||
90 | "[%p] TX end skb=%lx q=%d stat=%x rssi=%d ant=%x", | ||
91 | __entry->priv, __entry->skbaddr, __entry->qnum, | ||
92 | __entry->ts_status, __entry->ts_rssi, __entry->ts_antenna | ||
93 | ) | ||
94 | ); | ||
95 | |||
96 | #endif /* __TRACE_ATH5K_H */ | ||
97 | |||
98 | #ifdef CONFIG_ATH5K_TRACER | ||
99 | |||
100 | #undef TRACE_INCLUDE_PATH | ||
101 | #define TRACE_INCLUDE_PATH ../../drivers/net/wireless/ath/ath5k | ||
102 | #undef TRACE_INCLUDE_FILE | ||
103 | #define TRACE_INCLUDE_FILE trace | ||
104 | |||
105 | #include <trace/define_trace.h> | ||
106 | |||
107 | #endif | ||
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index aca01621c205..4d66ca8042eb 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile | |||
@@ -4,7 +4,6 @@ ath9k-y += beacon.o \ | |||
4 | main.o \ | 4 | main.o \ |
5 | recv.o \ | 5 | recv.o \ |
6 | xmit.o \ | 6 | xmit.o \ |
7 | virtual.o \ | ||
8 | 7 | ||
9 | ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o | 8 | ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o |
10 | ath9k-$(CONFIG_PCI) += pci.o | 9 | ath9k-$(CONFIG_PCI) += pci.o |
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c index 25a6e4417cdb..993672105963 100644 --- a/drivers/net/wireless/ath/ath9k/ahb.c +++ b/drivers/net/wireless/ath/ath9k/ahb.c | |||
@@ -54,7 +54,6 @@ static struct ath_bus_ops ath_ahb_bus_ops = { | |||
54 | static int ath_ahb_probe(struct platform_device *pdev) | 54 | static int ath_ahb_probe(struct platform_device *pdev) |
55 | { | 55 | { |
56 | void __iomem *mem; | 56 | void __iomem *mem; |
57 | struct ath_wiphy *aphy; | ||
58 | struct ath_softc *sc; | 57 | struct ath_softc *sc; |
59 | struct ieee80211_hw *hw; | 58 | struct ieee80211_hw *hw; |
60 | struct resource *res; | 59 | struct resource *res; |
@@ -92,8 +91,7 @@ static int ath_ahb_probe(struct platform_device *pdev) | |||
92 | 91 | ||
93 | irq = res->start; | 92 | irq = res->start; |
94 | 93 | ||
95 | hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy) + | 94 | hw = ieee80211_alloc_hw(sizeof(struct ath_softc), &ath9k_ops); |
96 | sizeof(struct ath_softc), &ath9k_ops); | ||
97 | if (hw == NULL) { | 95 | if (hw == NULL) { |
98 | dev_err(&pdev->dev, "no memory for ieee80211_hw\n"); | 96 | dev_err(&pdev->dev, "no memory for ieee80211_hw\n"); |
99 | ret = -ENOMEM; | 97 | ret = -ENOMEM; |
@@ -103,11 +101,7 @@ static int ath_ahb_probe(struct platform_device *pdev) | |||
103 | SET_IEEE80211_DEV(hw, &pdev->dev); | 101 | SET_IEEE80211_DEV(hw, &pdev->dev); |
104 | platform_set_drvdata(pdev, hw); | 102 | platform_set_drvdata(pdev, hw); |
105 | 103 | ||
106 | aphy = hw->priv; | 104 | sc = hw->priv; |
107 | sc = (struct ath_softc *) (aphy + 1); | ||
108 | aphy->sc = sc; | ||
109 | aphy->hw = hw; | ||
110 | sc->pri_wiphy = aphy; | ||
111 | sc->hw = hw; | 105 | sc->hw = hw; |
112 | sc->dev = &pdev->dev; | 106 | sc->dev = &pdev->dev; |
113 | sc->mem = mem; | 107 | sc->mem = mem; |
@@ -151,8 +145,7 @@ static int ath_ahb_remove(struct platform_device *pdev) | |||
151 | struct ieee80211_hw *hw = platform_get_drvdata(pdev); | 145 | struct ieee80211_hw *hw = platform_get_drvdata(pdev); |
152 | 146 | ||
153 | if (hw) { | 147 | if (hw) { |
154 | struct ath_wiphy *aphy = hw->priv; | 148 | struct ath_softc *sc = hw->priv; |
155 | struct ath_softc *sc = aphy->sc; | ||
156 | void __iomem *mem = sc->mem; | 149 | void __iomem *mem = sc->mem; |
157 | 150 | ||
158 | ath9k_deinit_device(sc); | 151 | ath9k_deinit_device(sc); |
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c index f8a7771faee2..f44c84ab5dce 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c | |||
@@ -426,9 +426,8 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah, | |||
426 | } | 426 | } |
427 | 427 | ||
428 | /* WAR for ASPM system hang */ | 428 | /* WAR for ASPM system hang */ |
429 | if (AR_SREV_9280(ah) || AR_SREV_9285(ah) || AR_SREV_9287(ah)) { | 429 | if (AR_SREV_9285(ah) || AR_SREV_9287(ah)) |
430 | val |= (AR_WA_BIT6 | AR_WA_BIT7); | 430 | val |= (AR_WA_BIT6 | AR_WA_BIT7); |
431 | } | ||
432 | 431 | ||
433 | if (AR_SREV_9285E_20(ah)) | 432 | if (AR_SREV_9285E_20(ah)) |
434 | val |= AR_WA_BIT23; | 433 | val |= AR_WA_BIT23; |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index a25655640f48..4a9271802991 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | |||
@@ -3673,7 +3673,7 @@ static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah) | |||
3673 | return; | 3673 | return; |
3674 | 3674 | ||
3675 | reg_pmu_set = (5 << 1) | (7 << 4) | (1 << 8) | | 3675 | reg_pmu_set = (5 << 1) | (7 << 4) | (1 << 8) | |
3676 | (7 << 14) | (6 << 17) | (1 << 20) | | 3676 | (2 << 14) | (6 << 17) | (1 << 20) | |
3677 | (3 << 24) | (1 << 28); | 3677 | (3 << 24) | (1 << 28); |
3678 | 3678 | ||
3679 | REG_WRITE(ah, AR_PHY_PMU1, reg_pmu_set); | 3679 | REG_WRITE(ah, AR_PHY_PMU1, reg_pmu_set); |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 6636f3c6dcf9..bd85e311c51b 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -233,7 +233,6 @@ struct ath_buf { | |||
233 | bool bf_stale; | 233 | bool bf_stale; |
234 | u16 bf_flags; | 234 | u16 bf_flags; |
235 | struct ath_buf_state bf_state; | 235 | struct ath_buf_state bf_state; |
236 | struct ath_wiphy *aphy; | ||
237 | }; | 236 | }; |
238 | 237 | ||
239 | struct ath_atx_tid { | 238 | struct ath_atx_tid { |
@@ -311,6 +310,8 @@ struct ath_rx { | |||
311 | struct ath_descdma rxdma; | 310 | struct ath_descdma rxdma; |
312 | struct ath_buf *rx_bufptr; | 311 | struct ath_buf *rx_bufptr; |
313 | struct ath_rx_edma rx_edma[ATH9K_RX_QUEUE_MAX]; | 312 | struct ath_rx_edma rx_edma[ATH9K_RX_QUEUE_MAX]; |
313 | |||
314 | struct sk_buff *frag; | ||
314 | }; | 315 | }; |
315 | 316 | ||
316 | int ath_startrecv(struct ath_softc *sc); | 317 | int ath_startrecv(struct ath_softc *sc); |
@@ -388,7 +389,6 @@ struct ath_beacon { | |||
388 | u32 ast_be_xmit; | 389 | u32 ast_be_xmit; |
389 | u64 bc_tstamp; | 390 | u64 bc_tstamp; |
390 | struct ieee80211_vif *bslot[ATH_BCBUF]; | 391 | struct ieee80211_vif *bslot[ATH_BCBUF]; |
391 | struct ath_wiphy *bslot_aphy[ATH_BCBUF]; | ||
392 | int slottime; | 392 | int slottime; |
393 | int slotupdate; | 393 | int slotupdate; |
394 | struct ath9k_tx_queue_info beacon_qi; | 394 | struct ath9k_tx_queue_info beacon_qi; |
@@ -399,7 +399,7 @@ struct ath_beacon { | |||
399 | 399 | ||
400 | void ath_beacon_tasklet(unsigned long data); | 400 | void ath_beacon_tasklet(unsigned long data); |
401 | void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif); | 401 | void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif); |
402 | int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif); | 402 | int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif); |
403 | void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp); | 403 | void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp); |
404 | int ath_beaconq_config(struct ath_softc *sc); | 404 | int ath_beaconq_config(struct ath_softc *sc); |
405 | 405 | ||
@@ -536,7 +536,6 @@ struct ath_ant_comb { | |||
536 | #define ATH_CABQ_READY_TIME 80 /* % of beacon interval */ | 536 | #define ATH_CABQ_READY_TIME 80 /* % of beacon interval */ |
537 | #define ATH_MAX_SW_RETRIES 10 | 537 | #define ATH_MAX_SW_RETRIES 10 |
538 | #define ATH_CHAN_MAX 255 | 538 | #define ATH_CHAN_MAX 255 |
539 | #define IEEE80211_WEP_NKID 4 /* number of key ids */ | ||
540 | 539 | ||
541 | #define ATH_TXPOWER_MAX 100 /* .5 dBm units */ | 540 | #define ATH_TXPOWER_MAX 100 /* .5 dBm units */ |
542 | #define ATH_RATE_DUMMY_MARKER 0 | 541 | #define ATH_RATE_DUMMY_MARKER 0 |
@@ -564,7 +563,6 @@ struct ath_ant_comb { | |||
564 | #define PS_WAIT_FOR_TX_ACK BIT(3) | 563 | #define PS_WAIT_FOR_TX_ACK BIT(3) |
565 | #define PS_BEACON_SYNC BIT(4) | 564 | #define PS_BEACON_SYNC BIT(4) |
566 | 565 | ||
567 | struct ath_wiphy; | ||
568 | struct ath_rate_table; | 566 | struct ath_rate_table; |
569 | 567 | ||
570 | struct ath9k_vif_iter_data { | 568 | struct ath9k_vif_iter_data { |
@@ -585,20 +583,8 @@ struct ath_softc { | |||
585 | struct ieee80211_hw *hw; | 583 | struct ieee80211_hw *hw; |
586 | struct device *dev; | 584 | struct device *dev; |
587 | 585 | ||
588 | spinlock_t wiphy_lock; /* spinlock to protect ath_wiphy data */ | ||
589 | struct ath_wiphy *pri_wiphy; | ||
590 | struct ath_wiphy **sec_wiphy; /* secondary wiphys (virtual radios); may | ||
591 | * have NULL entries */ | ||
592 | int num_sec_wiphy; /* number of sec_wiphy pointers in the array */ | ||
593 | int chan_idx; | 586 | int chan_idx; |
594 | int chan_is_ht; | 587 | int chan_is_ht; |
595 | struct ath_wiphy *next_wiphy; | ||
596 | struct work_struct chan_work; | ||
597 | int wiphy_select_failures; | ||
598 | unsigned long wiphy_select_first_fail; | ||
599 | struct delayed_work wiphy_work; | ||
600 | unsigned long wiphy_scheduler_int; | ||
601 | int wiphy_scheduler_index; | ||
602 | struct survey_info *cur_survey; | 588 | struct survey_info *cur_survey; |
603 | struct survey_info survey[ATH9K_NUM_CHANNELS]; | 589 | struct survey_info survey[ATH9K_NUM_CHANNELS]; |
604 | 590 | ||
@@ -642,6 +628,9 @@ struct ath_softc { | |||
642 | int led_on_cnt; | 628 | int led_on_cnt; |
643 | int led_off_cnt; | 629 | int led_off_cnt; |
644 | 630 | ||
631 | struct ath9k_hw_cal_data caldata; | ||
632 | int last_rssi; | ||
633 | |||
645 | int beacon_interval; | 634 | int beacon_interval; |
646 | 635 | ||
647 | #ifdef CONFIG_ATH9K_DEBUGFS | 636 | #ifdef CONFIG_ATH9K_DEBUGFS |
@@ -652,6 +641,7 @@ struct ath_softc { | |||
652 | #endif | 641 | #endif |
653 | struct ath_beacon_config cur_beacon_conf; | 642 | struct ath_beacon_config cur_beacon_conf; |
654 | struct delayed_work tx_complete_work; | 643 | struct delayed_work tx_complete_work; |
644 | struct delayed_work hw_pll_work; | ||
655 | struct ath_btcoex btcoex; | 645 | struct ath_btcoex btcoex; |
656 | 646 | ||
657 | struct ath_descdma txsdma; | 647 | struct ath_descdma txsdma; |
@@ -661,23 +651,6 @@ struct ath_softc { | |||
661 | struct pm_qos_request_list pm_qos_req; | 651 | struct pm_qos_request_list pm_qos_req; |
662 | }; | 652 | }; |
663 | 653 | ||
664 | struct ath_wiphy { | ||
665 | struct ath_softc *sc; /* shared for all virtual wiphys */ | ||
666 | struct ieee80211_hw *hw; | ||
667 | struct ath9k_hw_cal_data caldata; | ||
668 | enum ath_wiphy_state { | ||
669 | ATH_WIPHY_INACTIVE, | ||
670 | ATH_WIPHY_ACTIVE, | ||
671 | ATH_WIPHY_PAUSING, | ||
672 | ATH_WIPHY_PAUSED, | ||
673 | ATH_WIPHY_SCAN, | ||
674 | } state; | ||
675 | bool idle; | ||
676 | int chan_idx; | ||
677 | int chan_is_ht; | ||
678 | int last_rssi; | ||
679 | }; | ||
680 | |||
681 | void ath9k_tasklet(unsigned long data); | 654 | void ath9k_tasklet(unsigned long data); |
682 | int ath_reset(struct ath_softc *sc, bool retry_tx); | 655 | int ath_reset(struct ath_softc *sc, bool retry_tx); |
683 | int ath_cabq_update(struct ath_softc *); | 656 | int ath_cabq_update(struct ath_softc *); |
@@ -699,8 +672,6 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, | |||
699 | const struct ath_bus_ops *bus_ops); | 672 | const struct ath_bus_ops *bus_ops); |
700 | void ath9k_deinit_device(struct ath_softc *sc); | 673 | void ath9k_deinit_device(struct ath_softc *sc); |
701 | void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw); | 674 | void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw); |
702 | void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw, | ||
703 | struct ath9k_channel *ichan); | ||
704 | int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | 675 | int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, |
705 | struct ath9k_channel *hchan); | 676 | struct ath9k_channel *hchan); |
706 | 677 | ||
@@ -731,24 +702,6 @@ void ath9k_ps_restore(struct ath_softc *sc); | |||
731 | u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate); | 702 | u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate); |
732 | 703 | ||
733 | void ath9k_set_bssid_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif); | 704 | void ath9k_set_bssid_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif); |
734 | int ath9k_wiphy_add(struct ath_softc *sc); | ||
735 | int ath9k_wiphy_del(struct ath_wiphy *aphy); | ||
736 | void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, int ftype); | ||
737 | int ath9k_wiphy_pause(struct ath_wiphy *aphy); | ||
738 | int ath9k_wiphy_unpause(struct ath_wiphy *aphy); | ||
739 | int ath9k_wiphy_select(struct ath_wiphy *aphy); | ||
740 | void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int); | ||
741 | void ath9k_wiphy_chan_work(struct work_struct *work); | ||
742 | bool ath9k_wiphy_started(struct ath_softc *sc); | ||
743 | void ath9k_wiphy_pause_all_forced(struct ath_softc *sc, | ||
744 | struct ath_wiphy *selected); | ||
745 | bool ath9k_wiphy_scanning(struct ath_softc *sc); | ||
746 | void ath9k_wiphy_work(struct work_struct *work); | ||
747 | bool ath9k_all_wiphys_idle(struct ath_softc *sc); | ||
748 | void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle); | ||
749 | |||
750 | void ath_mac80211_stop_queue(struct ath_softc *sc, u16 skb_queue); | ||
751 | bool ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue); | ||
752 | 705 | ||
753 | void ath_start_rfkill_poll(struct ath_softc *sc); | 706 | void ath_start_rfkill_poll(struct ath_softc *sc); |
754 | extern void ath9k_rfkill_poll_state(struct ieee80211_hw *hw); | 707 | extern void ath9k_rfkill_poll_state(struct ieee80211_hw *hw); |
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index ab8c05cf62f3..87ba44c06692 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c | |||
@@ -112,8 +112,7 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, | |||
112 | 112 | ||
113 | static void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) | 113 | static void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) |
114 | { | 114 | { |
115 | struct ath_wiphy *aphy = hw->priv; | 115 | struct ath_softc *sc = hw->priv; |
116 | struct ath_softc *sc = aphy->sc; | ||
117 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 116 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
118 | struct ath_tx_control txctl; | 117 | struct ath_tx_control txctl; |
119 | 118 | ||
@@ -132,8 +131,7 @@ static void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
132 | static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, | 131 | static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, |
133 | struct ieee80211_vif *vif) | 132 | struct ieee80211_vif *vif) |
134 | { | 133 | { |
135 | struct ath_wiphy *aphy = hw->priv; | 134 | struct ath_softc *sc = hw->priv; |
136 | struct ath_softc *sc = aphy->sc; | ||
137 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 135 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
138 | struct ath_buf *bf; | 136 | struct ath_buf *bf; |
139 | struct ath_vif *avp; | 137 | struct ath_vif *avp; |
@@ -142,9 +140,6 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, | |||
142 | struct ieee80211_tx_info *info; | 140 | struct ieee80211_tx_info *info; |
143 | int cabq_depth; | 141 | int cabq_depth; |
144 | 142 | ||
145 | if (aphy->state != ATH_WIPHY_ACTIVE) | ||
146 | return NULL; | ||
147 | |||
148 | avp = (void *)vif->drv_priv; | 143 | avp = (void *)vif->drv_priv; |
149 | cabq = sc->beacon.cabq; | 144 | cabq = sc->beacon.cabq; |
150 | 145 | ||
@@ -225,9 +220,8 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, | |||
225 | return bf; | 220 | return bf; |
226 | } | 221 | } |
227 | 222 | ||
228 | int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif) | 223 | int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif) |
229 | { | 224 | { |
230 | struct ath_softc *sc = aphy->sc; | ||
231 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 225 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
232 | struct ath_vif *avp; | 226 | struct ath_vif *avp; |
233 | struct ath_buf *bf; | 227 | struct ath_buf *bf; |
@@ -261,7 +255,6 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif) | |||
261 | } | 255 | } |
262 | BUG_ON(sc->beacon.bslot[avp->av_bslot] != NULL); | 256 | BUG_ON(sc->beacon.bslot[avp->av_bslot] != NULL); |
263 | sc->beacon.bslot[avp->av_bslot] = vif; | 257 | sc->beacon.bslot[avp->av_bslot] = vif; |
264 | sc->beacon.bslot_aphy[avp->av_bslot] = aphy; | ||
265 | sc->nbcnvifs++; | 258 | sc->nbcnvifs++; |
266 | } | 259 | } |
267 | } | 260 | } |
@@ -332,7 +325,6 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp) | |||
332 | 325 | ||
333 | if (avp->av_bslot != -1) { | 326 | if (avp->av_bslot != -1) { |
334 | sc->beacon.bslot[avp->av_bslot] = NULL; | 327 | sc->beacon.bslot[avp->av_bslot] = NULL; |
335 | sc->beacon.bslot_aphy[avp->av_bslot] = NULL; | ||
336 | sc->nbcnvifs--; | 328 | sc->nbcnvifs--; |
337 | } | 329 | } |
338 | 330 | ||
@@ -358,7 +350,6 @@ void ath_beacon_tasklet(unsigned long data) | |||
358 | struct ath_common *common = ath9k_hw_common(ah); | 350 | struct ath_common *common = ath9k_hw_common(ah); |
359 | struct ath_buf *bf = NULL; | 351 | struct ath_buf *bf = NULL; |
360 | struct ieee80211_vif *vif; | 352 | struct ieee80211_vif *vif; |
361 | struct ath_wiphy *aphy; | ||
362 | int slot; | 353 | int slot; |
363 | u32 bfaddr, bc = 0, tsftu; | 354 | u32 bfaddr, bc = 0, tsftu; |
364 | u64 tsf; | 355 | u64 tsf; |
@@ -416,7 +407,6 @@ void ath_beacon_tasklet(unsigned long data) | |||
416 | */ | 407 | */ |
417 | slot = ATH_BCBUF - slot - 1; | 408 | slot = ATH_BCBUF - slot - 1; |
418 | vif = sc->beacon.bslot[slot]; | 409 | vif = sc->beacon.bslot[slot]; |
419 | aphy = sc->beacon.bslot_aphy[slot]; | ||
420 | 410 | ||
421 | ath_dbg(common, ATH_DBG_BEACON, | 411 | ath_dbg(common, ATH_DBG_BEACON, |
422 | "slot %d [tsf %llu tsftu %u intval %u] vif %p\n", | 412 | "slot %d [tsf %llu tsftu %u intval %u] vif %p\n", |
@@ -424,7 +414,7 @@ void ath_beacon_tasklet(unsigned long data) | |||
424 | 414 | ||
425 | bfaddr = 0; | 415 | bfaddr = 0; |
426 | if (vif) { | 416 | if (vif) { |
427 | bf = ath_beacon_generate(aphy->hw, vif); | 417 | bf = ath_beacon_generate(sc->hw, vif); |
428 | if (bf != NULL) { | 418 | if (bf != NULL) { |
429 | bfaddr = bf->bf_daddr; | 419 | bfaddr = bf->bf_daddr; |
430 | bc = 1; | 420 | bc = 1; |
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h index a126bddebb0a..4c7020b3a5a0 100644 --- a/drivers/net/wireless/ath/ath9k/common.h +++ b/drivers/net/wireless/ath/ath9k/common.h | |||
@@ -23,8 +23,6 @@ | |||
23 | 23 | ||
24 | /* Common header for Atheros 802.11n base driver cores */ | 24 | /* Common header for Atheros 802.11n base driver cores */ |
25 | 25 | ||
26 | #define IEEE80211_WEP_NKID 4 | ||
27 | |||
28 | #define WME_NUM_TID 16 | 26 | #define WME_NUM_TID 16 |
29 | #define WME_BA_BMP_SIZE 64 | 27 | #define WME_BA_BMP_SIZE 64 |
30 | #define WME_MAX_BA WME_BA_BMP_SIZE | 28 | #define WME_MAX_BA WME_BA_BMP_SIZE |
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index f0c80ec290d1..9cdc41b0ec44 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -381,41 +381,21 @@ static const struct file_operations fops_interrupt = { | |||
381 | .llseek = default_llseek, | 381 | .llseek = default_llseek, |
382 | }; | 382 | }; |
383 | 383 | ||
384 | static const char * ath_wiphy_state_str(enum ath_wiphy_state state) | ||
385 | { | ||
386 | switch (state) { | ||
387 | case ATH_WIPHY_INACTIVE: | ||
388 | return "INACTIVE"; | ||
389 | case ATH_WIPHY_ACTIVE: | ||
390 | return "ACTIVE"; | ||
391 | case ATH_WIPHY_PAUSING: | ||
392 | return "PAUSING"; | ||
393 | case ATH_WIPHY_PAUSED: | ||
394 | return "PAUSED"; | ||
395 | case ATH_WIPHY_SCAN: | ||
396 | return "SCAN"; | ||
397 | } | ||
398 | return "?"; | ||
399 | } | ||
400 | |||
401 | static ssize_t read_file_wiphy(struct file *file, char __user *user_buf, | 384 | static ssize_t read_file_wiphy(struct file *file, char __user *user_buf, |
402 | size_t count, loff_t *ppos) | 385 | size_t count, loff_t *ppos) |
403 | { | 386 | { |
404 | struct ath_softc *sc = file->private_data; | 387 | struct ath_softc *sc = file->private_data; |
405 | struct ath_wiphy *aphy = sc->pri_wiphy; | 388 | struct ieee80211_channel *chan = sc->hw->conf.channel; |
406 | struct ieee80211_channel *chan = aphy->hw->conf.channel; | ||
407 | char buf[512]; | 389 | char buf[512]; |
408 | unsigned int len = 0; | 390 | unsigned int len = 0; |
409 | int i; | ||
410 | u8 addr[ETH_ALEN]; | 391 | u8 addr[ETH_ALEN]; |
411 | u32 tmp; | 392 | u32 tmp; |
412 | 393 | ||
413 | len += snprintf(buf + len, sizeof(buf) - len, | 394 | len += snprintf(buf + len, sizeof(buf) - len, |
414 | "primary: %s (%s chan=%d ht=%d)\n", | 395 | "%s (chan=%d ht=%d)\n", |
415 | wiphy_name(sc->pri_wiphy->hw->wiphy), | 396 | wiphy_name(sc->hw->wiphy), |
416 | ath_wiphy_state_str(sc->pri_wiphy->state), | ||
417 | ieee80211_frequency_to_channel(chan->center_freq), | 397 | ieee80211_frequency_to_channel(chan->center_freq), |
418 | aphy->chan_is_ht); | 398 | conf_is_ht(&sc->hw->conf)); |
419 | 399 | ||
420 | put_unaligned_le32(REG_READ_D(sc->sc_ah, AR_STA_ID0), addr); | 400 | put_unaligned_le32(REG_READ_D(sc->sc_ah, AR_STA_ID0), addr); |
421 | put_unaligned_le16(REG_READ_D(sc->sc_ah, AR_STA_ID1) & 0xffff, addr + 4); | 401 | put_unaligned_le16(REG_READ_D(sc->sc_ah, AR_STA_ID1) & 0xffff, addr + 4); |
@@ -457,136 +437,28 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf, | |||
457 | else | 437 | else |
458 | len += snprintf(buf + len, sizeof(buf) - len, "\n"); | 438 | len += snprintf(buf + len, sizeof(buf) - len, "\n"); |
459 | 439 | ||
460 | /* Put variable-length stuff down here, and check for overflows. */ | ||
461 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
462 | struct ath_wiphy *aphy_tmp = sc->sec_wiphy[i]; | ||
463 | if (aphy_tmp == NULL) | ||
464 | continue; | ||
465 | chan = aphy_tmp->hw->conf.channel; | ||
466 | len += snprintf(buf + len, sizeof(buf) - len, | ||
467 | "secondary: %s (%s chan=%d ht=%d)\n", | ||
468 | wiphy_name(aphy_tmp->hw->wiphy), | ||
469 | ath_wiphy_state_str(aphy_tmp->state), | ||
470 | ieee80211_frequency_to_channel(chan->center_freq), | ||
471 | aphy_tmp->chan_is_ht); | ||
472 | } | ||
473 | if (len > sizeof(buf)) | 440 | if (len > sizeof(buf)) |
474 | len = sizeof(buf); | 441 | len = sizeof(buf); |
475 | 442 | ||
476 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | 443 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); |
477 | } | 444 | } |
478 | 445 | ||
479 | static struct ath_wiphy * get_wiphy(struct ath_softc *sc, const char *name) | ||
480 | { | ||
481 | int i; | ||
482 | if (strcmp(name, wiphy_name(sc->pri_wiphy->hw->wiphy)) == 0) | ||
483 | return sc->pri_wiphy; | ||
484 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
485 | struct ath_wiphy *aphy = sc->sec_wiphy[i]; | ||
486 | if (aphy && strcmp(name, wiphy_name(aphy->hw->wiphy)) == 0) | ||
487 | return aphy; | ||
488 | } | ||
489 | return NULL; | ||
490 | } | ||
491 | |||
492 | static int del_wiphy(struct ath_softc *sc, const char *name) | ||
493 | { | ||
494 | struct ath_wiphy *aphy = get_wiphy(sc, name); | ||
495 | if (!aphy) | ||
496 | return -ENOENT; | ||
497 | return ath9k_wiphy_del(aphy); | ||
498 | } | ||
499 | |||
500 | static int pause_wiphy(struct ath_softc *sc, const char *name) | ||
501 | { | ||
502 | struct ath_wiphy *aphy = get_wiphy(sc, name); | ||
503 | if (!aphy) | ||
504 | return -ENOENT; | ||
505 | return ath9k_wiphy_pause(aphy); | ||
506 | } | ||
507 | |||
508 | static int unpause_wiphy(struct ath_softc *sc, const char *name) | ||
509 | { | ||
510 | struct ath_wiphy *aphy = get_wiphy(sc, name); | ||
511 | if (!aphy) | ||
512 | return -ENOENT; | ||
513 | return ath9k_wiphy_unpause(aphy); | ||
514 | } | ||
515 | |||
516 | static int select_wiphy(struct ath_softc *sc, const char *name) | ||
517 | { | ||
518 | struct ath_wiphy *aphy = get_wiphy(sc, name); | ||
519 | if (!aphy) | ||
520 | return -ENOENT; | ||
521 | return ath9k_wiphy_select(aphy); | ||
522 | } | ||
523 | |||
524 | static int schedule_wiphy(struct ath_softc *sc, const char *msec) | ||
525 | { | ||
526 | ath9k_wiphy_set_scheduler(sc, simple_strtoul(msec, NULL, 0)); | ||
527 | return 0; | ||
528 | } | ||
529 | |||
530 | static ssize_t write_file_wiphy(struct file *file, const char __user *user_buf, | ||
531 | size_t count, loff_t *ppos) | ||
532 | { | ||
533 | struct ath_softc *sc = file->private_data; | ||
534 | char buf[50]; | ||
535 | size_t len; | ||
536 | |||
537 | len = min(count, sizeof(buf) - 1); | ||
538 | if (copy_from_user(buf, user_buf, len)) | ||
539 | return -EFAULT; | ||
540 | buf[len] = '\0'; | ||
541 | if (len > 0 && buf[len - 1] == '\n') | ||
542 | buf[len - 1] = '\0'; | ||
543 | |||
544 | if (strncmp(buf, "add", 3) == 0) { | ||
545 | int res = ath9k_wiphy_add(sc); | ||
546 | if (res < 0) | ||
547 | return res; | ||
548 | } else if (strncmp(buf, "del=", 4) == 0) { | ||
549 | int res = del_wiphy(sc, buf + 4); | ||
550 | if (res < 0) | ||
551 | return res; | ||
552 | } else if (strncmp(buf, "pause=", 6) == 0) { | ||
553 | int res = pause_wiphy(sc, buf + 6); | ||
554 | if (res < 0) | ||
555 | return res; | ||
556 | } else if (strncmp(buf, "unpause=", 8) == 0) { | ||
557 | int res = unpause_wiphy(sc, buf + 8); | ||
558 | if (res < 0) | ||
559 | return res; | ||
560 | } else if (strncmp(buf, "select=", 7) == 0) { | ||
561 | int res = select_wiphy(sc, buf + 7); | ||
562 | if (res < 0) | ||
563 | return res; | ||
564 | } else if (strncmp(buf, "schedule=", 9) == 0) { | ||
565 | int res = schedule_wiphy(sc, buf + 9); | ||
566 | if (res < 0) | ||
567 | return res; | ||
568 | } else | ||
569 | return -EOPNOTSUPP; | ||
570 | |||
571 | return count; | ||
572 | } | ||
573 | |||
574 | static const struct file_operations fops_wiphy = { | 446 | static const struct file_operations fops_wiphy = { |
575 | .read = read_file_wiphy, | 447 | .read = read_file_wiphy, |
576 | .write = write_file_wiphy, | ||
577 | .open = ath9k_debugfs_open, | 448 | .open = ath9k_debugfs_open, |
578 | .owner = THIS_MODULE, | 449 | .owner = THIS_MODULE, |
579 | .llseek = default_llseek, | 450 | .llseek = default_llseek, |
580 | }; | 451 | }; |
581 | 452 | ||
453 | #define PR_QNUM(_n) sc->tx.txq_map[_n]->axq_qnum | ||
582 | #define PR(str, elem) \ | 454 | #define PR(str, elem) \ |
583 | do { \ | 455 | do { \ |
584 | len += snprintf(buf + len, size - len, \ | 456 | len += snprintf(buf + len, size - len, \ |
585 | "%s%13u%11u%10u%10u\n", str, \ | 457 | "%s%13u%11u%10u%10u\n", str, \ |
586 | sc->debug.stats.txstats[WME_AC_BE].elem, \ | 458 | sc->debug.stats.txstats[PR_QNUM(WME_AC_BE)].elem, \ |
587 | sc->debug.stats.txstats[WME_AC_BK].elem, \ | 459 | sc->debug.stats.txstats[PR_QNUM(WME_AC_BK)].elem, \ |
588 | sc->debug.stats.txstats[WME_AC_VI].elem, \ | 460 | sc->debug.stats.txstats[PR_QNUM(WME_AC_VI)].elem, \ |
589 | sc->debug.stats.txstats[WME_AC_VO].elem); \ | 461 | sc->debug.stats.txstats[PR_QNUM(WME_AC_VO)].elem); \ |
590 | if (len >= size) \ | 462 | if (len >= size) \ |
591 | goto done; \ | 463 | goto done; \ |
592 | } while(0) | 464 | } while(0) |
@@ -595,10 +467,10 @@ static const struct file_operations fops_wiphy = { | |||
595 | do { \ | 467 | do { \ |
596 | len += snprintf(buf + len, size - len, \ | 468 | len += snprintf(buf + len, size - len, \ |
597 | "%s%13u%11u%10u%10u\n", str, \ | 469 | "%s%13u%11u%10u%10u\n", str, \ |
598 | (unsigned int)(sc->tx.txq[ATH_TXQ_AC_BE].elem), \ | 470 | (unsigned int)(sc->tx.txq_map[WME_AC_BE]->elem), \ |
599 | (unsigned int)(sc->tx.txq[ATH_TXQ_AC_BK].elem), \ | 471 | (unsigned int)(sc->tx.txq_map[WME_AC_BK]->elem), \ |
600 | (unsigned int)(sc->tx.txq[ATH_TXQ_AC_VI].elem), \ | 472 | (unsigned int)(sc->tx.txq_map[WME_AC_VI]->elem), \ |
601 | (unsigned int)(sc->tx.txq[ATH_TXQ_AC_VO].elem)); \ | 473 | (unsigned int)(sc->tx.txq_map[WME_AC_VO]->elem)); \ |
602 | if (len >= size) \ | 474 | if (len >= size) \ |
603 | goto done; \ | 475 | goto done; \ |
604 | } while(0) | 476 | } while(0) |
@@ -607,10 +479,10 @@ do { \ | |||
607 | do { \ | 479 | do { \ |
608 | len += snprintf(buf + len, size - len, \ | 480 | len += snprintf(buf + len, size - len, \ |
609 | "%s%13i%11i%10i%10i\n", str, \ | 481 | "%s%13i%11i%10i%10i\n", str, \ |
610 | list_empty(&sc->tx.txq[ATH_TXQ_AC_BE].elem), \ | 482 | list_empty(&sc->tx.txq_map[WME_AC_BE]->elem), \ |
611 | list_empty(&sc->tx.txq[ATH_TXQ_AC_BK].elem), \ | 483 | list_empty(&sc->tx.txq_map[WME_AC_BK]->elem), \ |
612 | list_empty(&sc->tx.txq[ATH_TXQ_AC_VI].elem), \ | 484 | list_empty(&sc->tx.txq_map[WME_AC_VI]->elem), \ |
613 | list_empty(&sc->tx.txq[ATH_TXQ_AC_VO].elem)); \ | 485 | list_empty(&sc->tx.txq_map[WME_AC_VO]->elem)); \ |
614 | if (len >= size) \ | 486 | if (len >= size) \ |
615 | goto done; \ | 487 | goto done; \ |
616 | } while (0) | 488 | } while (0) |
@@ -657,10 +529,10 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, | |||
657 | PR("hw-tx-proc-desc: ", txprocdesc); | 529 | PR("hw-tx-proc-desc: ", txprocdesc); |
658 | len += snprintf(buf + len, size - len, | 530 | len += snprintf(buf + len, size - len, |
659 | "%s%11p%11p%10p%10p\n", "txq-memory-address:", | 531 | "%s%11p%11p%10p%10p\n", "txq-memory-address:", |
660 | &(sc->tx.txq[ATH_TXQ_AC_BE]), | 532 | &(sc->tx.txq_map[WME_AC_BE]), |
661 | &(sc->tx.txq[ATH_TXQ_AC_BK]), | 533 | &(sc->tx.txq_map[WME_AC_BK]), |
662 | &(sc->tx.txq[ATH_TXQ_AC_VI]), | 534 | &(sc->tx.txq_map[WME_AC_VI]), |
663 | &(sc->tx.txq[ATH_TXQ_AC_VO])); | 535 | &(sc->tx.txq_map[WME_AC_VO])); |
664 | if (len >= size) | 536 | if (len >= size) |
665 | goto done; | 537 | goto done; |
666 | 538 | ||
@@ -880,9 +752,9 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf, | |||
880 | } | 752 | } |
881 | 753 | ||
882 | void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, | 754 | void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, |
883 | struct ath_tx_status *ts) | 755 | struct ath_tx_status *ts, struct ath_txq *txq) |
884 | { | 756 | { |
885 | int qnum = skb_get_queue_mapping(bf->bf_mpdu); | 757 | int qnum = txq->axq_qnum; |
886 | 758 | ||
887 | TX_STAT_INC(qnum, tx_pkts_all); | 759 | TX_STAT_INC(qnum, tx_pkts_all); |
888 | sc->debug.stats.txstats[qnum].tx_bytes_all += bf->bf_mpdu->len; | 760 | sc->debug.stats.txstats[qnum].tx_bytes_all += bf->bf_mpdu->len; |
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 980c9fa194b9..59338de0ce19 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h | |||
@@ -175,7 +175,7 @@ int ath9k_init_debug(struct ath_hw *ah); | |||
175 | 175 | ||
176 | void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); | 176 | void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); |
177 | void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, | 177 | void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, |
178 | struct ath_tx_status *ts); | 178 | struct ath_tx_status *ts, struct ath_txq *txq); |
179 | void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs); | 179 | void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs); |
180 | 180 | ||
181 | #else | 181 | #else |
@@ -192,7 +192,8 @@ static inline void ath_debug_stat_interrupt(struct ath_softc *sc, | |||
192 | 192 | ||
193 | static inline void ath_debug_stat_tx(struct ath_softc *sc, | 193 | static inline void ath_debug_stat_tx(struct ath_softc *sc, |
194 | struct ath_buf *bf, | 194 | struct ath_buf *bf, |
195 | struct ath_tx_status *ts) | 195 | struct ath_tx_status *ts, |
196 | struct ath_txq *txq) | ||
196 | { | 197 | { |
197 | } | 198 | } |
198 | 199 | ||
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index c9318ff40964..fccd87df7300 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c | |||
@@ -247,9 +247,9 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah) | |||
247 | } | 247 | } |
248 | 248 | ||
249 | /* Enable fixup for AR_AN_TOP2 if necessary */ | 249 | /* Enable fixup for AR_AN_TOP2 if necessary */ |
250 | if (AR_SREV_9280_20_OR_LATER(ah) && | 250 | if ((ah->hw_version.devid == AR9280_DEVID_PCI) && |
251 | (eep->baseEepHeader.version & 0xff) > 0x0a && | 251 | ((eep->baseEepHeader.version & 0xff) > 0x0a) && |
252 | eep->baseEepHeader.pwdclkind == 0) | 252 | (eep->baseEepHeader.pwdclkind == 0)) |
253 | ah->need_an_top2_fixup = 1; | 253 | ah->need_an_top2_fixup = 1; |
254 | 254 | ||
255 | if ((common->bus_ops->ath_bus_type == ATH_USB) && | 255 | if ((common->bus_ops->ath_bus_type == ATH_USB) && |
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index 133764069246..fb4f17a5183d 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c | |||
@@ -201,8 +201,7 @@ static bool ath_is_rfkill_set(struct ath_softc *sc) | |||
201 | 201 | ||
202 | void ath9k_rfkill_poll_state(struct ieee80211_hw *hw) | 202 | void ath9k_rfkill_poll_state(struct ieee80211_hw *hw) |
203 | { | 203 | { |
204 | struct ath_wiphy *aphy = hw->priv; | 204 | struct ath_softc *sc = hw->priv; |
205 | struct ath_softc *sc = aphy->sc; | ||
206 | bool blocked = !!ath_is_rfkill_set(sc); | 205 | bool blocked = !!ath_is_rfkill_set(sc); |
207 | 206 | ||
208 | wiphy_rfkill_set_hw_state(hw->wiphy, blocked); | 207 | wiphy_rfkill_set_hw_state(hw->wiphy, blocked); |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 8e04586c5256..a7bc26d1bd66 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
@@ -142,9 +142,6 @@ static void ath9k_deinit_priv(struct ath9k_htc_priv *priv) | |||
142 | { | 142 | { |
143 | ath9k_htc_exit_debug(priv->ah); | 143 | ath9k_htc_exit_debug(priv->ah); |
144 | ath9k_hw_deinit(priv->ah); | 144 | ath9k_hw_deinit(priv->ah); |
145 | tasklet_kill(&priv->swba_tasklet); | ||
146 | tasklet_kill(&priv->rx_tasklet); | ||
147 | tasklet_kill(&priv->tx_tasklet); | ||
148 | kfree(priv->ah); | 145 | kfree(priv->ah); |
149 | priv->ah = NULL; | 146 | priv->ah = NULL; |
150 | } | 147 | } |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index f14f37d29f45..a702089f18d0 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
@@ -1026,12 +1026,6 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) | |||
1026 | int ret = 0; | 1026 | int ret = 0; |
1027 | u8 cmd_rsp; | 1027 | u8 cmd_rsp; |
1028 | 1028 | ||
1029 | /* Cancel all the running timers/work .. */ | ||
1030 | cancel_work_sync(&priv->fatal_work); | ||
1031 | cancel_work_sync(&priv->ps_work); | ||
1032 | cancel_delayed_work_sync(&priv->ath9k_led_blink_work); | ||
1033 | ath9k_led_stop_brightness(priv); | ||
1034 | |||
1035 | mutex_lock(&priv->mutex); | 1029 | mutex_lock(&priv->mutex); |
1036 | 1030 | ||
1037 | if (priv->op_flags & OP_INVALID) { | 1031 | if (priv->op_flags & OP_INVALID) { |
@@ -1045,8 +1039,23 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) | |||
1045 | WMI_CMD(WMI_DISABLE_INTR_CMDID); | 1039 | WMI_CMD(WMI_DISABLE_INTR_CMDID); |
1046 | WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); | 1040 | WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); |
1047 | WMI_CMD(WMI_STOP_RECV_CMDID); | 1041 | WMI_CMD(WMI_STOP_RECV_CMDID); |
1042 | |||
1043 | tasklet_kill(&priv->swba_tasklet); | ||
1044 | tasklet_kill(&priv->rx_tasklet); | ||
1045 | tasklet_kill(&priv->tx_tasklet); | ||
1046 | |||
1048 | skb_queue_purge(&priv->tx_queue); | 1047 | skb_queue_purge(&priv->tx_queue); |
1049 | 1048 | ||
1049 | mutex_unlock(&priv->mutex); | ||
1050 | |||
1051 | /* Cancel all the running timers/work .. */ | ||
1052 | cancel_work_sync(&priv->fatal_work); | ||
1053 | cancel_work_sync(&priv->ps_work); | ||
1054 | cancel_delayed_work_sync(&priv->ath9k_led_blink_work); | ||
1055 | ath9k_led_stop_brightness(priv); | ||
1056 | |||
1057 | mutex_lock(&priv->mutex); | ||
1058 | |||
1050 | /* Remove monitor interface here */ | 1059 | /* Remove monitor interface here */ |
1051 | if (ah->opmode == NL80211_IFTYPE_MONITOR) { | 1060 | if (ah->opmode == NL80211_IFTYPE_MONITOR) { |
1052 | if (ath9k_htc_remove_monitor_interface(priv)) | 1061 | if (ath9k_htc_remove_monitor_interface(priv)) |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 4615fd9c9aa0..f9cf81551817 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -671,13 +671,50 @@ static void ath9k_hw_init_qos(struct ath_hw *ah) | |||
671 | REGWRITE_BUFFER_FLUSH(ah); | 671 | REGWRITE_BUFFER_FLUSH(ah); |
672 | } | 672 | } |
673 | 673 | ||
674 | unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah) | ||
675 | { | ||
676 | REG_WRITE(ah, PLL3, (REG_READ(ah, PLL3) & ~(PLL3_DO_MEAS_MASK))); | ||
677 | udelay(100); | ||
678 | REG_WRITE(ah, PLL3, (REG_READ(ah, PLL3) | PLL3_DO_MEAS_MASK)); | ||
679 | |||
680 | while ((REG_READ(ah, PLL4) & PLL4_MEAS_DONE) == 0) | ||
681 | udelay(100); | ||
682 | |||
683 | return (REG_READ(ah, PLL3) & SQSUM_DVC_MASK) >> 3; | ||
684 | } | ||
685 | EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc); | ||
686 | |||
687 | #define DPLL2_KD_VAL 0x3D | ||
688 | #define DPLL2_KI_VAL 0x06 | ||
689 | #define DPLL3_PHASE_SHIFT_VAL 0x1 | ||
690 | |||
674 | static void ath9k_hw_init_pll(struct ath_hw *ah, | 691 | static void ath9k_hw_init_pll(struct ath_hw *ah, |
675 | struct ath9k_channel *chan) | 692 | struct ath9k_channel *chan) |
676 | { | 693 | { |
677 | u32 pll; | 694 | u32 pll; |
678 | 695 | ||
679 | if (AR_SREV_9485(ah)) | 696 | if (AR_SREV_9485(ah)) { |
680 | REG_WRITE(ah, AR_RTC_PLL_CONTROL2, 0x886666); | 697 | REG_WRITE(ah, AR_RTC_PLL_CONTROL2, 0x886666); |
698 | REG_WRITE(ah, AR_CH0_DDR_DPLL2, 0x19e82f01); | ||
699 | |||
700 | REG_RMW_FIELD(ah, AR_CH0_DDR_DPLL3, | ||
701 | AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL); | ||
702 | |||
703 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c); | ||
704 | udelay(100); | ||
705 | |||
706 | REG_WRITE(ah, AR_RTC_PLL_CONTROL2, 0x886666); | ||
707 | |||
708 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, | ||
709 | AR_CH0_DPLL2_KD, DPLL2_KD_VAL); | ||
710 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, | ||
711 | AR_CH0_DPLL2_KI, DPLL2_KI_VAL); | ||
712 | |||
713 | REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3, | ||
714 | AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL); | ||
715 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x142c); | ||
716 | udelay(110); | ||
717 | } | ||
681 | 718 | ||
682 | pll = ath9k_hw_compute_pll_control(ah, chan); | 719 | pll = ath9k_hw_compute_pll_control(ah, chan); |
683 | 720 | ||
@@ -1349,8 +1386,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1349 | ath9k_hw_spur_mitigate_freq(ah, chan); | 1386 | ath9k_hw_spur_mitigate_freq(ah, chan); |
1350 | ah->eep_ops->set_board_values(ah, chan); | 1387 | ah->eep_ops->set_board_values(ah, chan); |
1351 | 1388 | ||
1352 | ath9k_hw_set_operating_mode(ah, ah->opmode); | ||
1353 | |||
1354 | ENABLE_REGWRITE_BUFFER(ah); | 1389 | ENABLE_REGWRITE_BUFFER(ah); |
1355 | 1390 | ||
1356 | REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr)); | 1391 | REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr)); |
@@ -1368,6 +1403,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1368 | 1403 | ||
1369 | REGWRITE_BUFFER_FLUSH(ah); | 1404 | REGWRITE_BUFFER_FLUSH(ah); |
1370 | 1405 | ||
1406 | ath9k_hw_set_operating_mode(ah, ah->opmode); | ||
1407 | |||
1371 | r = ath9k_hw_rf_set_freq(ah, chan); | 1408 | r = ath9k_hw_rf_set_freq(ah, chan); |
1372 | if (r) | 1409 | if (r) |
1373 | return r; | 1410 | return r; |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index ad8c2c702130..ef79f4c876ca 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -929,6 +929,7 @@ void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64); | |||
929 | void ath9k_hw_reset_tsf(struct ath_hw *ah); | 929 | void ath9k_hw_reset_tsf(struct ath_hw *ah); |
930 | void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting); | 930 | void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting); |
931 | void ath9k_hw_init_global_settings(struct ath_hw *ah); | 931 | void ath9k_hw_init_global_settings(struct ath_hw *ah); |
932 | unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah); | ||
932 | void ath9k_hw_set11nmac2040(struct ath_hw *ah); | 933 | void ath9k_hw_set11nmac2040(struct ath_hw *ah); |
933 | void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period); | 934 | void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period); |
934 | void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, | 935 | void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 5279653c90c7..e5c1eead98a2 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -254,8 +254,7 @@ static int ath9k_reg_notifier(struct wiphy *wiphy, | |||
254 | struct regulatory_request *request) | 254 | struct regulatory_request *request) |
255 | { | 255 | { |
256 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); | 256 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); |
257 | struct ath_wiphy *aphy = hw->priv; | 257 | struct ath_softc *sc = hw->priv; |
258 | struct ath_softc *sc = aphy->sc; | ||
259 | struct ath_regulatory *reg = ath9k_hw_regulatory(sc->sc_ah); | 258 | struct ath_regulatory *reg = ath9k_hw_regulatory(sc->sc_ah); |
260 | 259 | ||
261 | return ath_reg_notifier_apply(wiphy, request, reg); | 260 | return ath_reg_notifier_apply(wiphy, request, reg); |
@@ -517,10 +516,8 @@ static void ath9k_init_misc(struct ath_softc *sc) | |||
517 | 516 | ||
518 | sc->beacon.slottime = ATH9K_SLOT_TIME_9; | 517 | sc->beacon.slottime = ATH9K_SLOT_TIME_9; |
519 | 518 | ||
520 | for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) { | 519 | for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) |
521 | sc->beacon.bslot[i] = NULL; | 520 | sc->beacon.bslot[i] = NULL; |
522 | sc->beacon.bslot_aphy[i] = NULL; | ||
523 | } | ||
524 | 521 | ||
525 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) | 522 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) |
526 | sc->ant_comb.count = ATH_ANT_DIV_COMB_INIT_COUNT; | 523 | sc->ant_comb.count = ATH_ANT_DIV_COMB_INIT_COUNT; |
@@ -556,7 +553,6 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, | |||
556 | common->btcoex_enabled = ath9k_btcoex_enable == 1; | 553 | common->btcoex_enabled = ath9k_btcoex_enable == 1; |
557 | spin_lock_init(&common->cc_lock); | 554 | spin_lock_init(&common->cc_lock); |
558 | 555 | ||
559 | spin_lock_init(&sc->wiphy_lock); | ||
560 | spin_lock_init(&sc->sc_serial_rw); | 556 | spin_lock_init(&sc->sc_serial_rw); |
561 | spin_lock_init(&sc->sc_pm_lock); | 557 | spin_lock_init(&sc->sc_pm_lock); |
562 | mutex_init(&sc->mutex); | 558 | mutex_init(&sc->mutex); |
@@ -604,8 +600,6 @@ err_btcoex: | |||
604 | err_queues: | 600 | err_queues: |
605 | ath9k_hw_deinit(ah); | 601 | ath9k_hw_deinit(ah); |
606 | err_hw: | 602 | err_hw: |
607 | tasklet_kill(&sc->intr_tq); | ||
608 | tasklet_kill(&sc->bcon_tasklet); | ||
609 | 603 | ||
610 | kfree(ah); | 604 | kfree(ah); |
611 | sc->sc_ah = NULL; | 605 | sc->sc_ah = NULL; |
@@ -707,7 +701,6 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, | |||
707 | const struct ath_bus_ops *bus_ops) | 701 | const struct ath_bus_ops *bus_ops) |
708 | { | 702 | { |
709 | struct ieee80211_hw *hw = sc->hw; | 703 | struct ieee80211_hw *hw = sc->hw; |
710 | struct ath_wiphy *aphy = hw->priv; | ||
711 | struct ath_common *common; | 704 | struct ath_common *common; |
712 | struct ath_hw *ah; | 705 | struct ath_hw *ah; |
713 | int error = 0; | 706 | int error = 0; |
@@ -762,10 +755,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, | |||
762 | 755 | ||
763 | INIT_WORK(&sc->hw_check_work, ath_hw_check); | 756 | INIT_WORK(&sc->hw_check_work, ath_hw_check); |
764 | INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); | 757 | INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); |
765 | INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work); | 758 | sc->last_rssi = ATH_RSSI_DUMMY_MARKER; |
766 | INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work); | ||
767 | sc->wiphy_scheduler_int = msecs_to_jiffies(500); | ||
768 | aphy->last_rssi = ATH_RSSI_DUMMY_MARKER; | ||
769 | 759 | ||
770 | ath_init_leds(sc); | 760 | ath_init_leds(sc); |
771 | ath_start_rfkill_poll(sc); | 761 | ath_start_rfkill_poll(sc); |
@@ -813,9 +803,6 @@ static void ath9k_deinit_softc(struct ath_softc *sc) | |||
813 | 803 | ||
814 | ath9k_hw_deinit(sc->sc_ah); | 804 | ath9k_hw_deinit(sc->sc_ah); |
815 | 805 | ||
816 | tasklet_kill(&sc->intr_tq); | ||
817 | tasklet_kill(&sc->bcon_tasklet); | ||
818 | |||
819 | kfree(sc->sc_ah); | 806 | kfree(sc->sc_ah); |
820 | sc->sc_ah = NULL; | 807 | sc->sc_ah = NULL; |
821 | } | 808 | } |
@@ -823,28 +810,19 @@ static void ath9k_deinit_softc(struct ath_softc *sc) | |||
823 | void ath9k_deinit_device(struct ath_softc *sc) | 810 | void ath9k_deinit_device(struct ath_softc *sc) |
824 | { | 811 | { |
825 | struct ieee80211_hw *hw = sc->hw; | 812 | struct ieee80211_hw *hw = sc->hw; |
826 | int i = 0; | ||
827 | 813 | ||
828 | ath9k_ps_wakeup(sc); | 814 | ath9k_ps_wakeup(sc); |
829 | 815 | ||
830 | wiphy_rfkill_stop_polling(sc->hw->wiphy); | 816 | wiphy_rfkill_stop_polling(sc->hw->wiphy); |
831 | ath_deinit_leds(sc); | 817 | ath_deinit_leds(sc); |
832 | 818 | ||
833 | for (i = 0; i < sc->num_sec_wiphy; i++) { | 819 | ath9k_ps_restore(sc); |
834 | struct ath_wiphy *aphy = sc->sec_wiphy[i]; | ||
835 | if (aphy == NULL) | ||
836 | continue; | ||
837 | sc->sec_wiphy[i] = NULL; | ||
838 | ieee80211_unregister_hw(aphy->hw); | ||
839 | ieee80211_free_hw(aphy->hw); | ||
840 | } | ||
841 | 820 | ||
842 | ieee80211_unregister_hw(hw); | 821 | ieee80211_unregister_hw(hw); |
843 | pm_qos_remove_request(&sc->pm_qos_req); | 822 | pm_qos_remove_request(&sc->pm_qos_req); |
844 | ath_rx_cleanup(sc); | 823 | ath_rx_cleanup(sc); |
845 | ath_tx_cleanup(sc); | 824 | ath_tx_cleanup(sc); |
846 | ath9k_deinit_softc(sc); | 825 | ath9k_deinit_softc(sc); |
847 | kfree(sc->sec_wiphy); | ||
848 | } | 826 | } |
849 | 827 | ||
850 | void ath_descdma_cleanup(struct ath_softc *sc, | 828 | void ath_descdma_cleanup(struct ath_softc *sc, |
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index 7512f97e8f49..04d58ae923bb 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h | |||
@@ -639,6 +639,8 @@ enum ath9k_rx_filter { | |||
639 | ATH9K_RX_FILTER_PHYERR = 0x00000100, | 639 | ATH9K_RX_FILTER_PHYERR = 0x00000100, |
640 | ATH9K_RX_FILTER_MYBEACON = 0x00000200, | 640 | ATH9K_RX_FILTER_MYBEACON = 0x00000200, |
641 | ATH9K_RX_FILTER_COMP_BAR = 0x00000400, | 641 | ATH9K_RX_FILTER_COMP_BAR = 0x00000400, |
642 | ATH9K_RX_FILTER_COMP_BA = 0x00000800, | ||
643 | ATH9K_RX_FILTER_UNCOMP_BA_BAR = 0x00001000, | ||
642 | ATH9K_RX_FILTER_PSPOLL = 0x00004000, | 644 | ATH9K_RX_FILTER_PSPOLL = 0x00004000, |
643 | ATH9K_RX_FILTER_PHYRADAR = 0x00002000, | 645 | ATH9K_RX_FILTER_PHYRADAR = 0x00002000, |
644 | ATH9K_RX_FILTER_MCAST_BCAST_ALL = 0x00008000, | 646 | ATH9K_RX_FILTER_MCAST_BCAST_ALL = 0x00008000, |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index facff102dd0e..1447b55a8d0a 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -73,7 +73,7 @@ static struct ath9k_channel *ath_get_curchannel(struct ath_softc *sc, | |||
73 | 73 | ||
74 | chan_idx = curchan->hw_value; | 74 | chan_idx = curchan->hw_value; |
75 | channel = &sc->sc_ah->channels[chan_idx]; | 75 | channel = &sc->sc_ah->channels[chan_idx]; |
76 | ath9k_update_ichannel(sc, hw, channel); | 76 | ath9k_cmn_update_ichannel(channel, curchan, hw->conf.channel_type); |
77 | return channel; | 77 | return channel; |
78 | } | 78 | } |
79 | 79 | ||
@@ -215,7 +215,6 @@ static void ath_update_survey_stats(struct ath_softc *sc) | |||
215 | int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | 215 | int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, |
216 | struct ath9k_channel *hchan) | 216 | struct ath9k_channel *hchan) |
217 | { | 217 | { |
218 | struct ath_wiphy *aphy = hw->priv; | ||
219 | struct ath_hw *ah = sc->sc_ah; | 218 | struct ath_hw *ah = sc->sc_ah; |
220 | struct ath_common *common = ath9k_hw_common(ah); | 219 | struct ath_common *common = ath9k_hw_common(ah); |
221 | struct ieee80211_conf *conf = &common->hw->conf; | 220 | struct ieee80211_conf *conf = &common->hw->conf; |
@@ -231,6 +230,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
231 | cancel_work_sync(&sc->paprd_work); | 230 | cancel_work_sync(&sc->paprd_work); |
232 | cancel_work_sync(&sc->hw_check_work); | 231 | cancel_work_sync(&sc->hw_check_work); |
233 | cancel_delayed_work_sync(&sc->tx_complete_work); | 232 | cancel_delayed_work_sync(&sc->tx_complete_work); |
233 | cancel_delayed_work_sync(&sc->hw_pll_work); | ||
234 | 234 | ||
235 | ath9k_ps_wakeup(sc); | 235 | ath9k_ps_wakeup(sc); |
236 | 236 | ||
@@ -262,7 +262,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
262 | fastcc = false; | 262 | fastcc = false; |
263 | 263 | ||
264 | if (!(sc->sc_flags & SC_OP_OFFCHANNEL)) | 264 | if (!(sc->sc_flags & SC_OP_OFFCHANNEL)) |
265 | caldata = &aphy->caldata; | 265 | caldata = &sc->caldata; |
266 | 266 | ||
267 | ath_dbg(common, ATH_DBG_CONFIG, | 267 | ath_dbg(common, ATH_DBG_CONFIG, |
268 | "(%u MHz) -> (%u MHz), conf_is_ht40: %d fastcc: %d\n", | 268 | "(%u MHz) -> (%u MHz), conf_is_ht40: %d fastcc: %d\n", |
@@ -291,10 +291,13 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
291 | if (sc->sc_flags & SC_OP_BEACONS) | 291 | if (sc->sc_flags & SC_OP_BEACONS) |
292 | ath_beacon_config(sc, NULL); | 292 | ath_beacon_config(sc, NULL); |
293 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); | 293 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); |
294 | ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/2); | ||
294 | ath_start_ani(common); | 295 | ath_start_ani(common); |
295 | } | 296 | } |
296 | 297 | ||
297 | ps_restore: | 298 | ps_restore: |
299 | ieee80211_wake_queues(hw); | ||
300 | |||
298 | spin_unlock_bh(&sc->sc_pcu_lock); | 301 | spin_unlock_bh(&sc->sc_pcu_lock); |
299 | 302 | ||
300 | ath9k_ps_restore(sc); | 303 | ath9k_ps_restore(sc); |
@@ -328,6 +331,8 @@ static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int | |||
328 | { | 331 | { |
329 | struct ieee80211_hw *hw = sc->hw; | 332 | struct ieee80211_hw *hw = sc->hw; |
330 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 333 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
334 | struct ath_hw *ah = sc->sc_ah; | ||
335 | struct ath_common *common = ath9k_hw_common(ah); | ||
331 | struct ath_tx_control txctl; | 336 | struct ath_tx_control txctl; |
332 | int time_left; | 337 | int time_left; |
333 | 338 | ||
@@ -345,8 +350,12 @@ static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int | |||
345 | init_completion(&sc->paprd_complete); | 350 | init_completion(&sc->paprd_complete); |
346 | sc->paprd_pending = true; | 351 | sc->paprd_pending = true; |
347 | txctl.paprd = BIT(chain); | 352 | txctl.paprd = BIT(chain); |
348 | if (ath_tx_start(hw, skb, &txctl) != 0) | 353 | |
354 | if (ath_tx_start(hw, skb, &txctl) != 0) { | ||
355 | ath_dbg(common, ATH_DBG_XMIT, "PAPRD TX failed\n"); | ||
356 | dev_kfree_skb_any(skb); | ||
349 | return false; | 357 | return false; |
358 | } | ||
350 | 359 | ||
351 | time_left = wait_for_completion_timeout(&sc->paprd_complete, | 360 | time_left = wait_for_completion_timeout(&sc->paprd_complete, |
352 | msecs_to_jiffies(ATH_PAPRD_TIMEOUT)); | 361 | msecs_to_jiffies(ATH_PAPRD_TIMEOUT)); |
@@ -803,54 +812,11 @@ chip_reset: | |||
803 | #undef SCHED_INTR | 812 | #undef SCHED_INTR |
804 | } | 813 | } |
805 | 814 | ||
806 | static u32 ath_get_extchanmode(struct ath_softc *sc, | ||
807 | struct ieee80211_channel *chan, | ||
808 | enum nl80211_channel_type channel_type) | ||
809 | { | ||
810 | u32 chanmode = 0; | ||
811 | |||
812 | switch (chan->band) { | ||
813 | case IEEE80211_BAND_2GHZ: | ||
814 | switch(channel_type) { | ||
815 | case NL80211_CHAN_NO_HT: | ||
816 | case NL80211_CHAN_HT20: | ||
817 | chanmode = CHANNEL_G_HT20; | ||
818 | break; | ||
819 | case NL80211_CHAN_HT40PLUS: | ||
820 | chanmode = CHANNEL_G_HT40PLUS; | ||
821 | break; | ||
822 | case NL80211_CHAN_HT40MINUS: | ||
823 | chanmode = CHANNEL_G_HT40MINUS; | ||
824 | break; | ||
825 | } | ||
826 | break; | ||
827 | case IEEE80211_BAND_5GHZ: | ||
828 | switch(channel_type) { | ||
829 | case NL80211_CHAN_NO_HT: | ||
830 | case NL80211_CHAN_HT20: | ||
831 | chanmode = CHANNEL_A_HT20; | ||
832 | break; | ||
833 | case NL80211_CHAN_HT40PLUS: | ||
834 | chanmode = CHANNEL_A_HT40PLUS; | ||
835 | break; | ||
836 | case NL80211_CHAN_HT40MINUS: | ||
837 | chanmode = CHANNEL_A_HT40MINUS; | ||
838 | break; | ||
839 | } | ||
840 | break; | ||
841 | default: | ||
842 | break; | ||
843 | } | ||
844 | |||
845 | return chanmode; | ||
846 | } | ||
847 | |||
848 | static void ath9k_bss_assoc_info(struct ath_softc *sc, | 815 | static void ath9k_bss_assoc_info(struct ath_softc *sc, |
849 | struct ieee80211_hw *hw, | 816 | struct ieee80211_hw *hw, |
850 | struct ieee80211_vif *vif, | 817 | struct ieee80211_vif *vif, |
851 | struct ieee80211_bss_conf *bss_conf) | 818 | struct ieee80211_bss_conf *bss_conf) |
852 | { | 819 | { |
853 | struct ath_wiphy *aphy = hw->priv; | ||
854 | struct ath_hw *ah = sc->sc_ah; | 820 | struct ath_hw *ah = sc->sc_ah; |
855 | struct ath_common *common = ath9k_hw_common(ah); | 821 | struct ath_common *common = ath9k_hw_common(ah); |
856 | 822 | ||
@@ -874,7 +840,7 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc, | |||
874 | ath_beacon_config(sc, vif); | 840 | ath_beacon_config(sc, vif); |
875 | 841 | ||
876 | /* Reset rssi stats */ | 842 | /* Reset rssi stats */ |
877 | aphy->last_rssi = ATH_RSSI_DUMMY_MARKER; | 843 | sc->last_rssi = ATH_RSSI_DUMMY_MARKER; |
878 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; | 844 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; |
879 | 845 | ||
880 | sc->sc_flags |= SC_OP_ANI_RUN; | 846 | sc->sc_flags |= SC_OP_ANI_RUN; |
@@ -977,8 +943,6 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
977 | 943 | ||
978 | spin_unlock_bh(&sc->sc_pcu_lock); | 944 | spin_unlock_bh(&sc->sc_pcu_lock); |
979 | ath9k_ps_restore(sc); | 945 | ath9k_ps_restore(sc); |
980 | |||
981 | ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP); | ||
982 | } | 946 | } |
983 | 947 | ||
984 | int ath_reset(struct ath_softc *sc, bool retry_tx) | 948 | int ath_reset(struct ath_softc *sc, bool retry_tx) |
@@ -1043,38 +1007,13 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) | |||
1043 | return r; | 1007 | return r; |
1044 | } | 1008 | } |
1045 | 1009 | ||
1046 | /* XXX: Remove me once we don't depend on ath9k_channel for all | ||
1047 | * this redundant data */ | ||
1048 | void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw, | ||
1049 | struct ath9k_channel *ichan) | ||
1050 | { | ||
1051 | struct ieee80211_channel *chan = hw->conf.channel; | ||
1052 | struct ieee80211_conf *conf = &hw->conf; | ||
1053 | |||
1054 | ichan->channel = chan->center_freq; | ||
1055 | ichan->chan = chan; | ||
1056 | |||
1057 | if (chan->band == IEEE80211_BAND_2GHZ) { | ||
1058 | ichan->chanmode = CHANNEL_G; | ||
1059 | ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM | CHANNEL_G; | ||
1060 | } else { | ||
1061 | ichan->chanmode = CHANNEL_A; | ||
1062 | ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM; | ||
1063 | } | ||
1064 | |||
1065 | if (conf_is_ht(conf)) | ||
1066 | ichan->chanmode = ath_get_extchanmode(sc, chan, | ||
1067 | conf->channel_type); | ||
1068 | } | ||
1069 | |||
1070 | /**********************/ | 1010 | /**********************/ |
1071 | /* mac80211 callbacks */ | 1011 | /* mac80211 callbacks */ |
1072 | /**********************/ | 1012 | /**********************/ |
1073 | 1013 | ||
1074 | static int ath9k_start(struct ieee80211_hw *hw) | 1014 | static int ath9k_start(struct ieee80211_hw *hw) |
1075 | { | 1015 | { |
1076 | struct ath_wiphy *aphy = hw->priv; | 1016 | struct ath_softc *sc = hw->priv; |
1077 | struct ath_softc *sc = aphy->sc; | ||
1078 | struct ath_hw *ah = sc->sc_ah; | 1017 | struct ath_hw *ah = sc->sc_ah; |
1079 | struct ath_common *common = ath9k_hw_common(ah); | 1018 | struct ath_common *common = ath9k_hw_common(ah); |
1080 | struct ieee80211_channel *curchan = hw->conf.channel; | 1019 | struct ieee80211_channel *curchan = hw->conf.channel; |
@@ -1087,29 +1026,7 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1087 | 1026 | ||
1088 | mutex_lock(&sc->mutex); | 1027 | mutex_lock(&sc->mutex); |
1089 | 1028 | ||
1090 | if (ath9k_wiphy_started(sc)) { | ||
1091 | if (sc->chan_idx == curchan->hw_value) { | ||
1092 | /* | ||
1093 | * Already on the operational channel, the new wiphy | ||
1094 | * can be marked active. | ||
1095 | */ | ||
1096 | aphy->state = ATH_WIPHY_ACTIVE; | ||
1097 | ieee80211_wake_queues(hw); | ||
1098 | } else { | ||
1099 | /* | ||
1100 | * Another wiphy is on another channel, start the new | ||
1101 | * wiphy in paused state. | ||
1102 | */ | ||
1103 | aphy->state = ATH_WIPHY_PAUSED; | ||
1104 | ieee80211_stop_queues(hw); | ||
1105 | } | ||
1106 | mutex_unlock(&sc->mutex); | ||
1107 | return 0; | ||
1108 | } | ||
1109 | aphy->state = ATH_WIPHY_ACTIVE; | ||
1110 | |||
1111 | /* setup initial channel */ | 1029 | /* setup initial channel */ |
1112 | |||
1113 | sc->chan_idx = curchan->hw_value; | 1030 | sc->chan_idx = curchan->hw_value; |
1114 | 1031 | ||
1115 | init_channel = ath_get_curchannel(sc, hw); | 1032 | init_channel = ath_get_curchannel(sc, hw); |
@@ -1213,19 +1130,11 @@ mutex_unlock: | |||
1213 | static int ath9k_tx(struct ieee80211_hw *hw, | 1130 | static int ath9k_tx(struct ieee80211_hw *hw, |
1214 | struct sk_buff *skb) | 1131 | struct sk_buff *skb) |
1215 | { | 1132 | { |
1216 | struct ath_wiphy *aphy = hw->priv; | 1133 | struct ath_softc *sc = hw->priv; |
1217 | struct ath_softc *sc = aphy->sc; | ||
1218 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1134 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1219 | struct ath_tx_control txctl; | 1135 | struct ath_tx_control txctl; |
1220 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 1136 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
1221 | 1137 | ||
1222 | if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) { | ||
1223 | ath_dbg(common, ATH_DBG_XMIT, | ||
1224 | "ath9k: %s: TX in unexpected wiphy state %d\n", | ||
1225 | wiphy_name(hw->wiphy), aphy->state); | ||
1226 | goto exit; | ||
1227 | } | ||
1228 | |||
1229 | if (sc->ps_enabled) { | 1138 | if (sc->ps_enabled) { |
1230 | /* | 1139 | /* |
1231 | * mac80211 does not set PM field for normal data frames, so we | 1140 | * mac80211 does not set PM field for normal data frames, so we |
@@ -1284,44 +1193,26 @@ exit: | |||
1284 | 1193 | ||
1285 | static void ath9k_stop(struct ieee80211_hw *hw) | 1194 | static void ath9k_stop(struct ieee80211_hw *hw) |
1286 | { | 1195 | { |
1287 | struct ath_wiphy *aphy = hw->priv; | 1196 | struct ath_softc *sc = hw->priv; |
1288 | struct ath_softc *sc = aphy->sc; | ||
1289 | struct ath_hw *ah = sc->sc_ah; | 1197 | struct ath_hw *ah = sc->sc_ah; |
1290 | struct ath_common *common = ath9k_hw_common(ah); | 1198 | struct ath_common *common = ath9k_hw_common(ah); |
1291 | int i; | ||
1292 | 1199 | ||
1293 | mutex_lock(&sc->mutex); | 1200 | mutex_lock(&sc->mutex); |
1294 | 1201 | ||
1295 | aphy->state = ATH_WIPHY_INACTIVE; | ||
1296 | |||
1297 | if (led_blink) | 1202 | if (led_blink) |
1298 | cancel_delayed_work_sync(&sc->ath_led_blink_work); | 1203 | cancel_delayed_work_sync(&sc->ath_led_blink_work); |
1299 | 1204 | ||
1300 | cancel_delayed_work_sync(&sc->tx_complete_work); | 1205 | cancel_delayed_work_sync(&sc->tx_complete_work); |
1206 | cancel_delayed_work_sync(&sc->hw_pll_work); | ||
1301 | cancel_work_sync(&sc->paprd_work); | 1207 | cancel_work_sync(&sc->paprd_work); |
1302 | cancel_work_sync(&sc->hw_check_work); | 1208 | cancel_work_sync(&sc->hw_check_work); |
1303 | 1209 | ||
1304 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
1305 | if (sc->sec_wiphy[i]) | ||
1306 | break; | ||
1307 | } | ||
1308 | |||
1309 | if (i == sc->num_sec_wiphy) { | ||
1310 | cancel_delayed_work_sync(&sc->wiphy_work); | ||
1311 | cancel_work_sync(&sc->chan_work); | ||
1312 | } | ||
1313 | |||
1314 | if (sc->sc_flags & SC_OP_INVALID) { | 1210 | if (sc->sc_flags & SC_OP_INVALID) { |
1315 | ath_dbg(common, ATH_DBG_ANY, "Device not present\n"); | 1211 | ath_dbg(common, ATH_DBG_ANY, "Device not present\n"); |
1316 | mutex_unlock(&sc->mutex); | 1212 | mutex_unlock(&sc->mutex); |
1317 | return; | 1213 | return; |
1318 | } | 1214 | } |
1319 | 1215 | ||
1320 | if (ath9k_wiphy_started(sc)) { | ||
1321 | mutex_unlock(&sc->mutex); | ||
1322 | return; /* another wiphy still in use */ | ||
1323 | } | ||
1324 | |||
1325 | /* Ensure HW is awake when we try to shut it down. */ | 1216 | /* Ensure HW is awake when we try to shut it down. */ |
1326 | ath9k_ps_wakeup(sc); | 1217 | ath9k_ps_wakeup(sc); |
1327 | 1218 | ||
@@ -1333,6 +1224,9 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
1333 | 1224 | ||
1334 | spin_lock_bh(&sc->sc_pcu_lock); | 1225 | spin_lock_bh(&sc->sc_pcu_lock); |
1335 | 1226 | ||
1227 | /* prevent tasklets to enable interrupts once we disable them */ | ||
1228 | ah->imask &= ~ATH9K_INT_GLOBAL; | ||
1229 | |||
1336 | /* make sure h/w will not generate any interrupt | 1230 | /* make sure h/w will not generate any interrupt |
1337 | * before setting the invalid flag. */ | 1231 | * before setting the invalid flag. */ |
1338 | ath9k_hw_disable_interrupts(ah); | 1232 | ath9k_hw_disable_interrupts(ah); |
@@ -1344,16 +1238,26 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
1344 | } else | 1238 | } else |
1345 | sc->rx.rxlink = NULL; | 1239 | sc->rx.rxlink = NULL; |
1346 | 1240 | ||
1241 | if (sc->rx.frag) { | ||
1242 | dev_kfree_skb_any(sc->rx.frag); | ||
1243 | sc->rx.frag = NULL; | ||
1244 | } | ||
1245 | |||
1347 | /* disable HAL and put h/w to sleep */ | 1246 | /* disable HAL and put h/w to sleep */ |
1348 | ath9k_hw_disable(ah); | 1247 | ath9k_hw_disable(ah); |
1349 | ath9k_hw_configpcipowersave(ah, 1, 1); | 1248 | ath9k_hw_configpcipowersave(ah, 1, 1); |
1350 | 1249 | ||
1351 | spin_unlock_bh(&sc->sc_pcu_lock); | 1250 | spin_unlock_bh(&sc->sc_pcu_lock); |
1352 | 1251 | ||
1252 | /* we can now sync irq and kill any running tasklets, since we already | ||
1253 | * disabled interrupts and not holding a spin lock */ | ||
1254 | synchronize_irq(sc->irq); | ||
1255 | tasklet_kill(&sc->intr_tq); | ||
1256 | tasklet_kill(&sc->bcon_tasklet); | ||
1257 | |||
1353 | ath9k_ps_restore(sc); | 1258 | ath9k_ps_restore(sc); |
1354 | 1259 | ||
1355 | sc->ps_idle = true; | 1260 | sc->ps_idle = true; |
1356 | ath9k_set_wiphy_idle(aphy, true); | ||
1357 | ath_radio_disable(sc, hw); | 1261 | ath_radio_disable(sc, hw); |
1358 | 1262 | ||
1359 | sc->sc_flags |= SC_OP_INVALID; | 1263 | sc->sc_flags |= SC_OP_INVALID; |
@@ -1439,11 +1343,9 @@ void ath9k_calculate_iter_data(struct ieee80211_hw *hw, | |||
1439 | struct ieee80211_vif *vif, | 1343 | struct ieee80211_vif *vif, |
1440 | struct ath9k_vif_iter_data *iter_data) | 1344 | struct ath9k_vif_iter_data *iter_data) |
1441 | { | 1345 | { |
1442 | struct ath_wiphy *aphy = hw->priv; | 1346 | struct ath_softc *sc = hw->priv; |
1443 | struct ath_softc *sc = aphy->sc; | ||
1444 | struct ath_hw *ah = sc->sc_ah; | 1347 | struct ath_hw *ah = sc->sc_ah; |
1445 | struct ath_common *common = ath9k_hw_common(ah); | 1348 | struct ath_common *common = ath9k_hw_common(ah); |
1446 | int i; | ||
1447 | 1349 | ||
1448 | /* | 1350 | /* |
1449 | * Use the hardware MAC address as reference, the hardware uses it | 1351 | * Use the hardware MAC address as reference, the hardware uses it |
@@ -1457,24 +1359,15 @@ void ath9k_calculate_iter_data(struct ieee80211_hw *hw, | |||
1457 | ath9k_vif_iter(iter_data, vif->addr, vif); | 1359 | ath9k_vif_iter(iter_data, vif->addr, vif); |
1458 | 1360 | ||
1459 | /* Get list of all active MAC addresses */ | 1361 | /* Get list of all active MAC addresses */ |
1460 | spin_lock_bh(&sc->wiphy_lock); | ||
1461 | ieee80211_iterate_active_interfaces_atomic(sc->hw, ath9k_vif_iter, | 1362 | ieee80211_iterate_active_interfaces_atomic(sc->hw, ath9k_vif_iter, |
1462 | iter_data); | 1363 | iter_data); |
1463 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
1464 | if (sc->sec_wiphy[i] == NULL) | ||
1465 | continue; | ||
1466 | ieee80211_iterate_active_interfaces_atomic( | ||
1467 | sc->sec_wiphy[i]->hw, ath9k_vif_iter, iter_data); | ||
1468 | } | ||
1469 | spin_unlock_bh(&sc->wiphy_lock); | ||
1470 | } | 1364 | } |
1471 | 1365 | ||
1472 | /* Called with sc->mutex held. */ | 1366 | /* Called with sc->mutex held. */ |
1473 | static void ath9k_calculate_summary_state(struct ieee80211_hw *hw, | 1367 | static void ath9k_calculate_summary_state(struct ieee80211_hw *hw, |
1474 | struct ieee80211_vif *vif) | 1368 | struct ieee80211_vif *vif) |
1475 | { | 1369 | { |
1476 | struct ath_wiphy *aphy = hw->priv; | 1370 | struct ath_softc *sc = hw->priv; |
1477 | struct ath_softc *sc = aphy->sc; | ||
1478 | struct ath_hw *ah = sc->sc_ah; | 1371 | struct ath_hw *ah = sc->sc_ah; |
1479 | struct ath_common *common = ath9k_hw_common(ah); | 1372 | struct ath_common *common = ath9k_hw_common(ah); |
1480 | struct ath9k_vif_iter_data iter_data; | 1373 | struct ath9k_vif_iter_data iter_data; |
@@ -1530,8 +1423,7 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw, | |||
1530 | static void ath9k_do_vif_add_setup(struct ieee80211_hw *hw, | 1423 | static void ath9k_do_vif_add_setup(struct ieee80211_hw *hw, |
1531 | struct ieee80211_vif *vif) | 1424 | struct ieee80211_vif *vif) |
1532 | { | 1425 | { |
1533 | struct ath_wiphy *aphy = hw->priv; | 1426 | struct ath_softc *sc = hw->priv; |
1534 | struct ath_softc *sc = aphy->sc; | ||
1535 | 1427 | ||
1536 | ath9k_calculate_summary_state(hw, vif); | 1428 | ath9k_calculate_summary_state(hw, vif); |
1537 | 1429 | ||
@@ -1544,7 +1436,7 @@ static void ath9k_do_vif_add_setup(struct ieee80211_hw *hw, | |||
1544 | * in the info_changed method and set up beacons properly | 1436 | * in the info_changed method and set up beacons properly |
1545 | * there. | 1437 | * there. |
1546 | */ | 1438 | */ |
1547 | error = ath_beacon_alloc(aphy, vif); | 1439 | error = ath_beacon_alloc(sc, vif); |
1548 | if (error) | 1440 | if (error) |
1549 | ath9k_reclaim_beacon(sc, vif); | 1441 | ath9k_reclaim_beacon(sc, vif); |
1550 | else | 1442 | else |
@@ -1556,8 +1448,7 @@ static void ath9k_do_vif_add_setup(struct ieee80211_hw *hw, | |||
1556 | static int ath9k_add_interface(struct ieee80211_hw *hw, | 1448 | static int ath9k_add_interface(struct ieee80211_hw *hw, |
1557 | struct ieee80211_vif *vif) | 1449 | struct ieee80211_vif *vif) |
1558 | { | 1450 | { |
1559 | struct ath_wiphy *aphy = hw->priv; | 1451 | struct ath_softc *sc = hw->priv; |
1560 | struct ath_softc *sc = aphy->sc; | ||
1561 | struct ath_hw *ah = sc->sc_ah; | 1452 | struct ath_hw *ah = sc->sc_ah; |
1562 | struct ath_common *common = ath9k_hw_common(ah); | 1453 | struct ath_common *common = ath9k_hw_common(ah); |
1563 | struct ath_vif *avp = (void *)vif->drv_priv; | 1454 | struct ath_vif *avp = (void *)vif->drv_priv; |
@@ -1617,8 +1508,7 @@ static int ath9k_change_interface(struct ieee80211_hw *hw, | |||
1617 | enum nl80211_iftype new_type, | 1508 | enum nl80211_iftype new_type, |
1618 | bool p2p) | 1509 | bool p2p) |
1619 | { | 1510 | { |
1620 | struct ath_wiphy *aphy = hw->priv; | 1511 | struct ath_softc *sc = hw->priv; |
1621 | struct ath_softc *sc = aphy->sc; | ||
1622 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1512 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1623 | int ret = 0; | 1513 | int ret = 0; |
1624 | 1514 | ||
@@ -1660,8 +1550,7 @@ out: | |||
1660 | static void ath9k_remove_interface(struct ieee80211_hw *hw, | 1550 | static void ath9k_remove_interface(struct ieee80211_hw *hw, |
1661 | struct ieee80211_vif *vif) | 1551 | struct ieee80211_vif *vif) |
1662 | { | 1552 | { |
1663 | struct ath_wiphy *aphy = hw->priv; | 1553 | struct ath_softc *sc = hw->priv; |
1664 | struct ath_softc *sc = aphy->sc; | ||
1665 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1554 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1666 | 1555 | ||
1667 | ath_dbg(common, ATH_DBG_CONFIG, "Detach Interface\n"); | 1556 | ath_dbg(common, ATH_DBG_CONFIG, "Detach Interface\n"); |
@@ -1715,12 +1604,11 @@ static void ath9k_disable_ps(struct ath_softc *sc) | |||
1715 | 1604 | ||
1716 | static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | 1605 | static int ath9k_config(struct ieee80211_hw *hw, u32 changed) |
1717 | { | 1606 | { |
1718 | struct ath_wiphy *aphy = hw->priv; | 1607 | struct ath_softc *sc = hw->priv; |
1719 | struct ath_softc *sc = aphy->sc; | ||
1720 | struct ath_hw *ah = sc->sc_ah; | 1608 | struct ath_hw *ah = sc->sc_ah; |
1721 | struct ath_common *common = ath9k_hw_common(ah); | 1609 | struct ath_common *common = ath9k_hw_common(ah); |
1722 | struct ieee80211_conf *conf = &hw->conf; | 1610 | struct ieee80211_conf *conf = &hw->conf; |
1723 | bool disable_radio; | 1611 | bool disable_radio = false; |
1724 | 1612 | ||
1725 | mutex_lock(&sc->mutex); | 1613 | mutex_lock(&sc->mutex); |
1726 | 1614 | ||
@@ -1731,29 +1619,13 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
1731 | * the end. | 1619 | * the end. |
1732 | */ | 1620 | */ |
1733 | if (changed & IEEE80211_CONF_CHANGE_IDLE) { | 1621 | if (changed & IEEE80211_CONF_CHANGE_IDLE) { |
1734 | bool enable_radio; | 1622 | sc->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE); |
1735 | bool all_wiphys_idle; | 1623 | if (!sc->ps_idle) { |
1736 | bool idle = !!(conf->flags & IEEE80211_CONF_IDLE); | ||
1737 | |||
1738 | spin_lock_bh(&sc->wiphy_lock); | ||
1739 | all_wiphys_idle = ath9k_all_wiphys_idle(sc); | ||
1740 | ath9k_set_wiphy_idle(aphy, idle); | ||
1741 | |||
1742 | enable_radio = (!idle && all_wiphys_idle); | ||
1743 | |||
1744 | /* | ||
1745 | * After we unlock here its possible another wiphy | ||
1746 | * can be re-renabled so to account for that we will | ||
1747 | * only disable the radio toward the end of this routine | ||
1748 | * if by then all wiphys are still idle. | ||
1749 | */ | ||
1750 | spin_unlock_bh(&sc->wiphy_lock); | ||
1751 | |||
1752 | if (enable_radio) { | ||
1753 | sc->ps_idle = false; | ||
1754 | ath_radio_enable(sc, hw); | 1624 | ath_radio_enable(sc, hw); |
1755 | ath_dbg(common, ATH_DBG_CONFIG, | 1625 | ath_dbg(common, ATH_DBG_CONFIG, |
1756 | "not-idle: enabling radio\n"); | 1626 | "not-idle: enabling radio\n"); |
1627 | } else { | ||
1628 | disable_radio = true; | ||
1757 | } | 1629 | } |
1758 | } | 1630 | } |
1759 | 1631 | ||
@@ -1794,29 +1666,16 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
1794 | if (ah->curchan) | 1666 | if (ah->curchan) |
1795 | old_pos = ah->curchan - &ah->channels[0]; | 1667 | old_pos = ah->curchan - &ah->channels[0]; |
1796 | 1668 | ||
1797 | aphy->chan_idx = pos; | ||
1798 | aphy->chan_is_ht = conf_is_ht(conf); | ||
1799 | if (hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) | 1669 | if (hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) |
1800 | sc->sc_flags |= SC_OP_OFFCHANNEL; | 1670 | sc->sc_flags |= SC_OP_OFFCHANNEL; |
1801 | else | 1671 | else |
1802 | sc->sc_flags &= ~SC_OP_OFFCHANNEL; | 1672 | sc->sc_flags &= ~SC_OP_OFFCHANNEL; |
1803 | 1673 | ||
1804 | if (aphy->state == ATH_WIPHY_SCAN || | ||
1805 | aphy->state == ATH_WIPHY_ACTIVE) | ||
1806 | ath9k_wiphy_pause_all_forced(sc, aphy); | ||
1807 | else { | ||
1808 | /* | ||
1809 | * Do not change operational channel based on a paused | ||
1810 | * wiphy changes. | ||
1811 | */ | ||
1812 | goto skip_chan_change; | ||
1813 | } | ||
1814 | |||
1815 | ath_dbg(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n", | 1674 | ath_dbg(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n", |
1816 | curchan->center_freq); | 1675 | curchan->center_freq); |
1817 | 1676 | ||
1818 | /* XXX: remove me eventualy */ | 1677 | ath9k_cmn_update_ichannel(&sc->sc_ah->channels[pos], |
1819 | ath9k_update_ichannel(sc, hw, &sc->sc_ah->channels[pos]); | 1678 | curchan, conf->channel_type); |
1820 | 1679 | ||
1821 | /* update survey stats for the old channel before switching */ | 1680 | /* update survey stats for the old channel before switching */ |
1822 | spin_lock_irqsave(&common->cc_lock, flags); | 1681 | spin_lock_irqsave(&common->cc_lock, flags); |
@@ -1858,7 +1717,6 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
1858 | ath_update_survey_nf(sc, old_pos); | 1717 | ath_update_survey_nf(sc, old_pos); |
1859 | } | 1718 | } |
1860 | 1719 | ||
1861 | skip_chan_change: | ||
1862 | if (changed & IEEE80211_CONF_CHANGE_POWER) { | 1720 | if (changed & IEEE80211_CONF_CHANGE_POWER) { |
1863 | sc->config.txpowlimit = 2 * conf->power_level; | 1721 | sc->config.txpowlimit = 2 * conf->power_level; |
1864 | ath9k_ps_wakeup(sc); | 1722 | ath9k_ps_wakeup(sc); |
@@ -1866,13 +1724,8 @@ skip_chan_change: | |||
1866 | ath9k_ps_restore(sc); | 1724 | ath9k_ps_restore(sc); |
1867 | } | 1725 | } |
1868 | 1726 | ||
1869 | spin_lock_bh(&sc->wiphy_lock); | ||
1870 | disable_radio = ath9k_all_wiphys_idle(sc); | ||
1871 | spin_unlock_bh(&sc->wiphy_lock); | ||
1872 | |||
1873 | if (disable_radio) { | 1727 | if (disable_radio) { |
1874 | ath_dbg(common, ATH_DBG_CONFIG, "idle: disabling radio\n"); | 1728 | ath_dbg(common, ATH_DBG_CONFIG, "idle: disabling radio\n"); |
1875 | sc->ps_idle = true; | ||
1876 | ath_radio_disable(sc, hw); | 1729 | ath_radio_disable(sc, hw); |
1877 | } | 1730 | } |
1878 | 1731 | ||
@@ -1897,8 +1750,7 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw, | |||
1897 | unsigned int *total_flags, | 1750 | unsigned int *total_flags, |
1898 | u64 multicast) | 1751 | u64 multicast) |
1899 | { | 1752 | { |
1900 | struct ath_wiphy *aphy = hw->priv; | 1753 | struct ath_softc *sc = hw->priv; |
1901 | struct ath_softc *sc = aphy->sc; | ||
1902 | u32 rfilt; | 1754 | u32 rfilt; |
1903 | 1755 | ||
1904 | changed_flags &= SUPPORTED_FILTERS; | 1756 | changed_flags &= SUPPORTED_FILTERS; |
@@ -1918,8 +1770,7 @@ static int ath9k_sta_add(struct ieee80211_hw *hw, | |||
1918 | struct ieee80211_vif *vif, | 1770 | struct ieee80211_vif *vif, |
1919 | struct ieee80211_sta *sta) | 1771 | struct ieee80211_sta *sta) |
1920 | { | 1772 | { |
1921 | struct ath_wiphy *aphy = hw->priv; | 1773 | struct ath_softc *sc = hw->priv; |
1922 | struct ath_softc *sc = aphy->sc; | ||
1923 | 1774 | ||
1924 | ath_node_attach(sc, sta); | 1775 | ath_node_attach(sc, sta); |
1925 | 1776 | ||
@@ -1930,8 +1781,7 @@ static int ath9k_sta_remove(struct ieee80211_hw *hw, | |||
1930 | struct ieee80211_vif *vif, | 1781 | struct ieee80211_vif *vif, |
1931 | struct ieee80211_sta *sta) | 1782 | struct ieee80211_sta *sta) |
1932 | { | 1783 | { |
1933 | struct ath_wiphy *aphy = hw->priv; | 1784 | struct ath_softc *sc = hw->priv; |
1934 | struct ath_softc *sc = aphy->sc; | ||
1935 | 1785 | ||
1936 | ath_node_detach(sc, sta); | 1786 | ath_node_detach(sc, sta); |
1937 | 1787 | ||
@@ -1941,8 +1791,7 @@ static int ath9k_sta_remove(struct ieee80211_hw *hw, | |||
1941 | static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue, | 1791 | static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue, |
1942 | const struct ieee80211_tx_queue_params *params) | 1792 | const struct ieee80211_tx_queue_params *params) |
1943 | { | 1793 | { |
1944 | struct ath_wiphy *aphy = hw->priv; | 1794 | struct ath_softc *sc = hw->priv; |
1945 | struct ath_softc *sc = aphy->sc; | ||
1946 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1795 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1947 | struct ath_txq *txq; | 1796 | struct ath_txq *txq; |
1948 | struct ath9k_tx_queue_info qi; | 1797 | struct ath9k_tx_queue_info qi; |
@@ -1986,8 +1835,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw, | |||
1986 | struct ieee80211_sta *sta, | 1835 | struct ieee80211_sta *sta, |
1987 | struct ieee80211_key_conf *key) | 1836 | struct ieee80211_key_conf *key) |
1988 | { | 1837 | { |
1989 | struct ath_wiphy *aphy = hw->priv; | 1838 | struct ath_softc *sc = hw->priv; |
1990 | struct ath_softc *sc = aphy->sc; | ||
1991 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1839 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1992 | int ret = 0; | 1840 | int ret = 0; |
1993 | 1841 | ||
@@ -2031,8 +1879,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
2031 | struct ieee80211_bss_conf *bss_conf, | 1879 | struct ieee80211_bss_conf *bss_conf, |
2032 | u32 changed) | 1880 | u32 changed) |
2033 | { | 1881 | { |
2034 | struct ath_wiphy *aphy = hw->priv; | 1882 | struct ath_softc *sc = hw->priv; |
2035 | struct ath_softc *sc = aphy->sc; | ||
2036 | struct ath_hw *ah = sc->sc_ah; | 1883 | struct ath_hw *ah = sc->sc_ah; |
2037 | struct ath_common *common = ath9k_hw_common(ah); | 1884 | struct ath_common *common = ath9k_hw_common(ah); |
2038 | struct ath_vif *avp = (void *)vif->drv_priv; | 1885 | struct ath_vif *avp = (void *)vif->drv_priv; |
@@ -2062,7 +1909,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
2062 | if ((changed & BSS_CHANGED_BEACON) || | 1909 | if ((changed & BSS_CHANGED_BEACON) || |
2063 | ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon)) { | 1910 | ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon)) { |
2064 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | 1911 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); |
2065 | error = ath_beacon_alloc(aphy, vif); | 1912 | error = ath_beacon_alloc(sc, vif); |
2066 | if (!error) | 1913 | if (!error) |
2067 | ath_beacon_config(sc, vif); | 1914 | ath_beacon_config(sc, vif); |
2068 | } | 1915 | } |
@@ -2099,7 +1946,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
2099 | if (vif->type == NL80211_IFTYPE_AP) { | 1946 | if (vif->type == NL80211_IFTYPE_AP) { |
2100 | sc->sc_flags |= SC_OP_TSF_RESET; | 1947 | sc->sc_flags |= SC_OP_TSF_RESET; |
2101 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | 1948 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); |
2102 | error = ath_beacon_alloc(aphy, vif); | 1949 | error = ath_beacon_alloc(sc, vif); |
2103 | if (!error) | 1950 | if (!error) |
2104 | ath_beacon_config(sc, vif); | 1951 | ath_beacon_config(sc, vif); |
2105 | } else { | 1952 | } else { |
@@ -2137,9 +1984,8 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
2137 | 1984 | ||
2138 | static u64 ath9k_get_tsf(struct ieee80211_hw *hw) | 1985 | static u64 ath9k_get_tsf(struct ieee80211_hw *hw) |
2139 | { | 1986 | { |
1987 | struct ath_softc *sc = hw->priv; | ||
2140 | u64 tsf; | 1988 | u64 tsf; |
2141 | struct ath_wiphy *aphy = hw->priv; | ||
2142 | struct ath_softc *sc = aphy->sc; | ||
2143 | 1989 | ||
2144 | mutex_lock(&sc->mutex); | 1990 | mutex_lock(&sc->mutex); |
2145 | ath9k_ps_wakeup(sc); | 1991 | ath9k_ps_wakeup(sc); |
@@ -2152,8 +1998,7 @@ static u64 ath9k_get_tsf(struct ieee80211_hw *hw) | |||
2152 | 1998 | ||
2153 | static void ath9k_set_tsf(struct ieee80211_hw *hw, u64 tsf) | 1999 | static void ath9k_set_tsf(struct ieee80211_hw *hw, u64 tsf) |
2154 | { | 2000 | { |
2155 | struct ath_wiphy *aphy = hw->priv; | 2001 | struct ath_softc *sc = hw->priv; |
2156 | struct ath_softc *sc = aphy->sc; | ||
2157 | 2002 | ||
2158 | mutex_lock(&sc->mutex); | 2003 | mutex_lock(&sc->mutex); |
2159 | ath9k_ps_wakeup(sc); | 2004 | ath9k_ps_wakeup(sc); |
@@ -2164,8 +2009,7 @@ static void ath9k_set_tsf(struct ieee80211_hw *hw, u64 tsf) | |||
2164 | 2009 | ||
2165 | static void ath9k_reset_tsf(struct ieee80211_hw *hw) | 2010 | static void ath9k_reset_tsf(struct ieee80211_hw *hw) |
2166 | { | 2011 | { |
2167 | struct ath_wiphy *aphy = hw->priv; | 2012 | struct ath_softc *sc = hw->priv; |
2168 | struct ath_softc *sc = aphy->sc; | ||
2169 | 2013 | ||
2170 | mutex_lock(&sc->mutex); | 2014 | mutex_lock(&sc->mutex); |
2171 | 2015 | ||
@@ -2182,8 +2026,7 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, | |||
2182 | struct ieee80211_sta *sta, | 2026 | struct ieee80211_sta *sta, |
2183 | u16 tid, u16 *ssn, u8 buf_size) | 2027 | u16 tid, u16 *ssn, u8 buf_size) |
2184 | { | 2028 | { |
2185 | struct ath_wiphy *aphy = hw->priv; | 2029 | struct ath_softc *sc = hw->priv; |
2186 | struct ath_softc *sc = aphy->sc; | ||
2187 | int ret = 0; | 2030 | int ret = 0; |
2188 | 2031 | ||
2189 | local_bh_disable(); | 2032 | local_bh_disable(); |
@@ -2228,8 +2071,7 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, | |||
2228 | static int ath9k_get_survey(struct ieee80211_hw *hw, int idx, | 2071 | static int ath9k_get_survey(struct ieee80211_hw *hw, int idx, |
2229 | struct survey_info *survey) | 2072 | struct survey_info *survey) |
2230 | { | 2073 | { |
2231 | struct ath_wiphy *aphy = hw->priv; | 2074 | struct ath_softc *sc = hw->priv; |
2232 | struct ath_softc *sc = aphy->sc; | ||
2233 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 2075 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
2234 | struct ieee80211_supported_band *sband; | 2076 | struct ieee80211_supported_band *sband; |
2235 | struct ieee80211_channel *chan; | 2077 | struct ieee80211_channel *chan; |
@@ -2263,47 +2105,9 @@ static int ath9k_get_survey(struct ieee80211_hw *hw, int idx, | |||
2263 | return 0; | 2105 | return 0; |
2264 | } | 2106 | } |
2265 | 2107 | ||
2266 | static void ath9k_sw_scan_start(struct ieee80211_hw *hw) | ||
2267 | { | ||
2268 | struct ath_wiphy *aphy = hw->priv; | ||
2269 | struct ath_softc *sc = aphy->sc; | ||
2270 | |||
2271 | mutex_lock(&sc->mutex); | ||
2272 | if (ath9k_wiphy_scanning(sc)) { | ||
2273 | /* | ||
2274 | * There is a race here in mac80211 but fixing it requires | ||
2275 | * we revisit how we handle the scan complete callback. | ||
2276 | * After mac80211 fixes we will not have configured hardware | ||
2277 | * to the home channel nor would we have configured the RX | ||
2278 | * filter yet. | ||
2279 | */ | ||
2280 | mutex_unlock(&sc->mutex); | ||
2281 | return; | ||
2282 | } | ||
2283 | |||
2284 | aphy->state = ATH_WIPHY_SCAN; | ||
2285 | ath9k_wiphy_pause_all_forced(sc, aphy); | ||
2286 | mutex_unlock(&sc->mutex); | ||
2287 | } | ||
2288 | |||
2289 | /* | ||
2290 | * XXX: this requires a revisit after the driver | ||
2291 | * scan_complete gets moved to another place/removed in mac80211. | ||
2292 | */ | ||
2293 | static void ath9k_sw_scan_complete(struct ieee80211_hw *hw) | ||
2294 | { | ||
2295 | struct ath_wiphy *aphy = hw->priv; | ||
2296 | struct ath_softc *sc = aphy->sc; | ||
2297 | |||
2298 | mutex_lock(&sc->mutex); | ||
2299 | aphy->state = ATH_WIPHY_ACTIVE; | ||
2300 | mutex_unlock(&sc->mutex); | ||
2301 | } | ||
2302 | |||
2303 | static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) | 2108 | static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) |
2304 | { | 2109 | { |
2305 | struct ath_wiphy *aphy = hw->priv; | 2110 | struct ath_softc *sc = hw->priv; |
2306 | struct ath_softc *sc = aphy->sc; | ||
2307 | struct ath_hw *ah = sc->sc_ah; | 2111 | struct ath_hw *ah = sc->sc_ah; |
2308 | 2112 | ||
2309 | mutex_lock(&sc->mutex); | 2113 | mutex_lock(&sc->mutex); |
@@ -2331,8 +2135,6 @@ struct ieee80211_ops ath9k_ops = { | |||
2331 | .reset_tsf = ath9k_reset_tsf, | 2135 | .reset_tsf = ath9k_reset_tsf, |
2332 | .ampdu_action = ath9k_ampdu_action, | 2136 | .ampdu_action = ath9k_ampdu_action, |
2333 | .get_survey = ath9k_get_survey, | 2137 | .get_survey = ath9k_get_survey, |
2334 | .sw_scan_start = ath9k_sw_scan_start, | ||
2335 | .sw_scan_complete = ath9k_sw_scan_complete, | ||
2336 | .rfkill_poll = ath9k_rfkill_poll_state, | 2138 | .rfkill_poll = ath9k_rfkill_poll_state, |
2337 | .set_coverage_class = ath9k_set_coverage_class, | 2139 | .set_coverage_class = ath9k_set_coverage_class, |
2338 | }; | 2140 | }; |
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index 78ef1f13386f..e83128c50f7b 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c | |||
@@ -126,7 +126,6 @@ static const struct ath_bus_ops ath_pci_bus_ops = { | |||
126 | static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | 126 | static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) |
127 | { | 127 | { |
128 | void __iomem *mem; | 128 | void __iomem *mem; |
129 | struct ath_wiphy *aphy; | ||
130 | struct ath_softc *sc; | 129 | struct ath_softc *sc; |
131 | struct ieee80211_hw *hw; | 130 | struct ieee80211_hw *hw; |
132 | u8 csz; | 131 | u8 csz; |
@@ -198,8 +197,7 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
198 | goto err_iomap; | 197 | goto err_iomap; |
199 | } | 198 | } |
200 | 199 | ||
201 | hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy) + | 200 | hw = ieee80211_alloc_hw(sizeof(struct ath_softc), &ath9k_ops); |
202 | sizeof(struct ath_softc), &ath9k_ops); | ||
203 | if (!hw) { | 201 | if (!hw) { |
204 | dev_err(&pdev->dev, "No memory for ieee80211_hw\n"); | 202 | dev_err(&pdev->dev, "No memory for ieee80211_hw\n"); |
205 | ret = -ENOMEM; | 203 | ret = -ENOMEM; |
@@ -209,11 +207,7 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
209 | SET_IEEE80211_DEV(hw, &pdev->dev); | 207 | SET_IEEE80211_DEV(hw, &pdev->dev); |
210 | pci_set_drvdata(pdev, hw); | 208 | pci_set_drvdata(pdev, hw); |
211 | 209 | ||
212 | aphy = hw->priv; | 210 | sc = hw->priv; |
213 | sc = (struct ath_softc *) (aphy + 1); | ||
214 | aphy->sc = sc; | ||
215 | aphy->hw = hw; | ||
216 | sc->pri_wiphy = aphy; | ||
217 | sc->hw = hw; | 211 | sc->hw = hw; |
218 | sc->dev = &pdev->dev; | 212 | sc->dev = &pdev->dev; |
219 | sc->mem = mem; | 213 | sc->mem = mem; |
@@ -260,8 +254,7 @@ err_dma: | |||
260 | static void ath_pci_remove(struct pci_dev *pdev) | 254 | static void ath_pci_remove(struct pci_dev *pdev) |
261 | { | 255 | { |
262 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); | 256 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); |
263 | struct ath_wiphy *aphy = hw->priv; | 257 | struct ath_softc *sc = hw->priv; |
264 | struct ath_softc *sc = aphy->sc; | ||
265 | void __iomem *mem = sc->mem; | 258 | void __iomem *mem = sc->mem; |
266 | 259 | ||
267 | if (!is_ath9k_unloaded) | 260 | if (!is_ath9k_unloaded) |
@@ -281,8 +274,7 @@ static int ath_pci_suspend(struct device *device) | |||
281 | { | 274 | { |
282 | struct pci_dev *pdev = to_pci_dev(device); | 275 | struct pci_dev *pdev = to_pci_dev(device); |
283 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); | 276 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); |
284 | struct ath_wiphy *aphy = hw->priv; | 277 | struct ath_softc *sc = hw->priv; |
285 | struct ath_softc *sc = aphy->sc; | ||
286 | 278 | ||
287 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); | 279 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); |
288 | 280 | ||
@@ -293,8 +285,7 @@ static int ath_pci_resume(struct device *device) | |||
293 | { | 285 | { |
294 | struct pci_dev *pdev = to_pci_dev(device); | 286 | struct pci_dev *pdev = to_pci_dev(device); |
295 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); | 287 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); |
296 | struct ath_wiphy *aphy = hw->priv; | 288 | struct ath_softc *sc = hw->priv; |
297 | struct ath_softc *sc = aphy->sc; | ||
298 | u32 val; | 289 | u32 val; |
299 | 290 | ||
300 | /* | 291 | /* |
@@ -320,7 +311,6 @@ static int ath_pci_resume(struct device *device) | |||
320 | ath9k_ps_restore(sc); | 311 | ath9k_ps_restore(sc); |
321 | 312 | ||
322 | sc->ps_idle = true; | 313 | sc->ps_idle = true; |
323 | ath9k_set_wiphy_idle(aphy, true); | ||
324 | ath_radio_disable(sc, hw); | 314 | ath_radio_disable(sc, hw); |
325 | 315 | ||
326 | return 0; | 316 | return 0; |
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index e45147820eae..960d717ca7c2 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c | |||
@@ -1560,8 +1560,7 @@ static void ath_rate_add_sta_debugfs(void *priv, void *priv_sta, | |||
1560 | 1560 | ||
1561 | static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) | 1561 | static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) |
1562 | { | 1562 | { |
1563 | struct ath_wiphy *aphy = hw->priv; | 1563 | return hw->priv; |
1564 | return aphy->sc; | ||
1565 | } | 1564 | } |
1566 | 1565 | ||
1567 | static void ath_rate_free(void *priv) | 1566 | static void ath_rate_free(void *priv) |
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 116f0582af24..daf171d2f610 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -34,27 +34,6 @@ static inline bool ath9k_check_auto_sleep(struct ath_softc *sc) | |||
34 | (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP); | 34 | (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP); |
35 | } | 35 | } |
36 | 36 | ||
37 | static struct ieee80211_hw * ath_get_virt_hw(struct ath_softc *sc, | ||
38 | struct ieee80211_hdr *hdr) | ||
39 | { | ||
40 | struct ieee80211_hw *hw = sc->pri_wiphy->hw; | ||
41 | int i; | ||
42 | |||
43 | spin_lock_bh(&sc->wiphy_lock); | ||
44 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
45 | struct ath_wiphy *aphy = sc->sec_wiphy[i]; | ||
46 | if (aphy == NULL) | ||
47 | continue; | ||
48 | if (compare_ether_addr(hdr->addr1, aphy->hw->wiphy->perm_addr) | ||
49 | == 0) { | ||
50 | hw = aphy->hw; | ||
51 | break; | ||
52 | } | ||
53 | } | ||
54 | spin_unlock_bh(&sc->wiphy_lock); | ||
55 | return hw; | ||
56 | } | ||
57 | |||
58 | /* | 37 | /* |
59 | * Setup and link descriptors. | 38 | * Setup and link descriptors. |
60 | * | 39 | * |
@@ -230,11 +209,6 @@ static int ath_rx_edma_init(struct ath_softc *sc, int nbufs) | |||
230 | int error = 0, i; | 209 | int error = 0, i; |
231 | u32 size; | 210 | u32 size; |
232 | 211 | ||
233 | |||
234 | common->rx_bufsize = roundup(IEEE80211_MAX_MPDU_LEN + | ||
235 | ah->caps.rx_status_len, | ||
236 | min(common->cachelsz, (u16)64)); | ||
237 | |||
238 | ath9k_hw_set_rx_bufsize(ah, common->rx_bufsize - | 212 | ath9k_hw_set_rx_bufsize(ah, common->rx_bufsize - |
239 | ah->caps.rx_status_len); | 213 | ah->caps.rx_status_len); |
240 | 214 | ||
@@ -321,12 +295,12 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) | |||
321 | sc->sc_flags &= ~SC_OP_RXFLUSH; | 295 | sc->sc_flags &= ~SC_OP_RXFLUSH; |
322 | spin_lock_init(&sc->rx.rxbuflock); | 296 | spin_lock_init(&sc->rx.rxbuflock); |
323 | 297 | ||
298 | common->rx_bufsize = IEEE80211_MAX_MPDU_LEN / 2 + | ||
299 | sc->sc_ah->caps.rx_status_len; | ||
300 | |||
324 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { | 301 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { |
325 | return ath_rx_edma_init(sc, nbufs); | 302 | return ath_rx_edma_init(sc, nbufs); |
326 | } else { | 303 | } else { |
327 | common->rx_bufsize = roundup(IEEE80211_MAX_MPDU_LEN, | ||
328 | min(common->cachelsz, (u16)64)); | ||
329 | |||
330 | ath_dbg(common, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n", | 304 | ath_dbg(common, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n", |
331 | common->cachelsz, common->rx_bufsize); | 305 | common->cachelsz, common->rx_bufsize); |
332 | 306 | ||
@@ -463,8 +437,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc) | |||
463 | if (conf_is_ht(&sc->hw->conf)) | 437 | if (conf_is_ht(&sc->hw->conf)) |
464 | rfilt |= ATH9K_RX_FILTER_COMP_BAR; | 438 | rfilt |= ATH9K_RX_FILTER_COMP_BAR; |
465 | 439 | ||
466 | if (sc->sec_wiphy || (sc->nvifs > 1) || | 440 | if (sc->nvifs > 1 || (sc->rx.rxfilter & FIF_OTHER_BSS)) { |
467 | (sc->rx.rxfilter & FIF_OTHER_BSS)) { | ||
468 | /* The following may also be needed for other older chips */ | 441 | /* The following may also be needed for other older chips */ |
469 | if (sc->sc_ah->hw_version.macVersion == AR_SREV_VERSION_9160) | 442 | if (sc->sc_ah->hw_version.macVersion == AR_SREV_VERSION_9160) |
470 | rfilt |= ATH9K_RX_FILTER_PROM; | 443 | rfilt |= ATH9K_RX_FILTER_PROM; |
@@ -668,37 +641,6 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb) | |||
668 | } | 641 | } |
669 | } | 642 | } |
670 | 643 | ||
671 | static void ath_rx_send_to_mac80211(struct ieee80211_hw *hw, | ||
672 | struct ath_softc *sc, struct sk_buff *skb) | ||
673 | { | ||
674 | struct ieee80211_hdr *hdr; | ||
675 | |||
676 | hdr = (struct ieee80211_hdr *)skb->data; | ||
677 | |||
678 | /* Send the frame to mac80211 */ | ||
679 | if (is_multicast_ether_addr(hdr->addr1)) { | ||
680 | int i; | ||
681 | /* | ||
682 | * Deliver broadcast/multicast frames to all suitable | ||
683 | * virtual wiphys. | ||
684 | */ | ||
685 | /* TODO: filter based on channel configuration */ | ||
686 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
687 | struct ath_wiphy *aphy = sc->sec_wiphy[i]; | ||
688 | struct sk_buff *nskb; | ||
689 | if (aphy == NULL) | ||
690 | continue; | ||
691 | nskb = skb_copy(skb, GFP_ATOMIC); | ||
692 | if (!nskb) | ||
693 | continue; | ||
694 | ieee80211_rx(aphy->hw, nskb); | ||
695 | } | ||
696 | ieee80211_rx(sc->hw, skb); | ||
697 | } else | ||
698 | /* Deliver unicast frames based on receiver address */ | ||
699 | ieee80211_rx(hw, skb); | ||
700 | } | ||
701 | |||
702 | static bool ath_edma_get_buffers(struct ath_softc *sc, | 644 | static bool ath_edma_get_buffers(struct ath_softc *sc, |
703 | enum ath9k_rx_qtype qtype) | 645 | enum ath9k_rx_qtype qtype) |
704 | { | 646 | { |
@@ -868,15 +810,9 @@ static bool ath9k_rx_accept(struct ath_common *common, | |||
868 | if (rx_stats->rs_datalen > (common->rx_bufsize - rx_status_len)) | 810 | if (rx_stats->rs_datalen > (common->rx_bufsize - rx_status_len)) |
869 | return false; | 811 | return false; |
870 | 812 | ||
871 | /* | 813 | /* Only use error bits from the last fragment */ |
872 | * rs_more indicates chained descriptors which can be used | ||
873 | * to link buffers together for a sort of scatter-gather | ||
874 | * operation. | ||
875 | * reject the frame, we don't support scatter-gather yet and | ||
876 | * the frame is probably corrupt anyway | ||
877 | */ | ||
878 | if (rx_stats->rs_more) | 814 | if (rx_stats->rs_more) |
879 | return false; | 815 | return true; |
880 | 816 | ||
881 | /* | 817 | /* |
882 | * The rx_stats->rs_status will not be set until the end of the | 818 | * The rx_stats->rs_status will not be set until the end of the |
@@ -980,7 +916,7 @@ static void ath9k_process_rssi(struct ath_common *common, | |||
980 | struct ieee80211_hdr *hdr, | 916 | struct ieee80211_hdr *hdr, |
981 | struct ath_rx_status *rx_stats) | 917 | struct ath_rx_status *rx_stats) |
982 | { | 918 | { |
983 | struct ath_wiphy *aphy = hw->priv; | 919 | struct ath_softc *sc = hw->priv; |
984 | struct ath_hw *ah = common->ah; | 920 | struct ath_hw *ah = common->ah; |
985 | int last_rssi; | 921 | int last_rssi; |
986 | __le16 fc; | 922 | __le16 fc; |
@@ -1000,9 +936,9 @@ static void ath9k_process_rssi(struct ath_common *common, | |||
1000 | } | 936 | } |
1001 | 937 | ||
1002 | if (rx_stats->rs_rssi != ATH9K_RSSI_BAD && !rx_stats->rs_moreaggr) | 938 | if (rx_stats->rs_rssi != ATH9K_RSSI_BAD && !rx_stats->rs_moreaggr) |
1003 | ATH_RSSI_LPF(aphy->last_rssi, rx_stats->rs_rssi); | 939 | ATH_RSSI_LPF(sc->last_rssi, rx_stats->rs_rssi); |
1004 | 940 | ||
1005 | last_rssi = aphy->last_rssi; | 941 | last_rssi = sc->last_rssi; |
1006 | if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) | 942 | if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) |
1007 | rx_stats->rs_rssi = ATH_EP_RND(last_rssi, | 943 | rx_stats->rs_rssi = ATH_EP_RND(last_rssi, |
1008 | ATH_RSSI_EP_MULTIPLIER); | 944 | ATH_RSSI_EP_MULTIPLIER); |
@@ -1034,6 +970,10 @@ static int ath9k_rx_skb_preprocess(struct ath_common *common, | |||
1034 | if (!ath9k_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error)) | 970 | if (!ath9k_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error)) |
1035 | return -EINVAL; | 971 | return -EINVAL; |
1036 | 972 | ||
973 | /* Only use status info from the last fragment */ | ||
974 | if (rx_stats->rs_more) | ||
975 | return 0; | ||
976 | |||
1037 | ath9k_process_rssi(common, hw, hdr, rx_stats); | 977 | ath9k_process_rssi(common, hw, hdr, rx_stats); |
1038 | 978 | ||
1039 | if (ath9k_process_rate(common, hw, rx_stats, rx_status)) | 979 | if (ath9k_process_rate(common, hw, rx_stats, rx_status)) |
@@ -1635,7 +1575,7 @@ div_comb_done: | |||
1635 | int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | 1575 | int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) |
1636 | { | 1576 | { |
1637 | struct ath_buf *bf; | 1577 | struct ath_buf *bf; |
1638 | struct sk_buff *skb = NULL, *requeue_skb; | 1578 | struct sk_buff *skb = NULL, *requeue_skb, *hdr_skb; |
1639 | struct ieee80211_rx_status *rxs; | 1579 | struct ieee80211_rx_status *rxs; |
1640 | struct ath_hw *ah = sc->sc_ah; | 1580 | struct ath_hw *ah = sc->sc_ah; |
1641 | struct ath_common *common = ath9k_hw_common(ah); | 1581 | struct ath_common *common = ath9k_hw_common(ah); |
@@ -1644,7 +1584,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
1644 | * virtual wiphy so to account for that we iterate over the active | 1584 | * virtual wiphy so to account for that we iterate over the active |
1645 | * wiphys and find the appropriate wiphy and therefore hw. | 1585 | * wiphys and find the appropriate wiphy and therefore hw. |
1646 | */ | 1586 | */ |
1647 | struct ieee80211_hw *hw = NULL; | 1587 | struct ieee80211_hw *hw = sc->hw; |
1648 | struct ieee80211_hdr *hdr; | 1588 | struct ieee80211_hdr *hdr; |
1649 | int retval; | 1589 | int retval; |
1650 | bool decrypt_error = false; | 1590 | bool decrypt_error = false; |
@@ -1686,10 +1626,17 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
1686 | if (!skb) | 1626 | if (!skb) |
1687 | continue; | 1627 | continue; |
1688 | 1628 | ||
1689 | hdr = (struct ieee80211_hdr *) (skb->data + rx_status_len); | 1629 | /* |
1690 | rxs = IEEE80211_SKB_RXCB(skb); | 1630 | * Take frame header from the first fragment and RX status from |
1631 | * the last one. | ||
1632 | */ | ||
1633 | if (sc->rx.frag) | ||
1634 | hdr_skb = sc->rx.frag; | ||
1635 | else | ||
1636 | hdr_skb = skb; | ||
1691 | 1637 | ||
1692 | hw = ath_get_virt_hw(sc, hdr); | 1638 | hdr = (struct ieee80211_hdr *) (hdr_skb->data + rx_status_len); |
1639 | rxs = IEEE80211_SKB_RXCB(hdr_skb); | ||
1693 | 1640 | ||
1694 | ath_debug_stat_rx(sc, &rs); | 1641 | ath_debug_stat_rx(sc, &rs); |
1695 | 1642 | ||
@@ -1698,12 +1645,12 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
1698 | * chain it back at the queue without processing it. | 1645 | * chain it back at the queue without processing it. |
1699 | */ | 1646 | */ |
1700 | if (flush) | 1647 | if (flush) |
1701 | goto requeue; | 1648 | goto requeue_drop_frag; |
1702 | 1649 | ||
1703 | retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs, | 1650 | retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs, |
1704 | rxs, &decrypt_error); | 1651 | rxs, &decrypt_error); |
1705 | if (retval) | 1652 | if (retval) |
1706 | goto requeue; | 1653 | goto requeue_drop_frag; |
1707 | 1654 | ||
1708 | rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp; | 1655 | rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp; |
1709 | if (rs.rs_tstamp > tsf_lower && | 1656 | if (rs.rs_tstamp > tsf_lower && |
@@ -1723,7 +1670,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
1723 | * skb and put it at the tail of the sc->rx.rxbuf list for | 1670 | * skb and put it at the tail of the sc->rx.rxbuf list for |
1724 | * processing. */ | 1671 | * processing. */ |
1725 | if (!requeue_skb) | 1672 | if (!requeue_skb) |
1726 | goto requeue; | 1673 | goto requeue_drop_frag; |
1727 | 1674 | ||
1728 | /* Unmap the frame */ | 1675 | /* Unmap the frame */ |
1729 | dma_unmap_single(sc->dev, bf->bf_buf_addr, | 1676 | dma_unmap_single(sc->dev, bf->bf_buf_addr, |
@@ -1734,8 +1681,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
1734 | if (ah->caps.rx_status_len) | 1681 | if (ah->caps.rx_status_len) |
1735 | skb_pull(skb, ah->caps.rx_status_len); | 1682 | skb_pull(skb, ah->caps.rx_status_len); |
1736 | 1683 | ||
1737 | ath9k_rx_skb_postprocess(common, skb, &rs, | 1684 | if (!rs.rs_more) |
1738 | rxs, decrypt_error); | 1685 | ath9k_rx_skb_postprocess(common, hdr_skb, &rs, |
1686 | rxs, decrypt_error); | ||
1739 | 1687 | ||
1740 | /* We will now give hardware our shiny new allocated skb */ | 1688 | /* We will now give hardware our shiny new allocated skb */ |
1741 | bf->bf_mpdu = requeue_skb; | 1689 | bf->bf_mpdu = requeue_skb; |
@@ -1748,10 +1696,42 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
1748 | bf->bf_mpdu = NULL; | 1696 | bf->bf_mpdu = NULL; |
1749 | bf->bf_buf_addr = 0; | 1697 | bf->bf_buf_addr = 0; |
1750 | ath_err(common, "dma_mapping_error() on RX\n"); | 1698 | ath_err(common, "dma_mapping_error() on RX\n"); |
1751 | ath_rx_send_to_mac80211(hw, sc, skb); | 1699 | ieee80211_rx(hw, skb); |
1752 | break; | 1700 | break; |
1753 | } | 1701 | } |
1754 | 1702 | ||
1703 | if (rs.rs_more) { | ||
1704 | /* | ||
1705 | * rs_more indicates chained descriptors which can be | ||
1706 | * used to link buffers together for a sort of | ||
1707 | * scatter-gather operation. | ||
1708 | */ | ||
1709 | if (sc->rx.frag) { | ||
1710 | /* too many fragments - cannot handle frame */ | ||
1711 | dev_kfree_skb_any(sc->rx.frag); | ||
1712 | dev_kfree_skb_any(skb); | ||
1713 | skb = NULL; | ||
1714 | } | ||
1715 | sc->rx.frag = skb; | ||
1716 | goto requeue; | ||
1717 | } | ||
1718 | |||
1719 | if (sc->rx.frag) { | ||
1720 | int space = skb->len - skb_tailroom(hdr_skb); | ||
1721 | |||
1722 | sc->rx.frag = NULL; | ||
1723 | |||
1724 | if (pskb_expand_head(hdr_skb, 0, space, GFP_ATOMIC) < 0) { | ||
1725 | dev_kfree_skb(skb); | ||
1726 | goto requeue_drop_frag; | ||
1727 | } | ||
1728 | |||
1729 | skb_copy_from_linear_data(skb, skb_put(hdr_skb, skb->len), | ||
1730 | skb->len); | ||
1731 | dev_kfree_skb_any(skb); | ||
1732 | skb = hdr_skb; | ||
1733 | } | ||
1734 | |||
1755 | /* | 1735 | /* |
1756 | * change the default rx antenna if rx diversity chooses the | 1736 | * change the default rx antenna if rx diversity chooses the |
1757 | * other antenna 3 times in a row. | 1737 | * other antenna 3 times in a row. |
@@ -1775,8 +1755,13 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
1775 | if (ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) | 1755 | if (ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) |
1776 | ath_ant_comb_scan(sc, &rs); | 1756 | ath_ant_comb_scan(sc, &rs); |
1777 | 1757 | ||
1778 | ath_rx_send_to_mac80211(hw, sc, skb); | 1758 | ieee80211_rx(hw, skb); |
1779 | 1759 | ||
1760 | requeue_drop_frag: | ||
1761 | if (sc->rx.frag) { | ||
1762 | dev_kfree_skb_any(sc->rx.frag); | ||
1763 | sc->rx.frag = NULL; | ||
1764 | } | ||
1780 | requeue: | 1765 | requeue: |
1781 | if (edma) { | 1766 | if (edma) { |
1782 | list_add_tail(&bf->list, &sc->rx.rxbuf); | 1767 | list_add_tail(&bf->list, &sc->rx.rxbuf); |
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 4df5659c6c16..b262e98709de 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h | |||
@@ -1083,6 +1083,17 @@ enum { | |||
1083 | #define AR_ENT_OTP 0x40d8 | 1083 | #define AR_ENT_OTP 0x40d8 |
1084 | #define AR_ENT_OTP_CHAIN2_DISABLE 0x00020000 | 1084 | #define AR_ENT_OTP_CHAIN2_DISABLE 0x00020000 |
1085 | #define AR_ENT_OTP_MPSD 0x00800000 | 1085 | #define AR_ENT_OTP_MPSD 0x00800000 |
1086 | #define AR_CH0_BB_DPLL2 0x16184 | ||
1087 | #define AR_CH0_BB_DPLL3 0x16188 | ||
1088 | #define AR_CH0_DDR_DPLL2 0x16244 | ||
1089 | #define AR_CH0_DDR_DPLL3 0x16248 | ||
1090 | #define AR_CH0_DPLL2_KD 0x03F80000 | ||
1091 | #define AR_CH0_DPLL2_KD_S 19 | ||
1092 | #define AR_CH0_DPLL2_KI 0x3C000000 | ||
1093 | #define AR_CH0_DPLL2_KI_S 26 | ||
1094 | #define AR_CH0_DPLL3_PHASE_SHIFT 0x3F800000 | ||
1095 | #define AR_CH0_DPLL3_PHASE_SHIFT_S 23 | ||
1096 | #define AR_PHY_CCA_NOM_VAL_2GHZ -118 | ||
1086 | 1097 | ||
1087 | #define AR_RTC_9300_PLL_DIV 0x000003ff | 1098 | #define AR_RTC_9300_PLL_DIV 0x000003ff |
1088 | #define AR_RTC_9300_PLL_DIV_S 0 | 1099 | #define AR_RTC_9300_PLL_DIV_S 0 |
@@ -1129,6 +1140,12 @@ enum { | |||
1129 | #define AR_RTC_PLL_CLKSEL 0x00000300 | 1140 | #define AR_RTC_PLL_CLKSEL 0x00000300 |
1130 | #define AR_RTC_PLL_CLKSEL_S 8 | 1141 | #define AR_RTC_PLL_CLKSEL_S 8 |
1131 | 1142 | ||
1143 | #define PLL3 0x16188 | ||
1144 | #define PLL3_DO_MEAS_MASK 0x40000000 | ||
1145 | #define PLL4 0x1618c | ||
1146 | #define PLL4_MEAS_DONE 0x8 | ||
1147 | #define SQSUM_DVC_MASK 0x007ffff8 | ||
1148 | |||
1132 | #define AR_RTC_RESET \ | 1149 | #define AR_RTC_RESET \ |
1133 | ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0040) : 0x7040) | 1150 | ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0040) : 0x7040) |
1134 | #define AR_RTC_RESET_EN (0x00000001) | 1151 | #define AR_RTC_RESET_EN (0x00000001) |
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c deleted file mode 100644 index d205c66cd972..000000000000 --- a/drivers/net/wireless/ath/ath9k/virtual.c +++ /dev/null | |||
@@ -1,669 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include <linux/slab.h> | ||
18 | |||
19 | #include "ath9k.h" | ||
20 | |||
21 | int ath9k_wiphy_add(struct ath_softc *sc) | ||
22 | { | ||
23 | int i, error; | ||
24 | struct ath_wiphy *aphy; | ||
25 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
26 | struct ieee80211_hw *hw; | ||
27 | u8 addr[ETH_ALEN]; | ||
28 | |||
29 | hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy), &ath9k_ops); | ||
30 | if (hw == NULL) | ||
31 | return -ENOMEM; | ||
32 | |||
33 | spin_lock_bh(&sc->wiphy_lock); | ||
34 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
35 | if (sc->sec_wiphy[i] == NULL) | ||
36 | break; | ||
37 | } | ||
38 | |||
39 | if (i == sc->num_sec_wiphy) { | ||
40 | /* No empty slot available; increase array length */ | ||
41 | struct ath_wiphy **n; | ||
42 | n = krealloc(sc->sec_wiphy, | ||
43 | (sc->num_sec_wiphy + 1) * | ||
44 | sizeof(struct ath_wiphy *), | ||
45 | GFP_ATOMIC); | ||
46 | if (n == NULL) { | ||
47 | spin_unlock_bh(&sc->wiphy_lock); | ||
48 | ieee80211_free_hw(hw); | ||
49 | return -ENOMEM; | ||
50 | } | ||
51 | n[i] = NULL; | ||
52 | sc->sec_wiphy = n; | ||
53 | sc->num_sec_wiphy++; | ||
54 | } | ||
55 | |||
56 | SET_IEEE80211_DEV(hw, sc->dev); | ||
57 | |||
58 | aphy = hw->priv; | ||
59 | aphy->sc = sc; | ||
60 | aphy->hw = hw; | ||
61 | sc->sec_wiphy[i] = aphy; | ||
62 | aphy->last_rssi = ATH_RSSI_DUMMY_MARKER; | ||
63 | spin_unlock_bh(&sc->wiphy_lock); | ||
64 | |||
65 | memcpy(addr, common->macaddr, ETH_ALEN); | ||
66 | addr[0] |= 0x02; /* Locally managed address */ | ||
67 | /* | ||
68 | * XOR virtual wiphy index into the least significant bits to generate | ||
69 | * a different MAC address for each virtual wiphy. | ||
70 | */ | ||
71 | addr[5] ^= i & 0xff; | ||
72 | addr[4] ^= (i & 0xff00) >> 8; | ||
73 | addr[3] ^= (i & 0xff0000) >> 16; | ||
74 | |||
75 | SET_IEEE80211_PERM_ADDR(hw, addr); | ||
76 | |||
77 | ath9k_set_hw_capab(sc, hw); | ||
78 | |||
79 | error = ieee80211_register_hw(hw); | ||
80 | |||
81 | if (error == 0) { | ||
82 | /* Make sure wiphy scheduler is started (if enabled) */ | ||
83 | ath9k_wiphy_set_scheduler(sc, sc->wiphy_scheduler_int); | ||
84 | } | ||
85 | |||
86 | return error; | ||
87 | } | ||
88 | |||
89 | int ath9k_wiphy_del(struct ath_wiphy *aphy) | ||
90 | { | ||
91 | struct ath_softc *sc = aphy->sc; | ||
92 | int i; | ||
93 | |||
94 | spin_lock_bh(&sc->wiphy_lock); | ||
95 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
96 | if (aphy == sc->sec_wiphy[i]) { | ||
97 | sc->sec_wiphy[i] = NULL; | ||
98 | spin_unlock_bh(&sc->wiphy_lock); | ||
99 | ieee80211_unregister_hw(aphy->hw); | ||
100 | ieee80211_free_hw(aphy->hw); | ||
101 | return 0; | ||
102 | } | ||
103 | } | ||
104 | spin_unlock_bh(&sc->wiphy_lock); | ||
105 | return -ENOENT; | ||
106 | } | ||
107 | |||
108 | static int ath9k_send_nullfunc(struct ath_wiphy *aphy, | ||
109 | struct ieee80211_vif *vif, const u8 *bssid, | ||
110 | int ps) | ||
111 | { | ||
112 | struct ath_softc *sc = aphy->sc; | ||
113 | struct ath_tx_control txctl; | ||
114 | struct sk_buff *skb; | ||
115 | struct ieee80211_hdr *hdr; | ||
116 | __le16 fc; | ||
117 | struct ieee80211_tx_info *info; | ||
118 | |||
119 | skb = dev_alloc_skb(24); | ||
120 | if (skb == NULL) | ||
121 | return -ENOMEM; | ||
122 | hdr = (struct ieee80211_hdr *) skb_put(skb, 24); | ||
123 | memset(hdr, 0, 24); | ||
124 | fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC | | ||
125 | IEEE80211_FCTL_TODS); | ||
126 | if (ps) | ||
127 | fc |= cpu_to_le16(IEEE80211_FCTL_PM); | ||
128 | hdr->frame_control = fc; | ||
129 | memcpy(hdr->addr1, bssid, ETH_ALEN); | ||
130 | memcpy(hdr->addr2, aphy->hw->wiphy->perm_addr, ETH_ALEN); | ||
131 | memcpy(hdr->addr3, bssid, ETH_ALEN); | ||
132 | |||
133 | info = IEEE80211_SKB_CB(skb); | ||
134 | memset(info, 0, sizeof(*info)); | ||
135 | info->flags = IEEE80211_TX_CTL_REQ_TX_STATUS; | ||
136 | info->control.vif = vif; | ||
137 | info->control.rates[0].idx = 0; | ||
138 | info->control.rates[0].count = 4; | ||
139 | info->control.rates[1].idx = -1; | ||
140 | |||
141 | memset(&txctl, 0, sizeof(struct ath_tx_control)); | ||
142 | txctl.txq = sc->tx.txq_map[WME_AC_VO]; | ||
143 | txctl.frame_type = ps ? ATH9K_IFT_PAUSE : ATH9K_IFT_UNPAUSE; | ||
144 | |||
145 | if (ath_tx_start(aphy->hw, skb, &txctl) != 0) | ||
146 | goto exit; | ||
147 | |||
148 | return 0; | ||
149 | exit: | ||
150 | dev_kfree_skb_any(skb); | ||
151 | return -1; | ||
152 | } | ||
153 | |||
154 | static bool __ath9k_wiphy_pausing(struct ath_softc *sc) | ||
155 | { | ||
156 | int i; | ||
157 | if (sc->pri_wiphy->state == ATH_WIPHY_PAUSING) | ||
158 | return true; | ||
159 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
160 | if (sc->sec_wiphy[i] && | ||
161 | sc->sec_wiphy[i]->state == ATH_WIPHY_PAUSING) | ||
162 | return true; | ||
163 | } | ||
164 | return false; | ||
165 | } | ||
166 | |||
167 | static bool ath9k_wiphy_pausing(struct ath_softc *sc) | ||
168 | { | ||
169 | bool ret; | ||
170 | spin_lock_bh(&sc->wiphy_lock); | ||
171 | ret = __ath9k_wiphy_pausing(sc); | ||
172 | spin_unlock_bh(&sc->wiphy_lock); | ||
173 | return ret; | ||
174 | } | ||
175 | |||
176 | static bool __ath9k_wiphy_scanning(struct ath_softc *sc) | ||
177 | { | ||
178 | int i; | ||
179 | if (sc->pri_wiphy->state == ATH_WIPHY_SCAN) | ||
180 | return true; | ||
181 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
182 | if (sc->sec_wiphy[i] && | ||
183 | sc->sec_wiphy[i]->state == ATH_WIPHY_SCAN) | ||
184 | return true; | ||
185 | } | ||
186 | return false; | ||
187 | } | ||
188 | |||
189 | bool ath9k_wiphy_scanning(struct ath_softc *sc) | ||
190 | { | ||
191 | bool ret; | ||
192 | spin_lock_bh(&sc->wiphy_lock); | ||
193 | ret = __ath9k_wiphy_scanning(sc); | ||
194 | spin_unlock_bh(&sc->wiphy_lock); | ||
195 | return ret; | ||
196 | } | ||
197 | |||
198 | static int __ath9k_wiphy_unpause(struct ath_wiphy *aphy); | ||
199 | |||
200 | /* caller must hold wiphy_lock */ | ||
201 | static void __ath9k_wiphy_unpause_ch(struct ath_wiphy *aphy) | ||
202 | { | ||
203 | if (aphy == NULL) | ||
204 | return; | ||
205 | if (aphy->chan_idx != aphy->sc->chan_idx) | ||
206 | return; /* wiphy not on the selected channel */ | ||
207 | __ath9k_wiphy_unpause(aphy); | ||
208 | } | ||
209 | |||
210 | static void ath9k_wiphy_unpause_channel(struct ath_softc *sc) | ||
211 | { | ||
212 | int i; | ||
213 | spin_lock_bh(&sc->wiphy_lock); | ||
214 | __ath9k_wiphy_unpause_ch(sc->pri_wiphy); | ||
215 | for (i = 0; i < sc->num_sec_wiphy; i++) | ||
216 | __ath9k_wiphy_unpause_ch(sc->sec_wiphy[i]); | ||
217 | spin_unlock_bh(&sc->wiphy_lock); | ||
218 | } | ||
219 | |||
220 | void ath9k_wiphy_chan_work(struct work_struct *work) | ||
221 | { | ||
222 | struct ath_softc *sc = container_of(work, struct ath_softc, chan_work); | ||
223 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
224 | struct ath_wiphy *aphy = sc->next_wiphy; | ||
225 | |||
226 | if (aphy == NULL) | ||
227 | return; | ||
228 | |||
229 | /* | ||
230 | * All pending interfaces paused; ready to change | ||
231 | * channels. | ||
232 | */ | ||
233 | |||
234 | /* Change channels */ | ||
235 | mutex_lock(&sc->mutex); | ||
236 | /* XXX: remove me eventually */ | ||
237 | ath9k_update_ichannel(sc, aphy->hw, | ||
238 | &sc->sc_ah->channels[sc->chan_idx]); | ||
239 | |||
240 | /* sync hw configuration for hw code */ | ||
241 | common->hw = aphy->hw; | ||
242 | |||
243 | if (ath_set_channel(sc, aphy->hw, | ||
244 | &sc->sc_ah->channels[sc->chan_idx]) < 0) { | ||
245 | printk(KERN_DEBUG "ath9k: Failed to set channel for new " | ||
246 | "virtual wiphy\n"); | ||
247 | mutex_unlock(&sc->mutex); | ||
248 | return; | ||
249 | } | ||
250 | mutex_unlock(&sc->mutex); | ||
251 | |||
252 | ath9k_wiphy_unpause_channel(sc); | ||
253 | } | ||
254 | |||
255 | /* | ||
256 | * ath9k version of ieee80211_tx_status() for TX frames that are generated | ||
257 | * internally in the driver. | ||
258 | */ | ||
259 | void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, int ftype) | ||
260 | { | ||
261 | struct ath_wiphy *aphy = hw->priv; | ||
262 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
263 | |||
264 | if (ftype == ATH9K_IFT_PAUSE && aphy->state == ATH_WIPHY_PAUSING) { | ||
265 | if (!(tx_info->flags & IEEE80211_TX_STAT_ACK)) { | ||
266 | printk(KERN_DEBUG "ath9k: %s: no ACK for pause " | ||
267 | "frame\n", wiphy_name(hw->wiphy)); | ||
268 | /* | ||
269 | * The AP did not reply; ignore this to allow us to | ||
270 | * continue. | ||
271 | */ | ||
272 | } | ||
273 | aphy->state = ATH_WIPHY_PAUSED; | ||
274 | if (!ath9k_wiphy_pausing(aphy->sc)) { | ||
275 | /* | ||
276 | * Drop from tasklet to work to allow mutex for channel | ||
277 | * change. | ||
278 | */ | ||
279 | ieee80211_queue_work(aphy->sc->hw, | ||
280 | &aphy->sc->chan_work); | ||
281 | } | ||
282 | } | ||
283 | |||
284 | dev_kfree_skb(skb); | ||
285 | } | ||
286 | |||
287 | static void ath9k_mark_paused(struct ath_wiphy *aphy) | ||
288 | { | ||
289 | struct ath_softc *sc = aphy->sc; | ||
290 | aphy->state = ATH_WIPHY_PAUSED; | ||
291 | if (!__ath9k_wiphy_pausing(sc)) | ||
292 | ieee80211_queue_work(sc->hw, &sc->chan_work); | ||
293 | } | ||
294 | |||
295 | static void ath9k_pause_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | ||
296 | { | ||
297 | struct ath_wiphy *aphy = data; | ||
298 | struct ath_vif *avp = (void *) vif->drv_priv; | ||
299 | |||
300 | switch (vif->type) { | ||
301 | case NL80211_IFTYPE_STATION: | ||
302 | if (!vif->bss_conf.assoc) { | ||
303 | ath9k_mark_paused(aphy); | ||
304 | break; | ||
305 | } | ||
306 | /* TODO: could avoid this if already in PS mode */ | ||
307 | if (ath9k_send_nullfunc(aphy, vif, avp->bssid, 1)) { | ||
308 | printk(KERN_DEBUG "%s: failed to send PS nullfunc\n", | ||
309 | __func__); | ||
310 | ath9k_mark_paused(aphy); | ||
311 | } | ||
312 | break; | ||
313 | case NL80211_IFTYPE_AP: | ||
314 | /* Beacon transmission is paused by aphy->state change */ | ||
315 | ath9k_mark_paused(aphy); | ||
316 | break; | ||
317 | default: | ||
318 | break; | ||
319 | } | ||
320 | } | ||
321 | |||
322 | /* caller must hold wiphy_lock */ | ||
323 | static int __ath9k_wiphy_pause(struct ath_wiphy *aphy) | ||
324 | { | ||
325 | ieee80211_stop_queues(aphy->hw); | ||
326 | aphy->state = ATH_WIPHY_PAUSING; | ||
327 | /* | ||
328 | * TODO: handle PAUSING->PAUSED for the case where there are multiple | ||
329 | * active vifs (now we do it on the first vif getting ready; should be | ||
330 | * on the last) | ||
331 | */ | ||
332 | ieee80211_iterate_active_interfaces_atomic(aphy->hw, ath9k_pause_iter, | ||
333 | aphy); | ||
334 | return 0; | ||
335 | } | ||
336 | |||
337 | int ath9k_wiphy_pause(struct ath_wiphy *aphy) | ||
338 | { | ||
339 | int ret; | ||
340 | spin_lock_bh(&aphy->sc->wiphy_lock); | ||
341 | ret = __ath9k_wiphy_pause(aphy); | ||
342 | spin_unlock_bh(&aphy->sc->wiphy_lock); | ||
343 | return ret; | ||
344 | } | ||
345 | |||
346 | static void ath9k_unpause_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | ||
347 | { | ||
348 | struct ath_wiphy *aphy = data; | ||
349 | struct ath_vif *avp = (void *) vif->drv_priv; | ||
350 | |||
351 | switch (vif->type) { | ||
352 | case NL80211_IFTYPE_STATION: | ||
353 | if (!vif->bss_conf.assoc) | ||
354 | break; | ||
355 | ath9k_send_nullfunc(aphy, vif, avp->bssid, 0); | ||
356 | break; | ||
357 | case NL80211_IFTYPE_AP: | ||
358 | /* Beacon transmission is re-enabled by aphy->state change */ | ||
359 | break; | ||
360 | default: | ||
361 | break; | ||
362 | } | ||
363 | } | ||
364 | |||
365 | /* caller must hold wiphy_lock */ | ||
366 | static int __ath9k_wiphy_unpause(struct ath_wiphy *aphy) | ||
367 | { | ||
368 | ieee80211_iterate_active_interfaces_atomic(aphy->hw, | ||
369 | ath9k_unpause_iter, aphy); | ||
370 | aphy->state = ATH_WIPHY_ACTIVE; | ||
371 | ieee80211_wake_queues(aphy->hw); | ||
372 | return 0; | ||
373 | } | ||
374 | |||
375 | int ath9k_wiphy_unpause(struct ath_wiphy *aphy) | ||
376 | { | ||
377 | int ret; | ||
378 | spin_lock_bh(&aphy->sc->wiphy_lock); | ||
379 | ret = __ath9k_wiphy_unpause(aphy); | ||
380 | spin_unlock_bh(&aphy->sc->wiphy_lock); | ||
381 | return ret; | ||
382 | } | ||
383 | |||
384 | static void __ath9k_wiphy_mark_all_paused(struct ath_softc *sc) | ||
385 | { | ||
386 | int i; | ||
387 | if (sc->pri_wiphy->state != ATH_WIPHY_INACTIVE) | ||
388 | sc->pri_wiphy->state = ATH_WIPHY_PAUSED; | ||
389 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
390 | if (sc->sec_wiphy[i] && | ||
391 | sc->sec_wiphy[i]->state != ATH_WIPHY_INACTIVE) | ||
392 | sc->sec_wiphy[i]->state = ATH_WIPHY_PAUSED; | ||
393 | } | ||
394 | } | ||
395 | |||
396 | /* caller must hold wiphy_lock */ | ||
397 | static void __ath9k_wiphy_pause_all(struct ath_softc *sc) | ||
398 | { | ||
399 | int i; | ||
400 | if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE) | ||
401 | __ath9k_wiphy_pause(sc->pri_wiphy); | ||
402 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
403 | if (sc->sec_wiphy[i] && | ||
404 | sc->sec_wiphy[i]->state == ATH_WIPHY_ACTIVE) | ||
405 | __ath9k_wiphy_pause(sc->sec_wiphy[i]); | ||
406 | } | ||
407 | } | ||
408 | |||
409 | int ath9k_wiphy_select(struct ath_wiphy *aphy) | ||
410 | { | ||
411 | struct ath_softc *sc = aphy->sc; | ||
412 | bool now; | ||
413 | |||
414 | spin_lock_bh(&sc->wiphy_lock); | ||
415 | if (__ath9k_wiphy_scanning(sc)) { | ||
416 | /* | ||
417 | * For now, we are using mac80211 sw scan and it expects to | ||
418 | * have full control over channel changes, so avoid wiphy | ||
419 | * scheduling during a scan. This could be optimized if the | ||
420 | * scanning control were moved into the driver. | ||
421 | */ | ||
422 | spin_unlock_bh(&sc->wiphy_lock); | ||
423 | return -EBUSY; | ||
424 | } | ||
425 | if (__ath9k_wiphy_pausing(sc)) { | ||
426 | if (sc->wiphy_select_failures == 0) | ||
427 | sc->wiphy_select_first_fail = jiffies; | ||
428 | sc->wiphy_select_failures++; | ||
429 | if (time_after(jiffies, sc->wiphy_select_first_fail + HZ / 2)) | ||
430 | { | ||
431 | printk(KERN_DEBUG "ath9k: Previous wiphy select timed " | ||
432 | "out; disable/enable hw to recover\n"); | ||
433 | __ath9k_wiphy_mark_all_paused(sc); | ||
434 | /* | ||
435 | * TODO: this workaround to fix hardware is unlikely to | ||
436 | * be specific to virtual wiphy changes. It can happen | ||
437 | * on normal channel change, too, and as such, this | ||
438 | * should really be made more generic. For example, | ||
439 | * tricker radio disable/enable on GTT interrupt burst | ||
440 | * (say, 10 GTT interrupts received without any TX | ||
441 | * frame being completed) | ||
442 | */ | ||
443 | spin_unlock_bh(&sc->wiphy_lock); | ||
444 | ath_radio_disable(sc, aphy->hw); | ||
445 | ath_radio_enable(sc, aphy->hw); | ||
446 | /* Only the primary wiphy hw is used for queuing work */ | ||
447 | ieee80211_queue_work(aphy->sc->hw, | ||
448 | &aphy->sc->chan_work); | ||
449 | return -EBUSY; /* previous select still in progress */ | ||
450 | } | ||
451 | spin_unlock_bh(&sc->wiphy_lock); | ||
452 | return -EBUSY; /* previous select still in progress */ | ||
453 | } | ||
454 | sc->wiphy_select_failures = 0; | ||
455 | |||
456 | /* Store the new channel */ | ||
457 | sc->chan_idx = aphy->chan_idx; | ||
458 | sc->chan_is_ht = aphy->chan_is_ht; | ||
459 | sc->next_wiphy = aphy; | ||
460 | |||
461 | __ath9k_wiphy_pause_all(sc); | ||
462 | now = !__ath9k_wiphy_pausing(aphy->sc); | ||
463 | spin_unlock_bh(&sc->wiphy_lock); | ||
464 | |||
465 | if (now) { | ||
466 | /* Ready to request channel change immediately */ | ||
467 | ieee80211_queue_work(aphy->sc->hw, &aphy->sc->chan_work); | ||
468 | } | ||
469 | |||
470 | /* | ||
471 | * wiphys will be unpaused in ath9k_tx_status() once channel has been | ||
472 | * changed if any wiphy needs time to become paused. | ||
473 | */ | ||
474 | |||
475 | return 0; | ||
476 | } | ||
477 | |||
478 | bool ath9k_wiphy_started(struct ath_softc *sc) | ||
479 | { | ||
480 | int i; | ||
481 | spin_lock_bh(&sc->wiphy_lock); | ||
482 | if (sc->pri_wiphy->state != ATH_WIPHY_INACTIVE) { | ||
483 | spin_unlock_bh(&sc->wiphy_lock); | ||
484 | return true; | ||
485 | } | ||
486 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
487 | if (sc->sec_wiphy[i] && | ||
488 | sc->sec_wiphy[i]->state != ATH_WIPHY_INACTIVE) { | ||
489 | spin_unlock_bh(&sc->wiphy_lock); | ||
490 | return true; | ||
491 | } | ||
492 | } | ||
493 | spin_unlock_bh(&sc->wiphy_lock); | ||
494 | return false; | ||
495 | } | ||
496 | |||
497 | static void ath9k_wiphy_pause_chan(struct ath_wiphy *aphy, | ||
498 | struct ath_wiphy *selected) | ||
499 | { | ||
500 | if (selected->state == ATH_WIPHY_SCAN) { | ||
501 | if (aphy == selected) | ||
502 | return; | ||
503 | /* | ||
504 | * Pause all other wiphys for the duration of the scan even if | ||
505 | * they are on the current channel now. | ||
506 | */ | ||
507 | } else if (aphy->chan_idx == selected->chan_idx) | ||
508 | return; | ||
509 | aphy->state = ATH_WIPHY_PAUSED; | ||
510 | ieee80211_stop_queues(aphy->hw); | ||
511 | } | ||
512 | |||
513 | void ath9k_wiphy_pause_all_forced(struct ath_softc *sc, | ||
514 | struct ath_wiphy *selected) | ||
515 | { | ||
516 | int i; | ||
517 | spin_lock_bh(&sc->wiphy_lock); | ||
518 | if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE) | ||
519 | ath9k_wiphy_pause_chan(sc->pri_wiphy, selected); | ||
520 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
521 | if (sc->sec_wiphy[i] && | ||
522 | sc->sec_wiphy[i]->state == ATH_WIPHY_ACTIVE) | ||
523 | ath9k_wiphy_pause_chan(sc->sec_wiphy[i], selected); | ||
524 | } | ||
525 | spin_unlock_bh(&sc->wiphy_lock); | ||
526 | } | ||
527 | |||
528 | void ath9k_wiphy_work(struct work_struct *work) | ||
529 | { | ||
530 | struct ath_softc *sc = container_of(work, struct ath_softc, | ||
531 | wiphy_work.work); | ||
532 | struct ath_wiphy *aphy = NULL; | ||
533 | bool first = true; | ||
534 | |||
535 | spin_lock_bh(&sc->wiphy_lock); | ||
536 | |||
537 | if (sc->wiphy_scheduler_int == 0) { | ||
538 | /* wiphy scheduler is disabled */ | ||
539 | spin_unlock_bh(&sc->wiphy_lock); | ||
540 | return; | ||
541 | } | ||
542 | |||
543 | try_again: | ||
544 | sc->wiphy_scheduler_index++; | ||
545 | while (sc->wiphy_scheduler_index <= sc->num_sec_wiphy) { | ||
546 | aphy = sc->sec_wiphy[sc->wiphy_scheduler_index - 1]; | ||
547 | if (aphy && aphy->state != ATH_WIPHY_INACTIVE) | ||
548 | break; | ||
549 | |||
550 | sc->wiphy_scheduler_index++; | ||
551 | aphy = NULL; | ||
552 | } | ||
553 | if (aphy == NULL) { | ||
554 | sc->wiphy_scheduler_index = 0; | ||
555 | if (sc->pri_wiphy->state == ATH_WIPHY_INACTIVE) { | ||
556 | if (first) { | ||
557 | first = false; | ||
558 | goto try_again; | ||
559 | } | ||
560 | /* No wiphy is ready to be scheduled */ | ||
561 | } else | ||
562 | aphy = sc->pri_wiphy; | ||
563 | } | ||
564 | |||
565 | spin_unlock_bh(&sc->wiphy_lock); | ||
566 | |||
567 | if (aphy && | ||
568 | aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN && | ||
569 | ath9k_wiphy_select(aphy)) { | ||
570 | printk(KERN_DEBUG "ath9k: Failed to schedule virtual wiphy " | ||
571 | "change\n"); | ||
572 | } | ||
573 | |||
574 | ieee80211_queue_delayed_work(sc->hw, | ||
575 | &sc->wiphy_work, | ||
576 | sc->wiphy_scheduler_int); | ||
577 | } | ||
578 | |||
579 | void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int) | ||
580 | { | ||
581 | cancel_delayed_work_sync(&sc->wiphy_work); | ||
582 | sc->wiphy_scheduler_int = msecs_to_jiffies(msec_int); | ||
583 | if (sc->wiphy_scheduler_int) | ||
584 | ieee80211_queue_delayed_work(sc->hw, &sc->wiphy_work, | ||
585 | sc->wiphy_scheduler_int); | ||
586 | } | ||
587 | |||
588 | /* caller must hold wiphy_lock */ | ||
589 | bool ath9k_all_wiphys_idle(struct ath_softc *sc) | ||
590 | { | ||
591 | unsigned int i; | ||
592 | if (!sc->pri_wiphy->idle) | ||
593 | return false; | ||
594 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
595 | struct ath_wiphy *aphy = sc->sec_wiphy[i]; | ||
596 | if (!aphy) | ||
597 | continue; | ||
598 | if (!aphy->idle) | ||
599 | return false; | ||
600 | } | ||
601 | return true; | ||
602 | } | ||
603 | |||
604 | /* caller must hold wiphy_lock */ | ||
605 | void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle) | ||
606 | { | ||
607 | struct ath_softc *sc = aphy->sc; | ||
608 | |||
609 | aphy->idle = idle; | ||
610 | ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG, | ||
611 | "Marking %s as %sidle\n", | ||
612 | wiphy_name(aphy->hw->wiphy), idle ? "" : "not-"); | ||
613 | } | ||
614 | /* Only bother starting a queue on an active virtual wiphy */ | ||
615 | bool ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue) | ||
616 | { | ||
617 | struct ieee80211_hw *hw = sc->pri_wiphy->hw; | ||
618 | unsigned int i; | ||
619 | bool txq_started = false; | ||
620 | |||
621 | spin_lock_bh(&sc->wiphy_lock); | ||
622 | |||
623 | /* Start the primary wiphy */ | ||
624 | if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE) { | ||
625 | ieee80211_wake_queue(hw, skb_queue); | ||
626 | txq_started = true; | ||
627 | goto unlock; | ||
628 | } | ||
629 | |||
630 | /* Now start the secondary wiphy queues */ | ||
631 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
632 | struct ath_wiphy *aphy = sc->sec_wiphy[i]; | ||
633 | if (!aphy) | ||
634 | continue; | ||
635 | if (aphy->state != ATH_WIPHY_ACTIVE) | ||
636 | continue; | ||
637 | |||
638 | hw = aphy->hw; | ||
639 | ieee80211_wake_queue(hw, skb_queue); | ||
640 | txq_started = true; | ||
641 | break; | ||
642 | } | ||
643 | |||
644 | unlock: | ||
645 | spin_unlock_bh(&sc->wiphy_lock); | ||
646 | return txq_started; | ||
647 | } | ||
648 | |||
649 | /* Go ahead and propagate information to all virtual wiphys, it won't hurt */ | ||
650 | void ath_mac80211_stop_queue(struct ath_softc *sc, u16 skb_queue) | ||
651 | { | ||
652 | struct ieee80211_hw *hw = sc->pri_wiphy->hw; | ||
653 | unsigned int i; | ||
654 | |||
655 | spin_lock_bh(&sc->wiphy_lock); | ||
656 | |||
657 | /* Stop the primary wiphy */ | ||
658 | ieee80211_stop_queue(hw, skb_queue); | ||
659 | |||
660 | /* Now stop the secondary wiphy queues */ | ||
661 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
662 | struct ath_wiphy *aphy = sc->sec_wiphy[i]; | ||
663 | if (!aphy) | ||
664 | continue; | ||
665 | hw = aphy->hw; | ||
666 | ieee80211_stop_queue(hw, skb_queue); | ||
667 | } | ||
668 | spin_unlock_bh(&sc->wiphy_lock); | ||
669 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index dcac811ddab5..68a1c7612e9b 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -55,8 +55,9 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | |||
55 | static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, | 55 | static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, |
56 | struct list_head *head); | 56 | struct list_head *head); |
57 | static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len); | 57 | static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len); |
58 | static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts, | 58 | static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf, |
59 | int nframes, int nbad, int txok, bool update_rc); | 59 | struct ath_tx_status *ts, int nframes, int nbad, |
60 | int txok, bool update_rc); | ||
60 | static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, | 61 | static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, |
61 | int seqno); | 62 | int seqno); |
62 | 63 | ||
@@ -295,7 +296,6 @@ static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf) | |||
295 | 296 | ||
296 | ATH_TXBUF_RESET(tbf); | 297 | ATH_TXBUF_RESET(tbf); |
297 | 298 | ||
298 | tbf->aphy = bf->aphy; | ||
299 | tbf->bf_mpdu = bf->bf_mpdu; | 299 | tbf->bf_mpdu = bf->bf_mpdu; |
300 | tbf->bf_buf_addr = bf->bf_buf_addr; | 300 | tbf->bf_buf_addr = bf->bf_buf_addr; |
301 | memcpy(tbf->bf_desc, bf->bf_desc, sc->sc_ah->caps.tx_desc_len); | 301 | memcpy(tbf->bf_desc, bf->bf_desc, sc->sc_ah->caps.tx_desc_len); |
@@ -343,7 +343,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
343 | struct ath_node *an = NULL; | 343 | struct ath_node *an = NULL; |
344 | struct sk_buff *skb; | 344 | struct sk_buff *skb; |
345 | struct ieee80211_sta *sta; | 345 | struct ieee80211_sta *sta; |
346 | struct ieee80211_hw *hw; | 346 | struct ieee80211_hw *hw = sc->hw; |
347 | struct ieee80211_hdr *hdr; | 347 | struct ieee80211_hdr *hdr; |
348 | struct ieee80211_tx_info *tx_info; | 348 | struct ieee80211_tx_info *tx_info; |
349 | struct ath_atx_tid *tid = NULL; | 349 | struct ath_atx_tid *tid = NULL; |
@@ -362,7 +362,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
362 | hdr = (struct ieee80211_hdr *)skb->data; | 362 | hdr = (struct ieee80211_hdr *)skb->data; |
363 | 363 | ||
364 | tx_info = IEEE80211_SKB_CB(skb); | 364 | tx_info = IEEE80211_SKB_CB(skb); |
365 | hw = bf->aphy->hw; | ||
366 | 365 | ||
367 | memcpy(rates, tx_info->control.rates, sizeof(rates)); | 366 | memcpy(rates, tx_info->control.rates, sizeof(rates)); |
368 | 367 | ||
@@ -381,7 +380,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
381 | !bf->bf_stale || bf_next != NULL) | 380 | !bf->bf_stale || bf_next != NULL) |
382 | list_move_tail(&bf->list, &bf_head); | 381 | list_move_tail(&bf->list, &bf_head); |
383 | 382 | ||
384 | ath_tx_rc_status(bf, ts, 1, 1, 0, false); | 383 | ath_tx_rc_status(sc, bf, ts, 1, 1, 0, false); |
385 | ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, | 384 | ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, |
386 | 0, 0); | 385 | 0, 0); |
387 | 386 | ||
@@ -487,10 +486,10 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
487 | 486 | ||
488 | if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) { | 487 | if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) { |
489 | memcpy(tx_info->control.rates, rates, sizeof(rates)); | 488 | memcpy(tx_info->control.rates, rates, sizeof(rates)); |
490 | ath_tx_rc_status(bf, ts, nframes, nbad, txok, true); | 489 | ath_tx_rc_status(sc, bf, ts, nframes, nbad, txok, true); |
491 | rc_update = false; | 490 | rc_update = false; |
492 | } else { | 491 | } else { |
493 | ath_tx_rc_status(bf, ts, nframes, nbad, txok, false); | 492 | ath_tx_rc_status(sc, bf, ts, nframes, nbad, txok, false); |
494 | } | 493 | } |
495 | 494 | ||
496 | ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, | 495 | ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, |
@@ -514,7 +513,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
514 | 513 | ||
515 | bf->bf_state.bf_type |= | 514 | bf->bf_state.bf_type |= |
516 | BUF_XRETRY; | 515 | BUF_XRETRY; |
517 | ath_tx_rc_status(bf, ts, nframes, | 516 | ath_tx_rc_status(sc, bf, ts, nframes, |
518 | nbad, 0, false); | 517 | nbad, 0, false); |
519 | ath_tx_complete_buf(sc, bf, txq, | 518 | ath_tx_complete_buf(sc, bf, txq, |
520 | &bf_head, | 519 | &bf_head, |
@@ -564,8 +563,11 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
564 | 563 | ||
565 | rcu_read_unlock(); | 564 | rcu_read_unlock(); |
566 | 565 | ||
567 | if (needreset) | 566 | if (needreset) { |
567 | spin_unlock_bh(&sc->sc_pcu_lock); | ||
568 | ath_reset(sc, false); | 568 | ath_reset(sc, false); |
569 | spin_lock_bh(&sc->sc_pcu_lock); | ||
570 | } | ||
569 | } | 571 | } |
570 | 572 | ||
571 | static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, | 573 | static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, |
@@ -1207,8 +1209,17 @@ bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) | |||
1207 | ath_err(common, "Failed to stop TX DMA!\n"); | 1209 | ath_err(common, "Failed to stop TX DMA!\n"); |
1208 | 1210 | ||
1209 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { | 1211 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { |
1210 | if (ATH_TXQ_SETUP(sc, i)) | 1212 | if (!ATH_TXQ_SETUP(sc, i)) |
1211 | ath_draintxq(sc, &sc->tx.txq[i], retry_tx); | 1213 | continue; |
1214 | |||
1215 | /* | ||
1216 | * The caller will resume queues with ieee80211_wake_queues. | ||
1217 | * Mark the queue as not stopped to prevent ath_tx_complete | ||
1218 | * from waking the queue too early. | ||
1219 | */ | ||
1220 | txq = &sc->tx.txq[i]; | ||
1221 | txq->stopped = false; | ||
1222 | ath_draintxq(sc, txq, retry_tx); | ||
1212 | } | 1223 | } |
1213 | 1224 | ||
1214 | return !npend; | 1225 | return !npend; |
@@ -1435,8 +1446,7 @@ static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb) | |||
1435 | static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb, | 1446 | static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb, |
1436 | int framelen) | 1447 | int framelen) |
1437 | { | 1448 | { |
1438 | struct ath_wiphy *aphy = hw->priv; | 1449 | struct ath_softc *sc = hw->priv; |
1439 | struct ath_softc *sc = aphy->sc; | ||
1440 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1450 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1441 | struct ieee80211_sta *sta = tx_info->control.sta; | 1451 | struct ieee80211_sta *sta = tx_info->control.sta; |
1442 | struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; | 1452 | struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; |
@@ -1654,8 +1664,7 @@ static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw, | |||
1654 | struct ath_txq *txq, | 1664 | struct ath_txq *txq, |
1655 | struct sk_buff *skb) | 1665 | struct sk_buff *skb) |
1656 | { | 1666 | { |
1657 | struct ath_wiphy *aphy = hw->priv; | 1667 | struct ath_softc *sc = hw->priv; |
1658 | struct ath_softc *sc = aphy->sc; | ||
1659 | struct ath_hw *ah = sc->sc_ah; | 1668 | struct ath_hw *ah = sc->sc_ah; |
1660 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1669 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1661 | struct ath_frame_info *fi = get_frame_info(skb); | 1670 | struct ath_frame_info *fi = get_frame_info(skb); |
@@ -1671,7 +1680,6 @@ static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw, | |||
1671 | 1680 | ||
1672 | ATH_TXBUF_RESET(bf); | 1681 | ATH_TXBUF_RESET(bf); |
1673 | 1682 | ||
1674 | bf->aphy = aphy; | ||
1675 | bf->bf_flags = setup_tx_flags(skb); | 1683 | bf->bf_flags = setup_tx_flags(skb); |
1676 | bf->bf_mpdu = skb; | 1684 | bf->bf_mpdu = skb; |
1677 | 1685 | ||
@@ -1757,8 +1765,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1757 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 1765 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
1758 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 1766 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1759 | struct ieee80211_sta *sta = info->control.sta; | 1767 | struct ieee80211_sta *sta = info->control.sta; |
1760 | struct ath_wiphy *aphy = hw->priv; | 1768 | struct ath_softc *sc = hw->priv; |
1761 | struct ath_softc *sc = aphy->sc; | ||
1762 | struct ath_txq *txq = txctl->txq; | 1769 | struct ath_txq *txq = txctl->txq; |
1763 | struct ath_buf *bf; | 1770 | struct ath_buf *bf; |
1764 | int padpos, padsize; | 1771 | int padpos, padsize; |
@@ -1810,7 +1817,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1810 | spin_lock_bh(&txq->axq_lock); | 1817 | spin_lock_bh(&txq->axq_lock); |
1811 | if (txq == sc->tx.txq_map[q] && | 1818 | if (txq == sc->tx.txq_map[q] && |
1812 | ++txq->pending_frames > ATH_MAX_QDEPTH && !txq->stopped) { | 1819 | ++txq->pending_frames > ATH_MAX_QDEPTH && !txq->stopped) { |
1813 | ath_mac80211_stop_queue(sc, q); | 1820 | ieee80211_stop_queue(sc->hw, q); |
1814 | txq->stopped = 1; | 1821 | txq->stopped = 1; |
1815 | } | 1822 | } |
1816 | spin_unlock_bh(&txq->axq_lock); | 1823 | spin_unlock_bh(&txq->axq_lock); |
@@ -1825,8 +1832,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1825 | /*****************/ | 1832 | /*****************/ |
1826 | 1833 | ||
1827 | static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | 1834 | static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, |
1828 | struct ath_wiphy *aphy, int tx_flags, int ftype, | 1835 | int tx_flags, int ftype, struct ath_txq *txq) |
1829 | struct ath_txq *txq) | ||
1830 | { | 1836 | { |
1831 | struct ieee80211_hw *hw = sc->hw; | 1837 | struct ieee80211_hw *hw = sc->hw; |
1832 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1838 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
@@ -1836,9 +1842,6 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
1836 | 1842 | ||
1837 | ath_dbg(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb); | 1843 | ath_dbg(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb); |
1838 | 1844 | ||
1839 | if (aphy) | ||
1840 | hw = aphy->hw; | ||
1841 | |||
1842 | if (tx_flags & ATH_TX_BAR) | 1845 | if (tx_flags & ATH_TX_BAR) |
1843 | tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; | 1846 | tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; |
1844 | 1847 | ||
@@ -1868,19 +1871,20 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
1868 | PS_WAIT_FOR_TX_ACK)); | 1871 | PS_WAIT_FOR_TX_ACK)); |
1869 | } | 1872 | } |
1870 | 1873 | ||
1871 | if (unlikely(ftype)) | 1874 | q = skb_get_queue_mapping(skb); |
1872 | ath9k_tx_status(hw, skb, ftype); | 1875 | if (txq == sc->tx.txq_map[q]) { |
1873 | else { | 1876 | spin_lock_bh(&txq->axq_lock); |
1874 | q = skb_get_queue_mapping(skb); | 1877 | if (WARN_ON(--txq->pending_frames < 0)) |
1875 | if (txq == sc->tx.txq_map[q]) { | 1878 | txq->pending_frames = 0; |
1876 | spin_lock_bh(&txq->axq_lock); | ||
1877 | if (WARN_ON(--txq->pending_frames < 0)) | ||
1878 | txq->pending_frames = 0; | ||
1879 | spin_unlock_bh(&txq->axq_lock); | ||
1880 | } | ||
1881 | 1879 | ||
1882 | ieee80211_tx_status(hw, skb); | 1880 | if (txq->stopped && txq->pending_frames < ATH_MAX_QDEPTH) { |
1881 | ieee80211_wake_queue(sc->hw, q); | ||
1882 | txq->stopped = 0; | ||
1883 | } | ||
1884 | spin_unlock_bh(&txq->axq_lock); | ||
1883 | } | 1885 | } |
1886 | |||
1887 | ieee80211_tx_status(hw, skb); | ||
1884 | } | 1888 | } |
1885 | 1889 | ||
1886 | static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | 1890 | static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, |
@@ -1910,8 +1914,8 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | |||
1910 | else | 1914 | else |
1911 | complete(&sc->paprd_complete); | 1915 | complete(&sc->paprd_complete); |
1912 | } else { | 1916 | } else { |
1913 | ath_debug_stat_tx(sc, bf, ts); | 1917 | ath_debug_stat_tx(sc, bf, ts, txq); |
1914 | ath_tx_complete(sc, skb, bf->aphy, tx_flags, | 1918 | ath_tx_complete(sc, skb, tx_flags, |
1915 | bf->bf_state.bfs_ftype, txq); | 1919 | bf->bf_state.bfs_ftype, txq); |
1916 | } | 1920 | } |
1917 | /* At this point, skb (bf->bf_mpdu) is consumed...make sure we don't | 1921 | /* At this point, skb (bf->bf_mpdu) is consumed...make sure we don't |
@@ -1927,14 +1931,14 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | |||
1927 | spin_unlock_irqrestore(&sc->tx.txbuflock, flags); | 1931 | spin_unlock_irqrestore(&sc->tx.txbuflock, flags); |
1928 | } | 1932 | } |
1929 | 1933 | ||
1930 | static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts, | 1934 | static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf, |
1931 | int nframes, int nbad, int txok, bool update_rc) | 1935 | struct ath_tx_status *ts, int nframes, int nbad, |
1936 | int txok, bool update_rc) | ||
1932 | { | 1937 | { |
1933 | struct sk_buff *skb = bf->bf_mpdu; | 1938 | struct sk_buff *skb = bf->bf_mpdu; |
1934 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 1939 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
1935 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1940 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1936 | struct ieee80211_hw *hw = bf->aphy->hw; | 1941 | struct ieee80211_hw *hw = sc->hw; |
1937 | struct ath_softc *sc = bf->aphy->sc; | ||
1938 | struct ath_hw *ah = sc->sc_ah; | 1942 | struct ath_hw *ah = sc->sc_ah; |
1939 | u8 i, tx_rateindex; | 1943 | u8 i, tx_rateindex; |
1940 | 1944 | ||
@@ -1985,18 +1989,6 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts, | |||
1985 | tx_info->status.rates[tx_rateindex].count = ts->ts_longretry + 1; | 1989 | tx_info->status.rates[tx_rateindex].count = ts->ts_longretry + 1; |
1986 | } | 1990 | } |
1987 | 1991 | ||
1988 | /* Has no locking. Must hold spin_lock_bh(&txq->axq_lock) | ||
1989 | * before calling this. | ||
1990 | */ | ||
1991 | static void __ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq) | ||
1992 | { | ||
1993 | if (txq->mac80211_qnum >= 0 && | ||
1994 | txq->stopped && txq->pending_frames < ATH_MAX_QDEPTH) { | ||
1995 | if (ath_mac80211_start_queue(sc, txq->mac80211_qnum)) | ||
1996 | txq->stopped = 0; | ||
1997 | } | ||
1998 | } | ||
1999 | |||
2000 | static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | 1992 | static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) |
2001 | { | 1993 | { |
2002 | struct ath_hw *ah = sc->sc_ah; | 1994 | struct ath_hw *ah = sc->sc_ah; |
@@ -2007,7 +1999,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
2007 | struct ath_tx_status ts; | 1999 | struct ath_tx_status ts; |
2008 | int txok; | 2000 | int txok; |
2009 | int status; | 2001 | int status; |
2010 | int qnum; | ||
2011 | 2002 | ||
2012 | ath_dbg(common, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n", | 2003 | ath_dbg(common, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n", |
2013 | txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum), | 2004 | txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum), |
@@ -2086,11 +2077,9 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
2086 | */ | 2077 | */ |
2087 | if (ts.ts_status & ATH9K_TXERR_XRETRY) | 2078 | if (ts.ts_status & ATH9K_TXERR_XRETRY) |
2088 | bf->bf_state.bf_type |= BUF_XRETRY; | 2079 | bf->bf_state.bf_type |= BUF_XRETRY; |
2089 | ath_tx_rc_status(bf, &ts, 1, txok ? 0 : 1, txok, true); | 2080 | ath_tx_rc_status(sc, bf, &ts, 1, txok ? 0 : 1, txok, true); |
2090 | } | 2081 | } |
2091 | 2082 | ||
2092 | qnum = skb_get_queue_mapping(bf->bf_mpdu); | ||
2093 | |||
2094 | if (bf_isampdu(bf)) | 2083 | if (bf_isampdu(bf)) |
2095 | ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, txok, | 2084 | ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, txok, |
2096 | true); | 2085 | true); |
@@ -2098,7 +2087,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
2098 | ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, txok, 0); | 2087 | ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, txok, 0); |
2099 | 2088 | ||
2100 | spin_lock_bh(&txq->axq_lock); | 2089 | spin_lock_bh(&txq->axq_lock); |
2101 | __ath_wake_mac80211_queue(sc, txq); | ||
2102 | 2090 | ||
2103 | if (sc->sc_flags & SC_OP_TXAGGR) | 2091 | if (sc->sc_flags & SC_OP_TXAGGR) |
2104 | ath_txq_schedule(sc, txq); | 2092 | ath_txq_schedule(sc, txq); |
@@ -2106,6 +2094,28 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
2106 | } | 2094 | } |
2107 | } | 2095 | } |
2108 | 2096 | ||
2097 | static void ath_hw_pll_work(struct work_struct *work) | ||
2098 | { | ||
2099 | struct ath_softc *sc = container_of(work, struct ath_softc, | ||
2100 | hw_pll_work.work); | ||
2101 | static int count; | ||
2102 | |||
2103 | if (AR_SREV_9485(sc->sc_ah)) { | ||
2104 | if (ar9003_get_pll_sqsum_dvc(sc->sc_ah) >= 0x40000) { | ||
2105 | count++; | ||
2106 | |||
2107 | if (count == 3) { | ||
2108 | /* Rx is hung for more than 500ms. Reset it */ | ||
2109 | ath_reset(sc, true); | ||
2110 | count = 0; | ||
2111 | } | ||
2112 | } else | ||
2113 | count = 0; | ||
2114 | |||
2115 | ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5); | ||
2116 | } | ||
2117 | } | ||
2118 | |||
2109 | static void ath_tx_complete_poll_work(struct work_struct *work) | 2119 | static void ath_tx_complete_poll_work(struct work_struct *work) |
2110 | { | 2120 | { |
2111 | struct ath_softc *sc = container_of(work, struct ath_softc, | 2121 | struct ath_softc *sc = container_of(work, struct ath_softc, |
@@ -2154,7 +2164,6 @@ static void ath_tx_complete_poll_work(struct work_struct *work) | |||
2154 | txq->pending_frames, | 2164 | txq->pending_frames, |
2155 | list_empty(&txq->axq_acq), | 2165 | list_empty(&txq->axq_acq), |
2156 | txq->stopped); | 2166 | txq->stopped); |
2157 | __ath_wake_mac80211_queue(sc, txq); | ||
2158 | ath_txq_schedule(sc, txq); | 2167 | ath_txq_schedule(sc, txq); |
2159 | } | 2168 | } |
2160 | } | 2169 | } |
@@ -2196,7 +2205,6 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) | |||
2196 | struct list_head bf_head; | 2205 | struct list_head bf_head; |
2197 | int status; | 2206 | int status; |
2198 | int txok; | 2207 | int txok; |
2199 | int qnum; | ||
2200 | 2208 | ||
2201 | for (;;) { | 2209 | for (;;) { |
2202 | status = ath9k_hw_txprocdesc(ah, NULL, (void *)&txs); | 2210 | status = ath9k_hw_txprocdesc(ah, NULL, (void *)&txs); |
@@ -2239,11 +2247,9 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) | |||
2239 | if (!bf_isampdu(bf)) { | 2247 | if (!bf_isampdu(bf)) { |
2240 | if (txs.ts_status & ATH9K_TXERR_XRETRY) | 2248 | if (txs.ts_status & ATH9K_TXERR_XRETRY) |
2241 | bf->bf_state.bf_type |= BUF_XRETRY; | 2249 | bf->bf_state.bf_type |= BUF_XRETRY; |
2242 | ath_tx_rc_status(bf, &txs, 1, txok ? 0 : 1, txok, true); | 2250 | ath_tx_rc_status(sc, bf, &txs, 1, txok ? 0 : 1, txok, true); |
2243 | } | 2251 | } |
2244 | 2252 | ||
2245 | qnum = skb_get_queue_mapping(bf->bf_mpdu); | ||
2246 | |||
2247 | if (bf_isampdu(bf)) | 2253 | if (bf_isampdu(bf)) |
2248 | ath_tx_complete_aggr(sc, txq, bf, &bf_head, &txs, | 2254 | ath_tx_complete_aggr(sc, txq, bf, &bf_head, &txs, |
2249 | txok, true); | 2255 | txok, true); |
@@ -2252,7 +2258,6 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) | |||
2252 | &txs, txok, 0); | 2258 | &txs, txok, 0); |
2253 | 2259 | ||
2254 | spin_lock_bh(&txq->axq_lock); | 2260 | spin_lock_bh(&txq->axq_lock); |
2255 | __ath_wake_mac80211_queue(sc, txq); | ||
2256 | 2261 | ||
2257 | if (!list_empty(&txq->txq_fifo_pending)) { | 2262 | if (!list_empty(&txq->txq_fifo_pending)) { |
2258 | INIT_LIST_HEAD(&bf_head); | 2263 | INIT_LIST_HEAD(&bf_head); |
@@ -2330,6 +2335,7 @@ int ath_tx_init(struct ath_softc *sc, int nbufs) | |||
2330 | } | 2335 | } |
2331 | 2336 | ||
2332 | INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work); | 2337 | INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work); |
2338 | INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work); | ||
2333 | 2339 | ||
2334 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { | 2340 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { |
2335 | error = ath_tx_edma_init(sc); | 2341 | error = ath_tx_edma_init(sc); |
diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index 2b14775e6bc6..f828f294ba89 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c | |||
@@ -158,6 +158,13 @@ ieee80211_regdomain *ath_world_regdomain(struct ath_regulatory *reg) | |||
158 | } | 158 | } |
159 | } | 159 | } |
160 | 160 | ||
161 | bool ath_is_49ghz_allowed(u16 regdomain) | ||
162 | { | ||
163 | /* possibly more */ | ||
164 | return regdomain == MKK9_MKKC; | ||
165 | } | ||
166 | EXPORT_SYMBOL(ath_is_49ghz_allowed); | ||
167 | |||
161 | /* Frequency is one where radar detection is required */ | 168 | /* Frequency is one where radar detection is required */ |
162 | static bool ath_is_radar_freq(u16 center_freq) | 169 | static bool ath_is_radar_freq(u16 center_freq) |
163 | { | 170 | { |
diff --git a/drivers/net/wireless/ath/regd.h b/drivers/net/wireless/ath/regd.h index 345dd9721b41..172f63f671cf 100644 --- a/drivers/net/wireless/ath/regd.h +++ b/drivers/net/wireless/ath/regd.h | |||
@@ -250,6 +250,7 @@ enum CountryCode { | |||
250 | }; | 250 | }; |
251 | 251 | ||
252 | bool ath_is_world_regd(struct ath_regulatory *reg); | 252 | bool ath_is_world_regd(struct ath_regulatory *reg); |
253 | bool ath_is_49ghz_allowed(u16 redomain); | ||
253 | int ath_regd_init(struct ath_regulatory *reg, struct wiphy *wiphy, | 254 | int ath_regd_init(struct ath_regulatory *reg, struct wiphy *wiphy, |
254 | int (*reg_notifier)(struct wiphy *wiphy, | 255 | int (*reg_notifier)(struct wiphy *wiphy, |
255 | struct regulatory_request *request)); | 256 | struct regulatory_request *request)); |