diff options
Diffstat (limited to 'drivers/net/wireless/ath5k/base.c')
-rw-r--r-- | drivers/net/wireless/ath5k/base.c | 574 |
1 files changed, 287 insertions, 287 deletions
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index 0676c6d84383..9b95c4049b31 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c | |||
@@ -72,7 +72,7 @@ MODULE_AUTHOR("Nick Kossifidis"); | |||
72 | MODULE_DESCRIPTION("Support for 5xxx series of Atheros 802.11 wireless LAN cards."); | 72 | MODULE_DESCRIPTION("Support for 5xxx series of Atheros 802.11 wireless LAN cards."); |
73 | MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards"); | 73 | MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards"); |
74 | MODULE_LICENSE("Dual BSD/GPL"); | 74 | MODULE_LICENSE("Dual BSD/GPL"); |
75 | MODULE_VERSION("0.5.0 (EXPERIMENTAL)"); | 75 | MODULE_VERSION("0.6.0 (EXPERIMENTAL)"); |
76 | 76 | ||
77 | 77 | ||
78 | /* Known PCI ids */ | 78 | /* Known PCI ids */ |
@@ -93,45 +93,94 @@ static struct pci_device_id ath5k_pci_id_table[] __devinitdata = { | |||
93 | { PCI_VDEVICE(ATHEROS, 0x0019), .driver_data = AR5K_AR5212 }, /* 5212 combatible */ | 93 | { PCI_VDEVICE(ATHEROS, 0x0019), .driver_data = AR5K_AR5212 }, /* 5212 combatible */ |
94 | { PCI_VDEVICE(ATHEROS, 0x001a), .driver_data = AR5K_AR5212 }, /* 2413 Griffin-lite */ | 94 | { PCI_VDEVICE(ATHEROS, 0x001a), .driver_data = AR5K_AR5212 }, /* 2413 Griffin-lite */ |
95 | { PCI_VDEVICE(ATHEROS, 0x001b), .driver_data = AR5K_AR5212 }, /* 5413 Eagle */ | 95 | { PCI_VDEVICE(ATHEROS, 0x001b), .driver_data = AR5K_AR5212 }, /* 5413 Eagle */ |
96 | { PCI_VDEVICE(ATHEROS, 0x001c), .driver_data = AR5K_AR5212 }, /* 5424 Condor (PCI-E)*/ | 96 | { PCI_VDEVICE(ATHEROS, 0x001c), .driver_data = AR5K_AR5212 }, /* PCI-E cards */ |
97 | { PCI_VDEVICE(ATHEROS, 0x001d), .driver_data = AR5K_AR5212 }, /* 2417 Nala */ | ||
97 | { 0 } | 98 | { 0 } |
98 | }; | 99 | }; |
99 | MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table); | 100 | MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table); |
100 | 101 | ||
101 | /* Known SREVs */ | 102 | /* Known SREVs */ |
102 | static struct ath5k_srev_name srev_names[] = { | 103 | static struct ath5k_srev_name srev_names[] = { |
103 | { "5210", AR5K_VERSION_VER, AR5K_SREV_VER_AR5210 }, | 104 | { "5210", AR5K_VERSION_MAC, AR5K_SREV_AR5210 }, |
104 | { "5311", AR5K_VERSION_VER, AR5K_SREV_VER_AR5311 }, | 105 | { "5311", AR5K_VERSION_MAC, AR5K_SREV_AR5311 }, |
105 | { "5311A", AR5K_VERSION_VER, AR5K_SREV_VER_AR5311A }, | 106 | { "5311A", AR5K_VERSION_MAC, AR5K_SREV_AR5311A }, |
106 | { "5311B", AR5K_VERSION_VER, AR5K_SREV_VER_AR5311B }, | 107 | { "5311B", AR5K_VERSION_MAC, AR5K_SREV_AR5311B }, |
107 | { "5211", AR5K_VERSION_VER, AR5K_SREV_VER_AR5211 }, | 108 | { "5211", AR5K_VERSION_MAC, AR5K_SREV_AR5211 }, |
108 | { "5212", AR5K_VERSION_VER, AR5K_SREV_VER_AR5212 }, | 109 | { "5212", AR5K_VERSION_MAC, AR5K_SREV_AR5212 }, |
109 | { "5213", AR5K_VERSION_VER, AR5K_SREV_VER_AR5213 }, | 110 | { "5213", AR5K_VERSION_MAC, AR5K_SREV_AR5213 }, |
110 | { "5213A", AR5K_VERSION_VER, AR5K_SREV_VER_AR5213A }, | 111 | { "5213A", AR5K_VERSION_MAC, AR5K_SREV_AR5213A }, |
111 | { "2413", AR5K_VERSION_VER, AR5K_SREV_VER_AR2413 }, | 112 | { "2413", AR5K_VERSION_MAC, AR5K_SREV_AR2413 }, |
112 | { "2414", AR5K_VERSION_VER, AR5K_SREV_VER_AR2414 }, | 113 | { "2414", AR5K_VERSION_MAC, AR5K_SREV_AR2414 }, |
113 | { "2424", AR5K_VERSION_VER, AR5K_SREV_VER_AR2424 }, | 114 | { "5424", AR5K_VERSION_MAC, AR5K_SREV_AR5424 }, |
114 | { "5424", AR5K_VERSION_VER, AR5K_SREV_VER_AR5424 }, | 115 | { "5413", AR5K_VERSION_MAC, AR5K_SREV_AR5413 }, |
115 | { "5413", AR5K_VERSION_VER, AR5K_SREV_VER_AR5413 }, | 116 | { "5414", AR5K_VERSION_MAC, AR5K_SREV_AR5414 }, |
116 | { "5414", AR5K_VERSION_VER, AR5K_SREV_VER_AR5414 }, | 117 | { "2415", AR5K_VERSION_MAC, AR5K_SREV_AR2415 }, |
117 | { "5416", AR5K_VERSION_VER, AR5K_SREV_VER_AR5416 }, | 118 | { "5416", AR5K_VERSION_MAC, AR5K_SREV_AR5416 }, |
118 | { "5418", AR5K_VERSION_VER, AR5K_SREV_VER_AR5418 }, | 119 | { "5418", AR5K_VERSION_MAC, AR5K_SREV_AR5418 }, |
119 | { "2425", AR5K_VERSION_VER, AR5K_SREV_VER_AR2425 }, | 120 | { "2425", AR5K_VERSION_MAC, AR5K_SREV_AR2425 }, |
120 | { "xxxxx", AR5K_VERSION_VER, AR5K_SREV_UNKNOWN }, | 121 | { "2417", AR5K_VERSION_MAC, AR5K_SREV_AR2417 }, |
122 | { "xxxxx", AR5K_VERSION_MAC, AR5K_SREV_UNKNOWN }, | ||
121 | { "5110", AR5K_VERSION_RAD, AR5K_SREV_RAD_5110 }, | 123 | { "5110", AR5K_VERSION_RAD, AR5K_SREV_RAD_5110 }, |
122 | { "5111", AR5K_VERSION_RAD, AR5K_SREV_RAD_5111 }, | 124 | { "5111", AR5K_VERSION_RAD, AR5K_SREV_RAD_5111 }, |
125 | { "5111A", AR5K_VERSION_RAD, AR5K_SREV_RAD_5111A }, | ||
123 | { "2111", AR5K_VERSION_RAD, AR5K_SREV_RAD_2111 }, | 126 | { "2111", AR5K_VERSION_RAD, AR5K_SREV_RAD_2111 }, |
124 | { "5112", AR5K_VERSION_RAD, AR5K_SREV_RAD_5112 }, | 127 | { "5112", AR5K_VERSION_RAD, AR5K_SREV_RAD_5112 }, |
125 | { "5112A", AR5K_VERSION_RAD, AR5K_SREV_RAD_5112A }, | 128 | { "5112A", AR5K_VERSION_RAD, AR5K_SREV_RAD_5112A }, |
129 | { "5112B", AR5K_VERSION_RAD, AR5K_SREV_RAD_5112B }, | ||
126 | { "2112", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112 }, | 130 | { "2112", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112 }, |
127 | { "2112A", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112A }, | 131 | { "2112A", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112A }, |
128 | { "SChip", AR5K_VERSION_RAD, AR5K_SREV_RAD_SC0 }, | 132 | { "2112B", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112B }, |
129 | { "SChip", AR5K_VERSION_RAD, AR5K_SREV_RAD_SC1 }, | 133 | { "2413", AR5K_VERSION_RAD, AR5K_SREV_RAD_2413 }, |
130 | { "SChip", AR5K_VERSION_RAD, AR5K_SREV_RAD_SC2 }, | 134 | { "5413", AR5K_VERSION_RAD, AR5K_SREV_RAD_5413 }, |
135 | { "2316", AR5K_VERSION_RAD, AR5K_SREV_RAD_2316 }, | ||
136 | { "2317", AR5K_VERSION_RAD, AR5K_SREV_RAD_2317 }, | ||
137 | { "5424", AR5K_VERSION_RAD, AR5K_SREV_RAD_5424 }, | ||
131 | { "5133", AR5K_VERSION_RAD, AR5K_SREV_RAD_5133 }, | 138 | { "5133", AR5K_VERSION_RAD, AR5K_SREV_RAD_5133 }, |
132 | { "xxxxx", AR5K_VERSION_RAD, AR5K_SREV_UNKNOWN }, | 139 | { "xxxxx", AR5K_VERSION_RAD, AR5K_SREV_UNKNOWN }, |
133 | }; | 140 | }; |
134 | 141 | ||
142 | static struct ieee80211_rate ath5k_rates[] = { | ||
143 | { .bitrate = 10, | ||
144 | .hw_value = ATH5K_RATE_CODE_1M, }, | ||
145 | { .bitrate = 20, | ||
146 | .hw_value = ATH5K_RATE_CODE_2M, | ||
147 | .hw_value_short = ATH5K_RATE_CODE_2M | AR5K_SET_SHORT_PREAMBLE, | ||
148 | .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
149 | { .bitrate = 55, | ||
150 | .hw_value = ATH5K_RATE_CODE_5_5M, | ||
151 | .hw_value_short = ATH5K_RATE_CODE_5_5M | AR5K_SET_SHORT_PREAMBLE, | ||
152 | .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
153 | { .bitrate = 110, | ||
154 | .hw_value = ATH5K_RATE_CODE_11M, | ||
155 | .hw_value_short = ATH5K_RATE_CODE_11M | AR5K_SET_SHORT_PREAMBLE, | ||
156 | .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
157 | { .bitrate = 60, | ||
158 | .hw_value = ATH5K_RATE_CODE_6M, | ||
159 | .flags = 0 }, | ||
160 | { .bitrate = 90, | ||
161 | .hw_value = ATH5K_RATE_CODE_9M, | ||
162 | .flags = 0 }, | ||
163 | { .bitrate = 120, | ||
164 | .hw_value = ATH5K_RATE_CODE_12M, | ||
165 | .flags = 0 }, | ||
166 | { .bitrate = 180, | ||
167 | .hw_value = ATH5K_RATE_CODE_18M, | ||
168 | .flags = 0 }, | ||
169 | { .bitrate = 240, | ||
170 | .hw_value = ATH5K_RATE_CODE_24M, | ||
171 | .flags = 0 }, | ||
172 | { .bitrate = 360, | ||
173 | .hw_value = ATH5K_RATE_CODE_36M, | ||
174 | .flags = 0 }, | ||
175 | { .bitrate = 480, | ||
176 | .hw_value = ATH5K_RATE_CODE_48M, | ||
177 | .flags = 0 }, | ||
178 | { .bitrate = 540, | ||
179 | .hw_value = ATH5K_RATE_CODE_54M, | ||
180 | .flags = 0 }, | ||
181 | /* XR missing */ | ||
182 | }; | ||
183 | |||
135 | /* | 184 | /* |
136 | * Prototypes - PCI stack related functions | 185 | * Prototypes - PCI stack related functions |
137 | */ | 186 | */ |
@@ -162,7 +211,8 @@ static struct pci_driver ath5k_pci_driver = { | |||
162 | * Prototypes - MAC 802.11 stack related functions | 211 | * Prototypes - MAC 802.11 stack related functions |
163 | */ | 212 | */ |
164 | static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb); | 213 | static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb); |
165 | static int ath5k_reset(struct ieee80211_hw *hw); | 214 | static int ath5k_reset(struct ath5k_softc *sc, bool stop, bool change_channel); |
215 | static int ath5k_reset_wake(struct ath5k_softc *sc); | ||
166 | static int ath5k_start(struct ieee80211_hw *hw); | 216 | static int ath5k_start(struct ieee80211_hw *hw); |
167 | static void ath5k_stop(struct ieee80211_hw *hw); | 217 | static void ath5k_stop(struct ieee80211_hw *hw); |
168 | static int ath5k_add_interface(struct ieee80211_hw *hw, | 218 | static int ath5k_add_interface(struct ieee80211_hw *hw, |
@@ -218,20 +268,16 @@ static void ath5k_detach(struct pci_dev *pdev, | |||
218 | struct ieee80211_hw *hw); | 268 | struct ieee80211_hw *hw); |
219 | /* Channel/mode setup */ | 269 | /* Channel/mode setup */ |
220 | static inline short ath5k_ieee2mhz(short chan); | 270 | static inline short ath5k_ieee2mhz(short chan); |
221 | static unsigned int ath5k_copy_rates(struct ieee80211_rate *rates, | ||
222 | const struct ath5k_rate_table *rt, | ||
223 | unsigned int max); | ||
224 | static unsigned int ath5k_copy_channels(struct ath5k_hw *ah, | 271 | static unsigned int ath5k_copy_channels(struct ath5k_hw *ah, |
225 | struct ieee80211_channel *channels, | 272 | struct ieee80211_channel *channels, |
226 | unsigned int mode, | 273 | unsigned int mode, |
227 | unsigned int max); | 274 | unsigned int max); |
228 | static int ath5k_getchannels(struct ieee80211_hw *hw); | 275 | static int ath5k_setup_bands(struct ieee80211_hw *hw); |
229 | static int ath5k_chan_set(struct ath5k_softc *sc, | 276 | static int ath5k_chan_set(struct ath5k_softc *sc, |
230 | struct ieee80211_channel *chan); | 277 | struct ieee80211_channel *chan); |
231 | static void ath5k_setcurmode(struct ath5k_softc *sc, | 278 | static void ath5k_setcurmode(struct ath5k_softc *sc, |
232 | unsigned int mode); | 279 | unsigned int mode); |
233 | static void ath5k_mode_setup(struct ath5k_softc *sc); | 280 | static void ath5k_mode_setup(struct ath5k_softc *sc); |
234 | static void ath5k_set_total_hw_rates(struct ath5k_softc *sc); | ||
235 | 281 | ||
236 | /* Descriptor setup */ | 282 | /* Descriptor setup */ |
237 | static int ath5k_desc_alloc(struct ath5k_softc *sc, | 283 | static int ath5k_desc_alloc(struct ath5k_softc *sc, |
@@ -351,7 +397,11 @@ ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val) | |||
351 | for (i = 0; i < ARRAY_SIZE(srev_names); i++) { | 397 | for (i = 0; i < ARRAY_SIZE(srev_names); i++) { |
352 | if (srev_names[i].sr_type != type) | 398 | if (srev_names[i].sr_type != type) |
353 | continue; | 399 | continue; |
354 | if ((val & 0xff) < srev_names[i + 1].sr_val) { | 400 | |
401 | if ((val & 0xf0) == srev_names[i].sr_val) | ||
402 | name = srev_names[i].sr_name; | ||
403 | |||
404 | if ((val & 0xff) == srev_names[i].sr_val) { | ||
355 | name = srev_names[i].sr_name; | 405 | name = srev_names[i].sr_name; |
356 | break; | 406 | break; |
357 | } | 407 | } |
@@ -446,6 +496,12 @@ ath5k_pci_probe(struct pci_dev *pdev, | |||
446 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | 496 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | |
447 | IEEE80211_HW_SIGNAL_DBM | | 497 | IEEE80211_HW_SIGNAL_DBM | |
448 | IEEE80211_HW_NOISE_DBM; | 498 | IEEE80211_HW_NOISE_DBM; |
499 | |||
500 | hw->wiphy->interface_modes = | ||
501 | BIT(NL80211_IFTYPE_STATION) | | ||
502 | BIT(NL80211_IFTYPE_ADHOC) | | ||
503 | BIT(NL80211_IFTYPE_MESH_POINT); | ||
504 | |||
449 | hw->extra_tx_headroom = 2; | 505 | hw->extra_tx_headroom = 2; |
450 | hw->channel_change_time = 5000; | 506 | hw->channel_change_time = 5000; |
451 | sc = hw->priv; | 507 | sc = hw->priv; |
@@ -462,7 +518,7 @@ ath5k_pci_probe(struct pci_dev *pdev, | |||
462 | 518 | ||
463 | sc->iobase = mem; /* So we can unmap it on detach */ | 519 | sc->iobase = mem; /* So we can unmap it on detach */ |
464 | sc->cachelsz = csz * sizeof(u32); /* convert to bytes */ | 520 | sc->cachelsz = csz * sizeof(u32); /* convert to bytes */ |
465 | sc->opmode = IEEE80211_IF_TYPE_STA; | 521 | sc->opmode = NL80211_IFTYPE_STATION; |
466 | mutex_init(&sc->lock); | 522 | mutex_init(&sc->lock); |
467 | spin_lock_init(&sc->rxbuflock); | 523 | spin_lock_init(&sc->rxbuflock); |
468 | spin_lock_init(&sc->txbuflock); | 524 | spin_lock_init(&sc->txbuflock); |
@@ -485,13 +541,19 @@ ath5k_pci_probe(struct pci_dev *pdev, | |||
485 | goto err_irq; | 541 | goto err_irq; |
486 | } | 542 | } |
487 | 543 | ||
544 | /* set up multi-rate retry capabilities */ | ||
545 | if (sc->ah->ah_version == AR5K_AR5212) { | ||
546 | hw->max_altrates = 3; | ||
547 | hw->max_altrate_tries = 11; | ||
548 | } | ||
549 | |||
488 | /* Finish private driver data initialization */ | 550 | /* Finish private driver data initialization */ |
489 | ret = ath5k_attach(pdev, hw); | 551 | ret = ath5k_attach(pdev, hw); |
490 | if (ret) | 552 | if (ret) |
491 | goto err_ah; | 553 | goto err_ah; |
492 | 554 | ||
493 | ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n", | 555 | ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n", |
494 | ath5k_chip_name(AR5K_VERSION_VER,sc->ah->ah_mac_srev), | 556 | ath5k_chip_name(AR5K_VERSION_MAC, sc->ah->ah_mac_srev), |
495 | sc->ah->ah_mac_srev, | 557 | sc->ah->ah_mac_srev, |
496 | sc->ah->ah_phy_revision); | 558 | sc->ah->ah_phy_revision); |
497 | 559 | ||
@@ -646,7 +708,6 @@ err_no_irq: | |||
646 | #endif /* CONFIG_PM */ | 708 | #endif /* CONFIG_PM */ |
647 | 709 | ||
648 | 710 | ||
649 | |||
650 | /***********************\ | 711 | /***********************\ |
651 | * Driver Initialization * | 712 | * Driver Initialization * |
652 | \***********************/ | 713 | \***********************/ |
@@ -669,7 +730,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) | |||
669 | * return false w/o doing anything. MAC's that do | 730 | * return false w/o doing anything. MAC's that do |
670 | * support it will return true w/o doing anything. | 731 | * support it will return true w/o doing anything. |
671 | */ | 732 | */ |
672 | ret = ah->ah_setup_xtx_desc(ah, NULL, 0, 0, 0, 0, 0, 0); | 733 | ret = ah->ah_setup_mrr_tx_desc(ah, NULL, 0, 0, 0, 0, 0, 0); |
673 | if (ret < 0) | 734 | if (ret < 0) |
674 | goto err; | 735 | goto err; |
675 | if (ret > 0) | 736 | if (ret > 0) |
@@ -688,15 +749,12 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) | |||
688 | * on settings like the phy mode and regulatory | 749 | * on settings like the phy mode and regulatory |
689 | * domain restrictions. | 750 | * domain restrictions. |
690 | */ | 751 | */ |
691 | ret = ath5k_getchannels(hw); | 752 | ret = ath5k_setup_bands(hw); |
692 | if (ret) { | 753 | if (ret) { |
693 | ATH5K_ERR(sc, "can't get channels\n"); | 754 | ATH5K_ERR(sc, "can't get channels\n"); |
694 | goto err; | 755 | goto err; |
695 | } | 756 | } |
696 | 757 | ||
697 | /* Set *_rates so we can map hw rate index */ | ||
698 | ath5k_set_total_hw_rates(sc); | ||
699 | |||
700 | /* NB: setup here so ath5k_rate_update is happy */ | 758 | /* NB: setup here so ath5k_rate_update is happy */ |
701 | if (test_bit(AR5K_MODE_11A, ah->ah_modes)) | 759 | if (test_bit(AR5K_MODE_11A, ah->ah_modes)) |
702 | ath5k_setcurmode(sc, AR5K_MODE_11A); | 760 | ath5k_setcurmode(sc, AR5K_MODE_11A); |
@@ -813,27 +871,6 @@ ath5k_ieee2mhz(short chan) | |||
813 | } | 871 | } |
814 | 872 | ||
815 | static unsigned int | 873 | static unsigned int |
816 | ath5k_copy_rates(struct ieee80211_rate *rates, | ||
817 | const struct ath5k_rate_table *rt, | ||
818 | unsigned int max) | ||
819 | { | ||
820 | unsigned int i, count; | ||
821 | |||
822 | if (rt == NULL) | ||
823 | return 0; | ||
824 | |||
825 | for (i = 0, count = 0; i < rt->rate_count && max > 0; i++) { | ||
826 | rates[count].bitrate = rt->rates[i].rate_kbps / 100; | ||
827 | rates[count].hw_value = rt->rates[i].rate_code; | ||
828 | rates[count].flags = rt->rates[i].modulation; | ||
829 | count++; | ||
830 | max--; | ||
831 | } | ||
832 | |||
833 | return count; | ||
834 | } | ||
835 | |||
836 | static unsigned int | ||
837 | ath5k_copy_channels(struct ath5k_hw *ah, | 874 | ath5k_copy_channels(struct ath5k_hw *ah, |
838 | struct ieee80211_channel *channels, | 875 | struct ieee80211_channel *channels, |
839 | unsigned int mode, | 876 | unsigned int mode, |
@@ -895,74 +932,97 @@ ath5k_copy_channels(struct ath5k_hw *ah, | |||
895 | return count; | 932 | return count; |
896 | } | 933 | } |
897 | 934 | ||
935 | static void | ||
936 | ath5k_setup_rate_idx(struct ath5k_softc *sc, struct ieee80211_supported_band *b) | ||
937 | { | ||
938 | u8 i; | ||
939 | |||
940 | for (i = 0; i < AR5K_MAX_RATES; i++) | ||
941 | sc->rate_idx[b->band][i] = -1; | ||
942 | |||
943 | for (i = 0; i < b->n_bitrates; i++) { | ||
944 | sc->rate_idx[b->band][b->bitrates[i].hw_value] = i; | ||
945 | if (b->bitrates[i].hw_value_short) | ||
946 | sc->rate_idx[b->band][b->bitrates[i].hw_value_short] = i; | ||
947 | } | ||
948 | } | ||
949 | |||
898 | static int | 950 | static int |
899 | ath5k_getchannels(struct ieee80211_hw *hw) | 951 | ath5k_setup_bands(struct ieee80211_hw *hw) |
900 | { | 952 | { |
901 | struct ath5k_softc *sc = hw->priv; | 953 | struct ath5k_softc *sc = hw->priv; |
902 | struct ath5k_hw *ah = sc->ah; | 954 | struct ath5k_hw *ah = sc->ah; |
903 | struct ieee80211_supported_band *sbands = sc->sbands; | 955 | struct ieee80211_supported_band *sband; |
904 | const struct ath5k_rate_table *hw_rates; | 956 | int max_c, count_c = 0; |
905 | unsigned int max_r, max_c, count_r, count_c; | 957 | int i; |
906 | int mode2g = AR5K_MODE_11G; | ||
907 | 958 | ||
908 | BUILD_BUG_ON(ARRAY_SIZE(sc->sbands) < IEEE80211_NUM_BANDS); | 959 | BUILD_BUG_ON(ARRAY_SIZE(sc->sbands) < IEEE80211_NUM_BANDS); |
909 | |||
910 | max_r = ARRAY_SIZE(sc->rates); | ||
911 | max_c = ARRAY_SIZE(sc->channels); | 960 | max_c = ARRAY_SIZE(sc->channels); |
912 | count_r = count_c = 0; | ||
913 | 961 | ||
914 | /* 2GHz band */ | 962 | /* 2GHz band */ |
915 | if (!test_bit(AR5K_MODE_11G, sc->ah->ah_capabilities.cap_mode)) { | 963 | sband = &sc->sbands[IEEE80211_BAND_2GHZ]; |
916 | mode2g = AR5K_MODE_11B; | 964 | sband->band = IEEE80211_BAND_2GHZ; |
917 | if (!test_bit(AR5K_MODE_11B, | 965 | sband->bitrates = &sc->rates[IEEE80211_BAND_2GHZ][0]; |
918 | sc->ah->ah_capabilities.cap_mode)) | ||
919 | mode2g = -1; | ||
920 | } | ||
921 | 966 | ||
922 | if (mode2g > 0) { | 967 | if (test_bit(AR5K_MODE_11G, sc->ah->ah_capabilities.cap_mode)) { |
923 | struct ieee80211_supported_band *sband = | 968 | /* G mode */ |
924 | &sbands[IEEE80211_BAND_2GHZ]; | 969 | memcpy(sband->bitrates, &ath5k_rates[0], |
970 | sizeof(struct ieee80211_rate) * 12); | ||
971 | sband->n_bitrates = 12; | ||
925 | 972 | ||
926 | sband->bitrates = sc->rates; | ||
927 | sband->channels = sc->channels; | 973 | sband->channels = sc->channels; |
928 | |||
929 | sband->band = IEEE80211_BAND_2GHZ; | ||
930 | sband->n_channels = ath5k_copy_channels(ah, sband->channels, | 974 | sband->n_channels = ath5k_copy_channels(ah, sband->channels, |
931 | mode2g, max_c); | 975 | AR5K_MODE_11G, max_c); |
932 | |||
933 | hw_rates = ath5k_hw_get_rate_table(ah, mode2g); | ||
934 | sband->n_bitrates = ath5k_copy_rates(sband->bitrates, | ||
935 | hw_rates, max_r); | ||
936 | 976 | ||
977 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; | ||
937 | count_c = sband->n_channels; | 978 | count_c = sband->n_channels; |
938 | count_r = sband->n_bitrates; | 979 | max_c -= count_c; |
980 | } else if (test_bit(AR5K_MODE_11B, sc->ah->ah_capabilities.cap_mode)) { | ||
981 | /* B mode */ | ||
982 | memcpy(sband->bitrates, &ath5k_rates[0], | ||
983 | sizeof(struct ieee80211_rate) * 4); | ||
984 | sband->n_bitrates = 4; | ||
985 | |||
986 | /* 5211 only supports B rates and uses 4bit rate codes | ||
987 | * (e.g normally we have 0x1B for 1M, but on 5211 we have 0x0B) | ||
988 | * fix them up here: | ||
989 | */ | ||
990 | if (ah->ah_version == AR5K_AR5211) { | ||
991 | for (i = 0; i < 4; i++) { | ||
992 | sband->bitrates[i].hw_value = | ||
993 | sband->bitrates[i].hw_value & 0xF; | ||
994 | sband->bitrates[i].hw_value_short = | ||
995 | sband->bitrates[i].hw_value_short & 0xF; | ||
996 | } | ||
997 | } | ||
939 | 998 | ||
940 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; | 999 | sband->channels = sc->channels; |
1000 | sband->n_channels = ath5k_copy_channels(ah, sband->channels, | ||
1001 | AR5K_MODE_11B, max_c); | ||
941 | 1002 | ||
942 | max_r -= count_r; | 1003 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; |
1004 | count_c = sband->n_channels; | ||
943 | max_c -= count_c; | 1005 | max_c -= count_c; |
944 | |||
945 | } | 1006 | } |
1007 | ath5k_setup_rate_idx(sc, sband); | ||
946 | 1008 | ||
947 | /* 5GHz band */ | 1009 | /* 5GHz band, A mode */ |
948 | |||
949 | if (test_bit(AR5K_MODE_11A, sc->ah->ah_capabilities.cap_mode)) { | 1010 | if (test_bit(AR5K_MODE_11A, sc->ah->ah_capabilities.cap_mode)) { |
950 | struct ieee80211_supported_band *sband = | 1011 | sband = &sc->sbands[IEEE80211_BAND_5GHZ]; |
951 | &sbands[IEEE80211_BAND_5GHZ]; | 1012 | sband->band = IEEE80211_BAND_5GHZ; |
1013 | sband->bitrates = &sc->rates[IEEE80211_BAND_5GHZ][0]; | ||
952 | 1014 | ||
953 | sband->bitrates = &sc->rates[count_r]; | 1015 | memcpy(sband->bitrates, &ath5k_rates[4], |
954 | sband->channels = &sc->channels[count_c]; | 1016 | sizeof(struct ieee80211_rate) * 8); |
1017 | sband->n_bitrates = 8; | ||
955 | 1018 | ||
956 | sband->band = IEEE80211_BAND_5GHZ; | 1019 | sband->channels = &sc->channels[count_c]; |
957 | sband->n_channels = ath5k_copy_channels(ah, sband->channels, | 1020 | sband->n_channels = ath5k_copy_channels(ah, sband->channels, |
958 | AR5K_MODE_11A, max_c); | 1021 | AR5K_MODE_11A, max_c); |
959 | 1022 | ||
960 | hw_rates = ath5k_hw_get_rate_table(ah, AR5K_MODE_11A); | ||
961 | sband->n_bitrates = ath5k_copy_rates(sband->bitrates, | ||
962 | hw_rates, max_r); | ||
963 | |||
964 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband; | 1023 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband; |
965 | } | 1024 | } |
1025 | ath5k_setup_rate_idx(sc, sband); | ||
966 | 1026 | ||
967 | ath5k_debug_dump_bands(sc); | 1027 | ath5k_debug_dump_bands(sc); |
968 | 1028 | ||
@@ -978,9 +1038,6 @@ ath5k_getchannels(struct ieee80211_hw *hw) | |||
978 | static int | 1038 | static int |
979 | ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) | 1039 | ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) |
980 | { | 1040 | { |
981 | struct ath5k_hw *ah = sc->ah; | ||
982 | int ret; | ||
983 | |||
984 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "(%u MHz) -> (%u MHz)\n", | 1041 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "(%u MHz) -> (%u MHz)\n", |
985 | sc->curchan->center_freq, chan->center_freq); | 1042 | sc->curchan->center_freq, chan->center_freq); |
986 | 1043 | ||
@@ -996,41 +1053,7 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) | |||
996 | * hardware at the new frequency, and then re-enable | 1053 | * hardware at the new frequency, and then re-enable |
997 | * the relevant bits of the h/w. | 1054 | * the relevant bits of the h/w. |
998 | */ | 1055 | */ |
999 | ath5k_hw_set_intr(ah, 0); /* disable interrupts */ | 1056 | return ath5k_reset(sc, true, true); |
1000 | ath5k_txq_cleanup(sc); /* clear pending tx frames */ | ||
1001 | ath5k_rx_stop(sc); /* turn off frame recv */ | ||
1002 | ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, true); | ||
1003 | if (ret) { | ||
1004 | ATH5K_ERR(sc, "%s: unable to reset channel " | ||
1005 | "(%u Mhz)\n", __func__, chan->center_freq); | ||
1006 | return ret; | ||
1007 | } | ||
1008 | |||
1009 | ath5k_hw_set_txpower_limit(sc->ah, 0); | ||
1010 | |||
1011 | /* | ||
1012 | * Re-enable rx framework. | ||
1013 | */ | ||
1014 | ret = ath5k_rx_start(sc); | ||
1015 | if (ret) { | ||
1016 | ATH5K_ERR(sc, "%s: unable to restart recv logic\n", | ||
1017 | __func__); | ||
1018 | return ret; | ||
1019 | } | ||
1020 | |||
1021 | /* | ||
1022 | * Change channels and update the h/w rate map | ||
1023 | * if we're switching; e.g. 11a to 11b/g. | ||
1024 | * | ||
1025 | * XXX needed? | ||
1026 | */ | ||
1027 | /* ath5k_chan_change(sc, chan); */ | ||
1028 | |||
1029 | ath5k_beacon_config(sc); | ||
1030 | /* | ||
1031 | * Re-enable interrupts. | ||
1032 | */ | ||
1033 | ath5k_hw_set_intr(ah, sc->imask); | ||
1034 | } | 1057 | } |
1035 | 1058 | ||
1036 | return 0; | 1059 | return 0; |
@@ -1068,75 +1091,13 @@ ath5k_mode_setup(struct ath5k_softc *sc) | |||
1068 | ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); | 1091 | ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); |
1069 | } | 1092 | } |
1070 | 1093 | ||
1071 | /* | ||
1072 | * Match the hw provided rate index (through descriptors) | ||
1073 | * to an index for sc->curband->bitrates, so it can be used | ||
1074 | * by the stack. | ||
1075 | * | ||
1076 | * This one is a little bit tricky but i think i'm right | ||
1077 | * about this... | ||
1078 | * | ||
1079 | * We have 4 rate tables in the following order: | ||
1080 | * XR (4 rates) | ||
1081 | * 802.11a (8 rates) | ||
1082 | * 802.11b (4 rates) | ||
1083 | * 802.11g (12 rates) | ||
1084 | * that make the hw rate table. | ||
1085 | * | ||
1086 | * Lets take a 5211 for example that supports a and b modes only. | ||
1087 | * First comes the 802.11a table and then 802.11b (total 12 rates). | ||
1088 | * When hw returns eg. 11 it points to the last 802.11b rate (11Mbit), | ||
1089 | * if it returns 2 it points to the second 802.11a rate etc. | ||
1090 | * | ||
1091 | * Same goes for 5212 who has xr/a/b/g support (total 28 rates). | ||
1092 | * First comes the XR table, then 802.11a, 802.11b and 802.11g. | ||
1093 | * When hw returns eg. 27 it points to the last 802.11g rate (54Mbits) etc | ||
1094 | */ | ||
1095 | static void | ||
1096 | ath5k_set_total_hw_rates(struct ath5k_softc *sc) { | ||
1097 | |||
1098 | struct ath5k_hw *ah = sc->ah; | ||
1099 | |||
1100 | if (test_bit(AR5K_MODE_11A, ah->ah_modes)) | ||
1101 | sc->a_rates = 8; | ||
1102 | |||
1103 | if (test_bit(AR5K_MODE_11B, ah->ah_modes)) | ||
1104 | sc->b_rates = 4; | ||
1105 | |||
1106 | if (test_bit(AR5K_MODE_11G, ah->ah_modes)) | ||
1107 | sc->g_rates = 12; | ||
1108 | |||
1109 | /* XXX: Need to see what what happens when | ||
1110 | xr disable bits in eeprom are set */ | ||
1111 | if (ah->ah_version >= AR5K_AR5212) | ||
1112 | sc->xr_rates = 4; | ||
1113 | |||
1114 | } | ||
1115 | |||
1116 | static inline int | 1094 | static inline int |
1117 | ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix) { | 1095 | ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix) |
1118 | 1096 | { | |
1119 | int mac80211_rix; | 1097 | WARN_ON(hw_rix < 0 || hw_rix > AR5K_MAX_RATES); |
1120 | 1098 | return sc->rate_idx[sc->curband->band][hw_rix]; | |
1121 | if(sc->curband->band == IEEE80211_BAND_2GHZ) { | ||
1122 | /* We setup a g ratetable for both b/g modes */ | ||
1123 | mac80211_rix = | ||
1124 | hw_rix - sc->b_rates - sc->a_rates - sc->xr_rates; | ||
1125 | } else { | ||
1126 | mac80211_rix = hw_rix - sc->xr_rates; | ||
1127 | } | ||
1128 | |||
1129 | /* Something went wrong, fallback to basic rate for this band */ | ||
1130 | if ((mac80211_rix >= sc->curband->n_bitrates) || | ||
1131 | (mac80211_rix <= 0 )) | ||
1132 | mac80211_rix = 1; | ||
1133 | |||
1134 | return mac80211_rix; | ||
1135 | } | 1099 | } |
1136 | 1100 | ||
1137 | |||
1138 | |||
1139 | |||
1140 | /***************\ | 1101 | /***************\ |
1141 | * Buffers setup * | 1102 | * Buffers setup * |
1142 | \***************/ | 1103 | \***************/ |
@@ -1199,7 +1160,7 @@ ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) | |||
1199 | ds = bf->desc; | 1160 | ds = bf->desc; |
1200 | ds->ds_link = bf->daddr; /* link to self */ | 1161 | ds->ds_link = bf->daddr; /* link to self */ |
1201 | ds->ds_data = bf->skbaddr; | 1162 | ds->ds_data = bf->skbaddr; |
1202 | ath5k_hw_setup_rx_desc(ah, ds, | 1163 | ah->ah_setup_rx_desc(ah, ds, |
1203 | skb_tailroom(skb), /* buffer size */ | 1164 | skb_tailroom(skb), /* buffer size */ |
1204 | 0); | 1165 | 0); |
1205 | 1166 | ||
@@ -1218,7 +1179,9 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) | |||
1218 | struct sk_buff *skb = bf->skb; | 1179 | struct sk_buff *skb = bf->skb; |
1219 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 1180 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1220 | unsigned int pktlen, flags, keyidx = AR5K_TXKEYIX_INVALID; | 1181 | unsigned int pktlen, flags, keyidx = AR5K_TXKEYIX_INVALID; |
1221 | int ret; | 1182 | struct ieee80211_rate *rate; |
1183 | unsigned int mrr_rate[3], mrr_tries[3]; | ||
1184 | int i, ret; | ||
1222 | 1185 | ||
1223 | flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK; | 1186 | flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK; |
1224 | 1187 | ||
@@ -1233,7 +1196,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) | |||
1233 | 1196 | ||
1234 | if (info->control.hw_key) { | 1197 | if (info->control.hw_key) { |
1235 | keyidx = info->control.hw_key->hw_key_idx; | 1198 | keyidx = info->control.hw_key->hw_key_idx; |
1236 | pktlen += info->control.icv_len; | 1199 | pktlen += info->control.hw_key->icv_len; |
1237 | } | 1200 | } |
1238 | ret = ah->ah_setup_tx_desc(ah, ds, pktlen, | 1201 | ret = ah->ah_setup_tx_desc(ah, ds, pktlen, |
1239 | ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL, | 1202 | ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL, |
@@ -1243,6 +1206,22 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) | |||
1243 | if (ret) | 1206 | if (ret) |
1244 | goto err_unmap; | 1207 | goto err_unmap; |
1245 | 1208 | ||
1209 | memset(mrr_rate, 0, sizeof(mrr_rate)); | ||
1210 | memset(mrr_tries, 0, sizeof(mrr_tries)); | ||
1211 | for (i = 0; i < 3; i++) { | ||
1212 | rate = ieee80211_get_alt_retry_rate(sc->hw, info, i); | ||
1213 | if (!rate) | ||
1214 | break; | ||
1215 | |||
1216 | mrr_rate[i] = rate->hw_value; | ||
1217 | mrr_tries[i] = info->control.retries[i].limit; | ||
1218 | } | ||
1219 | |||
1220 | ah->ah_setup_mrr_tx_desc(ah, ds, | ||
1221 | mrr_rate[0], mrr_tries[0], | ||
1222 | mrr_rate[1], mrr_tries[1], | ||
1223 | mrr_rate[2], mrr_tries[2]); | ||
1224 | |||
1246 | ds->ds_link = 0; | 1225 | ds->ds_link = 0; |
1247 | ds->ds_data = bf->skbaddr; | 1226 | ds->ds_data = bf->skbaddr; |
1248 | 1227 | ||
@@ -1250,12 +1229,12 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) | |||
1250 | list_add_tail(&bf->list, &txq->q); | 1229 | list_add_tail(&bf->list, &txq->q); |
1251 | sc->tx_stats[txq->qnum].len++; | 1230 | sc->tx_stats[txq->qnum].len++; |
1252 | if (txq->link == NULL) /* is this first packet? */ | 1231 | if (txq->link == NULL) /* is this first packet? */ |
1253 | ath5k_hw_put_tx_buf(ah, txq->qnum, bf->daddr); | 1232 | ath5k_hw_set_txdp(ah, txq->qnum, bf->daddr); |
1254 | else /* no, so only link it */ | 1233 | else /* no, so only link it */ |
1255 | *txq->link = bf->daddr; | 1234 | *txq->link = bf->daddr; |
1256 | 1235 | ||
1257 | txq->link = &ds->ds_link; | 1236 | txq->link = &ds->ds_link; |
1258 | ath5k_hw_tx_start(ah, txq->qnum); | 1237 | ath5k_hw_start_tx_dma(ah, txq->qnum); |
1259 | mmiowb(); | 1238 | mmiowb(); |
1260 | spin_unlock_bh(&txq->lock); | 1239 | spin_unlock_bh(&txq->lock); |
1261 | 1240 | ||
@@ -1433,7 +1412,8 @@ ath5k_beaconq_config(struct ath5k_softc *sc) | |||
1433 | ret = ath5k_hw_get_tx_queueprops(ah, sc->bhalq, &qi); | 1412 | ret = ath5k_hw_get_tx_queueprops(ah, sc->bhalq, &qi); |
1434 | if (ret) | 1413 | if (ret) |
1435 | return ret; | 1414 | return ret; |
1436 | if (sc->opmode == IEEE80211_IF_TYPE_AP) { | 1415 | if (sc->opmode == NL80211_IFTYPE_AP || |
1416 | sc->opmode == NL80211_IFTYPE_MESH_POINT) { | ||
1437 | /* | 1417 | /* |
1438 | * Always burst out beacon and CAB traffic | 1418 | * Always burst out beacon and CAB traffic |
1439 | * (aifs = cwmin = cwmax = 0) | 1419 | * (aifs = cwmin = cwmax = 0) |
@@ -1441,7 +1421,7 @@ ath5k_beaconq_config(struct ath5k_softc *sc) | |||
1441 | qi.tqi_aifs = 0; | 1421 | qi.tqi_aifs = 0; |
1442 | qi.tqi_cw_min = 0; | 1422 | qi.tqi_cw_min = 0; |
1443 | qi.tqi_cw_max = 0; | 1423 | qi.tqi_cw_max = 0; |
1444 | } else if (sc->opmode == IEEE80211_IF_TYPE_IBSS) { | 1424 | } else if (sc->opmode == NL80211_IFTYPE_ADHOC) { |
1445 | /* | 1425 | /* |
1446 | * Adhoc mode; backoff between 0 and (2 * cw_min). | 1426 | * Adhoc mode; backoff between 0 and (2 * cw_min). |
1447 | */ | 1427 | */ |
@@ -1454,7 +1434,7 @@ ath5k_beaconq_config(struct ath5k_softc *sc) | |||
1454 | "beacon queueprops tqi_aifs:%d tqi_cw_min:%d tqi_cw_max:%d\n", | 1434 | "beacon queueprops tqi_aifs:%d tqi_cw_min:%d tqi_cw_max:%d\n", |
1455 | qi.tqi_aifs, qi.tqi_cw_min, qi.tqi_cw_max); | 1435 | qi.tqi_aifs, qi.tqi_cw_min, qi.tqi_cw_max); |
1456 | 1436 | ||
1457 | ret = ath5k_hw_setup_tx_queueprops(ah, sc->bhalq, &qi); | 1437 | ret = ath5k_hw_set_tx_queueprops(ah, sc->bhalq, &qi); |
1458 | if (ret) { | 1438 | if (ret) { |
1459 | ATH5K_ERR(sc, "%s: unable to update parameters for beacon " | 1439 | ATH5K_ERR(sc, "%s: unable to update parameters for beacon " |
1460 | "hardware queue!\n", __func__); | 1440 | "hardware queue!\n", __func__); |
@@ -1503,14 +1483,14 @@ ath5k_txq_cleanup(struct ath5k_softc *sc) | |||
1503 | /* don't touch the hardware if marked invalid */ | 1483 | /* don't touch the hardware if marked invalid */ |
1504 | ath5k_hw_stop_tx_dma(ah, sc->bhalq); | 1484 | ath5k_hw_stop_tx_dma(ah, sc->bhalq); |
1505 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "beacon queue %x\n", | 1485 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "beacon queue %x\n", |
1506 | ath5k_hw_get_tx_buf(ah, sc->bhalq)); | 1486 | ath5k_hw_get_txdp(ah, sc->bhalq)); |
1507 | for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) | 1487 | for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) |
1508 | if (sc->txqs[i].setup) { | 1488 | if (sc->txqs[i].setup) { |
1509 | ath5k_hw_stop_tx_dma(ah, sc->txqs[i].qnum); | 1489 | ath5k_hw_stop_tx_dma(ah, sc->txqs[i].qnum); |
1510 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "txq [%u] %x, " | 1490 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "txq [%u] %x, " |
1511 | "link %p\n", | 1491 | "link %p\n", |
1512 | sc->txqs[i].qnum, | 1492 | sc->txqs[i].qnum, |
1513 | ath5k_hw_get_tx_buf(ah, | 1493 | ath5k_hw_get_txdp(ah, |
1514 | sc->txqs[i].qnum), | 1494 | sc->txqs[i].qnum), |
1515 | sc->txqs[i].link); | 1495 | sc->txqs[i].link); |
1516 | } | 1496 | } |
@@ -1570,8 +1550,8 @@ ath5k_rx_start(struct ath5k_softc *sc) | |||
1570 | bf = list_first_entry(&sc->rxbuf, struct ath5k_buf, list); | 1550 | bf = list_first_entry(&sc->rxbuf, struct ath5k_buf, list); |
1571 | spin_unlock_bh(&sc->rxbuflock); | 1551 | spin_unlock_bh(&sc->rxbuflock); |
1572 | 1552 | ||
1573 | ath5k_hw_put_rx_buf(ah, bf->daddr); | 1553 | ath5k_hw_set_rxdp(ah, bf->daddr); |
1574 | ath5k_hw_start_rx(ah); /* enable recv descriptors */ | 1554 | ath5k_hw_start_rx_dma(ah); /* enable recv descriptors */ |
1575 | ath5k_mode_setup(sc); /* set filters, etc. */ | 1555 | ath5k_mode_setup(sc); /* set filters, etc. */ |
1576 | ath5k_hw_start_rx_pcu(ah); /* re-enable PCU/DMA engine */ | 1556 | ath5k_hw_start_rx_pcu(ah); /* re-enable PCU/DMA engine */ |
1577 | 1557 | ||
@@ -1588,7 +1568,7 @@ ath5k_rx_stop(struct ath5k_softc *sc) | |||
1588 | { | 1568 | { |
1589 | struct ath5k_hw *ah = sc->ah; | 1569 | struct ath5k_hw *ah = sc->ah; |
1590 | 1570 | ||
1591 | ath5k_hw_stop_pcu_recv(ah); /* disable PCU */ | 1571 | ath5k_hw_stop_rx_pcu(ah); /* disable PCU */ |
1592 | ath5k_hw_set_rx_filter(ah, 0); /* clear recv filter */ | 1572 | ath5k_hw_set_rx_filter(ah, 0); /* clear recv filter */ |
1593 | ath5k_hw_stop_rx_dma(ah); /* disable DMA engine */ | 1573 | ath5k_hw_stop_rx_dma(ah); /* disable DMA engine */ |
1594 | 1574 | ||
@@ -1602,7 +1582,7 @@ ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds, | |||
1602 | struct sk_buff *skb, struct ath5k_rx_status *rs) | 1582 | struct sk_buff *skb, struct ath5k_rx_status *rs) |
1603 | { | 1583 | { |
1604 | struct ieee80211_hdr *hdr = (void *)skb->data; | 1584 | struct ieee80211_hdr *hdr = (void *)skb->data; |
1605 | unsigned int keyix, hlen = ieee80211_get_hdrlen_from_skb(skb); | 1585 | unsigned int keyix, hlen; |
1606 | 1586 | ||
1607 | if (!(rs->rs_status & AR5K_RXERR_DECRYPT) && | 1587 | if (!(rs->rs_status & AR5K_RXERR_DECRYPT) && |
1608 | rs->rs_keyix != AR5K_RXKEYIX_INVALID) | 1588 | rs->rs_keyix != AR5K_RXKEYIX_INVALID) |
@@ -1611,6 +1591,7 @@ ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds, | |||
1611 | /* Apparently when a default key is used to decrypt the packet | 1591 | /* Apparently when a default key is used to decrypt the packet |
1612 | the hw does not set the index used to decrypt. In such cases | 1592 | the hw does not set the index used to decrypt. In such cases |
1613 | get the index from the packet. */ | 1593 | get the index from the packet. */ |
1594 | hlen = ieee80211_hdrlen(hdr->frame_control); | ||
1614 | if (ieee80211_has_protected(hdr->frame_control) && | 1595 | if (ieee80211_has_protected(hdr->frame_control) && |
1615 | !(rs->rs_status & AR5K_RXERR_DECRYPT) && | 1596 | !(rs->rs_status & AR5K_RXERR_DECRYPT) && |
1616 | skb->len >= hlen + 4) { | 1597 | skb->len >= hlen + 4) { |
@@ -1768,7 +1749,7 @@ ath5k_tasklet_rx(unsigned long data) | |||
1768 | /* let crypto-error packets fall through in MNTR */ | 1749 | /* let crypto-error packets fall through in MNTR */ |
1769 | if ((rs.rs_status & | 1750 | if ((rs.rs_status & |
1770 | ~(AR5K_RXERR_DECRYPT|AR5K_RXERR_MIC)) || | 1751 | ~(AR5K_RXERR_DECRYPT|AR5K_RXERR_MIC)) || |
1771 | sc->opmode != IEEE80211_IF_TYPE_MNTR) | 1752 | sc->opmode != NL80211_IFTYPE_MONITOR) |
1772 | goto next; | 1753 | goto next; |
1773 | } | 1754 | } |
1774 | accept: | 1755 | accept: |
@@ -1824,10 +1805,14 @@ accept: | |||
1824 | rxs.rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate); | 1805 | rxs.rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate); |
1825 | rxs.flag |= ath5k_rx_decrypted(sc, ds, skb, &rs); | 1806 | rxs.flag |= ath5k_rx_decrypted(sc, ds, skb, &rs); |
1826 | 1807 | ||
1808 | if (rxs.rate_idx >= 0 && rs.rs_rate == | ||
1809 | sc->curband->bitrates[rxs.rate_idx].hw_value_short) | ||
1810 | rxs.flag |= RX_FLAG_SHORTPRE; | ||
1811 | |||
1827 | ath5k_debug_dump_skb(sc, skb, "RX ", 0); | 1812 | ath5k_debug_dump_skb(sc, skb, "RX ", 0); |
1828 | 1813 | ||
1829 | /* check beacons in IBSS mode */ | 1814 | /* check beacons in IBSS mode */ |
1830 | if (sc->opmode == IEEE80211_IF_TYPE_IBSS) | 1815 | if (sc->opmode == NL80211_IFTYPE_ADHOC) |
1831 | ath5k_check_ibss_tsf(sc, skb, &rxs); | 1816 | ath5k_check_ibss_tsf(sc, skb, &rxs); |
1832 | 1817 | ||
1833 | __ieee80211_rx(sc->hw, skb, &rxs); | 1818 | __ieee80211_rx(sc->hw, skb, &rxs); |
@@ -1853,7 +1838,7 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) | |||
1853 | struct ath5k_desc *ds; | 1838 | struct ath5k_desc *ds; |
1854 | struct sk_buff *skb; | 1839 | struct sk_buff *skb; |
1855 | struct ieee80211_tx_info *info; | 1840 | struct ieee80211_tx_info *info; |
1856 | int ret; | 1841 | int i, ret; |
1857 | 1842 | ||
1858 | spin_lock(&txq->lock); | 1843 | spin_lock(&txq->lock); |
1859 | list_for_each_entry_safe(bf, bf0, &txq->q, list) { | 1844 | list_for_each_entry_safe(bf, bf0, &txq->q, list) { |
@@ -1875,7 +1860,25 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) | |||
1875 | pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, | 1860 | pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, |
1876 | PCI_DMA_TODEVICE); | 1861 | PCI_DMA_TODEVICE); |
1877 | 1862 | ||
1878 | info->status.retry_count = ts.ts_shortretry + ts.ts_longretry / 6; | 1863 | memset(&info->status, 0, sizeof(info->status)); |
1864 | info->tx_rate_idx = ath5k_hw_to_driver_rix(sc, | ||
1865 | ts.ts_rate[ts.ts_final_idx]); | ||
1866 | info->status.retry_count = ts.ts_longretry; | ||
1867 | |||
1868 | for (i = 0; i < 4; i++) { | ||
1869 | struct ieee80211_tx_altrate *r = | ||
1870 | &info->status.retries[i]; | ||
1871 | |||
1872 | if (ts.ts_rate[i]) { | ||
1873 | r->rate_idx = ath5k_hw_to_driver_rix(sc, ts.ts_rate[i]); | ||
1874 | r->limit = ts.ts_retry[i]; | ||
1875 | } else { | ||
1876 | r->rate_idx = -1; | ||
1877 | r->limit = 0; | ||
1878 | } | ||
1879 | } | ||
1880 | |||
1881 | info->status.excessive_retries = 0; | ||
1879 | if (unlikely(ts.ts_status)) { | 1882 | if (unlikely(ts.ts_status)) { |
1880 | sc->ll_stats.dot11ACKFailureCount++; | 1883 | sc->ll_stats.dot11ACKFailureCount++; |
1881 | if (ts.ts_status & AR5K_TXERR_XRETRY) | 1884 | if (ts.ts_status & AR5K_TXERR_XRETRY) |
@@ -1942,7 +1945,7 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) | |||
1942 | ds = bf->desc; | 1945 | ds = bf->desc; |
1943 | 1946 | ||
1944 | flags = AR5K_TXDESC_NOACK; | 1947 | flags = AR5K_TXDESC_NOACK; |
1945 | if (sc->opmode == IEEE80211_IF_TYPE_IBSS && ath5k_hw_hasveol(ah)) { | 1948 | if (sc->opmode == NL80211_IFTYPE_ADHOC && ath5k_hw_hasveol(ah)) { |
1946 | ds->ds_link = bf->daddr; /* self-linked */ | 1949 | ds->ds_link = bf->daddr; /* self-linked */ |
1947 | flags |= AR5K_TXDESC_VEOL; | 1950 | flags |= AR5K_TXDESC_VEOL; |
1948 | /* | 1951 | /* |
@@ -1991,8 +1994,8 @@ ath5k_beacon_send(struct ath5k_softc *sc) | |||
1991 | 1994 | ||
1992 | ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "in beacon_send\n"); | 1995 | ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "in beacon_send\n"); |
1993 | 1996 | ||
1994 | if (unlikely(bf->skb == NULL || sc->opmode == IEEE80211_IF_TYPE_STA || | 1997 | if (unlikely(bf->skb == NULL || sc->opmode == NL80211_IFTYPE_STATION || |
1995 | sc->opmode == IEEE80211_IF_TYPE_MNTR)) { | 1998 | sc->opmode == NL80211_IFTYPE_MONITOR)) { |
1996 | ATH5K_WARN(sc, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL); | 1999 | ATH5K_WARN(sc, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL); |
1997 | return; | 2000 | return; |
1998 | } | 2001 | } |
@@ -2032,8 +2035,8 @@ ath5k_beacon_send(struct ath5k_softc *sc) | |||
2032 | /* NB: hw still stops DMA, so proceed */ | 2035 | /* NB: hw still stops DMA, so proceed */ |
2033 | } | 2036 | } |
2034 | 2037 | ||
2035 | ath5k_hw_put_tx_buf(ah, sc->bhalq, bf->daddr); | 2038 | ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr); |
2036 | ath5k_hw_tx_start(ah, sc->bhalq); | 2039 | ath5k_hw_start_tx_dma(ah, sc->bhalq); |
2037 | ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n", | 2040 | ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n", |
2038 | sc->bhalq, (unsigned long long)bf->daddr, bf->desc); | 2041 | sc->bhalq, (unsigned long long)bf->daddr, bf->desc); |
2039 | 2042 | ||
@@ -2162,13 +2165,13 @@ ath5k_beacon_config(struct ath5k_softc *sc) | |||
2162 | { | 2165 | { |
2163 | struct ath5k_hw *ah = sc->ah; | 2166 | struct ath5k_hw *ah = sc->ah; |
2164 | 2167 | ||
2165 | ath5k_hw_set_intr(ah, 0); | 2168 | ath5k_hw_set_imr(ah, 0); |
2166 | sc->bmisscount = 0; | 2169 | sc->bmisscount = 0; |
2167 | sc->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA); | 2170 | sc->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA); |
2168 | 2171 | ||
2169 | if (sc->opmode == IEEE80211_IF_TYPE_STA) { | 2172 | if (sc->opmode == NL80211_IFTYPE_STATION) { |
2170 | sc->imask |= AR5K_INT_BMISS; | 2173 | sc->imask |= AR5K_INT_BMISS; |
2171 | } else if (sc->opmode == IEEE80211_IF_TYPE_IBSS) { | 2174 | } else if (sc->opmode == NL80211_IFTYPE_ADHOC) { |
2172 | /* | 2175 | /* |
2173 | * In IBSS mode we use a self-linked tx descriptor and let the | 2176 | * In IBSS mode we use a self-linked tx descriptor and let the |
2174 | * hardware send the beacons automatically. We have to load it | 2177 | * hardware send the beacons automatically. We have to load it |
@@ -2188,7 +2191,7 @@ ath5k_beacon_config(struct ath5k_softc *sc) | |||
2188 | } | 2191 | } |
2189 | /* TODO else AP */ | 2192 | /* TODO else AP */ |
2190 | 2193 | ||
2191 | ath5k_hw_set_intr(ah, sc->imask); | 2194 | ath5k_hw_set_imr(ah, sc->imask); |
2192 | } | 2195 | } |
2193 | 2196 | ||
2194 | 2197 | ||
@@ -2220,36 +2223,13 @@ ath5k_init(struct ath5k_softc *sc) | |||
2220 | */ | 2223 | */ |
2221 | sc->curchan = sc->hw->conf.channel; | 2224 | sc->curchan = sc->hw->conf.channel; |
2222 | sc->curband = &sc->sbands[sc->curchan->band]; | 2225 | sc->curband = &sc->sbands[sc->curchan->band]; |
2223 | ret = ath5k_hw_reset(sc->ah, sc->opmode, sc->curchan, false); | ||
2224 | if (ret) { | ||
2225 | ATH5K_ERR(sc, "unable to reset hardware: %d\n", ret); | ||
2226 | goto done; | ||
2227 | } | ||
2228 | /* | ||
2229 | * This is needed only to setup initial state | ||
2230 | * but it's best done after a reset. | ||
2231 | */ | ||
2232 | ath5k_hw_set_txpower_limit(sc->ah, 0); | ||
2233 | |||
2234 | /* | ||
2235 | * Setup the hardware after reset: the key cache | ||
2236 | * is filled as needed and the receive engine is | ||
2237 | * set going. Frame transmit is handled entirely | ||
2238 | * in the frame output path; there's nothing to do | ||
2239 | * here except setup the interrupt mask. | ||
2240 | */ | ||
2241 | ret = ath5k_rx_start(sc); | ||
2242 | if (ret) | ||
2243 | goto done; | ||
2244 | |||
2245 | /* | ||
2246 | * Enable interrupts. | ||
2247 | */ | ||
2248 | sc->imask = AR5K_INT_RX | AR5K_INT_TX | AR5K_INT_RXEOL | | 2226 | sc->imask = AR5K_INT_RX | AR5K_INT_TX | AR5K_INT_RXEOL | |
2249 | AR5K_INT_RXORN | AR5K_INT_FATAL | AR5K_INT_GLOBAL | | 2227 | AR5K_INT_RXORN | AR5K_INT_FATAL | AR5K_INT_GLOBAL | |
2250 | AR5K_INT_MIB; | 2228 | AR5K_INT_MIB; |
2229 | ret = ath5k_reset(sc, false, false); | ||
2230 | if (ret) | ||
2231 | goto done; | ||
2251 | 2232 | ||
2252 | ath5k_hw_set_intr(sc->ah, sc->imask); | ||
2253 | /* Set ack to be sent at low bit-rates */ | 2233 | /* Set ack to be sent at low bit-rates */ |
2254 | ath5k_hw_set_ack_bitrate_high(sc->ah, false); | 2234 | ath5k_hw_set_ack_bitrate_high(sc->ah, false); |
2255 | 2235 | ||
@@ -2290,7 +2270,7 @@ ath5k_stop_locked(struct ath5k_softc *sc) | |||
2290 | 2270 | ||
2291 | if (!test_bit(ATH_STAT_INVALID, sc->status)) { | 2271 | if (!test_bit(ATH_STAT_INVALID, sc->status)) { |
2292 | ath5k_led_off(sc); | 2272 | ath5k_led_off(sc); |
2293 | ath5k_hw_set_intr(ah, 0); | 2273 | ath5k_hw_set_imr(ah, 0); |
2294 | synchronize_irq(sc->pdev->irq); | 2274 | synchronize_irq(sc->pdev->irq); |
2295 | } | 2275 | } |
2296 | ath5k_txq_cleanup(sc); | 2276 | ath5k_txq_cleanup(sc); |
@@ -2396,7 +2376,7 @@ ath5k_intr(int irq, void *dev_id) | |||
2396 | * transmission time) in order to detect wether | 2376 | * transmission time) in order to detect wether |
2397 | * automatic TSF updates happened. | 2377 | * automatic TSF updates happened. |
2398 | */ | 2378 | */ |
2399 | if (sc->opmode == IEEE80211_IF_TYPE_IBSS) { | 2379 | if (sc->opmode == NL80211_IFTYPE_ADHOC) { |
2400 | /* XXX: only if VEOL suppported */ | 2380 | /* XXX: only if VEOL suppported */ |
2401 | u64 tsf = ath5k_hw_get_tsf64(ah); | 2381 | u64 tsf = ath5k_hw_get_tsf64(ah); |
2402 | sc->nexttbtt += sc->bintval; | 2382 | sc->nexttbtt += sc->bintval; |
@@ -2451,7 +2431,7 @@ ath5k_tasklet_reset(unsigned long data) | |||
2451 | { | 2431 | { |
2452 | struct ath5k_softc *sc = (void *)data; | 2432 | struct ath5k_softc *sc = (void *)data; |
2453 | 2433 | ||
2454 | ath5k_reset(sc->hw); | 2434 | ath5k_reset_wake(sc); |
2455 | } | 2435 | } |
2456 | 2436 | ||
2457 | /* | 2437 | /* |
@@ -2474,7 +2454,7 @@ ath5k_calibrate(unsigned long data) | |||
2474 | * to load new gain values. | 2454 | * to load new gain values. |
2475 | */ | 2455 | */ |
2476 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "calibration, resetting\n"); | 2456 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "calibration, resetting\n"); |
2477 | ath5k_reset(sc->hw); | 2457 | ath5k_reset_wake(sc); |
2478 | } | 2458 | } |
2479 | if (ath5k_hw_phy_calibrate(ah, sc->curchan)) | 2459 | if (ath5k_hw_phy_calibrate(ah, sc->curchan)) |
2480 | ATH5K_ERR(sc, "calibration of channel %u failed\n", | 2460 | ATH5K_ERR(sc, "calibration of channel %u failed\n", |
@@ -2626,7 +2606,7 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
2626 | 2606 | ||
2627 | ath5k_debug_dump_skb(sc, skb, "TX ", 1); | 2607 | ath5k_debug_dump_skb(sc, skb, "TX ", 1); |
2628 | 2608 | ||
2629 | if (sc->opmode == IEEE80211_IF_TYPE_MNTR) | 2609 | if (sc->opmode == NL80211_IFTYPE_MONITOR) |
2630 | ATH5K_DBG(sc, ATH5K_DEBUG_XMIT, "tx in monitor (scan?)\n"); | 2610 | ATH5K_DBG(sc, ATH5K_DEBUG_XMIT, "tx in monitor (scan?)\n"); |
2631 | 2611 | ||
2632 | /* | 2612 | /* |
@@ -2675,48 +2655,67 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
2675 | } | 2655 | } |
2676 | 2656 | ||
2677 | static int | 2657 | static int |
2678 | ath5k_reset(struct ieee80211_hw *hw) | 2658 | ath5k_reset(struct ath5k_softc *sc, bool stop, bool change_channel) |
2679 | { | 2659 | { |
2680 | struct ath5k_softc *sc = hw->priv; | ||
2681 | struct ath5k_hw *ah = sc->ah; | 2660 | struct ath5k_hw *ah = sc->ah; |
2682 | int ret; | 2661 | int ret; |
2683 | 2662 | ||
2684 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n"); | 2663 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n"); |
2685 | 2664 | ||
2686 | ath5k_hw_set_intr(ah, 0); | 2665 | if (stop) { |
2687 | ath5k_txq_cleanup(sc); | 2666 | ath5k_hw_set_imr(ah, 0); |
2688 | ath5k_rx_stop(sc); | 2667 | ath5k_txq_cleanup(sc); |
2689 | 2668 | ath5k_rx_stop(sc); | |
2669 | } | ||
2690 | ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, true); | 2670 | ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, true); |
2691 | if (unlikely(ret)) { | 2671 | if (ret) { |
2692 | ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret); | 2672 | ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret); |
2693 | goto err; | 2673 | goto err; |
2694 | } | 2674 | } |
2675 | |||
2676 | /* | ||
2677 | * This is needed only to setup initial state | ||
2678 | * but it's best done after a reset. | ||
2679 | */ | ||
2695 | ath5k_hw_set_txpower_limit(sc->ah, 0); | 2680 | ath5k_hw_set_txpower_limit(sc->ah, 0); |
2696 | 2681 | ||
2697 | ret = ath5k_rx_start(sc); | 2682 | ret = ath5k_rx_start(sc); |
2698 | if (unlikely(ret)) { | 2683 | if (ret) { |
2699 | ATH5K_ERR(sc, "can't start recv logic\n"); | 2684 | ATH5K_ERR(sc, "can't start recv logic\n"); |
2700 | goto err; | 2685 | goto err; |
2701 | } | 2686 | } |
2687 | |||
2702 | /* | 2688 | /* |
2703 | * We may be doing a reset in response to an ioctl | 2689 | * Change channels and update the h/w rate map if we're switching; |
2704 | * that changes the channel so update any state that | 2690 | * e.g. 11a to 11b/g. |
2705 | * might change as a result. | 2691 | * |
2692 | * We may be doing a reset in response to an ioctl that changes the | ||
2693 | * channel so update any state that might change as a result. | ||
2706 | * | 2694 | * |
2707 | * XXX needed? | 2695 | * XXX needed? |
2708 | */ | 2696 | */ |
2709 | /* ath5k_chan_change(sc, c); */ | 2697 | /* ath5k_chan_change(sc, c); */ |
2710 | ath5k_beacon_config(sc); | ||
2711 | /* intrs are started by ath5k_beacon_config */ | ||
2712 | 2698 | ||
2713 | ieee80211_wake_queues(hw); | 2699 | ath5k_beacon_config(sc); |
2700 | /* intrs are enabled by ath5k_beacon_config */ | ||
2714 | 2701 | ||
2715 | return 0; | 2702 | return 0; |
2716 | err: | 2703 | err: |
2717 | return ret; | 2704 | return ret; |
2718 | } | 2705 | } |
2719 | 2706 | ||
2707 | static int | ||
2708 | ath5k_reset_wake(struct ath5k_softc *sc) | ||
2709 | { | ||
2710 | int ret; | ||
2711 | |||
2712 | ret = ath5k_reset(sc, true, true); | ||
2713 | if (!ret) | ||
2714 | ieee80211_wake_queues(sc->hw); | ||
2715 | |||
2716 | return ret; | ||
2717 | } | ||
2718 | |||
2720 | static int ath5k_start(struct ieee80211_hw *hw) | 2719 | static int ath5k_start(struct ieee80211_hw *hw) |
2721 | { | 2720 | { |
2722 | return ath5k_init(hw->priv); | 2721 | return ath5k_init(hw->priv); |
@@ -2742,9 +2741,9 @@ static int ath5k_add_interface(struct ieee80211_hw *hw, | |||
2742 | sc->vif = conf->vif; | 2741 | sc->vif = conf->vif; |
2743 | 2742 | ||
2744 | switch (conf->type) { | 2743 | switch (conf->type) { |
2745 | case IEEE80211_IF_TYPE_STA: | 2744 | case NL80211_IFTYPE_STATION: |
2746 | case IEEE80211_IF_TYPE_IBSS: | 2745 | case NL80211_IFTYPE_ADHOC: |
2747 | case IEEE80211_IF_TYPE_MNTR: | 2746 | case NL80211_IFTYPE_MONITOR: |
2748 | sc->opmode = conf->type; | 2747 | sc->opmode = conf->type; |
2749 | break; | 2748 | break; |
2750 | default: | 2749 | default: |
@@ -2815,7 +2814,7 @@ ath5k_config_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
2815 | } | 2814 | } |
2816 | 2815 | ||
2817 | if (conf->changed & IEEE80211_IFCC_BEACON && | 2816 | if (conf->changed & IEEE80211_IFCC_BEACON && |
2818 | vif->type == IEEE80211_IF_TYPE_IBSS) { | 2817 | vif->type == NL80211_IFTYPE_ADHOC) { |
2819 | struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); | 2818 | struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); |
2820 | if (!beacon) { | 2819 | if (!beacon) { |
2821 | ret = -ENOMEM; | 2820 | ret = -ENOMEM; |
@@ -2827,7 +2826,7 @@ ath5k_config_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
2827 | 2826 | ||
2828 | mutex_unlock(&sc->lock); | 2827 | mutex_unlock(&sc->lock); |
2829 | 2828 | ||
2830 | return ath5k_reset(hw); | 2829 | return ath5k_reset_wake(sc); |
2831 | unlock: | 2830 | unlock: |
2832 | mutex_unlock(&sc->lock); | 2831 | mutex_unlock(&sc->lock); |
2833 | return ret; | 2832 | return ret; |
@@ -2934,16 +2933,17 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw, | |||
2934 | 2933 | ||
2935 | /* XXX move these to mac80211, and add a beacon IFF flag to mac80211 */ | 2934 | /* XXX move these to mac80211, and add a beacon IFF flag to mac80211 */ |
2936 | 2935 | ||
2937 | if (sc->opmode == IEEE80211_IF_TYPE_MNTR) | 2936 | if (sc->opmode == NL80211_IFTYPE_MONITOR) |
2938 | rfilt |= AR5K_RX_FILTER_CONTROL | AR5K_RX_FILTER_BEACON | | 2937 | rfilt |= AR5K_RX_FILTER_CONTROL | AR5K_RX_FILTER_BEACON | |
2939 | AR5K_RX_FILTER_PROBEREQ | AR5K_RX_FILTER_PROM; | 2938 | AR5K_RX_FILTER_PROBEREQ | AR5K_RX_FILTER_PROM; |
2940 | if (sc->opmode != IEEE80211_IF_TYPE_STA) | 2939 | if (sc->opmode != NL80211_IFTYPE_STATION) |
2941 | rfilt |= AR5K_RX_FILTER_PROBEREQ; | 2940 | rfilt |= AR5K_RX_FILTER_PROBEREQ; |
2942 | if (sc->opmode != IEEE80211_IF_TYPE_AP && | 2941 | if (sc->opmode != NL80211_IFTYPE_AP && |
2942 | sc->opmode != NL80211_IFTYPE_MESH_POINT && | ||
2943 | test_bit(ATH_STAT_PROMISC, sc->status)) | 2943 | test_bit(ATH_STAT_PROMISC, sc->status)) |
2944 | rfilt |= AR5K_RX_FILTER_PROM; | 2944 | rfilt |= AR5K_RX_FILTER_PROM; |
2945 | if (sc->opmode == IEEE80211_IF_TYPE_STA || | 2945 | if (sc->opmode == NL80211_IFTYPE_STATION || |
2946 | sc->opmode == IEEE80211_IF_TYPE_IBSS) { | 2946 | sc->opmode == NL80211_IFTYPE_ADHOC) { |
2947 | rfilt |= AR5K_RX_FILTER_BEACON; | 2947 | rfilt |= AR5K_RX_FILTER_BEACON; |
2948 | } | 2948 | } |
2949 | 2949 | ||
@@ -3048,7 +3048,7 @@ ath5k_reset_tsf(struct ieee80211_hw *hw) | |||
3048 | * in IBSS mode we need to update the beacon timers too. | 3048 | * in IBSS mode we need to update the beacon timers too. |
3049 | * this will also reset the TSF if we call it with 0 | 3049 | * this will also reset the TSF if we call it with 0 |
3050 | */ | 3050 | */ |
3051 | if (sc->opmode == IEEE80211_IF_TYPE_IBSS) | 3051 | if (sc->opmode == NL80211_IFTYPE_ADHOC) |
3052 | ath5k_beacon_update_timers(sc, 0); | 3052 | ath5k_beacon_update_timers(sc, 0); |
3053 | else | 3053 | else |
3054 | ath5k_hw_reset_tsf(sc->ah); | 3054 | ath5k_hw_reset_tsf(sc->ah); |
@@ -3063,7 +3063,7 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
3063 | 3063 | ||
3064 | ath5k_debug_dump_skb(sc, skb, "BC ", 1); | 3064 | ath5k_debug_dump_skb(sc, skb, "BC ", 1); |
3065 | 3065 | ||
3066 | if (sc->opmode != IEEE80211_IF_TYPE_IBSS) { | 3066 | if (sc->opmode != NL80211_IFTYPE_ADHOC) { |
3067 | ret = -EIO; | 3067 | ret = -EIO; |
3068 | goto end; | 3068 | goto end; |
3069 | } | 3069 | } |