diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/net/wireless/ath/ath5k/base.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/net/wireless/ath/ath5k/base.c')
-rw-r--r-- | drivers/net/wireless/ath/ath5k/base.c | 267 |
1 files changed, 171 insertions, 96 deletions
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 95a8e232b58f..3abbe7513ab5 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #include <linux/pci.h> | 50 | #include <linux/pci.h> |
51 | #include <linux/ethtool.h> | 51 | #include <linux/ethtool.h> |
52 | #include <linux/uaccess.h> | 52 | #include <linux/uaccess.h> |
53 | #include <linux/slab.h> | ||
53 | 54 | ||
54 | #include <net/ieee80211_radiotap.h> | 55 | #include <net/ieee80211_radiotap.h> |
55 | 56 | ||
@@ -83,7 +84,7 @@ MODULE_VERSION("0.6.0 (EXPERIMENTAL)"); | |||
83 | 84 | ||
84 | 85 | ||
85 | /* Known PCI ids */ | 86 | /* Known PCI ids */ |
86 | static const struct pci_device_id ath5k_pci_id_table[] = { | 87 | static DEFINE_PCI_DEVICE_TABLE(ath5k_pci_id_table) = { |
87 | { PCI_VDEVICE(ATHEROS, 0x0207) }, /* 5210 early */ | 88 | { PCI_VDEVICE(ATHEROS, 0x0207) }, /* 5210 early */ |
88 | { PCI_VDEVICE(ATHEROS, 0x0007) }, /* 5210 */ | 89 | { PCI_VDEVICE(ATHEROS, 0x0007) }, /* 5210 */ |
89 | { PCI_VDEVICE(ATHEROS, 0x0011) }, /* 5311 - this is on AHB bus !*/ | 90 | { PCI_VDEVICE(ATHEROS, 0x0011) }, /* 5311 - this is on AHB bus !*/ |
@@ -195,12 +196,13 @@ static int __devinit ath5k_pci_probe(struct pci_dev *pdev, | |||
195 | const struct pci_device_id *id); | 196 | const struct pci_device_id *id); |
196 | static void __devexit ath5k_pci_remove(struct pci_dev *pdev); | 197 | static void __devexit ath5k_pci_remove(struct pci_dev *pdev); |
197 | #ifdef CONFIG_PM | 198 | #ifdef CONFIG_PM |
198 | static int ath5k_pci_suspend(struct pci_dev *pdev, | 199 | static int ath5k_pci_suspend(struct device *dev); |
199 | pm_message_t state); | 200 | static int ath5k_pci_resume(struct device *dev); |
200 | static int ath5k_pci_resume(struct pci_dev *pdev); | 201 | |
202 | SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume); | ||
203 | #define ATH5K_PM_OPS (&ath5k_pm_ops) | ||
201 | #else | 204 | #else |
202 | #define ath5k_pci_suspend NULL | 205 | #define ATH5K_PM_OPS NULL |
203 | #define ath5k_pci_resume NULL | ||
204 | #endif /* CONFIG_PM */ | 206 | #endif /* CONFIG_PM */ |
205 | 207 | ||
206 | static struct pci_driver ath5k_pci_driver = { | 208 | static struct pci_driver ath5k_pci_driver = { |
@@ -208,8 +210,7 @@ static struct pci_driver ath5k_pci_driver = { | |||
208 | .id_table = ath5k_pci_id_table, | 210 | .id_table = ath5k_pci_id_table, |
209 | .probe = ath5k_pci_probe, | 211 | .probe = ath5k_pci_probe, |
210 | .remove = __devexit_p(ath5k_pci_remove), | 212 | .remove = __devexit_p(ath5k_pci_remove), |
211 | .suspend = ath5k_pci_suspend, | 213 | .driver.pm = ATH5K_PM_OPS, |
212 | .resume = ath5k_pci_resume, | ||
213 | }; | 214 | }; |
214 | 215 | ||
215 | 216 | ||
@@ -225,9 +226,9 @@ static int ath5k_reset_wake(struct ath5k_softc *sc); | |||
225 | static int ath5k_start(struct ieee80211_hw *hw); | 226 | static int ath5k_start(struct ieee80211_hw *hw); |
226 | static void ath5k_stop(struct ieee80211_hw *hw); | 227 | static void ath5k_stop(struct ieee80211_hw *hw); |
227 | static int ath5k_add_interface(struct ieee80211_hw *hw, | 228 | static int ath5k_add_interface(struct ieee80211_hw *hw, |
228 | struct ieee80211_if_init_conf *conf); | 229 | struct ieee80211_vif *vif); |
229 | static void ath5k_remove_interface(struct ieee80211_hw *hw, | 230 | static void ath5k_remove_interface(struct ieee80211_hw *hw, |
230 | struct ieee80211_if_init_conf *conf); | 231 | struct ieee80211_vif *vif); |
231 | static int ath5k_config(struct ieee80211_hw *hw, u32 changed); | 232 | static int ath5k_config(struct ieee80211_hw *hw, u32 changed); |
232 | static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw, | 233 | static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw, |
233 | int mc_count, struct dev_addr_list *mc_list); | 234 | int mc_count, struct dev_addr_list *mc_list); |
@@ -241,8 +242,6 @@ static int ath5k_set_key(struct ieee80211_hw *hw, | |||
241 | struct ieee80211_key_conf *key); | 242 | struct ieee80211_key_conf *key); |
242 | static int ath5k_get_stats(struct ieee80211_hw *hw, | 243 | static int ath5k_get_stats(struct ieee80211_hw *hw, |
243 | struct ieee80211_low_level_stats *stats); | 244 | struct ieee80211_low_level_stats *stats); |
244 | static int ath5k_get_tx_stats(struct ieee80211_hw *hw, | ||
245 | struct ieee80211_tx_queue_stats *stats); | ||
246 | static u64 ath5k_get_tsf(struct ieee80211_hw *hw); | 245 | static u64 ath5k_get_tsf(struct ieee80211_hw *hw); |
247 | static void ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf); | 246 | static void ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf); |
248 | static void ath5k_reset_tsf(struct ieee80211_hw *hw); | 247 | static void ath5k_reset_tsf(struct ieee80211_hw *hw); |
@@ -254,6 +253,8 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw, | |||
254 | u32 changes); | 253 | u32 changes); |
255 | static void ath5k_sw_scan_start(struct ieee80211_hw *hw); | 254 | static void ath5k_sw_scan_start(struct ieee80211_hw *hw); |
256 | static void ath5k_sw_scan_complete(struct ieee80211_hw *hw); | 255 | static void ath5k_sw_scan_complete(struct ieee80211_hw *hw); |
256 | static void ath5k_set_coverage_class(struct ieee80211_hw *hw, | ||
257 | u8 coverage_class); | ||
257 | 258 | ||
258 | static const struct ieee80211_ops ath5k_hw_ops = { | 259 | static const struct ieee80211_ops ath5k_hw_ops = { |
259 | .tx = ath5k_tx, | 260 | .tx = ath5k_tx, |
@@ -267,13 +268,13 @@ static const struct ieee80211_ops ath5k_hw_ops = { | |||
267 | .set_key = ath5k_set_key, | 268 | .set_key = ath5k_set_key, |
268 | .get_stats = ath5k_get_stats, | 269 | .get_stats = ath5k_get_stats, |
269 | .conf_tx = NULL, | 270 | .conf_tx = NULL, |
270 | .get_tx_stats = ath5k_get_tx_stats, | ||
271 | .get_tsf = ath5k_get_tsf, | 271 | .get_tsf = ath5k_get_tsf, |
272 | .set_tsf = ath5k_set_tsf, | 272 | .set_tsf = ath5k_set_tsf, |
273 | .reset_tsf = ath5k_reset_tsf, | 273 | .reset_tsf = ath5k_reset_tsf, |
274 | .bss_info_changed = ath5k_bss_info_changed, | 274 | .bss_info_changed = ath5k_bss_info_changed, |
275 | .sw_scan_start = ath5k_sw_scan_start, | 275 | .sw_scan_start = ath5k_sw_scan_start, |
276 | .sw_scan_complete = ath5k_sw_scan_complete, | 276 | .sw_scan_complete = ath5k_sw_scan_complete, |
277 | .set_coverage_class = ath5k_set_coverage_class, | ||
277 | }; | 278 | }; |
278 | 279 | ||
279 | /* | 280 | /* |
@@ -323,10 +324,13 @@ static inline void ath5k_txbuf_free(struct ath5k_softc *sc, | |||
323 | static inline void ath5k_rxbuf_free(struct ath5k_softc *sc, | 324 | static inline void ath5k_rxbuf_free(struct ath5k_softc *sc, |
324 | struct ath5k_buf *bf) | 325 | struct ath5k_buf *bf) |
325 | { | 326 | { |
327 | struct ath5k_hw *ah = sc->ah; | ||
328 | struct ath_common *common = ath5k_hw_common(ah); | ||
329 | |||
326 | BUG_ON(!bf); | 330 | BUG_ON(!bf); |
327 | if (!bf->skb) | 331 | if (!bf->skb) |
328 | return; | 332 | return; |
329 | pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize, | 333 | pci_unmap_single(sc->pdev, bf->skbaddr, common->rx_bufsize, |
330 | PCI_DMA_FROMDEVICE); | 334 | PCI_DMA_FROMDEVICE); |
331 | dev_kfree_skb_any(bf->skb); | 335 | dev_kfree_skb_any(bf->skb); |
332 | bf->skb = NULL; | 336 | bf->skb = NULL; |
@@ -437,6 +441,22 @@ ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val) | |||
437 | 441 | ||
438 | return name; | 442 | return name; |
439 | } | 443 | } |
444 | static unsigned int ath5k_ioread32(void *hw_priv, u32 reg_offset) | ||
445 | { | ||
446 | struct ath5k_hw *ah = (struct ath5k_hw *) hw_priv; | ||
447 | return ath5k_hw_reg_read(ah, reg_offset); | ||
448 | } | ||
449 | |||
450 | static void ath5k_iowrite32(void *hw_priv, u32 val, u32 reg_offset) | ||
451 | { | ||
452 | struct ath5k_hw *ah = (struct ath5k_hw *) hw_priv; | ||
453 | ath5k_hw_reg_write(ah, val, reg_offset); | ||
454 | } | ||
455 | |||
456 | static const struct ath_ops ath5k_common_ops = { | ||
457 | .read = ath5k_ioread32, | ||
458 | .write = ath5k_iowrite32, | ||
459 | }; | ||
440 | 460 | ||
441 | static int __devinit | 461 | static int __devinit |
442 | ath5k_pci_probe(struct pci_dev *pdev, | 462 | ath5k_pci_probe(struct pci_dev *pdev, |
@@ -444,6 +464,7 @@ ath5k_pci_probe(struct pci_dev *pdev, | |||
444 | { | 464 | { |
445 | void __iomem *mem; | 465 | void __iomem *mem; |
446 | struct ath5k_softc *sc; | 466 | struct ath5k_softc *sc; |
467 | struct ath_common *common; | ||
447 | struct ieee80211_hw *hw; | 468 | struct ieee80211_hw *hw; |
448 | int ret; | 469 | int ret; |
449 | u8 csz; | 470 | u8 csz; |
@@ -547,7 +568,6 @@ ath5k_pci_probe(struct pci_dev *pdev, | |||
547 | __set_bit(ATH_STAT_INVALID, sc->status); | 568 | __set_bit(ATH_STAT_INVALID, sc->status); |
548 | 569 | ||
549 | sc->iobase = mem; /* So we can unmap it on detach */ | 570 | sc->iobase = mem; /* So we can unmap it on detach */ |
550 | sc->common.cachelsz = csz << 2; /* convert to bytes */ | ||
551 | sc->opmode = NL80211_IFTYPE_STATION; | 571 | sc->opmode = NL80211_IFTYPE_STATION; |
552 | sc->bintval = 1000; | 572 | sc->bintval = 1000; |
553 | mutex_init(&sc->lock); | 573 | mutex_init(&sc->lock); |
@@ -565,13 +585,28 @@ ath5k_pci_probe(struct pci_dev *pdev, | |||
565 | goto err_free; | 585 | goto err_free; |
566 | } | 586 | } |
567 | 587 | ||
568 | /* Initialize device */ | 588 | /*If we passed the test malloc a ath5k_hw struct*/ |
569 | sc->ah = ath5k_hw_attach(sc); | 589 | sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL); |
570 | if (IS_ERR(sc->ah)) { | 590 | if (!sc->ah) { |
571 | ret = PTR_ERR(sc->ah); | 591 | ret = -ENOMEM; |
592 | ATH5K_ERR(sc, "out of memory\n"); | ||
572 | goto err_irq; | 593 | goto err_irq; |
573 | } | 594 | } |
574 | 595 | ||
596 | sc->ah->ah_sc = sc; | ||
597 | sc->ah->ah_iobase = sc->iobase; | ||
598 | common = ath5k_hw_common(sc->ah); | ||
599 | common->ops = &ath5k_common_ops; | ||
600 | common->ah = sc->ah; | ||
601 | common->hw = hw; | ||
602 | common->cachelsz = csz << 2; /* convert to bytes */ | ||
603 | |||
604 | /* Initialize device */ | ||
605 | ret = ath5k_hw_attach(sc); | ||
606 | if (ret) { | ||
607 | goto err_free_ah; | ||
608 | } | ||
609 | |||
575 | /* set up multi-rate retry capabilities */ | 610 | /* set up multi-rate retry capabilities */ |
576 | if (sc->ah->ah_version == AR5K_AR5212) { | 611 | if (sc->ah->ah_version == AR5K_AR5212) { |
577 | hw->max_rates = 4; | 612 | hw->max_rates = 4; |
@@ -640,6 +675,8 @@ err_ah: | |||
640 | ath5k_hw_detach(sc->ah); | 675 | ath5k_hw_detach(sc->ah); |
641 | err_irq: | 676 | err_irq: |
642 | free_irq(pdev->irq, sc); | 677 | free_irq(pdev->irq, sc); |
678 | err_free_ah: | ||
679 | kfree(sc->ah); | ||
643 | err_free: | 680 | err_free: |
644 | ieee80211_free_hw(hw); | 681 | ieee80211_free_hw(hw); |
645 | err_map: | 682 | err_map: |
@@ -661,6 +698,7 @@ ath5k_pci_remove(struct pci_dev *pdev) | |||
661 | ath5k_debug_finish_device(sc); | 698 | ath5k_debug_finish_device(sc); |
662 | ath5k_detach(pdev, hw); | 699 | ath5k_detach(pdev, hw); |
663 | ath5k_hw_detach(sc->ah); | 700 | ath5k_hw_detach(sc->ah); |
701 | kfree(sc->ah); | ||
664 | free_irq(pdev->irq, sc); | 702 | free_irq(pdev->irq, sc); |
665 | pci_iounmap(pdev, sc->iobase); | 703 | pci_iounmap(pdev, sc->iobase); |
666 | pci_release_region(pdev, 0); | 704 | pci_release_region(pdev, 0); |
@@ -669,33 +707,20 @@ ath5k_pci_remove(struct pci_dev *pdev) | |||
669 | } | 707 | } |
670 | 708 | ||
671 | #ifdef CONFIG_PM | 709 | #ifdef CONFIG_PM |
672 | static int | 710 | static int ath5k_pci_suspend(struct device *dev) |
673 | ath5k_pci_suspend(struct pci_dev *pdev, pm_message_t state) | ||
674 | { | 711 | { |
675 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); | 712 | struct ieee80211_hw *hw = pci_get_drvdata(to_pci_dev(dev)); |
676 | struct ath5k_softc *sc = hw->priv; | 713 | struct ath5k_softc *sc = hw->priv; |
677 | 714 | ||
678 | ath5k_led_off(sc); | 715 | ath5k_led_off(sc); |
679 | |||
680 | pci_save_state(pdev); | ||
681 | pci_disable_device(pdev); | ||
682 | pci_set_power_state(pdev, PCI_D3hot); | ||
683 | |||
684 | return 0; | 716 | return 0; |
685 | } | 717 | } |
686 | 718 | ||
687 | static int | 719 | static int ath5k_pci_resume(struct device *dev) |
688 | ath5k_pci_resume(struct pci_dev *pdev) | ||
689 | { | 720 | { |
721 | struct pci_dev *pdev = to_pci_dev(dev); | ||
690 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); | 722 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); |
691 | struct ath5k_softc *sc = hw->priv; | 723 | struct ath5k_softc *sc = hw->priv; |
692 | int err; | ||
693 | |||
694 | pci_restore_state(pdev); | ||
695 | |||
696 | err = pci_enable_device(pdev); | ||
697 | if (err) | ||
698 | return err; | ||
699 | 724 | ||
700 | /* | 725 | /* |
701 | * Suspend/Resume resets the PCI configuration space, so we have to | 726 | * Suspend/Resume resets the PCI configuration space, so we have to |
@@ -718,7 +743,7 @@ static int ath5k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *re | |||
718 | { | 743 | { |
719 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); | 744 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); |
720 | struct ath5k_softc *sc = hw->priv; | 745 | struct ath5k_softc *sc = hw->priv; |
721 | struct ath_regulatory *regulatory = &sc->common.regulatory; | 746 | struct ath_regulatory *regulatory = ath5k_hw_regulatory(sc->ah); |
722 | 747 | ||
723 | return ath_reg_notifier_apply(wiphy, request, regulatory); | 748 | return ath_reg_notifier_apply(wiphy, request, regulatory); |
724 | } | 749 | } |
@@ -728,7 +753,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) | |||
728 | { | 753 | { |
729 | struct ath5k_softc *sc = hw->priv; | 754 | struct ath5k_softc *sc = hw->priv; |
730 | struct ath5k_hw *ah = sc->ah; | 755 | struct ath5k_hw *ah = sc->ah; |
731 | struct ath_regulatory *regulatory = &sc->common.regulatory; | 756 | struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah); |
732 | u8 mac[ETH_ALEN] = {}; | 757 | u8 mac[ETH_ALEN] = {}; |
733 | int ret; | 758 | int ret; |
734 | 759 | ||
@@ -815,7 +840,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) | |||
815 | 840 | ||
816 | SET_IEEE80211_PERM_ADDR(hw, mac); | 841 | SET_IEEE80211_PERM_ADDR(hw, mac); |
817 | /* All MAC address bits matter for ACKs */ | 842 | /* All MAC address bits matter for ACKs */ |
818 | memset(sc->bssidmask, 0xff, ETH_ALEN); | 843 | memcpy(sc->bssidmask, ath_bcast_mac, ETH_ALEN); |
819 | ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask); | 844 | ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask); |
820 | 845 | ||
821 | regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain; | 846 | regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain; |
@@ -1152,24 +1177,26 @@ ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix) | |||
1152 | static | 1177 | static |
1153 | struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_softc *sc, dma_addr_t *skb_addr) | 1178 | struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_softc *sc, dma_addr_t *skb_addr) |
1154 | { | 1179 | { |
1180 | struct ath_common *common = ath5k_hw_common(sc->ah); | ||
1155 | struct sk_buff *skb; | 1181 | struct sk_buff *skb; |
1156 | 1182 | ||
1157 | /* | 1183 | /* |
1158 | * Allocate buffer with headroom_needed space for the | 1184 | * Allocate buffer with headroom_needed space for the |
1159 | * fake physical layer header at the start. | 1185 | * fake physical layer header at the start. |
1160 | */ | 1186 | */ |
1161 | skb = ath_rxbuf_alloc(&sc->common, | 1187 | skb = ath_rxbuf_alloc(common, |
1162 | sc->rxbufsize + sc->common.cachelsz - 1, | 1188 | common->rx_bufsize, |
1163 | GFP_ATOMIC); | 1189 | GFP_ATOMIC); |
1164 | 1190 | ||
1165 | if (!skb) { | 1191 | if (!skb) { |
1166 | ATH5K_ERR(sc, "can't alloc skbuff of size %u\n", | 1192 | ATH5K_ERR(sc, "can't alloc skbuff of size %u\n", |
1167 | sc->rxbufsize + sc->common.cachelsz - 1); | 1193 | common->rx_bufsize); |
1168 | return NULL; | 1194 | return NULL; |
1169 | } | 1195 | } |
1170 | 1196 | ||
1171 | *skb_addr = pci_map_single(sc->pdev, | 1197 | *skb_addr = pci_map_single(sc->pdev, |
1172 | skb->data, sc->rxbufsize, PCI_DMA_FROMDEVICE); | 1198 | skb->data, common->rx_bufsize, |
1199 | PCI_DMA_FROMDEVICE); | ||
1173 | if (unlikely(pci_dma_mapping_error(sc->pdev, *skb_addr))) { | 1200 | if (unlikely(pci_dma_mapping_error(sc->pdev, *skb_addr))) { |
1174 | ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__); | 1201 | ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__); |
1175 | dev_kfree_skb(skb); | 1202 | dev_kfree_skb(skb); |
@@ -1220,6 +1247,29 @@ ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) | |||
1220 | return 0; | 1247 | return 0; |
1221 | } | 1248 | } |
1222 | 1249 | ||
1250 | static enum ath5k_pkt_type get_hw_packet_type(struct sk_buff *skb) | ||
1251 | { | ||
1252 | struct ieee80211_hdr *hdr; | ||
1253 | enum ath5k_pkt_type htype; | ||
1254 | __le16 fc; | ||
1255 | |||
1256 | hdr = (struct ieee80211_hdr *)skb->data; | ||
1257 | fc = hdr->frame_control; | ||
1258 | |||
1259 | if (ieee80211_is_beacon(fc)) | ||
1260 | htype = AR5K_PKT_TYPE_BEACON; | ||
1261 | else if (ieee80211_is_probe_resp(fc)) | ||
1262 | htype = AR5K_PKT_TYPE_PROBE_RESP; | ||
1263 | else if (ieee80211_is_atim(fc)) | ||
1264 | htype = AR5K_PKT_TYPE_ATIM; | ||
1265 | else if (ieee80211_is_pspoll(fc)) | ||
1266 | htype = AR5K_PKT_TYPE_PSPOLL; | ||
1267 | else | ||
1268 | htype = AR5K_PKT_TYPE_NORMAL; | ||
1269 | |||
1270 | return htype; | ||
1271 | } | ||
1272 | |||
1223 | static int | 1273 | static int |
1224 | ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, | 1274 | ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, |
1225 | struct ath5k_txq *txq) | 1275 | struct ath5k_txq *txq) |
@@ -1274,7 +1324,8 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, | |||
1274 | sc->vif, pktlen, info)); | 1324 | sc->vif, pktlen, info)); |
1275 | } | 1325 | } |
1276 | ret = ah->ah_setup_tx_desc(ah, ds, pktlen, | 1326 | ret = ah->ah_setup_tx_desc(ah, ds, pktlen, |
1277 | ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL, | 1327 | ieee80211_get_hdrlen_from_skb(skb), |
1328 | get_hw_packet_type(skb), | ||
1278 | (sc->power_level * 2), | 1329 | (sc->power_level * 2), |
1279 | hw_rate, | 1330 | hw_rate, |
1280 | info->control.rates[0].count, keyidx, ah->ah_tx_ant, flags, | 1331 | info->control.rates[0].count, keyidx, ah->ah_tx_ant, flags, |
@@ -1303,7 +1354,6 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, | |||
1303 | 1354 | ||
1304 | spin_lock_bh(&txq->lock); | 1355 | spin_lock_bh(&txq->lock); |
1305 | list_add_tail(&bf->list, &txq->q); | 1356 | list_add_tail(&bf->list, &txq->q); |
1306 | sc->tx_stats[txq->qnum].len++; | ||
1307 | if (txq->link == NULL) /* is this first packet? */ | 1357 | if (txq->link == NULL) /* is this first packet? */ |
1308 | ath5k_hw_set_txdp(ah, txq->qnum, bf->daddr); | 1358 | ath5k_hw_set_txdp(ah, txq->qnum, bf->daddr); |
1309 | else /* no, so only link it */ | 1359 | else /* no, so only link it */ |
@@ -1487,7 +1537,8 @@ ath5k_beaconq_config(struct ath5k_softc *sc) | |||
1487 | 1537 | ||
1488 | ret = ath5k_hw_get_tx_queueprops(ah, sc->bhalq, &qi); | 1538 | ret = ath5k_hw_get_tx_queueprops(ah, sc->bhalq, &qi); |
1489 | if (ret) | 1539 | if (ret) |
1490 | return ret; | 1540 | goto err; |
1541 | |||
1491 | if (sc->opmode == NL80211_IFTYPE_AP || | 1542 | if (sc->opmode == NL80211_IFTYPE_AP || |
1492 | sc->opmode == NL80211_IFTYPE_MESH_POINT) { | 1543 | sc->opmode == NL80211_IFTYPE_MESH_POINT) { |
1493 | /* | 1544 | /* |
@@ -1514,10 +1565,25 @@ ath5k_beaconq_config(struct ath5k_softc *sc) | |||
1514 | if (ret) { | 1565 | if (ret) { |
1515 | ATH5K_ERR(sc, "%s: unable to update parameters for beacon " | 1566 | ATH5K_ERR(sc, "%s: unable to update parameters for beacon " |
1516 | "hardware queue!\n", __func__); | 1567 | "hardware queue!\n", __func__); |
1517 | return ret; | 1568 | goto err; |
1518 | } | 1569 | } |
1570 | ret = ath5k_hw_reset_tx_queue(ah, sc->bhalq); /* push to h/w */ | ||
1571 | if (ret) | ||
1572 | goto err; | ||
1573 | |||
1574 | /* reconfigure cabq with ready time to 80% of beacon_interval */ | ||
1575 | ret = ath5k_hw_get_tx_queueprops(ah, AR5K_TX_QUEUE_ID_CAB, &qi); | ||
1576 | if (ret) | ||
1577 | goto err; | ||
1578 | |||
1579 | qi.tqi_ready_time = (sc->bintval * 80) / 100; | ||
1580 | ret = ath5k_hw_set_tx_queueprops(ah, AR5K_TX_QUEUE_ID_CAB, &qi); | ||
1581 | if (ret) | ||
1582 | goto err; | ||
1519 | 1583 | ||
1520 | return ath5k_hw_reset_tx_queue(ah, sc->bhalq); /* push to h/w */; | 1584 | ret = ath5k_hw_reset_tx_queue(ah, AR5K_TX_QUEUE_ID_CAB); |
1585 | err: | ||
1586 | return ret; | ||
1521 | } | 1587 | } |
1522 | 1588 | ||
1523 | static void | 1589 | static void |
@@ -1536,7 +1602,6 @@ ath5k_txq_drainq(struct ath5k_softc *sc, struct ath5k_txq *txq) | |||
1536 | ath5k_txbuf_free(sc, bf); | 1602 | ath5k_txbuf_free(sc, bf); |
1537 | 1603 | ||
1538 | spin_lock_bh(&sc->txbuflock); | 1604 | spin_lock_bh(&sc->txbuflock); |
1539 | sc->tx_stats[txq->qnum].len--; | ||
1540 | list_move_tail(&bf->list, &sc->txbuf); | 1605 | list_move_tail(&bf->list, &sc->txbuf); |
1541 | sc->txbuf_len++; | 1606 | sc->txbuf_len++; |
1542 | spin_unlock_bh(&sc->txbuflock); | 1607 | spin_unlock_bh(&sc->txbuflock); |
@@ -1605,13 +1670,14 @@ static int | |||
1605 | ath5k_rx_start(struct ath5k_softc *sc) | 1670 | ath5k_rx_start(struct ath5k_softc *sc) |
1606 | { | 1671 | { |
1607 | struct ath5k_hw *ah = sc->ah; | 1672 | struct ath5k_hw *ah = sc->ah; |
1673 | struct ath_common *common = ath5k_hw_common(ah); | ||
1608 | struct ath5k_buf *bf; | 1674 | struct ath5k_buf *bf; |
1609 | int ret; | 1675 | int ret; |
1610 | 1676 | ||
1611 | sc->rxbufsize = roundup(IEEE80211_MAX_LEN, sc->common.cachelsz); | 1677 | common->rx_bufsize = roundup(IEEE80211_MAX_LEN, common->cachelsz); |
1612 | 1678 | ||
1613 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rxbufsize %u\n", | 1679 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rx_bufsize %u\n", |
1614 | sc->common.cachelsz, sc->rxbufsize); | 1680 | common->cachelsz, common->rx_bufsize); |
1615 | 1681 | ||
1616 | spin_lock_bh(&sc->rxbuflock); | 1682 | spin_lock_bh(&sc->rxbuflock); |
1617 | sc->rxlink = NULL; | 1683 | sc->rxlink = NULL; |
@@ -1656,6 +1722,8 @@ static unsigned int | |||
1656 | ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds, | 1722 | ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds, |
1657 | struct sk_buff *skb, struct ath5k_rx_status *rs) | 1723 | struct sk_buff *skb, struct ath5k_rx_status *rs) |
1658 | { | 1724 | { |
1725 | struct ath5k_hw *ah = sc->ah; | ||
1726 | struct ath_common *common = ath5k_hw_common(ah); | ||
1659 | struct ieee80211_hdr *hdr = (void *)skb->data; | 1727 | struct ieee80211_hdr *hdr = (void *)skb->data; |
1660 | unsigned int keyix, hlen; | 1728 | unsigned int keyix, hlen; |
1661 | 1729 | ||
@@ -1672,7 +1740,7 @@ ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds, | |||
1672 | skb->len >= hlen + 4) { | 1740 | skb->len >= hlen + 4) { |
1673 | keyix = skb->data[hlen + 3] >> 6; | 1741 | keyix = skb->data[hlen + 3] >> 6; |
1674 | 1742 | ||
1675 | if (test_bit(keyix, sc->keymap)) | 1743 | if (test_bit(keyix, common->keymap)) |
1676 | return RX_FLAG_DECRYPTED; | 1744 | return RX_FLAG_DECRYPTED; |
1677 | } | 1745 | } |
1678 | 1746 | ||
@@ -1684,13 +1752,14 @@ static void | |||
1684 | ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb, | 1752 | ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb, |
1685 | struct ieee80211_rx_status *rxs) | 1753 | struct ieee80211_rx_status *rxs) |
1686 | { | 1754 | { |
1755 | struct ath_common *common = ath5k_hw_common(sc->ah); | ||
1687 | u64 tsf, bc_tstamp; | 1756 | u64 tsf, bc_tstamp; |
1688 | u32 hw_tu; | 1757 | u32 hw_tu; |
1689 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; | 1758 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; |
1690 | 1759 | ||
1691 | if (ieee80211_is_beacon(mgmt->frame_control) && | 1760 | if (ieee80211_is_beacon(mgmt->frame_control) && |
1692 | le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS && | 1761 | le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS && |
1693 | memcmp(mgmt->bssid, sc->ah->ah_bssid, ETH_ALEN) == 0) { | 1762 | memcmp(mgmt->bssid, common->curbssid, ETH_ALEN) == 0) { |
1694 | /* | 1763 | /* |
1695 | * Received an IBSS beacon with the same BSSID. Hardware *must* | 1764 | * Received an IBSS beacon with the same BSSID. Hardware *must* |
1696 | * have updated the local TSF. We have to work around various | 1765 | * have updated the local TSF. We have to work around various |
@@ -1745,6 +1814,8 @@ ath5k_tasklet_rx(unsigned long data) | |||
1745 | struct sk_buff *skb, *next_skb; | 1814 | struct sk_buff *skb, *next_skb; |
1746 | dma_addr_t next_skb_addr; | 1815 | dma_addr_t next_skb_addr; |
1747 | struct ath5k_softc *sc = (void *)data; | 1816 | struct ath5k_softc *sc = (void *)data; |
1817 | struct ath5k_hw *ah = sc->ah; | ||
1818 | struct ath_common *common = ath5k_hw_common(ah); | ||
1748 | struct ath5k_buf *bf; | 1819 | struct ath5k_buf *bf; |
1749 | struct ath5k_desc *ds; | 1820 | struct ath5k_desc *ds; |
1750 | int ret; | 1821 | int ret; |
@@ -1822,7 +1893,7 @@ accept: | |||
1822 | if (!next_skb) | 1893 | if (!next_skb) |
1823 | goto next; | 1894 | goto next; |
1824 | 1895 | ||
1825 | pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize, | 1896 | pci_unmap_single(sc->pdev, bf->skbaddr, common->rx_bufsize, |
1826 | PCI_DMA_FROMDEVICE); | 1897 | PCI_DMA_FROMDEVICE); |
1827 | skb_put(skb, rs.rs_datalen); | 1898 | skb_put(skb, rs.rs_datalen); |
1828 | 1899 | ||
@@ -1871,17 +1942,6 @@ accept: | |||
1871 | rxs->noise = sc->ah->ah_noise_floor; | 1942 | rxs->noise = sc->ah->ah_noise_floor; |
1872 | rxs->signal = rxs->noise + rs.rs_rssi; | 1943 | rxs->signal = rxs->noise + rs.rs_rssi; |
1873 | 1944 | ||
1874 | /* An rssi of 35 indicates you should be able use | ||
1875 | * 54 Mbps reliably. A more elaborate scheme can be used | ||
1876 | * here but it requires a map of SNR/throughput for each | ||
1877 | * possible mode used */ | ||
1878 | rxs->qual = rs.rs_rssi * 100 / 35; | ||
1879 | |||
1880 | /* rssi can be more than 35 though, anything above that | ||
1881 | * should be considered at 100% */ | ||
1882 | if (rxs->qual > 100) | ||
1883 | rxs->qual = 100; | ||
1884 | |||
1885 | rxs->antenna = rs.rs_antenna; | 1945 | rxs->antenna = rs.rs_antenna; |
1886 | rxs->rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate); | 1946 | rxs->rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate); |
1887 | rxs->flag |= ath5k_rx_decrypted(sc, ds, skb, &rs); | 1947 | rxs->flag |= ath5k_rx_decrypted(sc, ds, skb, &rs); |
@@ -1971,10 +2031,8 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) | |||
1971 | } | 2031 | } |
1972 | 2032 | ||
1973 | ieee80211_tx_status(sc->hw, skb); | 2033 | ieee80211_tx_status(sc->hw, skb); |
1974 | sc->tx_stats[txq->qnum].count++; | ||
1975 | 2034 | ||
1976 | spin_lock(&sc->txbuflock); | 2035 | spin_lock(&sc->txbuflock); |
1977 | sc->tx_stats[txq->qnum].len--; | ||
1978 | list_move_tail(&bf->list, &sc->txbuf); | 2036 | list_move_tail(&bf->list, &sc->txbuf); |
1979 | sc->txbuf_len++; | 2037 | sc->txbuf_len++; |
1980 | spin_unlock(&sc->txbuflock); | 2038 | spin_unlock(&sc->txbuflock); |
@@ -2349,6 +2407,9 @@ ath5k_init(struct ath5k_softc *sc) | |||
2349 | */ | 2407 | */ |
2350 | ath5k_stop_locked(sc); | 2408 | ath5k_stop_locked(sc); |
2351 | 2409 | ||
2410 | /* Set PHY calibration interval */ | ||
2411 | ah->ah_cal_intval = ath5k_calinterval; | ||
2412 | |||
2352 | /* | 2413 | /* |
2353 | * The basic interface to setting the hardware in a good | 2414 | * The basic interface to setting the hardware in a good |
2354 | * state is ``reset''. On return the hardware is known to | 2415 | * state is ``reset''. On return the hardware is known to |
@@ -2376,10 +2437,6 @@ ath5k_init(struct ath5k_softc *sc) | |||
2376 | 2437 | ||
2377 | /* Set ack to be sent at low bit-rates */ | 2438 | /* Set ack to be sent at low bit-rates */ |
2378 | ath5k_hw_set_ack_bitrate_high(ah, false); | 2439 | ath5k_hw_set_ack_bitrate_high(ah, false); |
2379 | |||
2380 | /* Set PHY calibration inteval */ | ||
2381 | ah->ah_cal_intval = ath5k_calinterval; | ||
2382 | |||
2383 | ret = 0; | 2440 | ret = 0; |
2384 | done: | 2441 | done: |
2385 | mmiowb(); | 2442 | mmiowb(); |
@@ -2753,7 +2810,7 @@ static void ath5k_stop(struct ieee80211_hw *hw) | |||
2753 | } | 2810 | } |
2754 | 2811 | ||
2755 | static int ath5k_add_interface(struct ieee80211_hw *hw, | 2812 | static int ath5k_add_interface(struct ieee80211_hw *hw, |
2756 | struct ieee80211_if_init_conf *conf) | 2813 | struct ieee80211_vif *vif) |
2757 | { | 2814 | { |
2758 | struct ath5k_softc *sc = hw->priv; | 2815 | struct ath5k_softc *sc = hw->priv; |
2759 | int ret; | 2816 | int ret; |
@@ -2764,22 +2821,22 @@ static int ath5k_add_interface(struct ieee80211_hw *hw, | |||
2764 | goto end; | 2821 | goto end; |
2765 | } | 2822 | } |
2766 | 2823 | ||
2767 | sc->vif = conf->vif; | 2824 | sc->vif = vif; |
2768 | 2825 | ||
2769 | switch (conf->type) { | 2826 | switch (vif->type) { |
2770 | case NL80211_IFTYPE_AP: | 2827 | case NL80211_IFTYPE_AP: |
2771 | case NL80211_IFTYPE_STATION: | 2828 | case NL80211_IFTYPE_STATION: |
2772 | case NL80211_IFTYPE_ADHOC: | 2829 | case NL80211_IFTYPE_ADHOC: |
2773 | case NL80211_IFTYPE_MESH_POINT: | 2830 | case NL80211_IFTYPE_MESH_POINT: |
2774 | case NL80211_IFTYPE_MONITOR: | 2831 | case NL80211_IFTYPE_MONITOR: |
2775 | sc->opmode = conf->type; | 2832 | sc->opmode = vif->type; |
2776 | break; | 2833 | break; |
2777 | default: | 2834 | default: |
2778 | ret = -EOPNOTSUPP; | 2835 | ret = -EOPNOTSUPP; |
2779 | goto end; | 2836 | goto end; |
2780 | } | 2837 | } |
2781 | 2838 | ||
2782 | ath5k_hw_set_lladdr(sc->ah, conf->mac_addr); | 2839 | ath5k_hw_set_lladdr(sc->ah, vif->addr); |
2783 | ath5k_mode_setup(sc); | 2840 | ath5k_mode_setup(sc); |
2784 | 2841 | ||
2785 | ret = 0; | 2842 | ret = 0; |
@@ -2790,13 +2847,13 @@ end: | |||
2790 | 2847 | ||
2791 | static void | 2848 | static void |
2792 | ath5k_remove_interface(struct ieee80211_hw *hw, | 2849 | ath5k_remove_interface(struct ieee80211_hw *hw, |
2793 | struct ieee80211_if_init_conf *conf) | 2850 | struct ieee80211_vif *vif) |
2794 | { | 2851 | { |
2795 | struct ath5k_softc *sc = hw->priv; | 2852 | struct ath5k_softc *sc = hw->priv; |
2796 | u8 mac[ETH_ALEN] = {}; | 2853 | u8 mac[ETH_ALEN] = {}; |
2797 | 2854 | ||
2798 | mutex_lock(&sc->lock); | 2855 | mutex_lock(&sc->lock); |
2799 | if (sc->vif != conf->vif) | 2856 | if (sc->vif != vif) |
2800 | goto end; | 2857 | goto end; |
2801 | 2858 | ||
2802 | ath5k_hw_set_lladdr(sc->ah, mac); | 2859 | ath5k_hw_set_lladdr(sc->ah, mac); |
@@ -3008,6 +3065,8 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
3008 | struct ieee80211_key_conf *key) | 3065 | struct ieee80211_key_conf *key) |
3009 | { | 3066 | { |
3010 | struct ath5k_softc *sc = hw->priv; | 3067 | struct ath5k_softc *sc = hw->priv; |
3068 | struct ath5k_hw *ah = sc->ah; | ||
3069 | struct ath_common *common = ath5k_hw_common(ah); | ||
3011 | int ret = 0; | 3070 | int ret = 0; |
3012 | 3071 | ||
3013 | if (modparam_nohwcrypt) | 3072 | if (modparam_nohwcrypt) |
@@ -3040,14 +3099,14 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
3040 | ATH5K_ERR(sc, "can't set the key\n"); | 3099 | ATH5K_ERR(sc, "can't set the key\n"); |
3041 | goto unlock; | 3100 | goto unlock; |
3042 | } | 3101 | } |
3043 | __set_bit(key->keyidx, sc->keymap); | 3102 | __set_bit(key->keyidx, common->keymap); |
3044 | key->hw_key_idx = key->keyidx; | 3103 | key->hw_key_idx = key->keyidx; |
3045 | key->flags |= (IEEE80211_KEY_FLAG_GENERATE_IV | | 3104 | key->flags |= (IEEE80211_KEY_FLAG_GENERATE_IV | |
3046 | IEEE80211_KEY_FLAG_GENERATE_MMIC); | 3105 | IEEE80211_KEY_FLAG_GENERATE_MMIC); |
3047 | break; | 3106 | break; |
3048 | case DISABLE_KEY: | 3107 | case DISABLE_KEY: |
3049 | ath5k_hw_reset_key(sc->ah, key->keyidx); | 3108 | ath5k_hw_reset_key(sc->ah, key->keyidx); |
3050 | __clear_bit(key->keyidx, sc->keymap); | 3109 | __clear_bit(key->keyidx, common->keymap); |
3051 | break; | 3110 | break; |
3052 | default: | 3111 | default: |
3053 | ret = -EINVAL; | 3112 | ret = -EINVAL; |
@@ -3075,17 +3134,6 @@ ath5k_get_stats(struct ieee80211_hw *hw, | |||
3075 | return 0; | 3134 | return 0; |
3076 | } | 3135 | } |
3077 | 3136 | ||
3078 | static int | ||
3079 | ath5k_get_tx_stats(struct ieee80211_hw *hw, | ||
3080 | struct ieee80211_tx_queue_stats *stats) | ||
3081 | { | ||
3082 | struct ath5k_softc *sc = hw->priv; | ||
3083 | |||
3084 | memcpy(stats, &sc->tx_stats, sizeof(sc->tx_stats)); | ||
3085 | |||
3086 | return 0; | ||
3087 | } | ||
3088 | |||
3089 | static u64 | 3137 | static u64 |
3090 | ath5k_get_tsf(struct ieee80211_hw *hw) | 3138 | ath5k_get_tsf(struct ieee80211_hw *hw) |
3091 | { | 3139 | { |
@@ -3176,6 +3224,7 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw, | |||
3176 | { | 3224 | { |
3177 | struct ath5k_softc *sc = hw->priv; | 3225 | struct ath5k_softc *sc = hw->priv; |
3178 | struct ath5k_hw *ah = sc->ah; | 3226 | struct ath5k_hw *ah = sc->ah; |
3227 | struct ath_common *common = ath5k_hw_common(ah); | ||
3179 | unsigned long flags; | 3228 | unsigned long flags; |
3180 | 3229 | ||
3181 | mutex_lock(&sc->lock); | 3230 | mutex_lock(&sc->lock); |
@@ -3184,10 +3233,9 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw, | |||
3184 | 3233 | ||
3185 | if (changes & BSS_CHANGED_BSSID) { | 3234 | if (changes & BSS_CHANGED_BSSID) { |
3186 | /* Cache for later use during resets */ | 3235 | /* Cache for later use during resets */ |
3187 | memcpy(ah->ah_bssid, bss_conf->bssid, ETH_ALEN); | 3236 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); |
3188 | /* XXX: assoc id is set to 0 for now, mac80211 doesn't have | 3237 | common->curaid = 0; |
3189 | * a clean way of letting us retrieve this yet. */ | 3238 | ath5k_hw_set_associd(ah); |
3190 | ath5k_hw_set_associd(ah, ah->ah_bssid, 0); | ||
3191 | mmiowb(); | 3239 | mmiowb(); |
3192 | } | 3240 | } |
3193 | 3241 | ||
@@ -3200,6 +3248,14 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw, | |||
3200 | set_beacon_filter(hw, sc->assoc); | 3248 | set_beacon_filter(hw, sc->assoc); |
3201 | ath5k_hw_set_ledstate(sc->ah, sc->assoc ? | 3249 | ath5k_hw_set_ledstate(sc->ah, sc->assoc ? |
3202 | AR5K_LED_ASSOC : AR5K_LED_INIT); | 3250 | AR5K_LED_ASSOC : AR5K_LED_INIT); |
3251 | if (bss_conf->assoc) { | ||
3252 | ATH5K_DBG(sc, ATH5K_DEBUG_ANY, | ||
3253 | "Bss Info ASSOC %d, bssid: %pM\n", | ||
3254 | bss_conf->aid, common->curbssid); | ||
3255 | common->curaid = bss_conf->aid; | ||
3256 | ath5k_hw_set_associd(ah); | ||
3257 | /* Once ANI is available you would start it here */ | ||
3258 | } | ||
3203 | } | 3259 | } |
3204 | 3260 | ||
3205 | if (changes & BSS_CHANGED_BEACON) { | 3261 | if (changes & BSS_CHANGED_BEACON) { |
@@ -3232,3 +3288,22 @@ static void ath5k_sw_scan_complete(struct ieee80211_hw *hw) | |||
3232 | ath5k_hw_set_ledstate(sc->ah, sc->assoc ? | 3288 | ath5k_hw_set_ledstate(sc->ah, sc->assoc ? |
3233 | AR5K_LED_ASSOC : AR5K_LED_INIT); | 3289 | AR5K_LED_ASSOC : AR5K_LED_INIT); |
3234 | } | 3290 | } |
3291 | |||
3292 | /** | ||
3293 | * ath5k_set_coverage_class - Set IEEE 802.11 coverage class | ||
3294 | * | ||
3295 | * @hw: struct ieee80211_hw pointer | ||
3296 | * @coverage_class: IEEE 802.11 coverage class number | ||
3297 | * | ||
3298 | * Mac80211 callback. Sets slot time, ACK timeout and CTS timeout for given | ||
3299 | * coverage class. The values are persistent, they are restored after device | ||
3300 | * reset. | ||
3301 | */ | ||
3302 | static void ath5k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) | ||
3303 | { | ||
3304 | struct ath5k_softc *sc = hw->priv; | ||
3305 | |||
3306 | mutex_lock(&sc->lock); | ||
3307 | ath5k_hw_set_coverage_class(sc->ah, coverage_class); | ||
3308 | mutex_unlock(&sc->lock); | ||
3309 | } | ||