diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath5k/base.c')
-rw-r--r-- | drivers/net/wireless/ath/ath5k/base.c | 2808 |
1 files changed, 1125 insertions, 1683 deletions
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index d77ce9906b6c..b6c5d3715b96 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -47,11 +47,10 @@ | |||
47 | #include <linux/io.h> | 47 | #include <linux/io.h> |
48 | #include <linux/netdevice.h> | 48 | #include <linux/netdevice.h> |
49 | #include <linux/cache.h> | 49 | #include <linux/cache.h> |
50 | #include <linux/pci.h> | ||
51 | #include <linux/pci-aspm.h> | ||
52 | #include <linux/ethtool.h> | 50 | #include <linux/ethtool.h> |
53 | #include <linux/uaccess.h> | 51 | #include <linux/uaccess.h> |
54 | #include <linux/slab.h> | 52 | #include <linux/slab.h> |
53 | #include <linux/etherdevice.h> | ||
55 | 54 | ||
56 | #include <net/ieee80211_radiotap.h> | 55 | #include <net/ieee80211_radiotap.h> |
57 | 56 | ||
@@ -62,18 +61,21 @@ | |||
62 | #include "debug.h" | 61 | #include "debug.h" |
63 | #include "ani.h" | 62 | #include "ani.h" |
64 | 63 | ||
65 | static int modparam_nohwcrypt; | 64 | #define CREATE_TRACE_POINTS |
66 | module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); | 65 | #include "trace.h" |
66 | |||
67 | int ath5k_modparam_nohwcrypt; | ||
68 | module_param_named(nohwcrypt, ath5k_modparam_nohwcrypt, bool, S_IRUGO); | ||
67 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); | 69 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); |
68 | 70 | ||
69 | static int modparam_all_channels; | 71 | static int modparam_all_channels; |
70 | module_param_named(all_channels, modparam_all_channels, bool, S_IRUGO); | 72 | module_param_named(all_channels, modparam_all_channels, bool, S_IRUGO); |
71 | MODULE_PARM_DESC(all_channels, "Expose all channels the device can use."); | 73 | MODULE_PARM_DESC(all_channels, "Expose all channels the device can use."); |
72 | 74 | ||
75 | static int modparam_fastchanswitch; | ||
76 | module_param_named(fastchanswitch, modparam_fastchanswitch, bool, S_IRUGO); | ||
77 | MODULE_PARM_DESC(fastchanswitch, "Enable fast channel switching for AR2413/AR5413 radios."); | ||
73 | 78 | ||
74 | /******************\ | ||
75 | * Internal defines * | ||
76 | \******************/ | ||
77 | 79 | ||
78 | /* Module info */ | 80 | /* Module info */ |
79 | MODULE_AUTHOR("Jiri Slaby"); | 81 | MODULE_AUTHOR("Jiri Slaby"); |
@@ -81,35 +83,24 @@ MODULE_AUTHOR("Nick Kossifidis"); | |||
81 | MODULE_DESCRIPTION("Support for 5xxx series of Atheros 802.11 wireless LAN cards."); | 83 | MODULE_DESCRIPTION("Support for 5xxx series of Atheros 802.11 wireless LAN cards."); |
82 | MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards"); | 84 | MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards"); |
83 | MODULE_LICENSE("Dual BSD/GPL"); | 85 | MODULE_LICENSE("Dual BSD/GPL"); |
84 | MODULE_VERSION("0.6.0 (EXPERIMENTAL)"); | 86 | |
85 | 87 | static int ath5k_init(struct ieee80211_hw *hw); | |
86 | 88 | static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan, | |
87 | /* Known PCI ids */ | 89 | bool skip_pcu); |
88 | static DEFINE_PCI_DEVICE_TABLE(ath5k_pci_id_table) = { | 90 | int ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif); |
89 | { PCI_VDEVICE(ATHEROS, 0x0207) }, /* 5210 early */ | 91 | void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf); |
90 | { PCI_VDEVICE(ATHEROS, 0x0007) }, /* 5210 */ | ||
91 | { PCI_VDEVICE(ATHEROS, 0x0011) }, /* 5311 - this is on AHB bus !*/ | ||
92 | { PCI_VDEVICE(ATHEROS, 0x0012) }, /* 5211 */ | ||
93 | { PCI_VDEVICE(ATHEROS, 0x0013) }, /* 5212 */ | ||
94 | { PCI_VDEVICE(3COM_2, 0x0013) }, /* 3com 5212 */ | ||
95 | { PCI_VDEVICE(3COM, 0x0013) }, /* 3com 3CRDAG675 5212 */ | ||
96 | { PCI_VDEVICE(ATHEROS, 0x1014) }, /* IBM minipci 5212 */ | ||
97 | { PCI_VDEVICE(ATHEROS, 0x0014) }, /* 5212 combatible */ | ||
98 | { PCI_VDEVICE(ATHEROS, 0x0015) }, /* 5212 combatible */ | ||
99 | { PCI_VDEVICE(ATHEROS, 0x0016) }, /* 5212 combatible */ | ||
100 | { PCI_VDEVICE(ATHEROS, 0x0017) }, /* 5212 combatible */ | ||
101 | { PCI_VDEVICE(ATHEROS, 0x0018) }, /* 5212 combatible */ | ||
102 | { PCI_VDEVICE(ATHEROS, 0x0019) }, /* 5212 combatible */ | ||
103 | { PCI_VDEVICE(ATHEROS, 0x001a) }, /* 2413 Griffin-lite */ | ||
104 | { PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */ | ||
105 | { PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */ | ||
106 | { PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */ | ||
107 | { 0 } | ||
108 | }; | ||
109 | MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table); | ||
110 | 92 | ||
111 | /* Known SREVs */ | 93 | /* Known SREVs */ |
112 | static const struct ath5k_srev_name srev_names[] = { | 94 | static const struct ath5k_srev_name srev_names[] = { |
95 | #ifdef CONFIG_ATHEROS_AR231X | ||
96 | { "5312", AR5K_VERSION_MAC, AR5K_SREV_AR5312_R2 }, | ||
97 | { "5312", AR5K_VERSION_MAC, AR5K_SREV_AR5312_R7 }, | ||
98 | { "2313", AR5K_VERSION_MAC, AR5K_SREV_AR2313_R8 }, | ||
99 | { "2315", AR5K_VERSION_MAC, AR5K_SREV_AR2315_R6 }, | ||
100 | { "2315", AR5K_VERSION_MAC, AR5K_SREV_AR2315_R7 }, | ||
101 | { "2317", AR5K_VERSION_MAC, AR5K_SREV_AR2317_R1 }, | ||
102 | { "2317", AR5K_VERSION_MAC, AR5K_SREV_AR2317_R2 }, | ||
103 | #else | ||
113 | { "5210", AR5K_VERSION_MAC, AR5K_SREV_AR5210 }, | 104 | { "5210", AR5K_VERSION_MAC, AR5K_SREV_AR5210 }, |
114 | { "5311", AR5K_VERSION_MAC, AR5K_SREV_AR5311 }, | 105 | { "5311", AR5K_VERSION_MAC, AR5K_SREV_AR5311 }, |
115 | { "5311A", AR5K_VERSION_MAC, AR5K_SREV_AR5311A }, | 106 | { "5311A", AR5K_VERSION_MAC, AR5K_SREV_AR5311A }, |
@@ -128,6 +119,7 @@ static const struct ath5k_srev_name srev_names[] = { | |||
128 | { "5418", AR5K_VERSION_MAC, AR5K_SREV_AR5418 }, | 119 | { "5418", AR5K_VERSION_MAC, AR5K_SREV_AR5418 }, |
129 | { "2425", AR5K_VERSION_MAC, AR5K_SREV_AR2425 }, | 120 | { "2425", AR5K_VERSION_MAC, AR5K_SREV_AR2425 }, |
130 | { "2417", AR5K_VERSION_MAC, AR5K_SREV_AR2417 }, | 121 | { "2417", AR5K_VERSION_MAC, AR5K_SREV_AR2417 }, |
122 | #endif | ||
131 | { "xxxxx", AR5K_VERSION_MAC, AR5K_SREV_UNKNOWN }, | 123 | { "xxxxx", AR5K_VERSION_MAC, AR5K_SREV_UNKNOWN }, |
132 | { "5110", AR5K_VERSION_RAD, AR5K_SREV_RAD_5110 }, | 124 | { "5110", AR5K_VERSION_RAD, AR5K_SREV_RAD_5110 }, |
133 | { "5111", AR5K_VERSION_RAD, AR5K_SREV_RAD_5111 }, | 125 | { "5111", AR5K_VERSION_RAD, AR5K_SREV_RAD_5111 }, |
@@ -141,10 +133,12 @@ static const struct ath5k_srev_name srev_names[] = { | |||
141 | { "2112B", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112B }, | 133 | { "2112B", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112B }, |
142 | { "2413", AR5K_VERSION_RAD, AR5K_SREV_RAD_2413 }, | 134 | { "2413", AR5K_VERSION_RAD, AR5K_SREV_RAD_2413 }, |
143 | { "5413", AR5K_VERSION_RAD, AR5K_SREV_RAD_5413 }, | 135 | { "5413", AR5K_VERSION_RAD, AR5K_SREV_RAD_5413 }, |
144 | { "2316", AR5K_VERSION_RAD, AR5K_SREV_RAD_2316 }, | ||
145 | { "2317", AR5K_VERSION_RAD, AR5K_SREV_RAD_2317 }, | ||
146 | { "5424", AR5K_VERSION_RAD, AR5K_SREV_RAD_5424 }, | 136 | { "5424", AR5K_VERSION_RAD, AR5K_SREV_RAD_5424 }, |
147 | { "5133", AR5K_VERSION_RAD, AR5K_SREV_RAD_5133 }, | 137 | { "5133", AR5K_VERSION_RAD, AR5K_SREV_RAD_5133 }, |
138 | #ifdef CONFIG_ATHEROS_AR231X | ||
139 | { "2316", AR5K_VERSION_RAD, AR5K_SREV_RAD_2316 }, | ||
140 | { "2317", AR5K_VERSION_RAD, AR5K_SREV_RAD_2317 }, | ||
141 | #endif | ||
148 | { "xxxxx", AR5K_VERSION_RAD, AR5K_SREV_UNKNOWN }, | 142 | { "xxxxx", AR5K_VERSION_RAD, AR5K_SREV_UNKNOWN }, |
149 | }; | 143 | }; |
150 | 144 | ||
@@ -190,190 +184,6 @@ static const struct ieee80211_rate ath5k_rates[] = { | |||
190 | /* XR missing */ | 184 | /* XR missing */ |
191 | }; | 185 | }; |
192 | 186 | ||
193 | /* | ||
194 | * Prototypes - PCI stack related functions | ||
195 | */ | ||
196 | static int __devinit ath5k_pci_probe(struct pci_dev *pdev, | ||
197 | const struct pci_device_id *id); | ||
198 | static void __devexit ath5k_pci_remove(struct pci_dev *pdev); | ||
199 | #ifdef CONFIG_PM_SLEEP | ||
200 | static int ath5k_pci_suspend(struct device *dev); | ||
201 | static int ath5k_pci_resume(struct device *dev); | ||
202 | |||
203 | static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume); | ||
204 | #define ATH5K_PM_OPS (&ath5k_pm_ops) | ||
205 | #else | ||
206 | #define ATH5K_PM_OPS NULL | ||
207 | #endif /* CONFIG_PM_SLEEP */ | ||
208 | |||
209 | static struct pci_driver ath5k_pci_driver = { | ||
210 | .name = KBUILD_MODNAME, | ||
211 | .id_table = ath5k_pci_id_table, | ||
212 | .probe = ath5k_pci_probe, | ||
213 | .remove = __devexit_p(ath5k_pci_remove), | ||
214 | .driver.pm = ATH5K_PM_OPS, | ||
215 | }; | ||
216 | |||
217 | |||
218 | |||
219 | /* | ||
220 | * Prototypes - MAC 802.11 stack related functions | ||
221 | */ | ||
222 | static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb); | ||
223 | static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
224 | struct ath5k_txq *txq); | ||
225 | static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan); | ||
226 | static int ath5k_start(struct ieee80211_hw *hw); | ||
227 | static void ath5k_stop(struct ieee80211_hw *hw); | ||
228 | static int ath5k_add_interface(struct ieee80211_hw *hw, | ||
229 | struct ieee80211_vif *vif); | ||
230 | static void ath5k_remove_interface(struct ieee80211_hw *hw, | ||
231 | struct ieee80211_vif *vif); | ||
232 | static int ath5k_config(struct ieee80211_hw *hw, u32 changed); | ||
233 | static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw, | ||
234 | struct netdev_hw_addr_list *mc_list); | ||
235 | static void ath5k_configure_filter(struct ieee80211_hw *hw, | ||
236 | unsigned int changed_flags, | ||
237 | unsigned int *new_flags, | ||
238 | u64 multicast); | ||
239 | static int ath5k_set_key(struct ieee80211_hw *hw, | ||
240 | enum set_key_cmd cmd, | ||
241 | struct ieee80211_vif *vif, struct ieee80211_sta *sta, | ||
242 | struct ieee80211_key_conf *key); | ||
243 | static int ath5k_get_stats(struct ieee80211_hw *hw, | ||
244 | struct ieee80211_low_level_stats *stats); | ||
245 | static int ath5k_get_survey(struct ieee80211_hw *hw, | ||
246 | int idx, struct survey_info *survey); | ||
247 | static u64 ath5k_get_tsf(struct ieee80211_hw *hw); | ||
248 | static void ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf); | ||
249 | static void ath5k_reset_tsf(struct ieee80211_hw *hw); | ||
250 | static int ath5k_beacon_update(struct ieee80211_hw *hw, | ||
251 | struct ieee80211_vif *vif); | ||
252 | static void ath5k_bss_info_changed(struct ieee80211_hw *hw, | ||
253 | struct ieee80211_vif *vif, | ||
254 | struct ieee80211_bss_conf *bss_conf, | ||
255 | u32 changes); | ||
256 | static void ath5k_sw_scan_start(struct ieee80211_hw *hw); | ||
257 | static void ath5k_sw_scan_complete(struct ieee80211_hw *hw); | ||
258 | static void ath5k_set_coverage_class(struct ieee80211_hw *hw, | ||
259 | u8 coverage_class); | ||
260 | |||
261 | static const struct ieee80211_ops ath5k_hw_ops = { | ||
262 | .tx = ath5k_tx, | ||
263 | .start = ath5k_start, | ||
264 | .stop = ath5k_stop, | ||
265 | .add_interface = ath5k_add_interface, | ||
266 | .remove_interface = ath5k_remove_interface, | ||
267 | .config = ath5k_config, | ||
268 | .prepare_multicast = ath5k_prepare_multicast, | ||
269 | .configure_filter = ath5k_configure_filter, | ||
270 | .set_key = ath5k_set_key, | ||
271 | .get_stats = ath5k_get_stats, | ||
272 | .get_survey = ath5k_get_survey, | ||
273 | .conf_tx = NULL, | ||
274 | .get_tsf = ath5k_get_tsf, | ||
275 | .set_tsf = ath5k_set_tsf, | ||
276 | .reset_tsf = ath5k_reset_tsf, | ||
277 | .bss_info_changed = ath5k_bss_info_changed, | ||
278 | .sw_scan_start = ath5k_sw_scan_start, | ||
279 | .sw_scan_complete = ath5k_sw_scan_complete, | ||
280 | .set_coverage_class = ath5k_set_coverage_class, | ||
281 | }; | ||
282 | |||
283 | /* | ||
284 | * Prototypes - Internal functions | ||
285 | */ | ||
286 | /* Attach detach */ | ||
287 | static int ath5k_attach(struct pci_dev *pdev, | ||
288 | struct ieee80211_hw *hw); | ||
289 | static void ath5k_detach(struct pci_dev *pdev, | ||
290 | struct ieee80211_hw *hw); | ||
291 | /* Channel/mode setup */ | ||
292 | static inline short ath5k_ieee2mhz(short chan); | ||
293 | static unsigned int ath5k_copy_channels(struct ath5k_hw *ah, | ||
294 | struct ieee80211_channel *channels, | ||
295 | unsigned int mode, | ||
296 | unsigned int max); | ||
297 | static int ath5k_setup_bands(struct ieee80211_hw *hw); | ||
298 | static int ath5k_chan_set(struct ath5k_softc *sc, | ||
299 | struct ieee80211_channel *chan); | ||
300 | static void ath5k_setcurmode(struct ath5k_softc *sc, | ||
301 | unsigned int mode); | ||
302 | static void ath5k_mode_setup(struct ath5k_softc *sc); | ||
303 | |||
304 | /* Descriptor setup */ | ||
305 | static int ath5k_desc_alloc(struct ath5k_softc *sc, | ||
306 | struct pci_dev *pdev); | ||
307 | static void ath5k_desc_free(struct ath5k_softc *sc, | ||
308 | struct pci_dev *pdev); | ||
309 | /* Buffers setup */ | ||
310 | static int ath5k_rxbuf_setup(struct ath5k_softc *sc, | ||
311 | struct ath5k_buf *bf); | ||
312 | static int ath5k_txbuf_setup(struct ath5k_softc *sc, | ||
313 | struct ath5k_buf *bf, | ||
314 | struct ath5k_txq *txq, int padsize); | ||
315 | |||
316 | static inline void ath5k_txbuf_free_skb(struct ath5k_softc *sc, | ||
317 | struct ath5k_buf *bf) | ||
318 | { | ||
319 | BUG_ON(!bf); | ||
320 | if (!bf->skb) | ||
321 | return; | ||
322 | pci_unmap_single(sc->pdev, bf->skbaddr, bf->skb->len, | ||
323 | PCI_DMA_TODEVICE); | ||
324 | dev_kfree_skb_any(bf->skb); | ||
325 | bf->skb = NULL; | ||
326 | bf->skbaddr = 0; | ||
327 | bf->desc->ds_data = 0; | ||
328 | } | ||
329 | |||
330 | static inline void ath5k_rxbuf_free_skb(struct ath5k_softc *sc, | ||
331 | struct ath5k_buf *bf) | ||
332 | { | ||
333 | struct ath5k_hw *ah = sc->ah; | ||
334 | struct ath_common *common = ath5k_hw_common(ah); | ||
335 | |||
336 | BUG_ON(!bf); | ||
337 | if (!bf->skb) | ||
338 | return; | ||
339 | pci_unmap_single(sc->pdev, bf->skbaddr, common->rx_bufsize, | ||
340 | PCI_DMA_FROMDEVICE); | ||
341 | dev_kfree_skb_any(bf->skb); | ||
342 | bf->skb = NULL; | ||
343 | bf->skbaddr = 0; | ||
344 | bf->desc->ds_data = 0; | ||
345 | } | ||
346 | |||
347 | |||
348 | /* Queues setup */ | ||
349 | static struct ath5k_txq *ath5k_txq_setup(struct ath5k_softc *sc, | ||
350 | int qtype, int subtype); | ||
351 | static int ath5k_beaconq_setup(struct ath5k_hw *ah); | ||
352 | static int ath5k_beaconq_config(struct ath5k_softc *sc); | ||
353 | static void ath5k_txq_drainq(struct ath5k_softc *sc, | ||
354 | struct ath5k_txq *txq); | ||
355 | static void ath5k_txq_cleanup(struct ath5k_softc *sc); | ||
356 | static void ath5k_txq_release(struct ath5k_softc *sc); | ||
357 | /* Rx handling */ | ||
358 | static int ath5k_rx_start(struct ath5k_softc *sc); | ||
359 | static void ath5k_rx_stop(struct ath5k_softc *sc); | ||
360 | static unsigned int ath5k_rx_decrypted(struct ath5k_softc *sc, | ||
361 | struct sk_buff *skb, | ||
362 | struct ath5k_rx_status *rs); | ||
363 | static void ath5k_tasklet_rx(unsigned long data); | ||
364 | /* Tx handling */ | ||
365 | static void ath5k_tx_processq(struct ath5k_softc *sc, | ||
366 | struct ath5k_txq *txq); | ||
367 | static void ath5k_tasklet_tx(unsigned long data); | ||
368 | /* Beacon handling */ | ||
369 | static int ath5k_beacon_setup(struct ath5k_softc *sc, | ||
370 | struct ath5k_buf *bf); | ||
371 | static void ath5k_beacon_send(struct ath5k_softc *sc); | ||
372 | static void ath5k_beacon_config(struct ath5k_softc *sc); | ||
373 | static void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf); | ||
374 | static void ath5k_tasklet_beacon(unsigned long data); | ||
375 | static void ath5k_tasklet_ani(unsigned long data); | ||
376 | |||
377 | static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp) | 187 | static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp) |
378 | { | 188 | { |
379 | u64 tsf = ath5k_hw_get_tsf64(ah); | 189 | u64 tsf = ath5k_hw_get_tsf64(ah); |
@@ -384,51 +194,7 @@ static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp) | |||
384 | return (tsf & ~0x7fff) | rstamp; | 194 | return (tsf & ~0x7fff) | rstamp; |
385 | } | 195 | } |
386 | 196 | ||
387 | /* Interrupt handling */ | 197 | const char * |
388 | static int ath5k_init(struct ath5k_softc *sc); | ||
389 | static int ath5k_stop_locked(struct ath5k_softc *sc); | ||
390 | static int ath5k_stop_hw(struct ath5k_softc *sc); | ||
391 | static irqreturn_t ath5k_intr(int irq, void *dev_id); | ||
392 | static void ath5k_reset_work(struct work_struct *work); | ||
393 | |||
394 | static void ath5k_tasklet_calibrate(unsigned long data); | ||
395 | |||
396 | /* | ||
397 | * Module init/exit functions | ||
398 | */ | ||
399 | static int __init | ||
400 | init_ath5k_pci(void) | ||
401 | { | ||
402 | int ret; | ||
403 | |||
404 | ath5k_debug_init(); | ||
405 | |||
406 | ret = pci_register_driver(&ath5k_pci_driver); | ||
407 | if (ret) { | ||
408 | printk(KERN_ERR "ath5k_pci: can't register pci driver\n"); | ||
409 | return ret; | ||
410 | } | ||
411 | |||
412 | return 0; | ||
413 | } | ||
414 | |||
415 | static void __exit | ||
416 | exit_ath5k_pci(void) | ||
417 | { | ||
418 | pci_unregister_driver(&ath5k_pci_driver); | ||
419 | |||
420 | ath5k_debug_finish(); | ||
421 | } | ||
422 | |||
423 | module_init(init_ath5k_pci); | ||
424 | module_exit(exit_ath5k_pci); | ||
425 | |||
426 | |||
427 | /********************\ | ||
428 | * PCI Initialization * | ||
429 | \********************/ | ||
430 | |||
431 | static const char * | ||
432 | ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val) | 198 | ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val) |
433 | { | 199 | { |
434 | const char *name = "xxxxx"; | 200 | const char *name = "xxxxx"; |
@@ -466,299 +232,6 @@ static const struct ath_ops ath5k_common_ops = { | |||
466 | .write = ath5k_iowrite32, | 232 | .write = ath5k_iowrite32, |
467 | }; | 233 | }; |
468 | 234 | ||
469 | static int __devinit | ||
470 | ath5k_pci_probe(struct pci_dev *pdev, | ||
471 | const struct pci_device_id *id) | ||
472 | { | ||
473 | void __iomem *mem; | ||
474 | struct ath5k_softc *sc; | ||
475 | struct ath_common *common; | ||
476 | struct ieee80211_hw *hw; | ||
477 | int ret; | ||
478 | u8 csz; | ||
479 | |||
480 | /* | ||
481 | * L0s needs to be disabled on all ath5k cards. | ||
482 | * | ||
483 | * For distributions shipping with CONFIG_PCIEASPM (this will be enabled | ||
484 | * by default in the future in 2.6.36) this will also mean both L1 and | ||
485 | * L0s will be disabled when a pre 1.1 PCIe device is detected. We do | ||
486 | * know L1 works correctly even for all ath5k pre 1.1 PCIe devices | ||
487 | * though but cannot currently undue the effect of a blacklist, for | ||
488 | * details you can read pcie_aspm_sanity_check() and see how it adjusts | ||
489 | * the device link capability. | ||
490 | * | ||
491 | * It may be possible in the future to implement some PCI API to allow | ||
492 | * drivers to override blacklists for pre 1.1 PCIe but for now it is | ||
493 | * best to accept that both L0s and L1 will be disabled completely for | ||
494 | * distributions shipping with CONFIG_PCIEASPM rather than having this | ||
495 | * issue present. Motivation for adding this new API will be to help | ||
496 | * with power consumption for some of these devices. | ||
497 | */ | ||
498 | pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S); | ||
499 | |||
500 | ret = pci_enable_device(pdev); | ||
501 | if (ret) { | ||
502 | dev_err(&pdev->dev, "can't enable device\n"); | ||
503 | goto err; | ||
504 | } | ||
505 | |||
506 | /* XXX 32-bit addressing only */ | ||
507 | ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | ||
508 | if (ret) { | ||
509 | dev_err(&pdev->dev, "32-bit DMA not available\n"); | ||
510 | goto err_dis; | ||
511 | } | ||
512 | |||
513 | /* | ||
514 | * Cache line size is used to size and align various | ||
515 | * structures used to communicate with the hardware. | ||
516 | */ | ||
517 | pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz); | ||
518 | if (csz == 0) { | ||
519 | /* | ||
520 | * Linux 2.4.18 (at least) writes the cache line size | ||
521 | * register as a 16-bit wide register which is wrong. | ||
522 | * We must have this setup properly for rx buffer | ||
523 | * DMA to work so force a reasonable value here if it | ||
524 | * comes up zero. | ||
525 | */ | ||
526 | csz = L1_CACHE_BYTES >> 2; | ||
527 | pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz); | ||
528 | } | ||
529 | /* | ||
530 | * The default setting of latency timer yields poor results, | ||
531 | * set it to the value used by other systems. It may be worth | ||
532 | * tweaking this setting more. | ||
533 | */ | ||
534 | pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8); | ||
535 | |||
536 | /* Enable bus mastering */ | ||
537 | pci_set_master(pdev); | ||
538 | |||
539 | /* | ||
540 | * Disable the RETRY_TIMEOUT register (0x41) to keep | ||
541 | * PCI Tx retries from interfering with C3 CPU state. | ||
542 | */ | ||
543 | pci_write_config_byte(pdev, 0x41, 0); | ||
544 | |||
545 | ret = pci_request_region(pdev, 0, "ath5k"); | ||
546 | if (ret) { | ||
547 | dev_err(&pdev->dev, "cannot reserve PCI memory region\n"); | ||
548 | goto err_dis; | ||
549 | } | ||
550 | |||
551 | mem = pci_iomap(pdev, 0, 0); | ||
552 | if (!mem) { | ||
553 | dev_err(&pdev->dev, "cannot remap PCI memory region\n") ; | ||
554 | ret = -EIO; | ||
555 | goto err_reg; | ||
556 | } | ||
557 | |||
558 | /* | ||
559 | * Allocate hw (mac80211 main struct) | ||
560 | * and hw->priv (driver private data) | ||
561 | */ | ||
562 | hw = ieee80211_alloc_hw(sizeof(*sc), &ath5k_hw_ops); | ||
563 | if (hw == NULL) { | ||
564 | dev_err(&pdev->dev, "cannot allocate ieee80211_hw\n"); | ||
565 | ret = -ENOMEM; | ||
566 | goto err_map; | ||
567 | } | ||
568 | |||
569 | dev_info(&pdev->dev, "registered as '%s'\n", wiphy_name(hw->wiphy)); | ||
570 | |||
571 | /* Initialize driver private data */ | ||
572 | SET_IEEE80211_DEV(hw, &pdev->dev); | ||
573 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | ||
574 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | ||
575 | IEEE80211_HW_SIGNAL_DBM; | ||
576 | |||
577 | hw->wiphy->interface_modes = | ||
578 | BIT(NL80211_IFTYPE_AP) | | ||
579 | BIT(NL80211_IFTYPE_STATION) | | ||
580 | BIT(NL80211_IFTYPE_ADHOC) | | ||
581 | BIT(NL80211_IFTYPE_MESH_POINT); | ||
582 | |||
583 | hw->extra_tx_headroom = 2; | ||
584 | hw->channel_change_time = 5000; | ||
585 | sc = hw->priv; | ||
586 | sc->hw = hw; | ||
587 | sc->pdev = pdev; | ||
588 | |||
589 | ath5k_debug_init_device(sc); | ||
590 | |||
591 | /* | ||
592 | * Mark the device as detached to avoid processing | ||
593 | * interrupts until setup is complete. | ||
594 | */ | ||
595 | __set_bit(ATH_STAT_INVALID, sc->status); | ||
596 | |||
597 | sc->iobase = mem; /* So we can unmap it on detach */ | ||
598 | sc->opmode = NL80211_IFTYPE_STATION; | ||
599 | sc->bintval = 1000; | ||
600 | mutex_init(&sc->lock); | ||
601 | spin_lock_init(&sc->rxbuflock); | ||
602 | spin_lock_init(&sc->txbuflock); | ||
603 | spin_lock_init(&sc->block); | ||
604 | |||
605 | /* Set private data */ | ||
606 | pci_set_drvdata(pdev, sc); | ||
607 | |||
608 | /* Setup interrupt handler */ | ||
609 | ret = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc); | ||
610 | if (ret) { | ||
611 | ATH5K_ERR(sc, "request_irq failed\n"); | ||
612 | goto err_free; | ||
613 | } | ||
614 | |||
615 | /*If we passed the test malloc a ath5k_hw struct*/ | ||
616 | sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL); | ||
617 | if (!sc->ah) { | ||
618 | ret = -ENOMEM; | ||
619 | ATH5K_ERR(sc, "out of memory\n"); | ||
620 | goto err_irq; | ||
621 | } | ||
622 | |||
623 | sc->ah->ah_sc = sc; | ||
624 | sc->ah->ah_iobase = sc->iobase; | ||
625 | common = ath5k_hw_common(sc->ah); | ||
626 | common->ops = &ath5k_common_ops; | ||
627 | common->ah = sc->ah; | ||
628 | common->hw = hw; | ||
629 | common->cachelsz = csz << 2; /* convert to bytes */ | ||
630 | |||
631 | /* Initialize device */ | ||
632 | ret = ath5k_hw_attach(sc); | ||
633 | if (ret) { | ||
634 | goto err_free_ah; | ||
635 | } | ||
636 | |||
637 | /* set up multi-rate retry capabilities */ | ||
638 | if (sc->ah->ah_version == AR5K_AR5212) { | ||
639 | hw->max_rates = 4; | ||
640 | hw->max_rate_tries = 11; | ||
641 | } | ||
642 | |||
643 | /* Finish private driver data initialization */ | ||
644 | ret = ath5k_attach(pdev, hw); | ||
645 | if (ret) | ||
646 | goto err_ah; | ||
647 | |||
648 | ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n", | ||
649 | ath5k_chip_name(AR5K_VERSION_MAC, sc->ah->ah_mac_srev), | ||
650 | sc->ah->ah_mac_srev, | ||
651 | sc->ah->ah_phy_revision); | ||
652 | |||
653 | if (!sc->ah->ah_single_chip) { | ||
654 | /* Single chip radio (!RF5111) */ | ||
655 | if (sc->ah->ah_radio_5ghz_revision && | ||
656 | !sc->ah->ah_radio_2ghz_revision) { | ||
657 | /* No 5GHz support -> report 2GHz radio */ | ||
658 | if (!test_bit(AR5K_MODE_11A, | ||
659 | sc->ah->ah_capabilities.cap_mode)) { | ||
660 | ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n", | ||
661 | ath5k_chip_name(AR5K_VERSION_RAD, | ||
662 | sc->ah->ah_radio_5ghz_revision), | ||
663 | sc->ah->ah_radio_5ghz_revision); | ||
664 | /* No 2GHz support (5110 and some | ||
665 | * 5Ghz only cards) -> report 5Ghz radio */ | ||
666 | } else if (!test_bit(AR5K_MODE_11B, | ||
667 | sc->ah->ah_capabilities.cap_mode)) { | ||
668 | ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n", | ||
669 | ath5k_chip_name(AR5K_VERSION_RAD, | ||
670 | sc->ah->ah_radio_5ghz_revision), | ||
671 | sc->ah->ah_radio_5ghz_revision); | ||
672 | /* Multiband radio */ | ||
673 | } else { | ||
674 | ATH5K_INFO(sc, "RF%s multiband radio found" | ||
675 | " (0x%x)\n", | ||
676 | ath5k_chip_name(AR5K_VERSION_RAD, | ||
677 | sc->ah->ah_radio_5ghz_revision), | ||
678 | sc->ah->ah_radio_5ghz_revision); | ||
679 | } | ||
680 | } | ||
681 | /* Multi chip radio (RF5111 - RF2111) -> | ||
682 | * report both 2GHz/5GHz radios */ | ||
683 | else if (sc->ah->ah_radio_5ghz_revision && | ||
684 | sc->ah->ah_radio_2ghz_revision){ | ||
685 | ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n", | ||
686 | ath5k_chip_name(AR5K_VERSION_RAD, | ||
687 | sc->ah->ah_radio_5ghz_revision), | ||
688 | sc->ah->ah_radio_5ghz_revision); | ||
689 | ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n", | ||
690 | ath5k_chip_name(AR5K_VERSION_RAD, | ||
691 | sc->ah->ah_radio_2ghz_revision), | ||
692 | sc->ah->ah_radio_2ghz_revision); | ||
693 | } | ||
694 | } | ||
695 | |||
696 | |||
697 | /* ready to process interrupts */ | ||
698 | __clear_bit(ATH_STAT_INVALID, sc->status); | ||
699 | |||
700 | return 0; | ||
701 | err_ah: | ||
702 | ath5k_hw_detach(sc->ah); | ||
703 | err_irq: | ||
704 | free_irq(pdev->irq, sc); | ||
705 | err_free_ah: | ||
706 | kfree(sc->ah); | ||
707 | err_free: | ||
708 | ieee80211_free_hw(hw); | ||
709 | err_map: | ||
710 | pci_iounmap(pdev, mem); | ||
711 | err_reg: | ||
712 | pci_release_region(pdev, 0); | ||
713 | err_dis: | ||
714 | pci_disable_device(pdev); | ||
715 | err: | ||
716 | return ret; | ||
717 | } | ||
718 | |||
719 | static void __devexit | ||
720 | ath5k_pci_remove(struct pci_dev *pdev) | ||
721 | { | ||
722 | struct ath5k_softc *sc = pci_get_drvdata(pdev); | ||
723 | |||
724 | ath5k_debug_finish_device(sc); | ||
725 | ath5k_detach(pdev, sc->hw); | ||
726 | ath5k_hw_detach(sc->ah); | ||
727 | kfree(sc->ah); | ||
728 | free_irq(pdev->irq, sc); | ||
729 | pci_iounmap(pdev, sc->iobase); | ||
730 | pci_release_region(pdev, 0); | ||
731 | pci_disable_device(pdev); | ||
732 | ieee80211_free_hw(sc->hw); | ||
733 | } | ||
734 | |||
735 | #ifdef CONFIG_PM_SLEEP | ||
736 | static int ath5k_pci_suspend(struct device *dev) | ||
737 | { | ||
738 | struct ath5k_softc *sc = pci_get_drvdata(to_pci_dev(dev)); | ||
739 | |||
740 | ath5k_led_off(sc); | ||
741 | return 0; | ||
742 | } | ||
743 | |||
744 | static int ath5k_pci_resume(struct device *dev) | ||
745 | { | ||
746 | struct pci_dev *pdev = to_pci_dev(dev); | ||
747 | struct ath5k_softc *sc = pci_get_drvdata(pdev); | ||
748 | |||
749 | /* | ||
750 | * Suspend/Resume resets the PCI configuration space, so we have to | ||
751 | * re-disable the RETRY_TIMEOUT register (0x41) to keep | ||
752 | * PCI Tx retries from interfering with C3 CPU state | ||
753 | */ | ||
754 | pci_write_config_byte(pdev, 0x41, 0); | ||
755 | |||
756 | ath5k_led_enable(sc); | ||
757 | return 0; | ||
758 | } | ||
759 | #endif /* CONFIG_PM_SLEEP */ | ||
760 | |||
761 | |||
762 | /***********************\ | 235 | /***********************\ |
763 | * Driver Initialization * | 236 | * Driver Initialization * |
764 | \***********************/ | 237 | \***********************/ |
@@ -772,260 +245,83 @@ static int ath5k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *re | |||
772 | return ath_reg_notifier_apply(wiphy, request, regulatory); | 245 | return ath_reg_notifier_apply(wiphy, request, regulatory); |
773 | } | 246 | } |
774 | 247 | ||
775 | static int | ||
776 | ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) | ||
777 | { | ||
778 | struct ath5k_softc *sc = hw->priv; | ||
779 | struct ath5k_hw *ah = sc->ah; | ||
780 | struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah); | ||
781 | u8 mac[ETH_ALEN] = {}; | ||
782 | int ret; | ||
783 | |||
784 | ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "devid 0x%x\n", pdev->device); | ||
785 | |||
786 | /* | ||
787 | * Check if the MAC has multi-rate retry support. | ||
788 | * We do this by trying to setup a fake extended | ||
789 | * descriptor. MAC's that don't have support will | ||
790 | * return false w/o doing anything. MAC's that do | ||
791 | * support it will return true w/o doing anything. | ||
792 | */ | ||
793 | ret = ath5k_hw_setup_mrr_tx_desc(ah, NULL, 0, 0, 0, 0, 0, 0); | ||
794 | |||
795 | if (ret < 0) | ||
796 | goto err; | ||
797 | if (ret > 0) | ||
798 | __set_bit(ATH_STAT_MRRETRY, sc->status); | ||
799 | |||
800 | /* | ||
801 | * Collect the channel list. The 802.11 layer | ||
802 | * is resposible for filtering this list based | ||
803 | * on settings like the phy mode and regulatory | ||
804 | * domain restrictions. | ||
805 | */ | ||
806 | ret = ath5k_setup_bands(hw); | ||
807 | if (ret) { | ||
808 | ATH5K_ERR(sc, "can't get channels\n"); | ||
809 | goto err; | ||
810 | } | ||
811 | |||
812 | /* NB: setup here so ath5k_rate_update is happy */ | ||
813 | if (test_bit(AR5K_MODE_11A, ah->ah_modes)) | ||
814 | ath5k_setcurmode(sc, AR5K_MODE_11A); | ||
815 | else | ||
816 | ath5k_setcurmode(sc, AR5K_MODE_11B); | ||
817 | |||
818 | /* | ||
819 | * Allocate tx+rx descriptors and populate the lists. | ||
820 | */ | ||
821 | ret = ath5k_desc_alloc(sc, pdev); | ||
822 | if (ret) { | ||
823 | ATH5K_ERR(sc, "can't allocate descriptors\n"); | ||
824 | goto err; | ||
825 | } | ||
826 | |||
827 | /* | ||
828 | * Allocate hardware transmit queues: one queue for | ||
829 | * beacon frames and one data queue for each QoS | ||
830 | * priority. Note that hw functions handle reseting | ||
831 | * these queues at the needed time. | ||
832 | */ | ||
833 | ret = ath5k_beaconq_setup(ah); | ||
834 | if (ret < 0) { | ||
835 | ATH5K_ERR(sc, "can't setup a beacon xmit queue\n"); | ||
836 | goto err_desc; | ||
837 | } | ||
838 | sc->bhalq = ret; | ||
839 | sc->cabq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_CAB, 0); | ||
840 | if (IS_ERR(sc->cabq)) { | ||
841 | ATH5K_ERR(sc, "can't setup cab queue\n"); | ||
842 | ret = PTR_ERR(sc->cabq); | ||
843 | goto err_bhal; | ||
844 | } | ||
845 | |||
846 | sc->txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BK); | ||
847 | if (IS_ERR(sc->txq)) { | ||
848 | ATH5K_ERR(sc, "can't setup xmit queue\n"); | ||
849 | ret = PTR_ERR(sc->txq); | ||
850 | goto err_queues; | ||
851 | } | ||
852 | |||
853 | tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc); | ||
854 | tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc); | ||
855 | tasklet_init(&sc->calib, ath5k_tasklet_calibrate, (unsigned long)sc); | ||
856 | tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc); | ||
857 | tasklet_init(&sc->ani_tasklet, ath5k_tasklet_ani, (unsigned long)sc); | ||
858 | |||
859 | INIT_WORK(&sc->reset_work, ath5k_reset_work); | ||
860 | |||
861 | ret = ath5k_eeprom_read_mac(ah, mac); | ||
862 | if (ret) { | ||
863 | ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n", | ||
864 | sc->pdev->device); | ||
865 | goto err_queues; | ||
866 | } | ||
867 | |||
868 | SET_IEEE80211_PERM_ADDR(hw, mac); | ||
869 | /* All MAC address bits matter for ACKs */ | ||
870 | memcpy(sc->bssidmask, ath_bcast_mac, ETH_ALEN); | ||
871 | ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask); | ||
872 | |||
873 | regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain; | ||
874 | ret = ath_regd_init(regulatory, hw->wiphy, ath5k_reg_notifier); | ||
875 | if (ret) { | ||
876 | ATH5K_ERR(sc, "can't initialize regulatory system\n"); | ||
877 | goto err_queues; | ||
878 | } | ||
879 | |||
880 | ret = ieee80211_register_hw(hw); | ||
881 | if (ret) { | ||
882 | ATH5K_ERR(sc, "can't register ieee80211 hw\n"); | ||
883 | goto err_queues; | ||
884 | } | ||
885 | |||
886 | if (!ath_is_world_regd(regulatory)) | ||
887 | regulatory_hint(hw->wiphy, regulatory->alpha2); | ||
888 | |||
889 | ath5k_init_leds(sc); | ||
890 | |||
891 | ath5k_sysfs_register(sc); | ||
892 | |||
893 | return 0; | ||
894 | err_queues: | ||
895 | ath5k_txq_release(sc); | ||
896 | err_bhal: | ||
897 | ath5k_hw_release_tx_queue(ah, sc->bhalq); | ||
898 | err_desc: | ||
899 | ath5k_desc_free(sc, pdev); | ||
900 | err: | ||
901 | return ret; | ||
902 | } | ||
903 | |||
904 | static void | ||
905 | ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw) | ||
906 | { | ||
907 | struct ath5k_softc *sc = hw->priv; | ||
908 | |||
909 | /* | ||
910 | * NB: the order of these is important: | ||
911 | * o call the 802.11 layer before detaching ath5k_hw to | ||
912 | * insure callbacks into the driver to delete global | ||
913 | * key cache entries can be handled | ||
914 | * o reclaim the tx queue data structures after calling | ||
915 | * the 802.11 layer as we'll get called back to reclaim | ||
916 | * node state and potentially want to use them | ||
917 | * o to cleanup the tx queues the hal is called, so detach | ||
918 | * it last | ||
919 | * XXX: ??? detach ath5k_hw ??? | ||
920 | * Other than that, it's straightforward... | ||
921 | */ | ||
922 | ieee80211_unregister_hw(hw); | ||
923 | ath5k_desc_free(sc, pdev); | ||
924 | ath5k_txq_release(sc); | ||
925 | ath5k_hw_release_tx_queue(sc->ah, sc->bhalq); | ||
926 | ath5k_unregister_leds(sc); | ||
927 | |||
928 | ath5k_sysfs_unregister(sc); | ||
929 | /* | ||
930 | * NB: can't reclaim these until after ieee80211_ifdetach | ||
931 | * returns because we'll get called back to reclaim node | ||
932 | * state and potentially want to use them. | ||
933 | */ | ||
934 | } | ||
935 | |||
936 | |||
937 | |||
938 | |||
939 | /********************\ | 248 | /********************\ |
940 | * Channel/mode setup * | 249 | * Channel/mode setup * |
941 | \********************/ | 250 | \********************/ |
942 | 251 | ||
943 | /* | 252 | /* |
944 | * Convert IEEE channel number to MHz frequency. | ||
945 | */ | ||
946 | static inline short | ||
947 | ath5k_ieee2mhz(short chan) | ||
948 | { | ||
949 | if (chan <= 14 || chan >= 27) | ||
950 | return ieee80211chan2mhz(chan); | ||
951 | else | ||
952 | return 2212 + chan * 20; | ||
953 | } | ||
954 | |||
955 | /* | ||
956 | * Returns true for the channel numbers used without all_channels modparam. | 253 | * Returns true for the channel numbers used without all_channels modparam. |
957 | */ | 254 | */ |
958 | static bool ath5k_is_standard_channel(short chan) | 255 | static bool ath5k_is_standard_channel(short chan, enum ieee80211_band band) |
959 | { | 256 | { |
960 | return ((chan <= 14) || | 257 | if (band == IEEE80211_BAND_2GHZ && chan <= 14) |
961 | /* UNII 1,2 */ | 258 | return true; |
962 | ((chan & 3) == 0 && chan >= 36 && chan <= 64) || | 259 | |
260 | return /* UNII 1,2 */ | ||
261 | (((chan & 3) == 0 && chan >= 36 && chan <= 64) || | ||
963 | /* midband */ | 262 | /* midband */ |
964 | ((chan & 3) == 0 && chan >= 100 && chan <= 140) || | 263 | ((chan & 3) == 0 && chan >= 100 && chan <= 140) || |
965 | /* UNII-3 */ | 264 | /* UNII-3 */ |
966 | ((chan & 3) == 1 && chan >= 149 && chan <= 165)); | 265 | ((chan & 3) == 1 && chan >= 149 && chan <= 165) || |
266 | /* 802.11j 5.030-5.080 GHz (20MHz) */ | ||
267 | (chan == 8 || chan == 12 || chan == 16) || | ||
268 | /* 802.11j 4.9GHz (20MHz) */ | ||
269 | (chan == 184 || chan == 188 || chan == 192 || chan == 196)); | ||
967 | } | 270 | } |
968 | 271 | ||
969 | static unsigned int | 272 | static unsigned int |
970 | ath5k_copy_channels(struct ath5k_hw *ah, | 273 | ath5k_setup_channels(struct ath5k_hw *ah, struct ieee80211_channel *channels, |
971 | struct ieee80211_channel *channels, | 274 | unsigned int mode, unsigned int max) |
972 | unsigned int mode, | ||
973 | unsigned int max) | ||
974 | { | 275 | { |
975 | unsigned int i, count, size, chfreq, freq, ch; | 276 | unsigned int count, size, chfreq, freq, ch; |
976 | 277 | enum ieee80211_band band; | |
977 | if (!test_bit(mode, ah->ah_modes)) | ||
978 | return 0; | ||
979 | 278 | ||
980 | switch (mode) { | 279 | switch (mode) { |
981 | case AR5K_MODE_11A: | 280 | case AR5K_MODE_11A: |
982 | case AR5K_MODE_11A_TURBO: | ||
983 | /* 1..220, but 2GHz frequencies are filtered by check_channel */ | 281 | /* 1..220, but 2GHz frequencies are filtered by check_channel */ |
984 | size = 220 ; | 282 | size = 220; |
985 | chfreq = CHANNEL_5GHZ; | 283 | chfreq = CHANNEL_5GHZ; |
284 | band = IEEE80211_BAND_5GHZ; | ||
986 | break; | 285 | break; |
987 | case AR5K_MODE_11B: | 286 | case AR5K_MODE_11B: |
988 | case AR5K_MODE_11G: | 287 | case AR5K_MODE_11G: |
989 | case AR5K_MODE_11G_TURBO: | ||
990 | size = 26; | 288 | size = 26; |
991 | chfreq = CHANNEL_2GHZ; | 289 | chfreq = CHANNEL_2GHZ; |
290 | band = IEEE80211_BAND_2GHZ; | ||
992 | break; | 291 | break; |
993 | default: | 292 | default: |
994 | ATH5K_WARN(ah->ah_sc, "bad mode, not copying channels\n"); | 293 | ATH5K_WARN(ah->ah_sc, "bad mode, not copying channels\n"); |
995 | return 0; | 294 | return 0; |
996 | } | 295 | } |
997 | 296 | ||
998 | for (i = 0, count = 0; i < size && max > 0; i++) { | 297 | count = 0; |
999 | ch = i + 1 ; | 298 | for (ch = 1; ch <= size && count < max; ch++) { |
1000 | freq = ath5k_ieee2mhz(ch); | 299 | freq = ieee80211_channel_to_frequency(ch, band); |
300 | |||
301 | if (freq == 0) /* mapping failed - not a standard channel */ | ||
302 | continue; | ||
1001 | 303 | ||
1002 | /* Check if channel is supported by the chipset */ | 304 | /* Check if channel is supported by the chipset */ |
1003 | if (!ath5k_channel_ok(ah, freq, chfreq)) | 305 | if (!ath5k_channel_ok(ah, freq, chfreq)) |
1004 | continue; | 306 | continue; |
1005 | 307 | ||
1006 | if (!modparam_all_channels && !ath5k_is_standard_channel(ch)) | 308 | if (!modparam_all_channels && |
309 | !ath5k_is_standard_channel(ch, band)) | ||
1007 | continue; | 310 | continue; |
1008 | 311 | ||
1009 | /* Write channel info and increment counter */ | 312 | /* Write channel info and increment counter */ |
1010 | channels[count].center_freq = freq; | 313 | channels[count].center_freq = freq; |
1011 | channels[count].band = (chfreq == CHANNEL_2GHZ) ? | 314 | channels[count].band = band; |
1012 | IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; | ||
1013 | switch (mode) { | 315 | switch (mode) { |
1014 | case AR5K_MODE_11A: | 316 | case AR5K_MODE_11A: |
1015 | case AR5K_MODE_11G: | 317 | case AR5K_MODE_11G: |
1016 | channels[count].hw_value = chfreq | CHANNEL_OFDM; | 318 | channels[count].hw_value = chfreq | CHANNEL_OFDM; |
1017 | break; | 319 | break; |
1018 | case AR5K_MODE_11A_TURBO: | ||
1019 | case AR5K_MODE_11G_TURBO: | ||
1020 | channels[count].hw_value = chfreq | | ||
1021 | CHANNEL_OFDM | CHANNEL_TURBO; | ||
1022 | break; | ||
1023 | case AR5K_MODE_11B: | 320 | case AR5K_MODE_11B: |
1024 | channels[count].hw_value = CHANNEL_B; | 321 | channels[count].hw_value = CHANNEL_B; |
1025 | } | 322 | } |
1026 | 323 | ||
1027 | count++; | 324 | count++; |
1028 | max--; | ||
1029 | } | 325 | } |
1030 | 326 | ||
1031 | return count; | 327 | return count; |
@@ -1070,7 +366,7 @@ ath5k_setup_bands(struct ieee80211_hw *hw) | |||
1070 | sband->n_bitrates = 12; | 366 | sband->n_bitrates = 12; |
1071 | 367 | ||
1072 | sband->channels = sc->channels; | 368 | sband->channels = sc->channels; |
1073 | sband->n_channels = ath5k_copy_channels(ah, sband->channels, | 369 | sband->n_channels = ath5k_setup_channels(ah, sband->channels, |
1074 | AR5K_MODE_11G, max_c); | 370 | AR5K_MODE_11G, max_c); |
1075 | 371 | ||
1076 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; | 372 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; |
@@ -1096,7 +392,7 @@ ath5k_setup_bands(struct ieee80211_hw *hw) | |||
1096 | } | 392 | } |
1097 | 393 | ||
1098 | sband->channels = sc->channels; | 394 | sband->channels = sc->channels; |
1099 | sband->n_channels = ath5k_copy_channels(ah, sband->channels, | 395 | sband->n_channels = ath5k_setup_channels(ah, sband->channels, |
1100 | AR5K_MODE_11B, max_c); | 396 | AR5K_MODE_11B, max_c); |
1101 | 397 | ||
1102 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; | 398 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; |
@@ -1116,7 +412,7 @@ ath5k_setup_bands(struct ieee80211_hw *hw) | |||
1116 | sband->n_bitrates = 8; | 412 | sband->n_bitrates = 8; |
1117 | 413 | ||
1118 | sband->channels = &sc->channels[count_c]; | 414 | sband->channels = &sc->channels[count_c]; |
1119 | sband->n_channels = ath5k_copy_channels(ah, sband->channels, | 415 | sband->n_channels = ath5k_setup_channels(ah, sband->channels, |
1120 | AR5K_MODE_11A, max_c); | 416 | AR5K_MODE_11A, max_c); |
1121 | 417 | ||
1122 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband; | 418 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband; |
@@ -1135,7 +431,7 @@ ath5k_setup_bands(struct ieee80211_hw *hw) | |||
1135 | * | 431 | * |
1136 | * Called with sc->lock. | 432 | * Called with sc->lock. |
1137 | */ | 433 | */ |
1138 | static int | 434 | int |
1139 | ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) | 435 | ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) |
1140 | { | 436 | { |
1141 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, | 437 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, |
@@ -1148,38 +444,102 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) | |||
1148 | * hardware at the new frequency, and then re-enable | 444 | * hardware at the new frequency, and then re-enable |
1149 | * the relevant bits of the h/w. | 445 | * the relevant bits of the h/w. |
1150 | */ | 446 | */ |
1151 | return ath5k_reset(sc, chan); | 447 | return ath5k_reset(sc, chan, true); |
1152 | } | 448 | } |
1153 | 449 | ||
1154 | static void | 450 | void ath5k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) |
1155 | ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode) | ||
1156 | { | 451 | { |
1157 | sc->curmode = mode; | 452 | struct ath5k_vif_iter_data *iter_data = data; |
453 | int i; | ||
454 | struct ath5k_vif *avf = (void *)vif->drv_priv; | ||
1158 | 455 | ||
1159 | if (mode == AR5K_MODE_11A) { | 456 | if (iter_data->hw_macaddr) |
1160 | sc->curband = &sc->sbands[IEEE80211_BAND_5GHZ]; | 457 | for (i = 0; i < ETH_ALEN; i++) |
1161 | } else { | 458 | iter_data->mask[i] &= |
1162 | sc->curband = &sc->sbands[IEEE80211_BAND_2GHZ]; | 459 | ~(iter_data->hw_macaddr[i] ^ mac[i]); |
460 | |||
461 | if (!iter_data->found_active) { | ||
462 | iter_data->found_active = true; | ||
463 | memcpy(iter_data->active_mac, mac, ETH_ALEN); | ||
464 | } | ||
465 | |||
466 | if (iter_data->need_set_hw_addr && iter_data->hw_macaddr) | ||
467 | if (compare_ether_addr(iter_data->hw_macaddr, mac) == 0) | ||
468 | iter_data->need_set_hw_addr = false; | ||
469 | |||
470 | if (!iter_data->any_assoc) { | ||
471 | if (avf->assoc) | ||
472 | iter_data->any_assoc = true; | ||
473 | } | ||
474 | |||
475 | /* Calculate combined mode - when APs are active, operate in AP mode. | ||
476 | * Otherwise use the mode of the new interface. This can currently | ||
477 | * only deal with combinations of APs and STAs. Only one ad-hoc | ||
478 | * interfaces is allowed. | ||
479 | */ | ||
480 | if (avf->opmode == NL80211_IFTYPE_AP) | ||
481 | iter_data->opmode = NL80211_IFTYPE_AP; | ||
482 | else { | ||
483 | if (avf->opmode == NL80211_IFTYPE_STATION) | ||
484 | iter_data->n_stas++; | ||
485 | if (iter_data->opmode == NL80211_IFTYPE_UNSPECIFIED) | ||
486 | iter_data->opmode = avf->opmode; | ||
1163 | } | 487 | } |
1164 | } | 488 | } |
1165 | 489 | ||
1166 | static void | 490 | void |
1167 | ath5k_mode_setup(struct ath5k_softc *sc) | 491 | ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc, |
492 | struct ieee80211_vif *vif) | ||
1168 | { | 493 | { |
1169 | struct ath5k_hw *ah = sc->ah; | 494 | struct ath_common *common = ath5k_hw_common(sc->ah); |
495 | struct ath5k_vif_iter_data iter_data; | ||
1170 | u32 rfilt; | 496 | u32 rfilt; |
1171 | 497 | ||
1172 | /* configure rx filter */ | 498 | /* |
1173 | rfilt = sc->filter_flags; | 499 | * Use the hardware MAC address as reference, the hardware uses it |
1174 | ath5k_hw_set_rx_filter(ah, rfilt); | 500 | * together with the BSSID mask when matching addresses. |
1175 | 501 | */ | |
1176 | if (ath5k_hw_hasbssidmask(ah)) | 502 | iter_data.hw_macaddr = common->macaddr; |
1177 | ath5k_hw_set_bssid_mask(ah, sc->bssidmask); | 503 | memset(&iter_data.mask, 0xff, ETH_ALEN); |
1178 | 504 | iter_data.found_active = false; | |
1179 | /* configure operational mode */ | 505 | iter_data.need_set_hw_addr = true; |
1180 | ath5k_hw_set_opmode(ah, sc->opmode); | 506 | iter_data.opmode = NL80211_IFTYPE_UNSPECIFIED; |
507 | iter_data.n_stas = 0; | ||
508 | |||
509 | if (vif) | ||
510 | ath5k_vif_iter(&iter_data, vif->addr, vif); | ||
511 | |||
512 | /* Get list of all active MAC addresses */ | ||
513 | ieee80211_iterate_active_interfaces_atomic(sc->hw, ath5k_vif_iter, | ||
514 | &iter_data); | ||
515 | memcpy(sc->bssidmask, iter_data.mask, ETH_ALEN); | ||
516 | |||
517 | sc->opmode = iter_data.opmode; | ||
518 | if (sc->opmode == NL80211_IFTYPE_UNSPECIFIED) | ||
519 | /* Nothing active, default to station mode */ | ||
520 | sc->opmode = NL80211_IFTYPE_STATION; | ||
521 | |||
522 | ath5k_hw_set_opmode(sc->ah, sc->opmode); | ||
523 | ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d (%s)\n", | ||
524 | sc->opmode, ath_opmode_to_string(sc->opmode)); | ||
525 | |||
526 | if (iter_data.need_set_hw_addr && iter_data.found_active) | ||
527 | ath5k_hw_set_lladdr(sc->ah, iter_data.active_mac); | ||
528 | |||
529 | if (ath5k_hw_hasbssidmask(sc->ah)) | ||
530 | ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask); | ||
531 | |||
532 | /* Set up RX Filter */ | ||
533 | if (iter_data.n_stas > 1) { | ||
534 | /* If you have multiple STA interfaces connected to | ||
535 | * different APs, ARPs are not received (most of the time?) | ||
536 | * Enabling PROMISC appears to fix that probem. | ||
537 | */ | ||
538 | sc->filter_flags |= AR5K_RX_FILTER_PROM; | ||
539 | } | ||
1181 | 540 | ||
1182 | ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d\n", sc->opmode); | 541 | rfilt = sc->filter_flags; |
542 | ath5k_hw_set_rx_filter(sc->ah, rfilt); | ||
1183 | ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); | 543 | ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); |
1184 | } | 544 | } |
1185 | 545 | ||
@@ -1193,7 +553,7 @@ ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix) | |||
1193 | "hw_rix out of bounds: %x\n", hw_rix)) | 553 | "hw_rix out of bounds: %x\n", hw_rix)) |
1194 | return 0; | 554 | return 0; |
1195 | 555 | ||
1196 | rix = sc->rate_idx[sc->curband->band][hw_rix]; | 556 | rix = sc->rate_idx[sc->curchan->band][hw_rix]; |
1197 | if (WARN(rix < 0, "invalid hw_rix: %x\n", hw_rix)) | 557 | if (WARN(rix < 0, "invalid hw_rix: %x\n", hw_rix)) |
1198 | rix = 0; | 558 | rix = 0; |
1199 | 559 | ||
@@ -1224,10 +584,11 @@ struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_softc *sc, dma_addr_t *skb_addr) | |||
1224 | return NULL; | 584 | return NULL; |
1225 | } | 585 | } |
1226 | 586 | ||
1227 | *skb_addr = pci_map_single(sc->pdev, | 587 | *skb_addr = dma_map_single(sc->dev, |
1228 | skb->data, common->rx_bufsize, | 588 | skb->data, common->rx_bufsize, |
1229 | PCI_DMA_FROMDEVICE); | 589 | DMA_FROM_DEVICE); |
1230 | if (unlikely(pci_dma_mapping_error(sc->pdev, *skb_addr))) { | 590 | |
591 | if (unlikely(dma_mapping_error(sc->dev, *skb_addr))) { | ||
1231 | ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__); | 592 | ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__); |
1232 | dev_kfree_skb(skb); | 593 | dev_kfree_skb(skb); |
1233 | return NULL; | 594 | return NULL; |
@@ -1323,8 +684,8 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, | |||
1323 | flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK; | 684 | flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK; |
1324 | 685 | ||
1325 | /* XXX endianness */ | 686 | /* XXX endianness */ |
1326 | bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len, | 687 | bf->skbaddr = dma_map_single(sc->dev, skb->data, skb->len, |
1327 | PCI_DMA_TODEVICE); | 688 | DMA_TO_DEVICE); |
1328 | 689 | ||
1329 | rate = ieee80211_get_tx_rate(sc->hw, info); | 690 | rate = ieee80211_get_tx_rate(sc->hw, info); |
1330 | if (!rate) { | 691 | if (!rate) { |
@@ -1352,13 +713,13 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, | |||
1352 | flags |= AR5K_TXDESC_RTSENA; | 713 | flags |= AR5K_TXDESC_RTSENA; |
1353 | cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value; | 714 | cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value; |
1354 | duration = le16_to_cpu(ieee80211_rts_duration(sc->hw, | 715 | duration = le16_to_cpu(ieee80211_rts_duration(sc->hw, |
1355 | sc->vif, pktlen, info)); | 716 | info->control.vif, pktlen, info)); |
1356 | } | 717 | } |
1357 | if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { | 718 | if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { |
1358 | flags |= AR5K_TXDESC_CTSENA; | 719 | flags |= AR5K_TXDESC_CTSENA; |
1359 | cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value; | 720 | cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value; |
1360 | duration = le16_to_cpu(ieee80211_ctstoself_duration(sc->hw, | 721 | duration = le16_to_cpu(ieee80211_ctstoself_duration(sc->hw, |
1361 | sc->vif, pktlen, info)); | 722 | info->control.vif, pktlen, info)); |
1362 | } | 723 | } |
1363 | ret = ah->ah_setup_tx_desc(ah, ds, pktlen, | 724 | ret = ah->ah_setup_tx_desc(ah, ds, pktlen, |
1364 | ieee80211_get_hdrlen_from_skb(skb), padsize, | 725 | ieee80211_get_hdrlen_from_skb(skb), padsize, |
@@ -1391,6 +752,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, | |||
1391 | 752 | ||
1392 | spin_lock_bh(&txq->lock); | 753 | spin_lock_bh(&txq->lock); |
1393 | list_add_tail(&bf->list, &txq->q); | 754 | list_add_tail(&bf->list, &txq->q); |
755 | txq->txq_len++; | ||
1394 | if (txq->link == NULL) /* is this first packet? */ | 756 | if (txq->link == NULL) /* is this first packet? */ |
1395 | ath5k_hw_set_txdp(ah, txq->qnum, bf->daddr); | 757 | ath5k_hw_set_txdp(ah, txq->qnum, bf->daddr); |
1396 | else /* no, so only link it */ | 758 | else /* no, so only link it */ |
@@ -1403,7 +765,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, | |||
1403 | 765 | ||
1404 | return 0; | 766 | return 0; |
1405 | err_unmap: | 767 | err_unmap: |
1406 | pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, PCI_DMA_TODEVICE); | 768 | dma_unmap_single(sc->dev, bf->skbaddr, skb->len, DMA_TO_DEVICE); |
1407 | return ret; | 769 | return ret; |
1408 | } | 770 | } |
1409 | 771 | ||
@@ -1412,7 +774,7 @@ err_unmap: | |||
1412 | \*******************/ | 774 | \*******************/ |
1413 | 775 | ||
1414 | static int | 776 | static int |
1415 | ath5k_desc_alloc(struct ath5k_softc *sc, struct pci_dev *pdev) | 777 | ath5k_desc_alloc(struct ath5k_softc *sc) |
1416 | { | 778 | { |
1417 | struct ath5k_desc *ds; | 779 | struct ath5k_desc *ds; |
1418 | struct ath5k_buf *bf; | 780 | struct ath5k_buf *bf; |
@@ -1423,7 +785,9 @@ ath5k_desc_alloc(struct ath5k_softc *sc, struct pci_dev *pdev) | |||
1423 | /* allocate descriptors */ | 785 | /* allocate descriptors */ |
1424 | sc->desc_len = sizeof(struct ath5k_desc) * | 786 | sc->desc_len = sizeof(struct ath5k_desc) * |
1425 | (ATH_TXBUF + ATH_RXBUF + ATH_BCBUF + 1); | 787 | (ATH_TXBUF + ATH_RXBUF + ATH_BCBUF + 1); |
1426 | sc->desc = pci_alloc_consistent(pdev, sc->desc_len, &sc->desc_daddr); | 788 | |
789 | sc->desc = dma_alloc_coherent(sc->dev, sc->desc_len, | ||
790 | &sc->desc_daddr, GFP_KERNEL); | ||
1427 | if (sc->desc == NULL) { | 791 | if (sc->desc == NULL) { |
1428 | ATH5K_ERR(sc, "can't allocate descriptors\n"); | 792 | ATH5K_ERR(sc, "can't allocate descriptors\n"); |
1429 | ret = -ENOMEM; | 793 | ret = -ENOMEM; |
@@ -1459,44 +823,75 @@ ath5k_desc_alloc(struct ath5k_softc *sc, struct pci_dev *pdev) | |||
1459 | list_add_tail(&bf->list, &sc->txbuf); | 823 | list_add_tail(&bf->list, &sc->txbuf); |
1460 | } | 824 | } |
1461 | 825 | ||
1462 | /* beacon buffer */ | 826 | /* beacon buffers */ |
1463 | bf->desc = ds; | 827 | INIT_LIST_HEAD(&sc->bcbuf); |
1464 | bf->daddr = da; | 828 | for (i = 0; i < ATH_BCBUF; i++, bf++, ds++, da += sizeof(*ds)) { |
1465 | sc->bbuf = bf; | 829 | bf->desc = ds; |
830 | bf->daddr = da; | ||
831 | list_add_tail(&bf->list, &sc->bcbuf); | ||
832 | } | ||
1466 | 833 | ||
1467 | return 0; | 834 | return 0; |
1468 | err_free: | 835 | err_free: |
1469 | pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr); | 836 | dma_free_coherent(sc->dev, sc->desc_len, sc->desc, sc->desc_daddr); |
1470 | err: | 837 | err: |
1471 | sc->desc = NULL; | 838 | sc->desc = NULL; |
1472 | return ret; | 839 | return ret; |
1473 | } | 840 | } |
1474 | 841 | ||
842 | void | ||
843 | ath5k_txbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf) | ||
844 | { | ||
845 | BUG_ON(!bf); | ||
846 | if (!bf->skb) | ||
847 | return; | ||
848 | dma_unmap_single(sc->dev, bf->skbaddr, bf->skb->len, | ||
849 | DMA_TO_DEVICE); | ||
850 | dev_kfree_skb_any(bf->skb); | ||
851 | bf->skb = NULL; | ||
852 | bf->skbaddr = 0; | ||
853 | bf->desc->ds_data = 0; | ||
854 | } | ||
855 | |||
856 | void | ||
857 | ath5k_rxbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf) | ||
858 | { | ||
859 | struct ath5k_hw *ah = sc->ah; | ||
860 | struct ath_common *common = ath5k_hw_common(ah); | ||
861 | |||
862 | BUG_ON(!bf); | ||
863 | if (!bf->skb) | ||
864 | return; | ||
865 | dma_unmap_single(sc->dev, bf->skbaddr, common->rx_bufsize, | ||
866 | DMA_FROM_DEVICE); | ||
867 | dev_kfree_skb_any(bf->skb); | ||
868 | bf->skb = NULL; | ||
869 | bf->skbaddr = 0; | ||
870 | bf->desc->ds_data = 0; | ||
871 | } | ||
872 | |||
1475 | static void | 873 | static void |
1476 | ath5k_desc_free(struct ath5k_softc *sc, struct pci_dev *pdev) | 874 | ath5k_desc_free(struct ath5k_softc *sc) |
1477 | { | 875 | { |
1478 | struct ath5k_buf *bf; | 876 | struct ath5k_buf *bf; |
1479 | 877 | ||
1480 | ath5k_txbuf_free_skb(sc, sc->bbuf); | ||
1481 | list_for_each_entry(bf, &sc->txbuf, list) | 878 | list_for_each_entry(bf, &sc->txbuf, list) |
1482 | ath5k_txbuf_free_skb(sc, bf); | 879 | ath5k_txbuf_free_skb(sc, bf); |
1483 | list_for_each_entry(bf, &sc->rxbuf, list) | 880 | list_for_each_entry(bf, &sc->rxbuf, list) |
1484 | ath5k_rxbuf_free_skb(sc, bf); | 881 | ath5k_rxbuf_free_skb(sc, bf); |
882 | list_for_each_entry(bf, &sc->bcbuf, list) | ||
883 | ath5k_txbuf_free_skb(sc, bf); | ||
1485 | 884 | ||
1486 | /* Free memory associated with all descriptors */ | 885 | /* Free memory associated with all descriptors */ |
1487 | pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr); | 886 | dma_free_coherent(sc->dev, sc->desc_len, sc->desc, sc->desc_daddr); |
1488 | sc->desc = NULL; | 887 | sc->desc = NULL; |
1489 | sc->desc_daddr = 0; | 888 | sc->desc_daddr = 0; |
1490 | 889 | ||
1491 | kfree(sc->bufptr); | 890 | kfree(sc->bufptr); |
1492 | sc->bufptr = NULL; | 891 | sc->bufptr = NULL; |
1493 | sc->bbuf = NULL; | ||
1494 | } | 892 | } |
1495 | 893 | ||
1496 | 894 | ||
1497 | |||
1498 | |||
1499 | |||
1500 | /**************\ | 895 | /**************\ |
1501 | * Queues setup * | 896 | * Queues setup * |
1502 | \**************/ | 897 | \**************/ |
@@ -1509,16 +904,18 @@ ath5k_txq_setup(struct ath5k_softc *sc, | |||
1509 | struct ath5k_txq *txq; | 904 | struct ath5k_txq *txq; |
1510 | struct ath5k_txq_info qi = { | 905 | struct ath5k_txq_info qi = { |
1511 | .tqi_subtype = subtype, | 906 | .tqi_subtype = subtype, |
1512 | .tqi_aifs = AR5K_TXQ_USEDEFAULT, | 907 | /* XXX: default values not correct for B and XR channels, |
1513 | .tqi_cw_min = AR5K_TXQ_USEDEFAULT, | 908 | * but who cares? */ |
1514 | .tqi_cw_max = AR5K_TXQ_USEDEFAULT | 909 | .tqi_aifs = AR5K_TUNE_AIFS, |
910 | .tqi_cw_min = AR5K_TUNE_CWMIN, | ||
911 | .tqi_cw_max = AR5K_TUNE_CWMAX | ||
1515 | }; | 912 | }; |
1516 | int qnum; | 913 | int qnum; |
1517 | 914 | ||
1518 | /* | 915 | /* |
1519 | * Enable interrupts only for EOL and DESC conditions. | 916 | * Enable interrupts only for EOL and DESC conditions. |
1520 | * We mark tx descriptors to receive a DESC interrupt | 917 | * We mark tx descriptors to receive a DESC interrupt |
1521 | * when a tx queue gets deep; otherwise waiting for the | 918 | * when a tx queue gets deep; otherwise we wait for the |
1522 | * EOL to reap descriptors. Note that this is done to | 919 | * EOL to reap descriptors. Note that this is done to |
1523 | * reduce interrupt load and this only defers reaping | 920 | * reduce interrupt load and this only defers reaping |
1524 | * descriptors, never transmitting frames. Aside from | 921 | * descriptors, never transmitting frames. Aside from |
@@ -1550,6 +947,10 @@ ath5k_txq_setup(struct ath5k_softc *sc, | |||
1550 | INIT_LIST_HEAD(&txq->q); | 947 | INIT_LIST_HEAD(&txq->q); |
1551 | spin_lock_init(&txq->lock); | 948 | spin_lock_init(&txq->lock); |
1552 | txq->setup = true; | 949 | txq->setup = true; |
950 | txq->txq_len = 0; | ||
951 | txq->txq_max = ATH5K_TXQ_LEN_MAX; | ||
952 | txq->txq_poll_mark = false; | ||
953 | txq->txq_stuck = 0; | ||
1553 | } | 954 | } |
1554 | return &sc->txqs[qnum]; | 955 | return &sc->txqs[qnum]; |
1555 | } | 956 | } |
@@ -1558,9 +959,11 @@ static int | |||
1558 | ath5k_beaconq_setup(struct ath5k_hw *ah) | 959 | ath5k_beaconq_setup(struct ath5k_hw *ah) |
1559 | { | 960 | { |
1560 | struct ath5k_txq_info qi = { | 961 | struct ath5k_txq_info qi = { |
1561 | .tqi_aifs = AR5K_TXQ_USEDEFAULT, | 962 | /* XXX: default values not correct for B and XR channels, |
1562 | .tqi_cw_min = AR5K_TXQ_USEDEFAULT, | 963 | * but who cares? */ |
1563 | .tqi_cw_max = AR5K_TXQ_USEDEFAULT, | 964 | .tqi_aifs = AR5K_TUNE_AIFS, |
965 | .tqi_cw_min = AR5K_TUNE_CWMIN, | ||
966 | .tqi_cw_max = AR5K_TUNE_CWMAX, | ||
1564 | /* NB: for dynamic turbo, don't enable any other interrupts */ | 967 | /* NB: for dynamic turbo, don't enable any other interrupts */ |
1565 | .tqi_flags = AR5K_TXQ_FLAG_TXDESCINT_ENABLE | 968 | .tqi_flags = AR5K_TXQ_FLAG_TXDESCINT_ENABLE |
1566 | }; | 969 | }; |
@@ -1594,7 +997,7 @@ ath5k_beaconq_config(struct ath5k_softc *sc) | |||
1594 | */ | 997 | */ |
1595 | qi.tqi_aifs = 0; | 998 | qi.tqi_aifs = 0; |
1596 | qi.tqi_cw_min = 0; | 999 | qi.tqi_cw_min = 0; |
1597 | qi.tqi_cw_max = 2 * ah->ah_cw_min; | 1000 | qi.tqi_cw_max = 2 * AR5K_TUNE_CWMIN; |
1598 | } | 1001 | } |
1599 | 1002 | ||
1600 | ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, | 1003 | ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, |
@@ -1626,60 +1029,44 @@ err: | |||
1626 | return ret; | 1029 | return ret; |
1627 | } | 1030 | } |
1628 | 1031 | ||
1032 | /** | ||
1033 | * ath5k_drain_tx_buffs - Empty tx buffers | ||
1034 | * | ||
1035 | * @sc The &struct ath5k_softc | ||
1036 | * | ||
1037 | * Empty tx buffers from all queues in preparation | ||
1038 | * of a reset or during shutdown. | ||
1039 | * | ||
1040 | * NB: this assumes output has been stopped and | ||
1041 | * we do not need to block ath5k_tx_tasklet | ||
1042 | */ | ||
1629 | static void | 1043 | static void |
1630 | ath5k_txq_drainq(struct ath5k_softc *sc, struct ath5k_txq *txq) | 1044 | ath5k_drain_tx_buffs(struct ath5k_softc *sc) |
1631 | { | 1045 | { |
1046 | struct ath5k_txq *txq; | ||
1632 | struct ath5k_buf *bf, *bf0; | 1047 | struct ath5k_buf *bf, *bf0; |
1048 | int i; | ||
1633 | 1049 | ||
1634 | /* | 1050 | for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) { |
1635 | * NB: this assumes output has been stopped and | 1051 | if (sc->txqs[i].setup) { |
1636 | * we do not need to block ath5k_tx_tasklet | 1052 | txq = &sc->txqs[i]; |
1637 | */ | 1053 | spin_lock_bh(&txq->lock); |
1638 | spin_lock_bh(&txq->lock); | 1054 | list_for_each_entry_safe(bf, bf0, &txq->q, list) { |
1639 | list_for_each_entry_safe(bf, bf0, &txq->q, list) { | 1055 | ath5k_debug_printtxbuf(sc, bf); |
1640 | ath5k_debug_printtxbuf(sc, bf); | ||
1641 | |||
1642 | ath5k_txbuf_free_skb(sc, bf); | ||
1643 | |||
1644 | spin_lock_bh(&sc->txbuflock); | ||
1645 | list_move_tail(&bf->list, &sc->txbuf); | ||
1646 | sc->txbuf_len++; | ||
1647 | spin_unlock_bh(&sc->txbuflock); | ||
1648 | } | ||
1649 | txq->link = NULL; | ||
1650 | spin_unlock_bh(&txq->lock); | ||
1651 | } | ||
1652 | 1056 | ||
1653 | /* | 1057 | ath5k_txbuf_free_skb(sc, bf); |
1654 | * Drain the transmit queues and reclaim resources. | ||
1655 | */ | ||
1656 | static void | ||
1657 | ath5k_txq_cleanup(struct ath5k_softc *sc) | ||
1658 | { | ||
1659 | struct ath5k_hw *ah = sc->ah; | ||
1660 | unsigned int i; | ||
1661 | 1058 | ||
1662 | /* XXX return value */ | 1059 | spin_lock_bh(&sc->txbuflock); |
1663 | if (likely(!test_bit(ATH_STAT_INVALID, sc->status))) { | 1060 | list_move_tail(&bf->list, &sc->txbuf); |
1664 | /* don't touch the hardware if marked invalid */ | 1061 | sc->txbuf_len++; |
1665 | ath5k_hw_stop_tx_dma(ah, sc->bhalq); | 1062 | txq->txq_len--; |
1666 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "beacon queue %x\n", | 1063 | spin_unlock_bh(&sc->txbuflock); |
1667 | ath5k_hw_get_txdp(ah, sc->bhalq)); | ||
1668 | for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) | ||
1669 | if (sc->txqs[i].setup) { | ||
1670 | ath5k_hw_stop_tx_dma(ah, sc->txqs[i].qnum); | ||
1671 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "txq [%u] %x, " | ||
1672 | "link %p\n", | ||
1673 | sc->txqs[i].qnum, | ||
1674 | ath5k_hw_get_txdp(ah, | ||
1675 | sc->txqs[i].qnum), | ||
1676 | sc->txqs[i].link); | ||
1677 | } | 1064 | } |
1065 | txq->link = NULL; | ||
1066 | txq->txq_poll_mark = false; | ||
1067 | spin_unlock_bh(&txq->lock); | ||
1068 | } | ||
1678 | } | 1069 | } |
1679 | |||
1680 | for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) | ||
1681 | if (sc->txqs[i].setup) | ||
1682 | ath5k_txq_drainq(sc, &sc->txqs[i]); | ||
1683 | } | 1070 | } |
1684 | 1071 | ||
1685 | static void | 1072 | static void |
@@ -1696,8 +1083,6 @@ ath5k_txq_release(struct ath5k_softc *sc) | |||
1696 | } | 1083 | } |
1697 | 1084 | ||
1698 | 1085 | ||
1699 | |||
1700 | |||
1701 | /*************\ | 1086 | /*************\ |
1702 | * RX Handling * | 1087 | * RX Handling * |
1703 | \*************/ | 1088 | \*************/ |
@@ -1713,7 +1098,7 @@ ath5k_rx_start(struct ath5k_softc *sc) | |||
1713 | struct ath5k_buf *bf; | 1098 | struct ath5k_buf *bf; |
1714 | int ret; | 1099 | int ret; |
1715 | 1100 | ||
1716 | common->rx_bufsize = roundup(IEEE80211_MAX_LEN, common->cachelsz); | 1101 | common->rx_bufsize = roundup(IEEE80211_MAX_FRAME_LEN, common->cachelsz); |
1717 | 1102 | ||
1718 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rx_bufsize %u\n", | 1103 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rx_bufsize %u\n", |
1719 | common->cachelsz, common->rx_bufsize); | 1104 | common->cachelsz, common->rx_bufsize); |
@@ -1732,7 +1117,7 @@ ath5k_rx_start(struct ath5k_softc *sc) | |||
1732 | spin_unlock_bh(&sc->rxbuflock); | 1117 | spin_unlock_bh(&sc->rxbuflock); |
1733 | 1118 | ||
1734 | ath5k_hw_start_rx_dma(ah); /* enable recv descriptors */ | 1119 | ath5k_hw_start_rx_dma(ah); /* enable recv descriptors */ |
1735 | ath5k_mode_setup(sc); /* set filters, etc. */ | 1120 | ath5k_update_bssid_mask_and_opmode(sc, NULL); /* set filters, etc. */ |
1736 | ath5k_hw_start_rx_pcu(ah); /* re-enable PCU/DMA engine */ | 1121 | ath5k_hw_start_rx_pcu(ah); /* re-enable PCU/DMA engine */ |
1737 | 1122 | ||
1738 | return 0; | 1123 | return 0; |
@@ -1741,16 +1126,19 @@ err: | |||
1741 | } | 1126 | } |
1742 | 1127 | ||
1743 | /* | 1128 | /* |
1744 | * Disable the receive h/w in preparation for a reset. | 1129 | * Disable the receive logic on PCU (DRU) |
1130 | * In preparation for a shutdown. | ||
1131 | * | ||
1132 | * Note: Doesn't stop rx DMA, ath5k_hw_dma_stop | ||
1133 | * does. | ||
1745 | */ | 1134 | */ |
1746 | static void | 1135 | static void |
1747 | ath5k_rx_stop(struct ath5k_softc *sc) | 1136 | ath5k_rx_stop(struct ath5k_softc *sc) |
1748 | { | 1137 | { |
1749 | struct ath5k_hw *ah = sc->ah; | 1138 | struct ath5k_hw *ah = sc->ah; |
1750 | 1139 | ||
1751 | ath5k_hw_stop_rx_pcu(ah); /* disable PCU */ | ||
1752 | ath5k_hw_set_rx_filter(ah, 0); /* clear recv filter */ | 1140 | ath5k_hw_set_rx_filter(ah, 0); /* clear recv filter */ |
1753 | ath5k_hw_stop_rx_dma(ah); /* disable DMA engine */ | 1141 | ath5k_hw_stop_rx_pcu(ah); /* disable PCU */ |
1754 | 1142 | ||
1755 | ath5k_debug_printrxbuffs(sc, ah); | 1143 | ath5k_debug_printrxbuffs(sc, ah); |
1756 | } | 1144 | } |
@@ -1840,6 +1228,15 @@ ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb, | |||
1840 | */ | 1228 | */ |
1841 | if (hw_tu >= sc->nexttbtt) | 1229 | if (hw_tu >= sc->nexttbtt) |
1842 | ath5k_beacon_update_timers(sc, bc_tstamp); | 1230 | ath5k_beacon_update_timers(sc, bc_tstamp); |
1231 | |||
1232 | /* Check if the beacon timers are still correct, because a TSF | ||
1233 | * update might have created a window between them - for a | ||
1234 | * longer description see the comment of this function: */ | ||
1235 | if (!ath5k_hw_check_beacon_timers(sc->ah, sc->bintval)) { | ||
1236 | ath5k_beacon_update_timers(sc, bc_tstamp); | ||
1237 | ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, | ||
1238 | "fixed beacon timers after beacon receive\n"); | ||
1239 | } | ||
1843 | } | 1240 | } |
1844 | } | 1241 | } |
1845 | 1242 | ||
@@ -1855,15 +1252,14 @@ ath5k_update_beacon_rssi(struct ath5k_softc *sc, struct sk_buff *skb, int rssi) | |||
1855 | memcmp(mgmt->bssid, common->curbssid, ETH_ALEN) != 0) | 1252 | memcmp(mgmt->bssid, common->curbssid, ETH_ALEN) != 0) |
1856 | return; | 1253 | return; |
1857 | 1254 | ||
1858 | ah->ah_beacon_rssi_avg = ath5k_moving_average(ah->ah_beacon_rssi_avg, | 1255 | ewma_add(&ah->ah_beacon_rssi_avg, rssi); |
1859 | rssi); | ||
1860 | 1256 | ||
1861 | /* in IBSS mode we should keep RSSI statistics per neighbour */ | 1257 | /* in IBSS mode we should keep RSSI statistics per neighbour */ |
1862 | /* le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS */ | 1258 | /* le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS */ |
1863 | } | 1259 | } |
1864 | 1260 | ||
1865 | /* | 1261 | /* |
1866 | * Compute padding position. skb must contains an IEEE 802.11 frame | 1262 | * Compute padding position. skb must contain an IEEE 802.11 frame |
1867 | */ | 1263 | */ |
1868 | static int ath5k_common_padpos(struct sk_buff *skb) | 1264 | static int ath5k_common_padpos(struct sk_buff *skb) |
1869 | { | 1265 | { |
@@ -1882,10 +1278,9 @@ static int ath5k_common_padpos(struct sk_buff *skb) | |||
1882 | } | 1278 | } |
1883 | 1279 | ||
1884 | /* | 1280 | /* |
1885 | * This function expects a 802.11 frame and returns the number of | 1281 | * This function expects an 802.11 frame and returns the number of |
1886 | * bytes added, or -1 if we don't have enought header room. | 1282 | * bytes added, or -1 if we don't have enough header room. |
1887 | */ | 1283 | */ |
1888 | |||
1889 | static int ath5k_add_padding(struct sk_buff *skb) | 1284 | static int ath5k_add_padding(struct sk_buff *skb) |
1890 | { | 1285 | { |
1891 | int padpos = ath5k_common_padpos(skb); | 1286 | int padpos = ath5k_common_padpos(skb); |
@@ -1905,10 +1300,18 @@ static int ath5k_add_padding(struct sk_buff *skb) | |||
1905 | } | 1300 | } |
1906 | 1301 | ||
1907 | /* | 1302 | /* |
1908 | * This function expects a 802.11 frame and returns the number of | 1303 | * The MAC header is padded to have 32-bit boundary if the |
1909 | * bytes removed | 1304 | * packet payload is non-zero. The general calculation for |
1305 | * padsize would take into account odd header lengths: | ||
1306 | * padsize = 4 - (hdrlen & 3); however, since only | ||
1307 | * even-length headers are used, padding can only be 0 or 2 | ||
1308 | * bytes and we can optimize this a bit. We must not try to | ||
1309 | * remove padding from short control frames that do not have a | ||
1310 | * payload. | ||
1311 | * | ||
1312 | * This function expects an 802.11 frame and returns the number of | ||
1313 | * bytes removed. | ||
1910 | */ | 1314 | */ |
1911 | |||
1912 | static int ath5k_remove_padding(struct sk_buff *skb) | 1315 | static int ath5k_remove_padding(struct sk_buff *skb) |
1913 | { | 1316 | { |
1914 | int padpos = ath5k_common_padpos(skb); | 1317 | int padpos = ath5k_common_padpos(skb); |
@@ -1929,14 +1332,6 @@ ath5k_receive_frame(struct ath5k_softc *sc, struct sk_buff *skb, | |||
1929 | { | 1332 | { |
1930 | struct ieee80211_rx_status *rxs; | 1333 | struct ieee80211_rx_status *rxs; |
1931 | 1334 | ||
1932 | /* The MAC header is padded to have 32-bit boundary if the | ||
1933 | * packet payload is non-zero. The general calculation for | ||
1934 | * padsize would take into account odd header lengths: | ||
1935 | * padsize = (4 - hdrlen % 4) % 4; However, since only | ||
1936 | * even-length headers are used, padding can only be 0 or 2 | ||
1937 | * bytes and we can optimize this a bit. In addition, we must | ||
1938 | * not try to remove padding from short control frames that do | ||
1939 | * not have payload. */ | ||
1940 | ath5k_remove_padding(skb); | 1335 | ath5k_remove_padding(skb); |
1941 | 1336 | ||
1942 | rxs = IEEE80211_SKB_RXCB(skb); | 1337 | rxs = IEEE80211_SKB_RXCB(skb); |
@@ -1966,10 +1361,10 @@ ath5k_receive_frame(struct ath5k_softc *sc, struct sk_buff *skb, | |||
1966 | * right now, so it's not too bad... | 1361 | * right now, so it's not too bad... |
1967 | */ | 1362 | */ |
1968 | rxs->mactime = ath5k_extend_tsf(sc->ah, rs->rs_tstamp); | 1363 | rxs->mactime = ath5k_extend_tsf(sc->ah, rs->rs_tstamp); |
1969 | rxs->flag |= RX_FLAG_TSFT; | 1364 | rxs->flag |= RX_FLAG_MACTIME_MPDU; |
1970 | 1365 | ||
1971 | rxs->freq = sc->curchan->center_freq; | 1366 | rxs->freq = sc->curchan->center_freq; |
1972 | rxs->band = sc->curband->band; | 1367 | rxs->band = sc->curchan->band; |
1973 | 1368 | ||
1974 | rxs->signal = sc->ah->ah_noise_floor + rs->rs_rssi; | 1369 | rxs->signal = sc->ah->ah_noise_floor + rs->rs_rssi; |
1975 | 1370 | ||
@@ -1984,10 +1379,10 @@ ath5k_receive_frame(struct ath5k_softc *sc, struct sk_buff *skb, | |||
1984 | rxs->flag |= ath5k_rx_decrypted(sc, skb, rs); | 1379 | rxs->flag |= ath5k_rx_decrypted(sc, skb, rs); |
1985 | 1380 | ||
1986 | if (rxs->rate_idx >= 0 && rs->rs_rate == | 1381 | if (rxs->rate_idx >= 0 && rs->rs_rate == |
1987 | sc->curband->bitrates[rxs->rate_idx].hw_value_short) | 1382 | sc->sbands[sc->curchan->band].bitrates[rxs->rate_idx].hw_value_short) |
1988 | rxs->flag |= RX_FLAG_SHORTPRE; | 1383 | rxs->flag |= RX_FLAG_SHORTPRE; |
1989 | 1384 | ||
1990 | ath5k_debug_dump_skb(sc, skb, "RX ", 0); | 1385 | trace_ath5k_rx(sc, skb); |
1991 | 1386 | ||
1992 | ath5k_update_beacon_rssi(sc, skb, rs->rs_rssi); | 1387 | ath5k_update_beacon_rssi(sc, skb, rs->rs_rssi); |
1993 | 1388 | ||
@@ -2007,6 +1402,7 @@ static bool | |||
2007 | ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs) | 1402 | ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs) |
2008 | { | 1403 | { |
2009 | sc->stats.rx_all_count++; | 1404 | sc->stats.rx_all_count++; |
1405 | sc->stats.rx_bytes_count += rs->rs_datalen; | ||
2010 | 1406 | ||
2011 | if (unlikely(rs->rs_status)) { | 1407 | if (unlikely(rs->rs_status)) { |
2012 | if (rs->rs_status & AR5K_RXERR_CRC) | 1408 | if (rs->rs_status & AR5K_RXERR_CRC) |
@@ -2040,9 +1436,8 @@ ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs) | |||
2040 | return true; | 1436 | return true; |
2041 | } | 1437 | } |
2042 | 1438 | ||
2043 | /* let crypto-error packets fall through in MNTR */ | 1439 | /* reject any frames with non-crypto errors */ |
2044 | if ((rs->rs_status & ~(AR5K_RXERR_DECRYPT|AR5K_RXERR_MIC)) || | 1440 | if (rs->rs_status & ~(AR5K_RXERR_DECRYPT)) |
2045 | sc->opmode != NL80211_IFTYPE_MONITOR) | ||
2046 | return false; | 1441 | return false; |
2047 | } | 1442 | } |
2048 | 1443 | ||
@@ -2054,6 +1449,21 @@ ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs) | |||
2054 | } | 1449 | } |
2055 | 1450 | ||
2056 | static void | 1451 | static void |
1452 | ath5k_set_current_imask(struct ath5k_softc *sc) | ||
1453 | { | ||
1454 | enum ath5k_int imask = sc->imask; | ||
1455 | unsigned long flags; | ||
1456 | |||
1457 | spin_lock_irqsave(&sc->irqlock, flags); | ||
1458 | if (sc->rx_pending) | ||
1459 | imask &= ~AR5K_INT_RX_ALL; | ||
1460 | if (sc->tx_pending) | ||
1461 | imask &= ~AR5K_INT_TX_ALL; | ||
1462 | ath5k_hw_set_imr(sc->ah, imask); | ||
1463 | spin_unlock_irqrestore(&sc->irqlock, flags); | ||
1464 | } | ||
1465 | |||
1466 | static void | ||
2057 | ath5k_tasklet_rx(unsigned long data) | 1467 | ath5k_tasklet_rx(unsigned long data) |
2058 | { | 1468 | { |
2059 | struct ath5k_rx_status rs = {}; | 1469 | struct ath5k_rx_status rs = {}; |
@@ -2100,9 +1510,9 @@ ath5k_tasklet_rx(unsigned long data) | |||
2100 | if (!next_skb) | 1510 | if (!next_skb) |
2101 | goto next; | 1511 | goto next; |
2102 | 1512 | ||
2103 | pci_unmap_single(sc->pdev, bf->skbaddr, | 1513 | dma_unmap_single(sc->dev, bf->skbaddr, |
2104 | common->rx_bufsize, | 1514 | common->rx_bufsize, |
2105 | PCI_DMA_FROMDEVICE); | 1515 | DMA_FROM_DEVICE); |
2106 | 1516 | ||
2107 | skb_put(skb, rs.rs_datalen); | 1517 | skb_put(skb, rs.rs_datalen); |
2108 | 1518 | ||
@@ -2116,6 +1526,8 @@ next: | |||
2116 | } while (ath5k_rxbuf_setup(sc, bf) == 0); | 1526 | } while (ath5k_rxbuf_setup(sc, bf) == 0); |
2117 | unlock: | 1527 | unlock: |
2118 | spin_unlock(&sc->rxbuflock); | 1528 | spin_unlock(&sc->rxbuflock); |
1529 | sc->rx_pending = false; | ||
1530 | ath5k_set_current_imask(sc); | ||
2119 | } | 1531 | } |
2120 | 1532 | ||
2121 | 1533 | ||
@@ -2123,6 +1535,122 @@ unlock: | |||
2123 | * TX Handling * | 1535 | * TX Handling * |
2124 | \*************/ | 1536 | \*************/ |
2125 | 1537 | ||
1538 | void | ||
1539 | ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
1540 | struct ath5k_txq *txq) | ||
1541 | { | ||
1542 | struct ath5k_softc *sc = hw->priv; | ||
1543 | struct ath5k_buf *bf; | ||
1544 | unsigned long flags; | ||
1545 | int padsize; | ||
1546 | |||
1547 | trace_ath5k_tx(sc, skb, txq); | ||
1548 | |||
1549 | /* | ||
1550 | * The hardware expects the header padded to 4 byte boundaries. | ||
1551 | * If this is not the case, we add the padding after the header. | ||
1552 | */ | ||
1553 | padsize = ath5k_add_padding(skb); | ||
1554 | if (padsize < 0) { | ||
1555 | ATH5K_ERR(sc, "tx hdrlen not %%4: not enough" | ||
1556 | " headroom to pad"); | ||
1557 | goto drop_packet; | ||
1558 | } | ||
1559 | |||
1560 | if (txq->txq_len >= txq->txq_max) | ||
1561 | ieee80211_stop_queue(hw, txq->qnum); | ||
1562 | |||
1563 | spin_lock_irqsave(&sc->txbuflock, flags); | ||
1564 | if (list_empty(&sc->txbuf)) { | ||
1565 | ATH5K_ERR(sc, "no further txbuf available, dropping packet\n"); | ||
1566 | spin_unlock_irqrestore(&sc->txbuflock, flags); | ||
1567 | ieee80211_stop_queues(hw); | ||
1568 | goto drop_packet; | ||
1569 | } | ||
1570 | bf = list_first_entry(&sc->txbuf, struct ath5k_buf, list); | ||
1571 | list_del(&bf->list); | ||
1572 | sc->txbuf_len--; | ||
1573 | if (list_empty(&sc->txbuf)) | ||
1574 | ieee80211_stop_queues(hw); | ||
1575 | spin_unlock_irqrestore(&sc->txbuflock, flags); | ||
1576 | |||
1577 | bf->skb = skb; | ||
1578 | |||
1579 | if (ath5k_txbuf_setup(sc, bf, txq, padsize)) { | ||
1580 | bf->skb = NULL; | ||
1581 | spin_lock_irqsave(&sc->txbuflock, flags); | ||
1582 | list_add_tail(&bf->list, &sc->txbuf); | ||
1583 | sc->txbuf_len++; | ||
1584 | spin_unlock_irqrestore(&sc->txbuflock, flags); | ||
1585 | goto drop_packet; | ||
1586 | } | ||
1587 | return; | ||
1588 | |||
1589 | drop_packet: | ||
1590 | dev_kfree_skb_any(skb); | ||
1591 | } | ||
1592 | |||
1593 | static void | ||
1594 | ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb, | ||
1595 | struct ath5k_txq *txq, struct ath5k_tx_status *ts) | ||
1596 | { | ||
1597 | struct ieee80211_tx_info *info; | ||
1598 | u8 tries[3]; | ||
1599 | int i; | ||
1600 | |||
1601 | sc->stats.tx_all_count++; | ||
1602 | sc->stats.tx_bytes_count += skb->len; | ||
1603 | info = IEEE80211_SKB_CB(skb); | ||
1604 | |||
1605 | tries[0] = info->status.rates[0].count; | ||
1606 | tries[1] = info->status.rates[1].count; | ||
1607 | tries[2] = info->status.rates[2].count; | ||
1608 | |||
1609 | ieee80211_tx_info_clear_status(info); | ||
1610 | |||
1611 | for (i = 0; i < ts->ts_final_idx; i++) { | ||
1612 | struct ieee80211_tx_rate *r = | ||
1613 | &info->status.rates[i]; | ||
1614 | |||
1615 | r->count = tries[i]; | ||
1616 | } | ||
1617 | |||
1618 | info->status.rates[ts->ts_final_idx].count = ts->ts_final_retry; | ||
1619 | info->status.rates[ts->ts_final_idx + 1].idx = -1; | ||
1620 | |||
1621 | if (unlikely(ts->ts_status)) { | ||
1622 | sc->stats.ack_fail++; | ||
1623 | if (ts->ts_status & AR5K_TXERR_FILT) { | ||
1624 | info->flags |= IEEE80211_TX_STAT_TX_FILTERED; | ||
1625 | sc->stats.txerr_filt++; | ||
1626 | } | ||
1627 | if (ts->ts_status & AR5K_TXERR_XRETRY) | ||
1628 | sc->stats.txerr_retry++; | ||
1629 | if (ts->ts_status & AR5K_TXERR_FIFO) | ||
1630 | sc->stats.txerr_fifo++; | ||
1631 | } else { | ||
1632 | info->flags |= IEEE80211_TX_STAT_ACK; | ||
1633 | info->status.ack_signal = ts->ts_rssi; | ||
1634 | |||
1635 | /* count the successful attempt as well */ | ||
1636 | info->status.rates[ts->ts_final_idx].count++; | ||
1637 | } | ||
1638 | |||
1639 | /* | ||
1640 | * Remove MAC header padding before giving the frame | ||
1641 | * back to mac80211. | ||
1642 | */ | ||
1643 | ath5k_remove_padding(skb); | ||
1644 | |||
1645 | if (ts->ts_antenna > 0 && ts->ts_antenna < 5) | ||
1646 | sc->stats.antenna_tx[ts->ts_antenna]++; | ||
1647 | else | ||
1648 | sc->stats.antenna_tx[0]++; /* invalid */ | ||
1649 | |||
1650 | trace_ath5k_tx_complete(sc, skb, txq, ts); | ||
1651 | ieee80211_tx_status(sc->hw, skb); | ||
1652 | } | ||
1653 | |||
2126 | static void | 1654 | static void |
2127 | ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) | 1655 | ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) |
2128 | { | 1656 | { |
@@ -2130,96 +1658,52 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) | |||
2130 | struct ath5k_buf *bf, *bf0; | 1658 | struct ath5k_buf *bf, *bf0; |
2131 | struct ath5k_desc *ds; | 1659 | struct ath5k_desc *ds; |
2132 | struct sk_buff *skb; | 1660 | struct sk_buff *skb; |
2133 | struct ieee80211_tx_info *info; | 1661 | int ret; |
2134 | int i, ret; | ||
2135 | 1662 | ||
2136 | spin_lock(&txq->lock); | 1663 | spin_lock(&txq->lock); |
2137 | list_for_each_entry_safe(bf, bf0, &txq->q, list) { | 1664 | list_for_each_entry_safe(bf, bf0, &txq->q, list) { |
2138 | ds = bf->desc; | ||
2139 | |||
2140 | /* | ||
2141 | * It's possible that the hardware can say the buffer is | ||
2142 | * completed when it hasn't yet loaded the ds_link from | ||
2143 | * host memory and moved on. If there are more TX | ||
2144 | * descriptors in the queue, wait for TXDP to change | ||
2145 | * before processing this one. | ||
2146 | */ | ||
2147 | if (ath5k_hw_get_txdp(sc->ah, txq->qnum) == bf->daddr && | ||
2148 | !list_is_last(&bf->list, &txq->q)) | ||
2149 | break; | ||
2150 | |||
2151 | ret = sc->ah->ah_proc_tx_desc(sc->ah, ds, &ts); | ||
2152 | if (unlikely(ret == -EINPROGRESS)) | ||
2153 | break; | ||
2154 | else if (unlikely(ret)) { | ||
2155 | ATH5K_ERR(sc, "error %d while processing queue %u\n", | ||
2156 | ret, txq->qnum); | ||
2157 | break; | ||
2158 | } | ||
2159 | |||
2160 | sc->stats.tx_all_count++; | ||
2161 | skb = bf->skb; | ||
2162 | info = IEEE80211_SKB_CB(skb); | ||
2163 | bf->skb = NULL; | ||
2164 | 1665 | ||
2165 | pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, | 1666 | txq->txq_poll_mark = false; |
2166 | PCI_DMA_TODEVICE); | ||
2167 | 1667 | ||
2168 | ieee80211_tx_info_clear_status(info); | 1668 | /* skb might already have been processed last time. */ |
2169 | for (i = 0; i < 4; i++) { | 1669 | if (bf->skb != NULL) { |
2170 | struct ieee80211_tx_rate *r = | 1670 | ds = bf->desc; |
2171 | &info->status.rates[i]; | ||
2172 | 1671 | ||
2173 | if (ts.ts_rate[i]) { | 1672 | ret = sc->ah->ah_proc_tx_desc(sc->ah, ds, &ts); |
2174 | r->idx = ath5k_hw_to_driver_rix(sc, ts.ts_rate[i]); | 1673 | if (unlikely(ret == -EINPROGRESS)) |
2175 | r->count = ts.ts_retry[i]; | 1674 | break; |
2176 | } else { | 1675 | else if (unlikely(ret)) { |
2177 | r->idx = -1; | 1676 | ATH5K_ERR(sc, |
2178 | r->count = 0; | 1677 | "error %d while processing " |
1678 | "queue %u\n", ret, txq->qnum); | ||
1679 | break; | ||
2179 | } | 1680 | } |
2180 | } | ||
2181 | 1681 | ||
2182 | /* count the successful attempt as well */ | 1682 | skb = bf->skb; |
2183 | info->status.rates[ts.ts_final_idx].count++; | 1683 | bf->skb = NULL; |
2184 | 1684 | ||
2185 | if (unlikely(ts.ts_status)) { | 1685 | dma_unmap_single(sc->dev, bf->skbaddr, skb->len, |
2186 | sc->stats.ack_fail++; | 1686 | DMA_TO_DEVICE); |
2187 | if (ts.ts_status & AR5K_TXERR_FILT) { | 1687 | ath5k_tx_frame_completed(sc, skb, txq, &ts); |
2188 | info->flags |= IEEE80211_TX_STAT_TX_FILTERED; | ||
2189 | sc->stats.txerr_filt++; | ||
2190 | } | ||
2191 | if (ts.ts_status & AR5K_TXERR_XRETRY) | ||
2192 | sc->stats.txerr_retry++; | ||
2193 | if (ts.ts_status & AR5K_TXERR_FIFO) | ||
2194 | sc->stats.txerr_fifo++; | ||
2195 | } else { | ||
2196 | info->flags |= IEEE80211_TX_STAT_ACK; | ||
2197 | info->status.ack_signal = ts.ts_rssi; | ||
2198 | } | 1688 | } |
2199 | 1689 | ||
2200 | /* | 1690 | /* |
2201 | * Remove MAC header padding before giving the frame | 1691 | * It's possible that the hardware can say the buffer is |
2202 | * back to mac80211. | 1692 | * completed when it hasn't yet loaded the ds_link from |
1693 | * host memory and moved on. | ||
1694 | * Always keep the last descriptor to avoid HW races... | ||
2203 | */ | 1695 | */ |
2204 | ath5k_remove_padding(skb); | 1696 | if (ath5k_hw_get_txdp(sc->ah, txq->qnum) != bf->daddr) { |
2205 | 1697 | spin_lock(&sc->txbuflock); | |
2206 | if (ts.ts_antenna > 0 && ts.ts_antenna < 5) | 1698 | list_move_tail(&bf->list, &sc->txbuf); |
2207 | sc->stats.antenna_tx[ts.ts_antenna]++; | 1699 | sc->txbuf_len++; |
2208 | else | 1700 | txq->txq_len--; |
2209 | sc->stats.antenna_tx[0]++; /* invalid */ | 1701 | spin_unlock(&sc->txbuflock); |
2210 | 1702 | } | |
2211 | ieee80211_tx_status(sc->hw, skb); | ||
2212 | |||
2213 | spin_lock(&sc->txbuflock); | ||
2214 | list_move_tail(&bf->list, &sc->txbuf); | ||
2215 | sc->txbuf_len++; | ||
2216 | spin_unlock(&sc->txbuflock); | ||
2217 | } | 1703 | } |
2218 | if (likely(list_empty(&txq->q))) | ||
2219 | txq->link = NULL; | ||
2220 | spin_unlock(&txq->lock); | 1704 | spin_unlock(&txq->lock); |
2221 | if (sc->txbuf_len > ATH_TXBUF / 5) | 1705 | if (txq->txq_len < ATH5K_TXQ_LEN_LOW && txq->qnum < 4) |
2222 | ieee80211_wake_queues(sc->hw); | 1706 | ieee80211_wake_queue(sc->hw, txq->qnum); |
2223 | } | 1707 | } |
2224 | 1708 | ||
2225 | static void | 1709 | static void |
@@ -2231,6 +1715,9 @@ ath5k_tasklet_tx(unsigned long data) | |||
2231 | for (i=0; i < AR5K_NUM_TX_QUEUES; i++) | 1715 | for (i=0; i < AR5K_NUM_TX_QUEUES; i++) |
2232 | if (sc->txqs[i].setup && (sc->ah->ah_txq_isr & BIT(i))) | 1716 | if (sc->txqs[i].setup && (sc->ah->ah_txq_isr & BIT(i))) |
2233 | ath5k_tx_processq(sc, &sc->txqs[i]); | 1717 | ath5k_tx_processq(sc, &sc->txqs[i]); |
1718 | |||
1719 | sc->tx_pending = false; | ||
1720 | ath5k_set_current_imask(sc); | ||
2234 | } | 1721 | } |
2235 | 1722 | ||
2236 | 1723 | ||
@@ -2253,12 +1740,13 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) | |||
2253 | u32 flags; | 1740 | u32 flags; |
2254 | const int padsize = 0; | 1741 | const int padsize = 0; |
2255 | 1742 | ||
2256 | bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len, | 1743 | bf->skbaddr = dma_map_single(sc->dev, skb->data, skb->len, |
2257 | PCI_DMA_TODEVICE); | 1744 | DMA_TO_DEVICE); |
2258 | ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "skb %p [data %p len %u] " | 1745 | ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "skb %p [data %p len %u] " |
2259 | "skbaddr %llx\n", skb, skb->data, skb->len, | 1746 | "skbaddr %llx\n", skb, skb->data, skb->len, |
2260 | (unsigned long long)bf->skbaddr); | 1747 | (unsigned long long)bf->skbaddr); |
2261 | if (pci_dma_mapping_error(sc->pdev, bf->skbaddr)) { | 1748 | |
1749 | if (dma_mapping_error(sc->dev, bf->skbaddr)) { | ||
2262 | ATH5K_ERR(sc, "beacon DMA mapping failed\n"); | 1750 | ATH5K_ERR(sc, "beacon DMA mapping failed\n"); |
2263 | return -EIO; | 1751 | return -EIO; |
2264 | } | 1752 | } |
@@ -2285,10 +1773,11 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) | |||
2285 | * default antenna which is supposed to be an omni. | 1773 | * default antenna which is supposed to be an omni. |
2286 | * | 1774 | * |
2287 | * Note2: On sectored scenarios it's possible to have | 1775 | * Note2: On sectored scenarios it's possible to have |
2288 | * multiple antennas (1omni -the default- and 14 sectors) | 1776 | * multiple antennas (1 omni -- the default -- and 14 |
2289 | * so if we choose to actually support this mode we need | 1777 | * sectors), so if we choose to actually support this |
2290 | * to allow user to set how many antennas we have and tweak | 1778 | * mode, we need to allow the user to set how many antennas |
2291 | * the code below to send beacons on all of them. | 1779 | * we have and tweak the code below to send beacons |
1780 | * on all of them. | ||
2292 | */ | 1781 | */ |
2293 | if (ah->ah_ant_mode == AR5K_ANTMODE_SECTOR_AP) | 1782 | if (ah->ah_ant_mode == AR5K_ANTMODE_SECTOR_AP) |
2294 | antenna = sc->bsent & 4 ? 2 : 1; | 1783 | antenna = sc->bsent & 4 ? 2 : 1; |
@@ -2309,7 +1798,43 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) | |||
2309 | 1798 | ||
2310 | return 0; | 1799 | return 0; |
2311 | err_unmap: | 1800 | err_unmap: |
2312 | pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, PCI_DMA_TODEVICE); | 1801 | dma_unmap_single(sc->dev, bf->skbaddr, skb->len, DMA_TO_DEVICE); |
1802 | return ret; | ||
1803 | } | ||
1804 | |||
1805 | /* | ||
1806 | * Updates the beacon that is sent by ath5k_beacon_send. For adhoc, | ||
1807 | * this is called only once at config_bss time, for AP we do it every | ||
1808 | * SWBA interrupt so that the TIM will reflect buffered frames. | ||
1809 | * | ||
1810 | * Called with the beacon lock. | ||
1811 | */ | ||
1812 | int | ||
1813 | ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | ||
1814 | { | ||
1815 | int ret; | ||
1816 | struct ath5k_softc *sc = hw->priv; | ||
1817 | struct ath5k_vif *avf = (void *)vif->drv_priv; | ||
1818 | struct sk_buff *skb; | ||
1819 | |||
1820 | if (WARN_ON(!vif)) { | ||
1821 | ret = -EINVAL; | ||
1822 | goto out; | ||
1823 | } | ||
1824 | |||
1825 | skb = ieee80211_beacon_get(hw, vif); | ||
1826 | |||
1827 | if (!skb) { | ||
1828 | ret = -ENOMEM; | ||
1829 | goto out; | ||
1830 | } | ||
1831 | |||
1832 | ath5k_txbuf_free_skb(sc, avf->bbuf); | ||
1833 | avf->bbuf->skb = skb; | ||
1834 | ret = ath5k_beacon_setup(sc, avf->bbuf); | ||
1835 | if (ret) | ||
1836 | avf->bbuf->skb = NULL; | ||
1837 | out: | ||
2313 | return ret; | 1838 | return ret; |
2314 | } | 1839 | } |
2315 | 1840 | ||
@@ -2324,20 +1849,17 @@ err_unmap: | |||
2324 | static void | 1849 | static void |
2325 | ath5k_beacon_send(struct ath5k_softc *sc) | 1850 | ath5k_beacon_send(struct ath5k_softc *sc) |
2326 | { | 1851 | { |
2327 | struct ath5k_buf *bf = sc->bbuf; | ||
2328 | struct ath5k_hw *ah = sc->ah; | 1852 | struct ath5k_hw *ah = sc->ah; |
1853 | struct ieee80211_vif *vif; | ||
1854 | struct ath5k_vif *avf; | ||
1855 | struct ath5k_buf *bf; | ||
2329 | struct sk_buff *skb; | 1856 | struct sk_buff *skb; |
2330 | 1857 | ||
2331 | ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "in beacon_send\n"); | 1858 | ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "in beacon_send\n"); |
2332 | 1859 | ||
2333 | if (unlikely(bf->skb == NULL || sc->opmode == NL80211_IFTYPE_STATION || | ||
2334 | sc->opmode == NL80211_IFTYPE_MONITOR)) { | ||
2335 | ATH5K_WARN(sc, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL); | ||
2336 | return; | ||
2337 | } | ||
2338 | /* | 1860 | /* |
2339 | * Check if the previous beacon has gone out. If | 1861 | * Check if the previous beacon has gone out. If |
2340 | * not don't don't try to post another, skip this | 1862 | * not, don't don't try to post another: skip this |
2341 | * period and wait for the next. Missed beacons | 1863 | * period and wait for the next. Missed beacons |
2342 | * indicate a problem and should not occur. If we | 1864 | * indicate a problem and should not occur. If we |
2343 | * miss too many consecutive beacons reset the device. | 1865 | * miss too many consecutive beacons reset the device. |
@@ -2363,35 +1885,60 @@ ath5k_beacon_send(struct ath5k_softc *sc) | |||
2363 | sc->bmisscount = 0; | 1885 | sc->bmisscount = 0; |
2364 | } | 1886 | } |
2365 | 1887 | ||
1888 | if ((sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) || | ||
1889 | sc->opmode == NL80211_IFTYPE_MESH_POINT) { | ||
1890 | u64 tsf = ath5k_hw_get_tsf64(ah); | ||
1891 | u32 tsftu = TSF_TO_TU(tsf); | ||
1892 | int slot = ((tsftu % sc->bintval) * ATH_BCBUF) / sc->bintval; | ||
1893 | vif = sc->bslot[(slot + 1) % ATH_BCBUF]; | ||
1894 | ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, | ||
1895 | "tsf %llx tsftu %x intval %u slot %u vif %p\n", | ||
1896 | (unsigned long long)tsf, tsftu, sc->bintval, slot, vif); | ||
1897 | } else /* only one interface */ | ||
1898 | vif = sc->bslot[0]; | ||
1899 | |||
1900 | if (!vif) | ||
1901 | return; | ||
1902 | |||
1903 | avf = (void *)vif->drv_priv; | ||
1904 | bf = avf->bbuf; | ||
1905 | if (unlikely(bf->skb == NULL || sc->opmode == NL80211_IFTYPE_STATION || | ||
1906 | sc->opmode == NL80211_IFTYPE_MONITOR)) { | ||
1907 | ATH5K_WARN(sc, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL); | ||
1908 | return; | ||
1909 | } | ||
1910 | |||
2366 | /* | 1911 | /* |
2367 | * Stop any current dma and put the new frame on the queue. | 1912 | * Stop any current dma and put the new frame on the queue. |
2368 | * This should never fail since we check above that no frames | 1913 | * This should never fail since we check above that no frames |
2369 | * are still pending on the queue. | 1914 | * are still pending on the queue. |
2370 | */ | 1915 | */ |
2371 | if (unlikely(ath5k_hw_stop_tx_dma(ah, sc->bhalq))) { | 1916 | if (unlikely(ath5k_hw_stop_beacon_queue(ah, sc->bhalq))) { |
2372 | ATH5K_WARN(sc, "beacon queue %u didn't start/stop ?\n", sc->bhalq); | 1917 | ATH5K_WARN(sc, "beacon queue %u didn't start/stop ?\n", sc->bhalq); |
2373 | /* NB: hw still stops DMA, so proceed */ | 1918 | /* NB: hw still stops DMA, so proceed */ |
2374 | } | 1919 | } |
2375 | 1920 | ||
2376 | /* refresh the beacon for AP mode */ | 1921 | /* refresh the beacon for AP or MESH mode */ |
2377 | if (sc->opmode == NL80211_IFTYPE_AP) | 1922 | if (sc->opmode == NL80211_IFTYPE_AP || |
2378 | ath5k_beacon_update(sc->hw, sc->vif); | 1923 | sc->opmode == NL80211_IFTYPE_MESH_POINT) |
1924 | ath5k_beacon_update(sc->hw, vif); | ||
1925 | |||
1926 | trace_ath5k_tx(sc, bf->skb, &sc->txqs[sc->bhalq]); | ||
2379 | 1927 | ||
2380 | ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr); | 1928 | ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr); |
2381 | ath5k_hw_start_tx_dma(ah, sc->bhalq); | 1929 | ath5k_hw_start_tx_dma(ah, sc->bhalq); |
2382 | ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n", | 1930 | ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n", |
2383 | sc->bhalq, (unsigned long long)bf->daddr, bf->desc); | 1931 | sc->bhalq, (unsigned long long)bf->daddr, bf->desc); |
2384 | 1932 | ||
2385 | skb = ieee80211_get_buffered_bc(sc->hw, sc->vif); | 1933 | skb = ieee80211_get_buffered_bc(sc->hw, vif); |
2386 | while (skb) { | 1934 | while (skb) { |
2387 | ath5k_tx_queue(sc->hw, skb, sc->cabq); | 1935 | ath5k_tx_queue(sc->hw, skb, sc->cabq); |
2388 | skb = ieee80211_get_buffered_bc(sc->hw, sc->vif); | 1936 | skb = ieee80211_get_buffered_bc(sc->hw, vif); |
2389 | } | 1937 | } |
2390 | 1938 | ||
2391 | sc->bsent++; | 1939 | sc->bsent++; |
2392 | } | 1940 | } |
2393 | 1941 | ||
2394 | |||
2395 | /** | 1942 | /** |
2396 | * ath5k_beacon_update_timers - update beacon timers | 1943 | * ath5k_beacon_update_timers - update beacon timers |
2397 | * | 1944 | * |
@@ -2408,7 +1955,7 @@ ath5k_beacon_send(struct ath5k_softc *sc) | |||
2408 | * when we otherwise know we have to update the timers, but we keep it in this | 1955 | * when we otherwise know we have to update the timers, but we keep it in this |
2409 | * function to have it all together in one place. | 1956 | * function to have it all together in one place. |
2410 | */ | 1957 | */ |
2411 | static void | 1958 | void |
2412 | ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf) | 1959 | ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf) |
2413 | { | 1960 | { |
2414 | struct ath5k_hw *ah = sc->ah; | 1961 | struct ath5k_hw *ah = sc->ah; |
@@ -2416,6 +1963,12 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf) | |||
2416 | u64 hw_tsf; | 1963 | u64 hw_tsf; |
2417 | 1964 | ||
2418 | intval = sc->bintval & AR5K_BEACON_PERIOD; | 1965 | intval = sc->bintval & AR5K_BEACON_PERIOD; |
1966 | if (sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) { | ||
1967 | intval /= ATH_BCBUF; /* staggered multi-bss beacons */ | ||
1968 | if (intval < 15) | ||
1969 | ATH5K_WARN(sc, "intval %u is too low, min 15\n", | ||
1970 | intval); | ||
1971 | } | ||
2419 | if (WARN_ON(!intval)) | 1972 | if (WARN_ON(!intval)) |
2420 | return; | 1973 | return; |
2421 | 1974 | ||
@@ -2426,8 +1979,11 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf) | |||
2426 | hw_tsf = ath5k_hw_get_tsf64(ah); | 1979 | hw_tsf = ath5k_hw_get_tsf64(ah); |
2427 | hw_tu = TSF_TO_TU(hw_tsf); | 1980 | hw_tu = TSF_TO_TU(hw_tsf); |
2428 | 1981 | ||
2429 | #define FUDGE 3 | 1982 | #define FUDGE AR5K_TUNE_SW_BEACON_RESP + 3 |
2430 | /* we use FUDGE to make sure the next TBTT is ahead of the current TU */ | 1983 | /* We use FUDGE to make sure the next TBTT is ahead of the current TU. |
1984 | * Since we later subtract AR5K_TUNE_SW_BEACON_RESP (10) in the timer | ||
1985 | * configuration we need to make sure it is bigger than that. */ | ||
1986 | |||
2431 | if (bc_tsf == -1) { | 1987 | if (bc_tsf == -1) { |
2432 | /* | 1988 | /* |
2433 | * no beacons received, called internally. | 1989 | * no beacons received, called internally. |
@@ -2443,7 +1999,7 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf) | |||
2443 | intval |= AR5K_BEACON_RESET_TSF; | 1999 | intval |= AR5K_BEACON_RESET_TSF; |
2444 | } else if (bc_tsf > hw_tsf) { | 2000 | } else if (bc_tsf > hw_tsf) { |
2445 | /* | 2001 | /* |
2446 | * beacon received, SW merge happend but HW TSF not yet updated. | 2002 | * beacon received, SW merge happened but HW TSF not yet updated. |
2447 | * not possible to reconfigure timers yet, but next time we | 2003 | * not possible to reconfigure timers yet, but next time we |
2448 | * receive a beacon with the same BSSID, the hardware will | 2004 | * receive a beacon with the same BSSID, the hardware will |
2449 | * automatically update the TSF and then we need to reconfigure | 2005 | * automatically update the TSF and then we need to reconfigure |
@@ -2493,7 +2049,6 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf) | |||
2493 | intval & AR5K_BEACON_RESET_TSF ? "AR5K_BEACON_RESET_TSF" : ""); | 2049 | intval & AR5K_BEACON_RESET_TSF ? "AR5K_BEACON_RESET_TSF" : ""); |
2494 | } | 2050 | } |
2495 | 2051 | ||
2496 | |||
2497 | /** | 2052 | /** |
2498 | * ath5k_beacon_config - Configure the beacon queues and interrupts | 2053 | * ath5k_beacon_config - Configure the beacon queues and interrupts |
2499 | * | 2054 | * |
@@ -2502,7 +2057,7 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf) | |||
2502 | * In IBSS mode we use a self-linked tx descriptor if possible. We enable SWBA | 2057 | * In IBSS mode we use a self-linked tx descriptor if possible. We enable SWBA |
2503 | * interrupts to detect TSF updates only. | 2058 | * interrupts to detect TSF updates only. |
2504 | */ | 2059 | */ |
2505 | static void | 2060 | void |
2506 | ath5k_beacon_config(struct ath5k_softc *sc) | 2061 | ath5k_beacon_config(struct ath5k_softc *sc) |
2507 | { | 2062 | { |
2508 | struct ath5k_hw *ah = sc->ah; | 2063 | struct ath5k_hw *ah = sc->ah; |
@@ -2530,7 +2085,7 @@ ath5k_beacon_config(struct ath5k_softc *sc) | |||
2530 | } else | 2085 | } else |
2531 | ath5k_beacon_update_timers(sc, -1); | 2086 | ath5k_beacon_update_timers(sc, -1); |
2532 | } else { | 2087 | } else { |
2533 | ath5k_hw_stop_tx_dma(sc->ah, sc->bhalq); | 2088 | ath5k_hw_stop_beacon_queue(sc->ah, sc->bhalq); |
2534 | } | 2089 | } |
2535 | 2090 | ||
2536 | ath5k_hw_set_imr(ah, sc->imask); | 2091 | ath5k_hw_set_imr(ah, sc->imask); |
@@ -2572,155 +2127,6 @@ static void ath5k_tasklet_beacon(unsigned long data) | |||
2572 | * Interrupt handling * | 2127 | * Interrupt handling * |
2573 | \********************/ | 2128 | \********************/ |
2574 | 2129 | ||
2575 | static int | ||
2576 | ath5k_init(struct ath5k_softc *sc) | ||
2577 | { | ||
2578 | struct ath5k_hw *ah = sc->ah; | ||
2579 | int ret, i; | ||
2580 | |||
2581 | mutex_lock(&sc->lock); | ||
2582 | |||
2583 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode); | ||
2584 | |||
2585 | /* | ||
2586 | * Stop anything previously setup. This is safe | ||
2587 | * no matter this is the first time through or not. | ||
2588 | */ | ||
2589 | ath5k_stop_locked(sc); | ||
2590 | |||
2591 | /* | ||
2592 | * The basic interface to setting the hardware in a good | ||
2593 | * state is ``reset''. On return the hardware is known to | ||
2594 | * be powered up and with interrupts disabled. This must | ||
2595 | * be followed by initialization of the appropriate bits | ||
2596 | * and then setup of the interrupt mask. | ||
2597 | */ | ||
2598 | sc->curchan = sc->hw->conf.channel; | ||
2599 | sc->curband = &sc->sbands[sc->curchan->band]; | ||
2600 | sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL | | ||
2601 | AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL | | ||
2602 | AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB; | ||
2603 | |||
2604 | ret = ath5k_reset(sc, NULL); | ||
2605 | if (ret) | ||
2606 | goto done; | ||
2607 | |||
2608 | ath5k_rfkill_hw_start(ah); | ||
2609 | |||
2610 | /* | ||
2611 | * Reset the key cache since some parts do not reset the | ||
2612 | * contents on initial power up or resume from suspend. | ||
2613 | */ | ||
2614 | for (i = 0; i < AR5K_KEYTABLE_SIZE; i++) | ||
2615 | ath5k_hw_reset_key(ah, i); | ||
2616 | |||
2617 | ath5k_hw_set_ack_bitrate_high(ah, true); | ||
2618 | ret = 0; | ||
2619 | done: | ||
2620 | mmiowb(); | ||
2621 | mutex_unlock(&sc->lock); | ||
2622 | return ret; | ||
2623 | } | ||
2624 | |||
2625 | static int | ||
2626 | ath5k_stop_locked(struct ath5k_softc *sc) | ||
2627 | { | ||
2628 | struct ath5k_hw *ah = sc->ah; | ||
2629 | |||
2630 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "invalid %u\n", | ||
2631 | test_bit(ATH_STAT_INVALID, sc->status)); | ||
2632 | |||
2633 | /* | ||
2634 | * Shutdown the hardware and driver: | ||
2635 | * stop output from above | ||
2636 | * disable interrupts | ||
2637 | * turn off timers | ||
2638 | * turn off the radio | ||
2639 | * clear transmit machinery | ||
2640 | * clear receive machinery | ||
2641 | * drain and release tx queues | ||
2642 | * reclaim beacon resources | ||
2643 | * power down hardware | ||
2644 | * | ||
2645 | * Note that some of this work is not possible if the | ||
2646 | * hardware is gone (invalid). | ||
2647 | */ | ||
2648 | ieee80211_stop_queues(sc->hw); | ||
2649 | |||
2650 | if (!test_bit(ATH_STAT_INVALID, sc->status)) { | ||
2651 | ath5k_led_off(sc); | ||
2652 | ath5k_hw_set_imr(ah, 0); | ||
2653 | synchronize_irq(sc->pdev->irq); | ||
2654 | } | ||
2655 | ath5k_txq_cleanup(sc); | ||
2656 | if (!test_bit(ATH_STAT_INVALID, sc->status)) { | ||
2657 | ath5k_rx_stop(sc); | ||
2658 | ath5k_hw_phy_disable(ah); | ||
2659 | } | ||
2660 | |||
2661 | return 0; | ||
2662 | } | ||
2663 | |||
2664 | static void stop_tasklets(struct ath5k_softc *sc) | ||
2665 | { | ||
2666 | tasklet_kill(&sc->rxtq); | ||
2667 | tasklet_kill(&sc->txtq); | ||
2668 | tasklet_kill(&sc->calib); | ||
2669 | tasklet_kill(&sc->beacontq); | ||
2670 | tasklet_kill(&sc->ani_tasklet); | ||
2671 | } | ||
2672 | |||
2673 | /* | ||
2674 | * Stop the device, grabbing the top-level lock to protect | ||
2675 | * against concurrent entry through ath5k_init (which can happen | ||
2676 | * if another thread does a system call and the thread doing the | ||
2677 | * stop is preempted). | ||
2678 | */ | ||
2679 | static int | ||
2680 | ath5k_stop_hw(struct ath5k_softc *sc) | ||
2681 | { | ||
2682 | int ret; | ||
2683 | |||
2684 | mutex_lock(&sc->lock); | ||
2685 | ret = ath5k_stop_locked(sc); | ||
2686 | if (ret == 0 && !test_bit(ATH_STAT_INVALID, sc->status)) { | ||
2687 | /* | ||
2688 | * Don't set the card in full sleep mode! | ||
2689 | * | ||
2690 | * a) When the device is in this state it must be carefully | ||
2691 | * woken up or references to registers in the PCI clock | ||
2692 | * domain may freeze the bus (and system). This varies | ||
2693 | * by chip and is mostly an issue with newer parts | ||
2694 | * (madwifi sources mentioned srev >= 0x78) that go to | ||
2695 | * sleep more quickly. | ||
2696 | * | ||
2697 | * b) On older chips full sleep results a weird behaviour | ||
2698 | * during wakeup. I tested various cards with srev < 0x78 | ||
2699 | * and they don't wake up after module reload, a second | ||
2700 | * module reload is needed to bring the card up again. | ||
2701 | * | ||
2702 | * Until we figure out what's going on don't enable | ||
2703 | * full chip reset on any chip (this is what Legacy HAL | ||
2704 | * and Sam's HAL do anyway). Instead Perform a full reset | ||
2705 | * on the device (same as initial state after attach) and | ||
2706 | * leave it idle (keep MAC/BB on warm reset) */ | ||
2707 | ret = ath5k_hw_on_hold(sc->ah); | ||
2708 | |||
2709 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, | ||
2710 | "putting device to sleep\n"); | ||
2711 | } | ||
2712 | ath5k_txbuf_free_skb(sc, sc->bbuf); | ||
2713 | |||
2714 | mmiowb(); | ||
2715 | mutex_unlock(&sc->lock); | ||
2716 | |||
2717 | stop_tasklets(sc); | ||
2718 | |||
2719 | ath5k_rfkill_hw_stop(sc->ah); | ||
2720 | |||
2721 | return ret; | ||
2722 | } | ||
2723 | |||
2724 | static void | 2130 | static void |
2725 | ath5k_intr_calibration_poll(struct ath5k_hw *ah) | 2131 | ath5k_intr_calibration_poll(struct ath5k_hw *ah) |
2726 | { | 2132 | { |
@@ -2741,7 +2147,21 @@ ath5k_intr_calibration_poll(struct ath5k_hw *ah) | |||
2741 | * AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI); */ | 2147 | * AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI); */ |
2742 | } | 2148 | } |
2743 | 2149 | ||
2744 | static irqreturn_t | 2150 | static void |
2151 | ath5k_schedule_rx(struct ath5k_softc *sc) | ||
2152 | { | ||
2153 | sc->rx_pending = true; | ||
2154 | tasklet_schedule(&sc->rxtq); | ||
2155 | } | ||
2156 | |||
2157 | static void | ||
2158 | ath5k_schedule_tx(struct ath5k_softc *sc) | ||
2159 | { | ||
2160 | sc->tx_pending = true; | ||
2161 | tasklet_schedule(&sc->txtq); | ||
2162 | } | ||
2163 | |||
2164 | irqreturn_t | ||
2745 | ath5k_intr(int irq, void *dev_id) | 2165 | ath5k_intr(int irq, void *dev_id) |
2746 | { | 2166 | { |
2747 | struct ath5k_softc *sc = dev_id; | 2167 | struct ath5k_softc *sc = dev_id; |
@@ -2750,7 +2170,8 @@ ath5k_intr(int irq, void *dev_id) | |||
2750 | unsigned int counter = 1000; | 2170 | unsigned int counter = 1000; |
2751 | 2171 | ||
2752 | if (unlikely(test_bit(ATH_STAT_INVALID, sc->status) || | 2172 | if (unlikely(test_bit(ATH_STAT_INVALID, sc->status) || |
2753 | !ath5k_hw_is_intr_pending(ah))) | 2173 | ((ath5k_get_bus_type(ah) != ATH_AHB) && |
2174 | !ath5k_hw_is_intr_pending(ah)))) | ||
2754 | return IRQ_NONE; | 2175 | return IRQ_NONE; |
2755 | 2176 | ||
2756 | do { | 2177 | do { |
@@ -2782,7 +2203,7 @@ ath5k_intr(int irq, void *dev_id) | |||
2782 | ieee80211_queue_work(sc->hw, &sc->reset_work); | 2203 | ieee80211_queue_work(sc->hw, &sc->reset_work); |
2783 | } | 2204 | } |
2784 | else | 2205 | else |
2785 | tasklet_schedule(&sc->rxtq); | 2206 | ath5k_schedule_rx(sc); |
2786 | } else { | 2207 | } else { |
2787 | if (status & AR5K_INT_SWBA) { | 2208 | if (status & AR5K_INT_SWBA) { |
2788 | tasklet_hi_schedule(&sc->beacontq); | 2209 | tasklet_hi_schedule(&sc->beacontq); |
@@ -2800,10 +2221,10 @@ ath5k_intr(int irq, void *dev_id) | |||
2800 | ath5k_hw_update_tx_triglevel(ah, true); | 2221 | ath5k_hw_update_tx_triglevel(ah, true); |
2801 | } | 2222 | } |
2802 | if (status & (AR5K_INT_RXOK | AR5K_INT_RXERR)) | 2223 | if (status & (AR5K_INT_RXOK | AR5K_INT_RXERR)) |
2803 | tasklet_schedule(&sc->rxtq); | 2224 | ath5k_schedule_rx(sc); |
2804 | if (status & (AR5K_INT_TXOK | AR5K_INT_TXDESC | 2225 | if (status & (AR5K_INT_TXOK | AR5K_INT_TXDESC |
2805 | | AR5K_INT_TXERR | AR5K_INT_TXEOL)) | 2226 | | AR5K_INT_TXERR | AR5K_INT_TXEOL)) |
2806 | tasklet_schedule(&sc->txtq); | 2227 | ath5k_schedule_tx(sc); |
2807 | if (status & AR5K_INT_BMISS) { | 2228 | if (status & AR5K_INT_BMISS) { |
2808 | /* TODO */ | 2229 | /* TODO */ |
2809 | } | 2230 | } |
@@ -2816,8 +2237,15 @@ ath5k_intr(int irq, void *dev_id) | |||
2816 | tasklet_schedule(&sc->rf_kill.toggleq); | 2237 | tasklet_schedule(&sc->rf_kill.toggleq); |
2817 | 2238 | ||
2818 | } | 2239 | } |
2240 | |||
2241 | if (ath5k_get_bus_type(ah) == ATH_AHB) | ||
2242 | break; | ||
2243 | |||
2819 | } while (ath5k_hw_is_intr_pending(ah) && --counter > 0); | 2244 | } while (ath5k_hw_is_intr_pending(ah) && --counter > 0); |
2820 | 2245 | ||
2246 | if (sc->rx_pending || sc->tx_pending) | ||
2247 | ath5k_set_current_imask(sc); | ||
2248 | |||
2821 | if (unlikely(!counter)) | 2249 | if (unlikely(!counter)) |
2822 | ATH5K_WARN(sc, "too many interrupts, giving up for now\n"); | 2250 | ATH5K_WARN(sc, "too many interrupts, giving up for now\n"); |
2823 | 2251 | ||
@@ -2857,14 +2285,13 @@ ath5k_tasklet_calibrate(unsigned long data) | |||
2857 | sc->curchan->center_freq)); | 2285 | sc->curchan->center_freq)); |
2858 | 2286 | ||
2859 | /* Noise floor calibration interrupts rx/tx path while I/Q calibration | 2287 | /* Noise floor calibration interrupts rx/tx path while I/Q calibration |
2860 | * doesn't. We stop the queues so that calibration doesn't interfere | 2288 | * doesn't. |
2861 | * with TX and don't run it as often */ | 2289 | * TODO: We should stop TX here, so that it doesn't interfere. |
2290 | * Note that stopping the queues is not enough to stop TX! */ | ||
2862 | if (time_is_before_eq_jiffies(ah->ah_cal_next_nf)) { | 2291 | if (time_is_before_eq_jiffies(ah->ah_cal_next_nf)) { |
2863 | ah->ah_cal_next_nf = jiffies + | 2292 | ah->ah_cal_next_nf = jiffies + |
2864 | msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_NF); | 2293 | msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_NF); |
2865 | ieee80211_stop_queues(sc->hw); | ||
2866 | ath5k_hw_update_noise_floor(ah); | 2294 | ath5k_hw_update_noise_floor(ah); |
2867 | ieee80211_wake_queues(sc->hw); | ||
2868 | } | 2295 | } |
2869 | 2296 | ||
2870 | ah->ah_cal_mask &= ~AR5K_CALIBRATION_FULL; | 2297 | ah->ah_cal_mask &= ~AR5K_CALIBRATION_FULL; |
@@ -2883,570 +2310,676 @@ ath5k_tasklet_ani(unsigned long data) | |||
2883 | } | 2310 | } |
2884 | 2311 | ||
2885 | 2312 | ||
2886 | /********************\ | 2313 | static void |
2887 | * Mac80211 functions * | 2314 | ath5k_tx_complete_poll_work(struct work_struct *work) |
2888 | \********************/ | ||
2889 | |||
2890 | static int | ||
2891 | ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
2892 | { | ||
2893 | struct ath5k_softc *sc = hw->priv; | ||
2894 | |||
2895 | return ath5k_tx_queue(hw, skb, sc->txq); | ||
2896 | } | ||
2897 | |||
2898 | static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
2899 | struct ath5k_txq *txq) | ||
2900 | { | 2315 | { |
2901 | struct ath5k_softc *sc = hw->priv; | 2316 | struct ath5k_softc *sc = container_of(work, struct ath5k_softc, |
2902 | struct ath5k_buf *bf; | 2317 | tx_complete_work.work); |
2903 | unsigned long flags; | 2318 | struct ath5k_txq *txq; |
2904 | int padsize; | 2319 | int i; |
2905 | 2320 | bool needreset = false; | |
2906 | ath5k_debug_dump_skb(sc, skb, "TX ", 1); | ||
2907 | 2321 | ||
2908 | if (sc->opmode == NL80211_IFTYPE_MONITOR) | 2322 | mutex_lock(&sc->lock); |
2909 | ATH5K_DBG(sc, ATH5K_DEBUG_XMIT, "tx in monitor (scan?)\n"); | ||
2910 | 2323 | ||
2911 | /* | 2324 | for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) { |
2912 | * the hardware expects the header padded to 4 byte boundaries | 2325 | if (sc->txqs[i].setup) { |
2913 | * if this is not the case we add the padding after the header | 2326 | txq = &sc->txqs[i]; |
2914 | */ | 2327 | spin_lock_bh(&txq->lock); |
2915 | padsize = ath5k_add_padding(skb); | 2328 | if (txq->txq_len > 1) { |
2916 | if (padsize < 0) { | 2329 | if (txq->txq_poll_mark) { |
2917 | ATH5K_ERR(sc, "tx hdrlen not %%4: not enough" | 2330 | ATH5K_DBG(sc, ATH5K_DEBUG_XMIT, |
2918 | " headroom to pad"); | 2331 | "TX queue stuck %d\n", |
2919 | goto drop_packet; | 2332 | txq->qnum); |
2333 | needreset = true; | ||
2334 | txq->txq_stuck++; | ||
2335 | spin_unlock_bh(&txq->lock); | ||
2336 | break; | ||
2337 | } else { | ||
2338 | txq->txq_poll_mark = true; | ||
2339 | } | ||
2340 | } | ||
2341 | spin_unlock_bh(&txq->lock); | ||
2342 | } | ||
2920 | } | 2343 | } |
2921 | 2344 | ||
2922 | spin_lock_irqsave(&sc->txbuflock, flags); | 2345 | if (needreset) { |
2923 | if (list_empty(&sc->txbuf)) { | 2346 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, |
2924 | ATH5K_ERR(sc, "no further txbuf available, dropping packet\n"); | 2347 | "TX queues stuck, resetting\n"); |
2925 | spin_unlock_irqrestore(&sc->txbuflock, flags); | 2348 | ath5k_reset(sc, NULL, true); |
2926 | ieee80211_stop_queue(hw, skb_get_queue_mapping(skb)); | ||
2927 | goto drop_packet; | ||
2928 | } | 2349 | } |
2929 | bf = list_first_entry(&sc->txbuf, struct ath5k_buf, list); | ||
2930 | list_del(&bf->list); | ||
2931 | sc->txbuf_len--; | ||
2932 | if (list_empty(&sc->txbuf)) | ||
2933 | ieee80211_stop_queues(hw); | ||
2934 | spin_unlock_irqrestore(&sc->txbuflock, flags); | ||
2935 | |||
2936 | bf->skb = skb; | ||
2937 | 2350 | ||
2938 | if (ath5k_txbuf_setup(sc, bf, txq, padsize)) { | 2351 | mutex_unlock(&sc->lock); |
2939 | bf->skb = NULL; | ||
2940 | spin_lock_irqsave(&sc->txbuflock, flags); | ||
2941 | list_add_tail(&bf->list, &sc->txbuf); | ||
2942 | sc->txbuf_len++; | ||
2943 | spin_unlock_irqrestore(&sc->txbuflock, flags); | ||
2944 | goto drop_packet; | ||
2945 | } | ||
2946 | return NETDEV_TX_OK; | ||
2947 | 2352 | ||
2948 | drop_packet: | 2353 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, |
2949 | dev_kfree_skb_any(skb); | 2354 | msecs_to_jiffies(ATH5K_TX_COMPLETE_POLL_INT)); |
2950 | return NETDEV_TX_OK; | ||
2951 | } | 2355 | } |
2952 | 2356 | ||
2953 | /* | 2357 | |
2954 | * Reset the hardware. If chan is not NULL, then also pause rx/tx | 2358 | /*************************\ |
2955 | * and change to the given channel. | 2359 | * Initialization routines * |
2956 | * | 2360 | \*************************/ |
2957 | * This should be called with sc->lock. | 2361 | |
2958 | */ | 2362 | int |
2959 | static int | 2363 | ath5k_init_softc(struct ath5k_softc *sc, const struct ath_bus_ops *bus_ops) |
2960 | ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan) | ||
2961 | { | 2364 | { |
2962 | struct ath5k_hw *ah = sc->ah; | 2365 | struct ieee80211_hw *hw = sc->hw; |
2366 | struct ath_common *common; | ||
2963 | int ret; | 2367 | int ret; |
2368 | int csz; | ||
2964 | 2369 | ||
2965 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n"); | 2370 | /* Initialize driver private data */ |
2371 | SET_IEEE80211_DEV(hw, sc->dev); | ||
2372 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | ||
2373 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | ||
2374 | IEEE80211_HW_SIGNAL_DBM | | ||
2375 | IEEE80211_HW_REPORTS_TX_ACK_STATUS; | ||
2966 | 2376 | ||
2967 | ath5k_hw_set_imr(ah, 0); | 2377 | hw->wiphy->interface_modes = |
2968 | synchronize_irq(sc->pdev->irq); | 2378 | BIT(NL80211_IFTYPE_AP) | |
2969 | stop_tasklets(sc); | 2379 | BIT(NL80211_IFTYPE_STATION) | |
2380 | BIT(NL80211_IFTYPE_ADHOC) | | ||
2381 | BIT(NL80211_IFTYPE_MESH_POINT); | ||
2970 | 2382 | ||
2971 | if (chan) { | 2383 | /* both antennas can be configured as RX or TX */ |
2972 | ath5k_txq_cleanup(sc); | 2384 | hw->wiphy->available_antennas_tx = 0x3; |
2973 | ath5k_rx_stop(sc); | 2385 | hw->wiphy->available_antennas_rx = 0x3; |
2974 | 2386 | ||
2975 | sc->curchan = chan; | 2387 | hw->extra_tx_headroom = 2; |
2976 | sc->curband = &sc->sbands[chan->band]; | 2388 | hw->channel_change_time = 5000; |
2977 | } | ||
2978 | ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, chan != NULL); | ||
2979 | if (ret) { | ||
2980 | ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret); | ||
2981 | goto err; | ||
2982 | } | ||
2983 | 2389 | ||
2984 | ret = ath5k_rx_start(sc); | 2390 | /* |
2391 | * Mark the device as detached to avoid processing | ||
2392 | * interrupts until setup is complete. | ||
2393 | */ | ||
2394 | __set_bit(ATH_STAT_INVALID, sc->status); | ||
2395 | |||
2396 | sc->opmode = NL80211_IFTYPE_STATION; | ||
2397 | sc->bintval = 1000; | ||
2398 | mutex_init(&sc->lock); | ||
2399 | spin_lock_init(&sc->rxbuflock); | ||
2400 | spin_lock_init(&sc->txbuflock); | ||
2401 | spin_lock_init(&sc->block); | ||
2402 | spin_lock_init(&sc->irqlock); | ||
2403 | |||
2404 | /* Setup interrupt handler */ | ||
2405 | ret = request_irq(sc->irq, ath5k_intr, IRQF_SHARED, "ath", sc); | ||
2985 | if (ret) { | 2406 | if (ret) { |
2986 | ATH5K_ERR(sc, "can't start recv logic\n"); | 2407 | ATH5K_ERR(sc, "request_irq failed\n"); |
2987 | goto err; | 2408 | goto err; |
2988 | } | 2409 | } |
2989 | 2410 | ||
2990 | ath5k_ani_init(ah, ah->ah_sc->ani_state.ani_mode); | 2411 | /* If we passed the test, malloc an ath5k_hw struct */ |
2412 | sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL); | ||
2413 | if (!sc->ah) { | ||
2414 | ret = -ENOMEM; | ||
2415 | ATH5K_ERR(sc, "out of memory\n"); | ||
2416 | goto err_irq; | ||
2417 | } | ||
2991 | 2418 | ||
2992 | ah->ah_cal_next_full = jiffies; | 2419 | sc->ah->ah_sc = sc; |
2993 | ah->ah_cal_next_ani = jiffies; | 2420 | sc->ah->ah_iobase = sc->iobase; |
2994 | ah->ah_cal_next_nf = jiffies; | 2421 | common = ath5k_hw_common(sc->ah); |
2422 | common->ops = &ath5k_common_ops; | ||
2423 | common->bus_ops = bus_ops; | ||
2424 | common->ah = sc->ah; | ||
2425 | common->hw = hw; | ||
2426 | common->priv = sc; | ||
2995 | 2427 | ||
2996 | /* | 2428 | /* |
2997 | * Change channels and update the h/w rate map if we're switching; | 2429 | * Cache line size is used to size and align various |
2998 | * e.g. 11a to 11b/g. | 2430 | * structures used to communicate with the hardware. |
2999 | * | ||
3000 | * We may be doing a reset in response to an ioctl that changes the | ||
3001 | * channel so update any state that might change as a result. | ||
3002 | * | ||
3003 | * XXX needed? | ||
3004 | */ | 2431 | */ |
3005 | /* ath5k_chan_change(sc, c); */ | 2432 | ath5k_read_cachesize(common, &csz); |
2433 | common->cachelsz = csz << 2; /* convert to bytes */ | ||
3006 | 2434 | ||
3007 | ath5k_beacon_config(sc); | 2435 | spin_lock_init(&common->cc_lock); |
3008 | /* intrs are enabled by ath5k_beacon_config */ | ||
3009 | 2436 | ||
3010 | ieee80211_wake_queues(sc->hw); | 2437 | /* Initialize device */ |
2438 | ret = ath5k_hw_init(sc); | ||
2439 | if (ret) | ||
2440 | goto err_free_ah; | ||
2441 | |||
2442 | /* set up multi-rate retry capabilities */ | ||
2443 | if (sc->ah->ah_version == AR5K_AR5212) { | ||
2444 | hw->max_rates = 4; | ||
2445 | hw->max_rate_tries = max(AR5K_INIT_RETRY_SHORT, | ||
2446 | AR5K_INIT_RETRY_LONG); | ||
2447 | } | ||
2448 | |||
2449 | hw->vif_data_size = sizeof(struct ath5k_vif); | ||
2450 | |||
2451 | /* Finish private driver data initialization */ | ||
2452 | ret = ath5k_init(hw); | ||
2453 | if (ret) | ||
2454 | goto err_ah; | ||
2455 | |||
2456 | ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n", | ||
2457 | ath5k_chip_name(AR5K_VERSION_MAC, sc->ah->ah_mac_srev), | ||
2458 | sc->ah->ah_mac_srev, | ||
2459 | sc->ah->ah_phy_revision); | ||
2460 | |||
2461 | if (!sc->ah->ah_single_chip) { | ||
2462 | /* Single chip radio (!RF5111) */ | ||
2463 | if (sc->ah->ah_radio_5ghz_revision && | ||
2464 | !sc->ah->ah_radio_2ghz_revision) { | ||
2465 | /* No 5GHz support -> report 2GHz radio */ | ||
2466 | if (!test_bit(AR5K_MODE_11A, | ||
2467 | sc->ah->ah_capabilities.cap_mode)) { | ||
2468 | ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n", | ||
2469 | ath5k_chip_name(AR5K_VERSION_RAD, | ||
2470 | sc->ah->ah_radio_5ghz_revision), | ||
2471 | sc->ah->ah_radio_5ghz_revision); | ||
2472 | /* No 2GHz support (5110 and some | ||
2473 | * 5Ghz only cards) -> report 5Ghz radio */ | ||
2474 | } else if (!test_bit(AR5K_MODE_11B, | ||
2475 | sc->ah->ah_capabilities.cap_mode)) { | ||
2476 | ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n", | ||
2477 | ath5k_chip_name(AR5K_VERSION_RAD, | ||
2478 | sc->ah->ah_radio_5ghz_revision), | ||
2479 | sc->ah->ah_radio_5ghz_revision); | ||
2480 | /* Multiband radio */ | ||
2481 | } else { | ||
2482 | ATH5K_INFO(sc, "RF%s multiband radio found" | ||
2483 | " (0x%x)\n", | ||
2484 | ath5k_chip_name(AR5K_VERSION_RAD, | ||
2485 | sc->ah->ah_radio_5ghz_revision), | ||
2486 | sc->ah->ah_radio_5ghz_revision); | ||
2487 | } | ||
2488 | } | ||
2489 | /* Multi chip radio (RF5111 - RF2111) -> | ||
2490 | * report both 2GHz/5GHz radios */ | ||
2491 | else if (sc->ah->ah_radio_5ghz_revision && | ||
2492 | sc->ah->ah_radio_2ghz_revision){ | ||
2493 | ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n", | ||
2494 | ath5k_chip_name(AR5K_VERSION_RAD, | ||
2495 | sc->ah->ah_radio_5ghz_revision), | ||
2496 | sc->ah->ah_radio_5ghz_revision); | ||
2497 | ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n", | ||
2498 | ath5k_chip_name(AR5K_VERSION_RAD, | ||
2499 | sc->ah->ah_radio_2ghz_revision), | ||
2500 | sc->ah->ah_radio_2ghz_revision); | ||
2501 | } | ||
2502 | } | ||
2503 | |||
2504 | ath5k_debug_init_device(sc); | ||
2505 | |||
2506 | /* ready to process interrupts */ | ||
2507 | __clear_bit(ATH_STAT_INVALID, sc->status); | ||
3011 | 2508 | ||
3012 | return 0; | 2509 | return 0; |
2510 | err_ah: | ||
2511 | ath5k_hw_deinit(sc->ah); | ||
2512 | err_free_ah: | ||
2513 | kfree(sc->ah); | ||
2514 | err_irq: | ||
2515 | free_irq(sc->irq, sc); | ||
3013 | err: | 2516 | err: |
3014 | return ret; | 2517 | return ret; |
3015 | } | 2518 | } |
3016 | 2519 | ||
3017 | static void ath5k_reset_work(struct work_struct *work) | 2520 | static int |
2521 | ath5k_stop_locked(struct ath5k_softc *sc) | ||
3018 | { | 2522 | { |
3019 | struct ath5k_softc *sc = container_of(work, struct ath5k_softc, | 2523 | struct ath5k_hw *ah = sc->ah; |
3020 | reset_work); | ||
3021 | 2524 | ||
3022 | mutex_lock(&sc->lock); | 2525 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "invalid %u\n", |
3023 | ath5k_reset(sc, sc->curchan); | 2526 | test_bit(ATH_STAT_INVALID, sc->status)); |
3024 | mutex_unlock(&sc->lock); | ||
3025 | } | ||
3026 | 2527 | ||
3027 | static int ath5k_start(struct ieee80211_hw *hw) | 2528 | /* |
3028 | { | 2529 | * Shutdown the hardware and driver: |
3029 | return ath5k_init(hw->priv); | 2530 | * stop output from above |
3030 | } | 2531 | * disable interrupts |
2532 | * turn off timers | ||
2533 | * turn off the radio | ||
2534 | * clear transmit machinery | ||
2535 | * clear receive machinery | ||
2536 | * drain and release tx queues | ||
2537 | * reclaim beacon resources | ||
2538 | * power down hardware | ||
2539 | * | ||
2540 | * Note that some of this work is not possible if the | ||
2541 | * hardware is gone (invalid). | ||
2542 | */ | ||
2543 | ieee80211_stop_queues(sc->hw); | ||
3031 | 2544 | ||
3032 | static void ath5k_stop(struct ieee80211_hw *hw) | 2545 | if (!test_bit(ATH_STAT_INVALID, sc->status)) { |
3033 | { | 2546 | ath5k_led_off(sc); |
3034 | ath5k_stop_hw(hw->priv); | 2547 | ath5k_hw_set_imr(ah, 0); |
2548 | synchronize_irq(sc->irq); | ||
2549 | ath5k_rx_stop(sc); | ||
2550 | ath5k_hw_dma_stop(ah); | ||
2551 | ath5k_drain_tx_buffs(sc); | ||
2552 | ath5k_hw_phy_disable(ah); | ||
2553 | } | ||
2554 | |||
2555 | return 0; | ||
3035 | } | 2556 | } |
3036 | 2557 | ||
3037 | static int ath5k_add_interface(struct ieee80211_hw *hw, | 2558 | int |
3038 | struct ieee80211_vif *vif) | 2559 | ath5k_init_hw(struct ath5k_softc *sc) |
3039 | { | 2560 | { |
3040 | struct ath5k_softc *sc = hw->priv; | 2561 | struct ath5k_hw *ah = sc->ah; |
3041 | int ret; | 2562 | struct ath_common *common = ath5k_hw_common(ah); |
2563 | int ret, i; | ||
3042 | 2564 | ||
3043 | mutex_lock(&sc->lock); | 2565 | mutex_lock(&sc->lock); |
3044 | if (sc->vif) { | ||
3045 | ret = 0; | ||
3046 | goto end; | ||
3047 | } | ||
3048 | 2566 | ||
3049 | sc->vif = vif; | 2567 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode); |
3050 | 2568 | ||
3051 | switch (vif->type) { | 2569 | /* |
3052 | case NL80211_IFTYPE_AP: | 2570 | * Stop anything previously setup. This is safe |
3053 | case NL80211_IFTYPE_STATION: | 2571 | * no matter this is the first time through or not. |
3054 | case NL80211_IFTYPE_ADHOC: | 2572 | */ |
3055 | case NL80211_IFTYPE_MESH_POINT: | 2573 | ath5k_stop_locked(sc); |
3056 | case NL80211_IFTYPE_MONITOR: | 2574 | |
3057 | sc->opmode = vif->type; | 2575 | /* |
3058 | break; | 2576 | * The basic interface to setting the hardware in a good |
3059 | default: | 2577 | * state is ``reset''. On return the hardware is known to |
3060 | ret = -EOPNOTSUPP; | 2578 | * be powered up and with interrupts disabled. This must |
3061 | goto end; | 2579 | * be followed by initialization of the appropriate bits |
3062 | } | 2580 | * and then setup of the interrupt mask. |
2581 | */ | ||
2582 | sc->curchan = sc->hw->conf.channel; | ||
2583 | sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL | | ||
2584 | AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL | | ||
2585 | AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB; | ||
3063 | 2586 | ||
3064 | ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "add interface mode %d\n", sc->opmode); | 2587 | ret = ath5k_reset(sc, NULL, false); |
2588 | if (ret) | ||
2589 | goto done; | ||
3065 | 2590 | ||
3066 | ath5k_hw_set_lladdr(sc->ah, vif->addr); | 2591 | ath5k_rfkill_hw_start(ah); |
3067 | ath5k_mode_setup(sc); | 2592 | |
2593 | /* | ||
2594 | * Reset the key cache since some parts do not reset the | ||
2595 | * contents on initial power up or resume from suspend. | ||
2596 | */ | ||
2597 | for (i = 0; i < common->keymax; i++) | ||
2598 | ath_hw_keyreset(common, (u16) i); | ||
2599 | |||
2600 | /* Use higher rates for acks instead of base | ||
2601 | * rate */ | ||
2602 | ah->ah_ack_bitrate_high = true; | ||
2603 | |||
2604 | for (i = 0; i < ARRAY_SIZE(sc->bslot); i++) | ||
2605 | sc->bslot[i] = NULL; | ||
3068 | 2606 | ||
3069 | ret = 0; | 2607 | ret = 0; |
3070 | end: | 2608 | done: |
2609 | mmiowb(); | ||
3071 | mutex_unlock(&sc->lock); | 2610 | mutex_unlock(&sc->lock); |
2611 | |||
2612 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, | ||
2613 | msecs_to_jiffies(ATH5K_TX_COMPLETE_POLL_INT)); | ||
2614 | |||
3072 | return ret; | 2615 | return ret; |
3073 | } | 2616 | } |
3074 | 2617 | ||
3075 | static void | 2618 | static void stop_tasklets(struct ath5k_softc *sc) |
3076 | ath5k_remove_interface(struct ieee80211_hw *hw, | ||
3077 | struct ieee80211_vif *vif) | ||
3078 | { | 2619 | { |
3079 | struct ath5k_softc *sc = hw->priv; | 2620 | sc->rx_pending = false; |
3080 | u8 mac[ETH_ALEN] = {}; | 2621 | sc->tx_pending = false; |
3081 | 2622 | tasklet_kill(&sc->rxtq); | |
3082 | mutex_lock(&sc->lock); | 2623 | tasklet_kill(&sc->txtq); |
3083 | if (sc->vif != vif) | 2624 | tasklet_kill(&sc->calib); |
3084 | goto end; | 2625 | tasklet_kill(&sc->beacontq); |
3085 | 2626 | tasklet_kill(&sc->ani_tasklet); | |
3086 | ath5k_hw_set_lladdr(sc->ah, mac); | ||
3087 | sc->vif = NULL; | ||
3088 | end: | ||
3089 | mutex_unlock(&sc->lock); | ||
3090 | } | 2627 | } |
3091 | 2628 | ||
3092 | /* | 2629 | /* |
3093 | * TODO: Phy disable/diversity etc | 2630 | * Stop the device, grabbing the top-level lock to protect |
2631 | * against concurrent entry through ath5k_init (which can happen | ||
2632 | * if another thread does a system call and the thread doing the | ||
2633 | * stop is preempted). | ||
3094 | */ | 2634 | */ |
3095 | static int | 2635 | int |
3096 | ath5k_config(struct ieee80211_hw *hw, u32 changed) | 2636 | ath5k_stop_hw(struct ath5k_softc *sc) |
3097 | { | 2637 | { |
3098 | struct ath5k_softc *sc = hw->priv; | 2638 | int ret; |
3099 | struct ath5k_hw *ah = sc->ah; | ||
3100 | struct ieee80211_conf *conf = &hw->conf; | ||
3101 | int ret = 0; | ||
3102 | 2639 | ||
3103 | mutex_lock(&sc->lock); | 2640 | mutex_lock(&sc->lock); |
2641 | ret = ath5k_stop_locked(sc); | ||
2642 | if (ret == 0 && !test_bit(ATH_STAT_INVALID, sc->status)) { | ||
2643 | /* | ||
2644 | * Don't set the card in full sleep mode! | ||
2645 | * | ||
2646 | * a) When the device is in this state it must be carefully | ||
2647 | * woken up or references to registers in the PCI clock | ||
2648 | * domain may freeze the bus (and system). This varies | ||
2649 | * by chip and is mostly an issue with newer parts | ||
2650 | * (madwifi sources mentioned srev >= 0x78) that go to | ||
2651 | * sleep more quickly. | ||
2652 | * | ||
2653 | * b) On older chips full sleep results a weird behaviour | ||
2654 | * during wakeup. I tested various cards with srev < 0x78 | ||
2655 | * and they don't wake up after module reload, a second | ||
2656 | * module reload is needed to bring the card up again. | ||
2657 | * | ||
2658 | * Until we figure out what's going on don't enable | ||
2659 | * full chip reset on any chip (this is what Legacy HAL | ||
2660 | * and Sam's HAL do anyway). Instead Perform a full reset | ||
2661 | * on the device (same as initial state after attach) and | ||
2662 | * leave it idle (keep MAC/BB on warm reset) */ | ||
2663 | ret = ath5k_hw_on_hold(sc->ah); | ||
3104 | 2664 | ||
3105 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { | 2665 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, |
3106 | ret = ath5k_chan_set(sc, conf->channel); | 2666 | "putting device to sleep\n"); |
3107 | if (ret < 0) | ||
3108 | goto unlock; | ||
3109 | } | ||
3110 | |||
3111 | if ((changed & IEEE80211_CONF_CHANGE_POWER) && | ||
3112 | (sc->power_level != conf->power_level)) { | ||
3113 | sc->power_level = conf->power_level; | ||
3114 | |||
3115 | /* Half dB steps */ | ||
3116 | ath5k_hw_set_txpower_limit(ah, (conf->power_level * 2)); | ||
3117 | } | 2667 | } |
3118 | 2668 | ||
3119 | /* TODO: | 2669 | mmiowb(); |
3120 | * 1) Move this on config_interface and handle each case | ||
3121 | * separately eg. when we have only one STA vif, use | ||
3122 | * AR5K_ANTMODE_SINGLE_AP | ||
3123 | * | ||
3124 | * 2) Allow the user to change antenna mode eg. when only | ||
3125 | * one antenna is present | ||
3126 | * | ||
3127 | * 3) Allow the user to set default/tx antenna when possible | ||
3128 | * | ||
3129 | * 4) Default mode should handle 90% of the cases, together | ||
3130 | * with fixed a/b and single AP modes we should be able to | ||
3131 | * handle 99%. Sectored modes are extreme cases and i still | ||
3132 | * haven't found a usage for them. If we decide to support them, | ||
3133 | * then we must allow the user to set how many tx antennas we | ||
3134 | * have available | ||
3135 | */ | ||
3136 | ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode); | ||
3137 | |||
3138 | unlock: | ||
3139 | mutex_unlock(&sc->lock); | 2670 | mutex_unlock(&sc->lock); |
3140 | return ret; | ||
3141 | } | ||
3142 | 2671 | ||
3143 | static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw, | 2672 | stop_tasklets(sc); |
3144 | struct netdev_hw_addr_list *mc_list) | ||
3145 | { | ||
3146 | u32 mfilt[2], val; | ||
3147 | u8 pos; | ||
3148 | struct netdev_hw_addr *ha; | ||
3149 | 2673 | ||
3150 | mfilt[0] = 0; | 2674 | cancel_delayed_work_sync(&sc->tx_complete_work); |
3151 | mfilt[1] = 1; | ||
3152 | 2675 | ||
3153 | netdev_hw_addr_list_for_each(ha, mc_list) { | 2676 | ath5k_rfkill_hw_stop(sc->ah); |
3154 | /* calculate XOR of eight 6-bit values */ | ||
3155 | val = get_unaligned_le32(ha->addr + 0); | ||
3156 | pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val; | ||
3157 | val = get_unaligned_le32(ha->addr + 3); | ||
3158 | pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val; | ||
3159 | pos &= 0x3f; | ||
3160 | mfilt[pos / 32] |= (1 << (pos % 32)); | ||
3161 | /* XXX: we might be able to just do this instead, | ||
3162 | * but not sure, needs testing, if we do use this we'd | ||
3163 | * neet to inform below to not reset the mcast */ | ||
3164 | /* ath5k_hw_set_mcast_filterindex(ah, | ||
3165 | * ha->addr[5]); */ | ||
3166 | } | ||
3167 | 2677 | ||
3168 | return ((u64)(mfilt[1]) << 32) | mfilt[0]; | 2678 | return ret; |
3169 | } | 2679 | } |
3170 | 2680 | ||
3171 | #define SUPPORTED_FIF_FLAGS \ | ||
3172 | FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | \ | ||
3173 | FIF_PLCPFAIL | FIF_CONTROL | FIF_OTHER_BSS | \ | ||
3174 | FIF_BCN_PRBRESP_PROMISC | ||
3175 | /* | 2681 | /* |
3176 | * o always accept unicast, broadcast, and multicast traffic | 2682 | * Reset the hardware. If chan is not NULL, then also pause rx/tx |
3177 | * o multicast traffic for all BSSIDs will be enabled if mac80211 | 2683 | * and change to the given channel. |
3178 | * says it should be | 2684 | * |
3179 | * o maintain current state of phy ofdm or phy cck error reception. | 2685 | * This should be called with sc->lock. |
3180 | * If the hardware detects any of these type of errors then | ||
3181 | * ath5k_hw_get_rx_filter() will pass to us the respective | ||
3182 | * hardware filters to be able to receive these type of frames. | ||
3183 | * o probe request frames are accepted only when operating in | ||
3184 | * hostap, adhoc, or monitor modes | ||
3185 | * o enable promiscuous mode according to the interface state | ||
3186 | * o accept beacons: | ||
3187 | * - when operating in adhoc mode so the 802.11 layer creates | ||
3188 | * node table entries for peers, | ||
3189 | * - when operating in station mode for collecting rssi data when | ||
3190 | * the station is otherwise quiet, or | ||
3191 | * - when scanning | ||
3192 | */ | 2686 | */ |
3193 | static void ath5k_configure_filter(struct ieee80211_hw *hw, | 2687 | static int |
3194 | unsigned int changed_flags, | 2688 | ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan, |
3195 | unsigned int *new_flags, | 2689 | bool skip_pcu) |
3196 | u64 multicast) | ||
3197 | { | 2690 | { |
3198 | struct ath5k_softc *sc = hw->priv; | ||
3199 | struct ath5k_hw *ah = sc->ah; | 2691 | struct ath5k_hw *ah = sc->ah; |
3200 | u32 mfilt[2], rfilt; | 2692 | struct ath_common *common = ath5k_hw_common(ah); |
2693 | int ret, ani_mode; | ||
2694 | bool fast; | ||
3201 | 2695 | ||
3202 | mutex_lock(&sc->lock); | 2696 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n"); |
3203 | 2697 | ||
3204 | mfilt[0] = multicast; | 2698 | ath5k_hw_set_imr(ah, 0); |
3205 | mfilt[1] = multicast >> 32; | 2699 | synchronize_irq(sc->irq); |
2700 | stop_tasklets(sc); | ||
3206 | 2701 | ||
3207 | /* Only deal with supported flags */ | 2702 | /* Save ani mode and disable ANI during |
3208 | changed_flags &= SUPPORTED_FIF_FLAGS; | 2703 | * reset. If we don't we might get false |
3209 | *new_flags &= SUPPORTED_FIF_FLAGS; | 2704 | * PHY error interrupts. */ |
2705 | ani_mode = ah->ah_sc->ani_state.ani_mode; | ||
2706 | ath5k_ani_init(ah, ATH5K_ANI_MODE_OFF); | ||
2707 | |||
2708 | /* We are going to empty hw queues | ||
2709 | * so we should also free any remaining | ||
2710 | * tx buffers */ | ||
2711 | ath5k_drain_tx_buffs(sc); | ||
2712 | if (chan) | ||
2713 | sc->curchan = chan; | ||
3210 | 2714 | ||
3211 | /* If HW detects any phy or radar errors, leave those filters on. | 2715 | fast = ((chan != NULL) && modparam_fastchanswitch) ? 1 : 0; |
3212 | * Also, always enable Unicast, Broadcasts and Multicast | ||
3213 | * XXX: move unicast, bssid broadcasts and multicast to mac80211 */ | ||
3214 | rfilt = (ath5k_hw_get_rx_filter(ah) & (AR5K_RX_FILTER_PHYERR)) | | ||
3215 | (AR5K_RX_FILTER_UCAST | AR5K_RX_FILTER_BCAST | | ||
3216 | AR5K_RX_FILTER_MCAST); | ||
3217 | 2716 | ||
3218 | if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) { | 2717 | ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, fast, |
3219 | if (*new_flags & FIF_PROMISC_IN_BSS) { | 2718 | skip_pcu); |
3220 | __set_bit(ATH_STAT_PROMISC, sc->status); | 2719 | if (ret) { |
3221 | } else { | 2720 | ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret); |
3222 | __clear_bit(ATH_STAT_PROMISC, sc->status); | 2721 | goto err; |
3223 | } | ||
3224 | } | 2722 | } |
3225 | 2723 | ||
3226 | if (test_bit(ATH_STAT_PROMISC, sc->status)) | 2724 | ret = ath5k_rx_start(sc); |
3227 | rfilt |= AR5K_RX_FILTER_PROM; | 2725 | if (ret) { |
3228 | 2726 | ATH5K_ERR(sc, "can't start recv logic\n"); | |
3229 | /* Note, AR5K_RX_FILTER_MCAST is already enabled */ | 2727 | goto err; |
3230 | if (*new_flags & FIF_ALLMULTI) { | ||
3231 | mfilt[0] = ~0; | ||
3232 | mfilt[1] = ~0; | ||
3233 | } | 2728 | } |
3234 | 2729 | ||
3235 | /* This is the best we can do */ | 2730 | ath5k_ani_init(ah, ani_mode); |
3236 | if (*new_flags & (FIF_FCSFAIL | FIF_PLCPFAIL)) | ||
3237 | rfilt |= AR5K_RX_FILTER_PHYERR; | ||
3238 | 2731 | ||
3239 | /* FIF_BCN_PRBRESP_PROMISC really means to enable beacons | 2732 | ah->ah_cal_next_full = jiffies; |
3240 | * and probes for any BSSID, this needs testing */ | 2733 | ah->ah_cal_next_ani = jiffies; |
3241 | if (*new_flags & FIF_BCN_PRBRESP_PROMISC) | 2734 | ah->ah_cal_next_nf = jiffies; |
3242 | rfilt |= AR5K_RX_FILTER_BEACON | AR5K_RX_FILTER_PROBEREQ; | 2735 | ewma_init(&ah->ah_beacon_rssi_avg, 1024, 8); |
3243 | 2736 | ||
3244 | /* FIF_CONTROL doc says that if FIF_PROMISC_IN_BSS is not | 2737 | /* clear survey data and cycle counters */ |
3245 | * set we should only pass on control frames for this | 2738 | memset(&sc->survey, 0, sizeof(sc->survey)); |
3246 | * station. This needs testing. I believe right now this | 2739 | spin_lock_bh(&common->cc_lock); |
3247 | * enables *all* control frames, which is OK.. but | 2740 | ath_hw_cycle_counters_update(common); |
3248 | * but we should see if we can improve on granularity */ | 2741 | memset(&common->cc_survey, 0, sizeof(common->cc_survey)); |
3249 | if (*new_flags & FIF_CONTROL) | 2742 | memset(&common->cc_ani, 0, sizeof(common->cc_ani)); |
3250 | rfilt |= AR5K_RX_FILTER_CONTROL; | 2743 | spin_unlock_bh(&common->cc_lock); |
3251 | 2744 | ||
3252 | /* Additional settings per mode -- this is per ath5k */ | 2745 | /* |
2746 | * Change channels and update the h/w rate map if we're switching; | ||
2747 | * e.g. 11a to 11b/g. | ||
2748 | * | ||
2749 | * We may be doing a reset in response to an ioctl that changes the | ||
2750 | * channel so update any state that might change as a result. | ||
2751 | * | ||
2752 | * XXX needed? | ||
2753 | */ | ||
2754 | /* ath5k_chan_change(sc, c); */ | ||
3253 | 2755 | ||
3254 | /* XXX move these to mac80211, and add a beacon IFF flag to mac80211 */ | 2756 | ath5k_beacon_config(sc); |
2757 | /* intrs are enabled by ath5k_beacon_config */ | ||
3255 | 2758 | ||
3256 | switch (sc->opmode) { | 2759 | ieee80211_wake_queues(sc->hw); |
3257 | case NL80211_IFTYPE_MESH_POINT: | ||
3258 | case NL80211_IFTYPE_MONITOR: | ||
3259 | rfilt |= AR5K_RX_FILTER_CONTROL | | ||
3260 | AR5K_RX_FILTER_BEACON | | ||
3261 | AR5K_RX_FILTER_PROBEREQ | | ||
3262 | AR5K_RX_FILTER_PROM; | ||
3263 | break; | ||
3264 | case NL80211_IFTYPE_AP: | ||
3265 | case NL80211_IFTYPE_ADHOC: | ||
3266 | rfilt |= AR5K_RX_FILTER_PROBEREQ | | ||
3267 | AR5K_RX_FILTER_BEACON; | ||
3268 | break; | ||
3269 | case NL80211_IFTYPE_STATION: | ||
3270 | if (sc->assoc) | ||
3271 | rfilt |= AR5K_RX_FILTER_BEACON; | ||
3272 | default: | ||
3273 | break; | ||
3274 | } | ||
3275 | 2760 | ||
3276 | /* Set filters */ | 2761 | return 0; |
3277 | ath5k_hw_set_rx_filter(ah, rfilt); | 2762 | err: |
2763 | return ret; | ||
2764 | } | ||
3278 | 2765 | ||
3279 | /* Set multicast bits */ | 2766 | static void ath5k_reset_work(struct work_struct *work) |
3280 | ath5k_hw_set_mcast_filter(ah, mfilt[0], mfilt[1]); | 2767 | { |
3281 | /* Set the cached hw filter flags, this will alter actually | 2768 | struct ath5k_softc *sc = container_of(work, struct ath5k_softc, |
3282 | * be set in HW */ | 2769 | reset_work); |
3283 | sc->filter_flags = rfilt; | ||
3284 | 2770 | ||
2771 | mutex_lock(&sc->lock); | ||
2772 | ath5k_reset(sc, NULL, true); | ||
3285 | mutex_unlock(&sc->lock); | 2773 | mutex_unlock(&sc->lock); |
3286 | } | 2774 | } |
3287 | 2775 | ||
3288 | static int | 2776 | static int |
3289 | ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | 2777 | ath5k_init(struct ieee80211_hw *hw) |
3290 | struct ieee80211_vif *vif, struct ieee80211_sta *sta, | ||
3291 | struct ieee80211_key_conf *key) | ||
3292 | { | 2778 | { |
2779 | |||
3293 | struct ath5k_softc *sc = hw->priv; | 2780 | struct ath5k_softc *sc = hw->priv; |
3294 | struct ath5k_hw *ah = sc->ah; | 2781 | struct ath5k_hw *ah = sc->ah; |
3295 | struct ath_common *common = ath5k_hw_common(ah); | 2782 | struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah); |
3296 | int ret = 0; | 2783 | struct ath5k_txq *txq; |
2784 | u8 mac[ETH_ALEN] = {}; | ||
2785 | int ret; | ||
3297 | 2786 | ||
3298 | if (modparam_nohwcrypt) | ||
3299 | return -EOPNOTSUPP; | ||
3300 | 2787 | ||
3301 | if (sc->opmode == NL80211_IFTYPE_AP) | 2788 | /* |
3302 | return -EOPNOTSUPP; | 2789 | * Check if the MAC has multi-rate retry support. |
2790 | * We do this by trying to setup a fake extended | ||
2791 | * descriptor. MACs that don't have support will | ||
2792 | * return false w/o doing anything. MACs that do | ||
2793 | * support it will return true w/o doing anything. | ||
2794 | */ | ||
2795 | ret = ath5k_hw_setup_mrr_tx_desc(ah, NULL, 0, 0, 0, 0, 0, 0); | ||
3303 | 2796 | ||
3304 | switch (key->alg) { | 2797 | if (ret < 0) |
3305 | case ALG_WEP: | 2798 | goto err; |
3306 | case ALG_TKIP: | 2799 | if (ret > 0) |
3307 | break; | 2800 | __set_bit(ATH_STAT_MRRETRY, sc->status); |
3308 | case ALG_CCMP: | ||
3309 | if (sc->ah->ah_aes_support) | ||
3310 | break; | ||
3311 | 2801 | ||
3312 | return -EOPNOTSUPP; | 2802 | /* |
3313 | default: | 2803 | * Collect the channel list. The 802.11 layer |
3314 | WARN_ON(1); | 2804 | * is resposible for filtering this list based |
3315 | return -EINVAL; | 2805 | * on settings like the phy mode and regulatory |
2806 | * domain restrictions. | ||
2807 | */ | ||
2808 | ret = ath5k_setup_bands(hw); | ||
2809 | if (ret) { | ||
2810 | ATH5K_ERR(sc, "can't get channels\n"); | ||
2811 | goto err; | ||
3316 | } | 2812 | } |
3317 | 2813 | ||
3318 | mutex_lock(&sc->lock); | 2814 | /* |
2815 | * Allocate tx+rx descriptors and populate the lists. | ||
2816 | */ | ||
2817 | ret = ath5k_desc_alloc(sc); | ||
2818 | if (ret) { | ||
2819 | ATH5K_ERR(sc, "can't allocate descriptors\n"); | ||
2820 | goto err; | ||
2821 | } | ||
3319 | 2822 | ||
3320 | switch (cmd) { | 2823 | /* |
3321 | case SET_KEY: | 2824 | * Allocate hardware transmit queues: one queue for |
3322 | ret = ath5k_hw_set_key(sc->ah, key->keyidx, key, | 2825 | * beacon frames and one data queue for each QoS |
3323 | sta ? sta->addr : NULL); | 2826 | * priority. Note that hw functions handle resetting |
3324 | if (ret) { | 2827 | * these queues at the needed time. |
3325 | ATH5K_ERR(sc, "can't set the key\n"); | 2828 | */ |
3326 | goto unlock; | 2829 | ret = ath5k_beaconq_setup(ah); |
3327 | } | 2830 | if (ret < 0) { |
3328 | __set_bit(key->keyidx, common->keymap); | 2831 | ATH5K_ERR(sc, "can't setup a beacon xmit queue\n"); |
3329 | key->hw_key_idx = key->keyidx; | 2832 | goto err_desc; |
3330 | key->flags |= (IEEE80211_KEY_FLAG_GENERATE_IV | | 2833 | } |
3331 | IEEE80211_KEY_FLAG_GENERATE_MMIC); | 2834 | sc->bhalq = ret; |
3332 | break; | 2835 | sc->cabq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_CAB, 0); |
3333 | case DISABLE_KEY: | 2836 | if (IS_ERR(sc->cabq)) { |
3334 | ath5k_hw_reset_key(sc->ah, key->keyidx); | 2837 | ATH5K_ERR(sc, "can't setup cab queue\n"); |
3335 | __clear_bit(key->keyidx, common->keymap); | 2838 | ret = PTR_ERR(sc->cabq); |
3336 | break; | 2839 | goto err_bhal; |
3337 | default: | ||
3338 | ret = -EINVAL; | ||
3339 | goto unlock; | ||
3340 | } | 2840 | } |
3341 | 2841 | ||
3342 | unlock: | 2842 | /* 5211 and 5212 usually support 10 queues but we better rely on the |
3343 | mmiowb(); | 2843 | * capability information */ |
3344 | mutex_unlock(&sc->lock); | 2844 | if (ah->ah_capabilities.cap_queues.q_tx_num >= 6) { |
3345 | return ret; | 2845 | /* This order matches mac80211's queue priority, so we can |
3346 | } | 2846 | * directly use the mac80211 queue number without any mapping */ |
2847 | txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_VO); | ||
2848 | if (IS_ERR(txq)) { | ||
2849 | ATH5K_ERR(sc, "can't setup xmit queue\n"); | ||
2850 | ret = PTR_ERR(txq); | ||
2851 | goto err_queues; | ||
2852 | } | ||
2853 | txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_VI); | ||
2854 | if (IS_ERR(txq)) { | ||
2855 | ATH5K_ERR(sc, "can't setup xmit queue\n"); | ||
2856 | ret = PTR_ERR(txq); | ||
2857 | goto err_queues; | ||
2858 | } | ||
2859 | txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BE); | ||
2860 | if (IS_ERR(txq)) { | ||
2861 | ATH5K_ERR(sc, "can't setup xmit queue\n"); | ||
2862 | ret = PTR_ERR(txq); | ||
2863 | goto err_queues; | ||
2864 | } | ||
2865 | txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BK); | ||
2866 | if (IS_ERR(txq)) { | ||
2867 | ATH5K_ERR(sc, "can't setup xmit queue\n"); | ||
2868 | ret = PTR_ERR(txq); | ||
2869 | goto err_queues; | ||
2870 | } | ||
2871 | hw->queues = 4; | ||
2872 | } else { | ||
2873 | /* older hardware (5210) can only support one data queue */ | ||
2874 | txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BE); | ||
2875 | if (IS_ERR(txq)) { | ||
2876 | ATH5K_ERR(sc, "can't setup xmit queue\n"); | ||
2877 | ret = PTR_ERR(txq); | ||
2878 | goto err_queues; | ||
2879 | } | ||
2880 | hw->queues = 1; | ||
2881 | } | ||
3347 | 2882 | ||
3348 | static int | 2883 | tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc); |
3349 | ath5k_get_stats(struct ieee80211_hw *hw, | 2884 | tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc); |
3350 | struct ieee80211_low_level_stats *stats) | 2885 | tasklet_init(&sc->calib, ath5k_tasklet_calibrate, (unsigned long)sc); |
3351 | { | 2886 | tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc); |
3352 | struct ath5k_softc *sc = hw->priv; | 2887 | tasklet_init(&sc->ani_tasklet, ath5k_tasklet_ani, (unsigned long)sc); |
3353 | 2888 | ||
3354 | /* Force update */ | 2889 | INIT_WORK(&sc->reset_work, ath5k_reset_work); |
3355 | ath5k_hw_update_mib_counters(sc->ah); | 2890 | INIT_DELAYED_WORK(&sc->tx_complete_work, ath5k_tx_complete_poll_work); |
3356 | 2891 | ||
3357 | stats->dot11ACKFailureCount = sc->stats.ack_fail; | 2892 | ret = ath5k_hw_common(ah)->bus_ops->eeprom_read_mac(ah, mac); |
3358 | stats->dot11RTSFailureCount = sc->stats.rts_fail; | 2893 | if (ret) { |
3359 | stats->dot11RTSSuccessCount = sc->stats.rts_ok; | 2894 | ATH5K_ERR(sc, "unable to read address from EEPROM\n"); |
3360 | stats->dot11FCSErrorCount = sc->stats.fcs_error; | 2895 | goto err_queues; |
2896 | } | ||
3361 | 2897 | ||
3362 | return 0; | 2898 | SET_IEEE80211_PERM_ADDR(hw, mac); |
3363 | } | 2899 | memcpy(&sc->lladdr, mac, ETH_ALEN); |
2900 | /* All MAC address bits matter for ACKs */ | ||
2901 | ath5k_update_bssid_mask_and_opmode(sc, NULL); | ||
3364 | 2902 | ||
3365 | static int ath5k_get_survey(struct ieee80211_hw *hw, int idx, | 2903 | regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain; |
3366 | struct survey_info *survey) | 2904 | ret = ath_regd_init(regulatory, hw->wiphy, ath5k_reg_notifier); |
3367 | { | 2905 | if (ret) { |
3368 | struct ath5k_softc *sc = hw->priv; | 2906 | ATH5K_ERR(sc, "can't initialize regulatory system\n"); |
3369 | struct ieee80211_conf *conf = &hw->conf; | 2907 | goto err_queues; |
2908 | } | ||
3370 | 2909 | ||
3371 | if (idx != 0) | 2910 | ret = ieee80211_register_hw(hw); |
3372 | return -ENOENT; | 2911 | if (ret) { |
2912 | ATH5K_ERR(sc, "can't register ieee80211 hw\n"); | ||
2913 | goto err_queues; | ||
2914 | } | ||
3373 | 2915 | ||
3374 | survey->channel = conf->channel; | 2916 | if (!ath_is_world_regd(regulatory)) |
3375 | survey->filled = SURVEY_INFO_NOISE_DBM; | 2917 | regulatory_hint(hw->wiphy, regulatory->alpha2); |
3376 | survey->noise = sc->ah->ah_noise_floor; | ||
3377 | 2918 | ||
3378 | return 0; | 2919 | ath5k_init_leds(sc); |
3379 | } | ||
3380 | 2920 | ||
3381 | static u64 | 2921 | ath5k_sysfs_register(sc); |
3382 | ath5k_get_tsf(struct ieee80211_hw *hw) | ||
3383 | { | ||
3384 | struct ath5k_softc *sc = hw->priv; | ||
3385 | 2922 | ||
3386 | return ath5k_hw_get_tsf64(sc->ah); | 2923 | return 0; |
2924 | err_queues: | ||
2925 | ath5k_txq_release(sc); | ||
2926 | err_bhal: | ||
2927 | ath5k_hw_release_tx_queue(ah, sc->bhalq); | ||
2928 | err_desc: | ||
2929 | ath5k_desc_free(sc); | ||
2930 | err: | ||
2931 | return ret; | ||
3387 | } | 2932 | } |
3388 | 2933 | ||
3389 | static void | 2934 | void |
3390 | ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf) | 2935 | ath5k_deinit_softc(struct ath5k_softc *sc) |
3391 | { | 2936 | { |
3392 | struct ath5k_softc *sc = hw->priv; | 2937 | struct ieee80211_hw *hw = sc->hw; |
3393 | 2938 | ||
3394 | ath5k_hw_set_tsf64(sc->ah, tsf); | 2939 | /* |
3395 | } | 2940 | * NB: the order of these is important: |
3396 | 2941 | * o call the 802.11 layer before detaching ath5k_hw to | |
3397 | static void | 2942 | * ensure callbacks into the driver to delete global |
3398 | ath5k_reset_tsf(struct ieee80211_hw *hw) | 2943 | * key cache entries can be handled |
3399 | { | 2944 | * o reclaim the tx queue data structures after calling |
3400 | struct ath5k_softc *sc = hw->priv; | 2945 | * the 802.11 layer as we'll get called back to reclaim |
2946 | * node state and potentially want to use them | ||
2947 | * o to cleanup the tx queues the hal is called, so detach | ||
2948 | * it last | ||
2949 | * XXX: ??? detach ath5k_hw ??? | ||
2950 | * Other than that, it's straightforward... | ||
2951 | */ | ||
2952 | ieee80211_unregister_hw(hw); | ||
2953 | ath5k_desc_free(sc); | ||
2954 | ath5k_txq_release(sc); | ||
2955 | ath5k_hw_release_tx_queue(sc->ah, sc->bhalq); | ||
2956 | ath5k_unregister_leds(sc); | ||
3401 | 2957 | ||
2958 | ath5k_sysfs_unregister(sc); | ||
3402 | /* | 2959 | /* |
3403 | * in IBSS mode we need to update the beacon timers too. | 2960 | * NB: can't reclaim these until after ieee80211_ifdetach |
3404 | * this will also reset the TSF if we call it with 0 | 2961 | * returns because we'll get called back to reclaim node |
2962 | * state and potentially want to use them. | ||
3405 | */ | 2963 | */ |
3406 | if (sc->opmode == NL80211_IFTYPE_ADHOC) | 2964 | ath5k_hw_deinit(sc->ah); |
3407 | ath5k_beacon_update_timers(sc, 0); | 2965 | free_irq(sc->irq, sc); |
3408 | else | ||
3409 | ath5k_hw_reset_tsf(sc->ah); | ||
3410 | } | 2966 | } |
3411 | 2967 | ||
3412 | /* | 2968 | bool |
3413 | * Updates the beacon that is sent by ath5k_beacon_send. For adhoc, | 2969 | ath_any_vif_assoc(struct ath5k_softc *sc) |
3414 | * this is called only once at config_bss time, for AP we do it every | ||
3415 | * SWBA interrupt so that the TIM will reflect buffered frames. | ||
3416 | * | ||
3417 | * Called with the beacon lock. | ||
3418 | */ | ||
3419 | static int | ||
3420 | ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | ||
3421 | { | 2970 | { |
3422 | int ret; | 2971 | struct ath5k_vif_iter_data iter_data; |
3423 | struct ath5k_softc *sc = hw->priv; | 2972 | iter_data.hw_macaddr = NULL; |
3424 | struct sk_buff *skb; | 2973 | iter_data.any_assoc = false; |
2974 | iter_data.need_set_hw_addr = false; | ||
2975 | iter_data.found_active = true; | ||
3425 | 2976 | ||
3426 | if (WARN_ON(!vif)) { | 2977 | ieee80211_iterate_active_interfaces_atomic(sc->hw, ath5k_vif_iter, |
3427 | ret = -EINVAL; | 2978 | &iter_data); |
3428 | goto out; | 2979 | return iter_data.any_assoc; |
3429 | } | ||
3430 | |||
3431 | skb = ieee80211_beacon_get(hw, vif); | ||
3432 | |||
3433 | if (!skb) { | ||
3434 | ret = -ENOMEM; | ||
3435 | goto out; | ||
3436 | } | ||
3437 | |||
3438 | ath5k_debug_dump_skb(sc, skb, "BC ", 1); | ||
3439 | |||
3440 | ath5k_txbuf_free_skb(sc, sc->bbuf); | ||
3441 | sc->bbuf->skb = skb; | ||
3442 | ret = ath5k_beacon_setup(sc, sc->bbuf); | ||
3443 | if (ret) | ||
3444 | sc->bbuf->skb = NULL; | ||
3445 | out: | ||
3446 | return ret; | ||
3447 | } | 2980 | } |
3448 | 2981 | ||
3449 | static void | 2982 | void |
3450 | set_beacon_filter(struct ieee80211_hw *hw, bool enable) | 2983 | set_beacon_filter(struct ieee80211_hw *hw, bool enable) |
3451 | { | 2984 | { |
3452 | struct ath5k_softc *sc = hw->priv; | 2985 | struct ath5k_softc *sc = hw->priv; |
@@ -3460,94 +2993,3 @@ set_beacon_filter(struct ieee80211_hw *hw, bool enable) | |||
3460 | ath5k_hw_set_rx_filter(ah, rfilt); | 2993 | ath5k_hw_set_rx_filter(ah, rfilt); |
3461 | sc->filter_flags = rfilt; | 2994 | sc->filter_flags = rfilt; |
3462 | } | 2995 | } |
3463 | |||
3464 | static void ath5k_bss_info_changed(struct ieee80211_hw *hw, | ||
3465 | struct ieee80211_vif *vif, | ||
3466 | struct ieee80211_bss_conf *bss_conf, | ||
3467 | u32 changes) | ||
3468 | { | ||
3469 | struct ath5k_softc *sc = hw->priv; | ||
3470 | struct ath5k_hw *ah = sc->ah; | ||
3471 | struct ath_common *common = ath5k_hw_common(ah); | ||
3472 | unsigned long flags; | ||
3473 | |||
3474 | mutex_lock(&sc->lock); | ||
3475 | if (WARN_ON(sc->vif != vif)) | ||
3476 | goto unlock; | ||
3477 | |||
3478 | if (changes & BSS_CHANGED_BSSID) { | ||
3479 | /* Cache for later use during resets */ | ||
3480 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); | ||
3481 | common->curaid = 0; | ||
3482 | ath5k_hw_set_associd(ah); | ||
3483 | mmiowb(); | ||
3484 | } | ||
3485 | |||
3486 | if (changes & BSS_CHANGED_BEACON_INT) | ||
3487 | sc->bintval = bss_conf->beacon_int; | ||
3488 | |||
3489 | if (changes & BSS_CHANGED_ASSOC) { | ||
3490 | sc->assoc = bss_conf->assoc; | ||
3491 | if (sc->opmode == NL80211_IFTYPE_STATION) | ||
3492 | set_beacon_filter(hw, sc->assoc); | ||
3493 | ath5k_hw_set_ledstate(sc->ah, sc->assoc ? | ||
3494 | AR5K_LED_ASSOC : AR5K_LED_INIT); | ||
3495 | if (bss_conf->assoc) { | ||
3496 | ATH5K_DBG(sc, ATH5K_DEBUG_ANY, | ||
3497 | "Bss Info ASSOC %d, bssid: %pM\n", | ||
3498 | bss_conf->aid, common->curbssid); | ||
3499 | common->curaid = bss_conf->aid; | ||
3500 | ath5k_hw_set_associd(ah); | ||
3501 | /* Once ANI is available you would start it here */ | ||
3502 | } | ||
3503 | } | ||
3504 | |||
3505 | if (changes & BSS_CHANGED_BEACON) { | ||
3506 | spin_lock_irqsave(&sc->block, flags); | ||
3507 | ath5k_beacon_update(hw, vif); | ||
3508 | spin_unlock_irqrestore(&sc->block, flags); | ||
3509 | } | ||
3510 | |||
3511 | if (changes & BSS_CHANGED_BEACON_ENABLED) | ||
3512 | sc->enable_beacon = bss_conf->enable_beacon; | ||
3513 | |||
3514 | if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED | | ||
3515 | BSS_CHANGED_BEACON_INT)) | ||
3516 | ath5k_beacon_config(sc); | ||
3517 | |||
3518 | unlock: | ||
3519 | mutex_unlock(&sc->lock); | ||
3520 | } | ||
3521 | |||
3522 | static void ath5k_sw_scan_start(struct ieee80211_hw *hw) | ||
3523 | { | ||
3524 | struct ath5k_softc *sc = hw->priv; | ||
3525 | if (!sc->assoc) | ||
3526 | ath5k_hw_set_ledstate(sc->ah, AR5K_LED_SCAN); | ||
3527 | } | ||
3528 | |||
3529 | static void ath5k_sw_scan_complete(struct ieee80211_hw *hw) | ||
3530 | { | ||
3531 | struct ath5k_softc *sc = hw->priv; | ||
3532 | ath5k_hw_set_ledstate(sc->ah, sc->assoc ? | ||
3533 | AR5K_LED_ASSOC : AR5K_LED_INIT); | ||
3534 | } | ||
3535 | |||
3536 | /** | ||
3537 | * ath5k_set_coverage_class - Set IEEE 802.11 coverage class | ||
3538 | * | ||
3539 | * @hw: struct ieee80211_hw pointer | ||
3540 | * @coverage_class: IEEE 802.11 coverage class number | ||
3541 | * | ||
3542 | * Mac80211 callback. Sets slot time, ACK timeout and CTS timeout for given | ||
3543 | * coverage class. The values are persistent, they are restored after device | ||
3544 | * reset. | ||
3545 | */ | ||
3546 | static void ath5k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) | ||
3547 | { | ||
3548 | struct ath5k_softc *sc = hw->priv; | ||
3549 | |||
3550 | mutex_lock(&sc->lock); | ||
3551 | ath5k_hw_set_coverage_class(sc->ah, coverage_class); | ||
3552 | mutex_unlock(&sc->lock); | ||
3553 | } | ||