aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSujith <Sujith.Manoharan@atheros.com>2008-08-07 01:24:57 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-08-07 09:49:44 -0400
commit86b89eed9aca2a4a335b9c1bf7380f9183db431f (patch)
treede9861a36de404fc74d8d7fbb87bd66e73891de4 /drivers
parent3b95978ddadbab594aad6280bfa660a49948af86 (diff)
ath9k: Revamp wireless mode usage
Use a single enum for managing modes, store supported modes by the HW in a bitmask. Register legacy rates with mac80211 only at init. Signed-off-by: Sujith Manoharan <Sujith.Manoharan@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/ath9k/ath9k.h48
-rw-r--r--drivers/net/wireless/ath9k/beacon.c2
-rw-r--r--drivers/net/wireless/ath9k/core.c150
-rw-r--r--drivers/net/wireless/ath9k/core.h2
-rw-r--r--drivers/net/wireless/ath9k/hw.c79
-rw-r--r--drivers/net/wireless/ath9k/main.c79
-rw-r--r--drivers/net/wireless/ath9k/rc.c30
-rw-r--r--drivers/net/wireless/ath9k/rc.h2
-rw-r--r--drivers/net/wireless/ath9k/regd.c107
-rw-r--r--drivers/net/wireless/ath9k/regd.h10
-rw-r--r--drivers/net/wireless/ath9k/regd_common.h18
-rw-r--r--drivers/net/wireless/ath9k/xmit.c2
12 files changed, 205 insertions, 324 deletions
diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h
index 82e71f9f316a..d1b0fbae5a32 100644
--- a/drivers/net/wireless/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath9k/ath9k.h
@@ -147,6 +147,19 @@ struct ath_desc {
147 147
148#define ATH9K_RXDESC_INTREQ 0x0020 148#define ATH9K_RXDESC_INTREQ 0x0020
149 149
150enum wireless_mode {
151 ATH9K_MODE_11A = 0,
152 ATH9K_MODE_11B = 2,
153 ATH9K_MODE_11G = 3,
154 ATH9K_MODE_11NA_HT20 = 6,
155 ATH9K_MODE_11NG_HT20 = 7,
156 ATH9K_MODE_11NA_HT40PLUS = 8,
157 ATH9K_MODE_11NA_HT40MINUS = 9,
158 ATH9K_MODE_11NG_HT40PLUS = 10,
159 ATH9K_MODE_11NG_HT40MINUS = 11,
160 ATH9K_MODE_MAX
161};
162
150enum ath9k_hw_caps { 163enum ath9k_hw_caps {
151 ATH9K_HW_CAP_CHAN_SPREAD = BIT(0), 164 ATH9K_HW_CAP_CHAN_SPREAD = BIT(0),
152 ATH9K_HW_CAP_MIC_AESCCM = BIT(1), 165 ATH9K_HW_CAP_MIC_AESCCM = BIT(1),
@@ -190,7 +203,7 @@ enum ath9k_capability_type {
190 203
191struct ath9k_hw_capabilities { 204struct ath9k_hw_capabilities {
192 u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */ 205 u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */
193 u32 wireless_modes; 206 DECLARE_BITMAP(wireless_modes, ATH9K_MODE_MAX); /* ATH9K_MODE_* */
194 u16 total_queues; 207 u16 total_queues;
195 u16 keycache_size; 208 u16 keycache_size;
196 u16 low_5ghz_chan, high_5ghz_chan; 209 u16 low_5ghz_chan, high_5ghz_chan;
@@ -813,37 +826,6 @@ struct ath_hal {
813#endif 826#endif
814}; 827};
815 828
816enum wireless_mode {
817 WIRELESS_MODE_11a = 0,
818 WIRELESS_MODE_11b = 2,
819 WIRELESS_MODE_11g = 3,
820 WIRELESS_MODE_11NA_HT20 = 6,
821 WIRELESS_MODE_11NG_HT20 = 7,
822 WIRELESS_MODE_11NA_HT40PLUS = 8,
823 WIRELESS_MODE_11NA_HT40MINUS = 9,
824 WIRELESS_MODE_11NG_HT40PLUS = 10,
825 WIRELESS_MODE_11NG_HT40MINUS = 11,
826 WIRELESS_MODE_MAX
827};
828
829enum {
830 ATH9K_MODE_SEL_11A = 0x00001,
831 ATH9K_MODE_SEL_11B = 0x00002,
832 ATH9K_MODE_SEL_11G = 0x00004,
833 ATH9K_MODE_SEL_11NG_HT20 = 0x00008,
834 ATH9K_MODE_SEL_11NA_HT20 = 0x00010,
835 ATH9K_MODE_SEL_11NG_HT40PLUS = 0x00020,
836 ATH9K_MODE_SEL_11NG_HT40MINUS = 0x00040,
837 ATH9K_MODE_SEL_11NA_HT40PLUS = 0x00080,
838 ATH9K_MODE_SEL_11NA_HT40MINUS = 0x00100,
839 ATH9K_MODE_SEL_2GHZ = (ATH9K_MODE_SEL_11B |
840 ATH9K_MODE_SEL_11G |
841 ATH9K_MODE_SEL_11NG_HT20),
842 ATH9K_MODE_SEL_5GHZ = (ATH9K_MODE_SEL_11A |
843 ATH9K_MODE_SEL_11NA_HT20),
844 ATH9K_MODE_SEL_ALL = 0xffffffff
845};
846
847struct chan_centers { 829struct chan_centers {
848 u16 synth_center; 830 u16 synth_center;
849 u16 ctl_center; 831 u16 ctl_center;
@@ -865,7 +847,7 @@ bool ath9k_regd_init_channels(struct ath_hal *ah,
865 u32 maxchans, u32 *nchans, 847 u32 maxchans, u32 *nchans,
866 u8 *regclassids, 848 u8 *regclassids,
867 u32 maxregids, u32 *nregids, 849 u32 maxregids, u32 *nregids,
868 u16 cc, u32 modeSelect, 850 u16 cc,
869 bool enableOutdoor, 851 bool enableOutdoor,
870 bool enableExtendedChannels); 852 bool enableExtendedChannels);
871u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags); 853u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags);
diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c
index 6e6538b31a4c..caf569401a34 100644
--- a/drivers/net/wireless/ath9k/beacon.c
+++ b/drivers/net/wireless/ath9k/beacon.c
@@ -108,7 +108,7 @@ static void ath_beacon_setup(struct ath_softc *sc,
108 * Calculate rate code. 108 * Calculate rate code.
109 * XXX everything at min xmit rate 109 * XXX everything at min xmit rate
110 */ 110 */
111 rix = sc->sc_minrateix; 111 rix = 0;
112 rt = sc->sc_currates; 112 rt = sc->sc_currates;
113 rate = rt->info[rix].rateCode; 113 rate = rt->info[rix].rateCode;
114 if (sc->sc_flags & ATH_PREAMBLE_SHORT) 114 if (sc->sc_flags & ATH_PREAMBLE_SHORT)
diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c
index f7bf0783f3be..f6c45288d0e7 100644
--- a/drivers/net/wireless/ath9k/core.c
+++ b/drivers/net/wireless/ath9k/core.c
@@ -64,7 +64,7 @@ static void ath_setcurmode(struct ath_softc *sc, enum wireless_mode mode)
64 int i; 64 int i;
65 65
66 memset(sc->sc_rixmap, 0xff, sizeof(sc->sc_rixmap)); 66 memset(sc->sc_rixmap, 0xff, sizeof(sc->sc_rixmap));
67 rt = sc->sc_rates[mode]; 67 rt = ath9k_hw_getratetable(sc->sc_ah, mode);
68 BUG_ON(!rt); 68 BUG_ON(!rt);
69 69
70 for (i = 0; i < rt->rateCount; i++) 70 for (i = 0; i < rt->rateCount; i++)
@@ -96,76 +96,52 @@ static void ath_setcurmode(struct ath_softc *sc, enum wireless_mode mode)
96 * 11g, otherwise at 1Mb/s. 96 * 11g, otherwise at 1Mb/s.
97 * XXX select protection rate index from rate table. 97 * XXX select protection rate index from rate table.
98 */ 98 */
99 sc->sc_protrix = (mode == WIRELESS_MODE_11g ? 1 : 0); 99 sc->sc_protrix = (mode == ATH9K_MODE_11G ? 1 : 0);
100 /* rate index used to send mgt frames */
101 sc->sc_minrateix = 0;
102} 100}
103 101
104/* 102/*
105 * Select Rate Table 103 * Set up rate table (legacy rates)
106 * 104 */
107 * Based on the wireless mode passed in, the rate table in the ATH object 105static void ath_setup_rates(struct ath_softc *sc, enum ieee80211_band band)
108 * is set to the mode specific rate table. This also calls the callback
109 * function to set the rate in the protocol layer object.
110*/
111
112static int ath_rate_setup(struct ath_softc *sc, enum wireless_mode mode)
113{ 106{
114 struct ath_hal *ah = sc->sc_ah; 107 struct ath_hal *ah = sc->sc_ah;
115 const struct ath9k_rate_table *rt; 108 const struct ath9k_rate_table *rt = NULL;
116 109 struct ieee80211_supported_band *sband;
117 switch (mode) { 110 struct ieee80211_rate *rate;
118 case WIRELESS_MODE_11a: 111 int i, maxrates;
119 sc->sc_rates[mode] = 112
120 ath9k_hw_getratetable(ah, ATH9K_MODE_SEL_11A); 113 switch (band) {
121 break; 114 case IEEE80211_BAND_2GHZ:
122 case WIRELESS_MODE_11b: 115 rt = ath9k_hw_getratetable(ah, ATH9K_MODE_11G);
123 sc->sc_rates[mode] =
124 ath9k_hw_getratetable(ah, ATH9K_MODE_SEL_11B);
125 break; 116 break;
126 case WIRELESS_MODE_11g: 117 case IEEE80211_BAND_5GHZ:
127 sc->sc_rates[mode] = 118 rt = ath9k_hw_getratetable(ah, ATH9K_MODE_11A);
128 ath9k_hw_getratetable(ah, ATH9K_MODE_SEL_11G);
129 break;
130 case WIRELESS_MODE_11NA_HT20:
131 sc->sc_rates[mode] =
132 ath9k_hw_getratetable(ah, ATH9K_MODE_SEL_11NA_HT20);
133 break;
134 case WIRELESS_MODE_11NG_HT20:
135 sc->sc_rates[mode] =
136 ath9k_hw_getratetable(ah, ATH9K_MODE_SEL_11NG_HT20);
137 break;
138 case WIRELESS_MODE_11NA_HT40PLUS:
139 sc->sc_rates[mode] =
140 ath9k_hw_getratetable(ah, ATH9K_MODE_SEL_11NA_HT40PLUS);
141 break;
142 case WIRELESS_MODE_11NA_HT40MINUS:
143 sc->sc_rates[mode] =
144 ath9k_hw_getratetable(ah,
145 ATH9K_MODE_SEL_11NA_HT40MINUS);
146 break;
147 case WIRELESS_MODE_11NG_HT40PLUS:
148 sc->sc_rates[mode] =
149 ath9k_hw_getratetable(ah, ATH9K_MODE_SEL_11NG_HT40PLUS);
150 break;
151 case WIRELESS_MODE_11NG_HT40MINUS:
152 sc->sc_rates[mode] =
153 ath9k_hw_getratetable(ah,
154 ATH9K_MODE_SEL_11NG_HT40MINUS);
155 break; 119 break;
156 default: 120 default:
157 DPRINTF(sc, ATH_DBG_FATAL, "%s: invalid mode %u\n", 121 break;
158 __func__, mode);
159 return 0;
160 } 122 }
161 rt = sc->sc_rates[mode];
162 if (rt == NULL)
163 return 0;
164 123
165 /* setup rate set in 802.11 protocol layer */ 124 if (rt == NULL)
166 ath_setup_rate(sc, mode, NORMAL_RATE, rt); 125 return;
167 126
168 return 1; 127 sband = &sc->sbands[band];
128 rate = sc->rates[band];
129
130 if (rt->rateCount > ATH_RATE_MAX)
131 maxrates = ATH_RATE_MAX;
132 else
133 maxrates = rt->rateCount;
134
135 for (i = 0; i < maxrates; i++) {
136 rate[i].bitrate = rt->info[i].rateKbps / 100;
137 rate[i].hw_value = rt->info[i].rateCode;
138 sband->n_bitrates++;
139 DPRINTF(sc, ATH_DBG_CONFIG,
140 "%s: Rate: %2dMbps, ratecode: %2d\n",
141 __func__,
142 rate[i].bitrate / 10,
143 rate[i].hw_value);
144 }
169} 145}
170 146
171/* 147/*
@@ -191,7 +167,6 @@ static int ath_setup_channels(struct ath_softc *sc)
191 ATH_REGCLASSIDS_MAX, 167 ATH_REGCLASSIDS_MAX,
192 &nregclass, 168 &nregclass,
193 CTRY_DEFAULT, 169 CTRY_DEFAULT,
194 ATH9K_MODE_SEL_ALL,
195 false, 170 false,
196 1)) { 171 1)) {
197 u32 rd = ah->ah_currentRD; 172 u32 rd = ah->ah_currentRD;
@@ -267,43 +242,26 @@ static int ath_setup_channels(struct ath_softc *sc)
267static enum wireless_mode ath_chan2mode(struct ath9k_channel *chan) 242static enum wireless_mode ath_chan2mode(struct ath9k_channel *chan)
268{ 243{
269 if (chan->chanmode == CHANNEL_A) 244 if (chan->chanmode == CHANNEL_A)
270 return WIRELESS_MODE_11a; 245 return ATH9K_MODE_11A;
271 else if (chan->chanmode == CHANNEL_G) 246 else if (chan->chanmode == CHANNEL_G)
272 return WIRELESS_MODE_11g; 247 return ATH9K_MODE_11G;
273 else if (chan->chanmode == CHANNEL_B) 248 else if (chan->chanmode == CHANNEL_B)
274 return WIRELESS_MODE_11b; 249 return ATH9K_MODE_11B;
275 else if (chan->chanmode == CHANNEL_A_HT20) 250 else if (chan->chanmode == CHANNEL_A_HT20)
276 return WIRELESS_MODE_11NA_HT20; 251 return ATH9K_MODE_11NA_HT20;
277 else if (chan->chanmode == CHANNEL_G_HT20) 252 else if (chan->chanmode == CHANNEL_G_HT20)
278 return WIRELESS_MODE_11NG_HT20; 253 return ATH9K_MODE_11NG_HT20;
279 else if (chan->chanmode == CHANNEL_A_HT40PLUS) 254 else if (chan->chanmode == CHANNEL_A_HT40PLUS)
280 return WIRELESS_MODE_11NA_HT40PLUS; 255 return ATH9K_MODE_11NA_HT40PLUS;
281 else if (chan->chanmode == CHANNEL_A_HT40MINUS) 256 else if (chan->chanmode == CHANNEL_A_HT40MINUS)
282 return WIRELESS_MODE_11NA_HT40MINUS; 257 return ATH9K_MODE_11NA_HT40MINUS;
283 else if (chan->chanmode == CHANNEL_G_HT40PLUS) 258 else if (chan->chanmode == CHANNEL_G_HT40PLUS)
284 return WIRELESS_MODE_11NG_HT40PLUS; 259 return ATH9K_MODE_11NG_HT40PLUS;
285 else if (chan->chanmode == CHANNEL_G_HT40MINUS) 260 else if (chan->chanmode == CHANNEL_G_HT40MINUS)
286 return WIRELESS_MODE_11NG_HT40MINUS; 261 return ATH9K_MODE_11NG_HT40MINUS;
287 262
288 /* NB: should not get here */ 263 /* NB: should not get here */
289 return WIRELESS_MODE_11b; 264 return ATH9K_MODE_11B;
290}
291
292/*
293 * Change Channels
294 *
295 * Performs the actions to change the channel in the hardware, and set up
296 * the current operating mode for the new channel.
297*/
298
299static void ath_chan_change(struct ath_softc *sc, struct ath9k_channel *chan)
300{
301 enum wireless_mode mode;
302
303 mode = ath_chan2mode(chan);
304
305 ath_rate_setup(sc, mode);
306 ath_setcurmode(sc, mode);
307} 265}
308 266
309/* 267/*
@@ -480,7 +438,8 @@ int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan)
480 * Change channels and update the h/w rate map 438 * Change channels and update the h/w rate map
481 * if we're switching; e.g. 11a to 11b/g. 439 * if we're switching; e.g. 11a to 11b/g.
482 */ 440 */
483 ath_chan_change(sc, hchan); 441 ath_setcurmode(sc, ath_chan2mode(hchan));
442
484 ath_update_txpow(sc); /* update tx power state */ 443 ath_update_txpow(sc); /* update tx power state */
485 /* 444 /*
486 * Re-enable interrupts. 445 * Re-enable interrupts.
@@ -860,7 +819,7 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan)
860 * vap and node data structures, which will be needed as soon 819 * vap and node data structures, which will be needed as soon
861 * as we start receiving. 820 * as we start receiving.
862 */ 821 */
863 ath_chan_change(sc, initial_chan); 822 ath_setcurmode(sc, ath_chan2mode(initial_chan));
864 823
865 /* XXX: we must make sure h/w is ready and clear invalid flag 824 /* XXX: we must make sure h/w is ready and clear invalid flag
866 * before turning on interrupt. */ 825 * before turning on interrupt. */
@@ -902,7 +861,7 @@ static int ath_reset_end(struct ath_softc *sc, u32 flag)
902 * that changes the channel so update any state that 861 * that changes the channel so update any state that
903 * might change as a result. 862 * might change as a result.
904 */ 863 */
905 ath_chan_change(sc, &sc->sc_curchan); 864 ath_setcurmode(sc, ath_chan2mode(&sc->sc_curchan));
906 865
907 ath_update_txpow(sc); /* update tx power state */ 866 ath_update_txpow(sc); /* update tx power state */
908 867
@@ -1212,14 +1171,13 @@ int ath_init(u16 devid, struct ath_softc *sc)
1212 /* default to STA mode */ 1171 /* default to STA mode */
1213 sc->sc_opmode = ATH9K_M_MONITOR; 1172 sc->sc_opmode = ATH9K_M_MONITOR;
1214 1173
1215 /* Setup rate tables for all potential media types. */ 1174 /* Setup rate tables */
1216 /* 11g encompasses b,g */
1217 1175
1218 ath_rate_setup(sc, WIRELESS_MODE_11a); 1176 ath_setup_rates(sc, IEEE80211_BAND_2GHZ);
1219 ath_rate_setup(sc, WIRELESS_MODE_11g); 1177 ath_setup_rates(sc, IEEE80211_BAND_5GHZ);
1220 1178
1221 /* NB: setup here so ath_rate_update is happy */ 1179 /* NB: setup here so ath_rate_update is happy */
1222 ath_setcurmode(sc, WIRELESS_MODE_11a); 1180 ath_setcurmode(sc, ATH9K_MODE_11A);
1223 1181
1224 /* 1182 /*
1225 * Allocate hardware transmit queues: one queue for 1183 * Allocate hardware transmit queues: one queue for
diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h
index e294c1b8ddb5..673b3d81133a 100644
--- a/drivers/net/wireless/ath9k/core.h
+++ b/drivers/net/wireless/ath9k/core.h
@@ -1004,10 +1004,8 @@ struct ath_softc {
1004 1004
1005 /* Rate */ 1005 /* Rate */
1006 struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX]; 1006 struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX];
1007 const struct ath9k_rate_table *sc_rates[WIRELESS_MODE_MAX];
1008 const struct ath9k_rate_table *sc_currates; 1007 const struct ath9k_rate_table *sc_currates;
1009 u8 sc_rixmap[256]; /* IEEE to h/w rate table ix */ 1008 u8 sc_rixmap[256]; /* IEEE to h/w rate table ix */
1010 u8 sc_minrateix; /* min h/w rate index */
1011 u8 sc_protrix; /* protection rate index */ 1009 u8 sc_protrix; /* protection rate index */
1012 struct { 1010 struct {
1013 u32 rateKbps; /* transfer rate in kbs */ 1011 u32 rateKbps; /* transfer rate in kbs */
diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c
index d4b7b63fa213..bde162f128ab 100644
--- a/drivers/net/wireless/ath9k/hw.c
+++ b/drivers/net/wireless/ath9k/hw.c
@@ -225,10 +225,10 @@ static enum wireless_mode ath9k_hw_chan2wmode(struct ath_hal *ah,
225 const struct ath9k_channel *chan) 225 const struct ath9k_channel *chan)
226{ 226{
227 if (IS_CHAN_CCK(chan)) 227 if (IS_CHAN_CCK(chan))
228 return WIRELESS_MODE_11b; 228 return ATH9K_MODE_11A;
229 if (IS_CHAN_G(chan)) 229 if (IS_CHAN_G(chan))
230 return WIRELESS_MODE_11g; 230 return ATH9K_MODE_11G;
231 return WIRELESS_MODE_11a; 231 return ATH9K_MODE_11A;
232} 232}
233 233
234static bool ath9k_hw_wait(struct ath_hal *ah, 234static bool ath9k_hw_wait(struct ath_hal *ah,
@@ -2416,7 +2416,7 @@ static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hal *ah)
2416 return; 2416 return;
2417 } else { 2417 } else {
2418 mode = ath9k_hw_chan2wmode(ah, chan); 2418 mode = ath9k_hw_chan2wmode(ah, chan);
2419 if (mode == WIRELESS_MODE_11g || mode == WIRELESS_MODE_11b) { 2419 if (mode == ATH9K_MODE_11G || mode == ATH9K_MODE_11B) {
2420 if (!aniState->ofdmWeakSigDetectOff) 2420 if (!aniState->ofdmWeakSigDetectOff)
2421 ath9k_hw_ani_control(ah, 2421 ath9k_hw_ani_control(ah,
2422 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, 2422 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
@@ -2462,7 +2462,7 @@ static void ath9k_hw_ani_cck_err_trigger(struct ath_hal *ah)
2462 aniState->firstepLevel + 1); 2462 aniState->firstepLevel + 1);
2463 } else { 2463 } else {
2464 mode = ath9k_hw_chan2wmode(ah, chan); 2464 mode = ath9k_hw_chan2wmode(ah, chan);
2465 if (mode == WIRELESS_MODE_11g || mode == WIRELESS_MODE_11b) { 2465 if (mode == ATH9K_MODE_11G || mode == ATH9K_MODE_11B) {
2466 if (aniState->firstepLevel > 0) 2466 if (aniState->firstepLevel > 0)
2467 ath9k_hw_ani_control(ah, 2467 ath9k_hw_ani_control(ah,
2468 ATH9K_ANI_FIRSTEP_LEVEL, 2468 ATH9K_ANI_FIRSTEP_LEVEL,
@@ -2970,29 +2970,40 @@ static bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
2970 ah->ah_currentRD); 2970 ah->ah_currentRD);
2971 } 2971 }
2972 2972
2973 pCap->wireless_modes = 0;
2974 eeval = ath9k_hw_get_eeprom(ahp, EEP_OP_MODE); 2973 eeval = ath9k_hw_get_eeprom(ahp, EEP_OP_MODE);
2974 bitmap_zero(pCap->wireless_modes, ATH9K_MODE_MAX);
2975 2975
2976 if (eeval & AR5416_OPFLAGS_11A) { 2976 if (eeval & AR5416_OPFLAGS_11A) {
2977 pCap->wireless_modes |= ATH9K_MODE_SEL_11A | 2977 set_bit(ATH9K_MODE_11A, pCap->wireless_modes);
2978 ((!ah->ah_config.ht_enable 2978 if (ah->ah_config.ht_enable) {
2979 || (eeval & AR5416_OPFLAGS_N_5G_HT20)) ? 0 2979 if (!(eeval & AR5416_OPFLAGS_N_5G_HT20))
2980 : (ATH9K_MODE_SEL_11NA_HT20 | 2980 set_bit(ATH9K_MODE_11NA_HT20,
2981 ((eeval & AR5416_OPFLAGS_N_5G_HT40) ? 0 2981 pCap->wireless_modes);
2982 : (ATH9K_MODE_SEL_11NA_HT40PLUS | 2982 if (!(eeval & AR5416_OPFLAGS_N_5G_HT40)) {
2983 ATH9K_MODE_SEL_11NA_HT40MINUS)))); 2983 set_bit(ATH9K_MODE_11NA_HT40PLUS,
2984 pCap->wireless_modes);
2985 set_bit(ATH9K_MODE_11NA_HT40MINUS,
2986 pCap->wireless_modes);
2987 }
2988 }
2984 } 2989 }
2985 if (eeval & AR5416_OPFLAGS_11G) {
2986 pCap->wireless_modes |=
2987 ATH9K_MODE_SEL_11B | ATH9K_MODE_SEL_11G |
2988 ((!ah->ah_config.ht_enable
2989 || (eeval & AR5416_OPFLAGS_N_2G_HT20)) ? 0
2990 : (ATH9K_MODE_SEL_11NG_HT20 |
2991 ((eeval & AR5416_OPFLAGS_N_2G_HT40) ? 0
2992 : (ATH9K_MODE_SEL_11NG_HT40PLUS |
2993 ATH9K_MODE_SEL_11NG_HT40MINUS))));
2994 2990
2991 if (eeval & AR5416_OPFLAGS_11G) {
2992 set_bit(ATH9K_MODE_11B, pCap->wireless_modes);
2993 set_bit(ATH9K_MODE_11G, pCap->wireless_modes);
2994 if (ah->ah_config.ht_enable) {
2995 if (!(eeval & AR5416_OPFLAGS_N_2G_HT20))
2996 set_bit(ATH9K_MODE_11NG_HT20,
2997 pCap->wireless_modes);
2998 if (!(eeval & AR5416_OPFLAGS_N_2G_HT40)) {
2999 set_bit(ATH9K_MODE_11NG_HT40PLUS,
3000 pCap->wireless_modes);
3001 set_bit(ATH9K_MODE_11NG_HT40MINUS,
3002 pCap->wireless_modes);
3003 }
3004 }
2995 } 3005 }
3006
2996 pCap->tx_chainmask = ath9k_hw_get_eeprom(ahp, EEP_TX_MASK); 3007 pCap->tx_chainmask = ath9k_hw_get_eeprom(ahp, EEP_TX_MASK);
2997 if ((ah->ah_isPciExpress) 3008 if ((ah->ah_isPciExpress)
2998 || (eeval & AR5416_OPFLAGS_11A)) { 3009 || (eeval & AR5416_OPFLAGS_11A)) {
@@ -5213,7 +5224,7 @@ static u32 ath9k_hw_mac_usec(struct ath_hal *ah, u32 clks)
5213 return clks / 5224 return clks /
5214 CLOCK_RATE[ath9k_hw_chan2wmode(ah, ah->ah_curchan)]; 5225 CLOCK_RATE[ath9k_hw_chan2wmode(ah, ah->ah_curchan)];
5215 else 5226 else
5216 return clks / CLOCK_RATE[WIRELESS_MODE_11b]; 5227 return clks / CLOCK_RATE[ATH9K_MODE_11B];
5217} 5228}
5218 5229
5219static u32 ath9k_hw_mac_to_usec(struct ath_hal *ah, u32 clks) 5230static u32 ath9k_hw_mac_to_usec(struct ath_hal *ah, u32 clks)
@@ -5232,7 +5243,7 @@ static u32 ath9k_hw_mac_clks(struct ath_hal *ah, u32 usecs)
5232 return usecs * CLOCK_RATE[ath9k_hw_chan2wmode(ah, 5243 return usecs * CLOCK_RATE[ath9k_hw_chan2wmode(ah,
5233 ah->ah_curchan)]; 5244 ah->ah_curchan)];
5234 else 5245 else
5235 return usecs * CLOCK_RATE[WIRELESS_MODE_11b]; 5246 return usecs * CLOCK_RATE[ATH9K_MODE_11B];
5236} 5247}
5237 5248
5238static u32 ath9k_hw_mac_to_clks(struct ath_hal *ah, u32 usecs) 5249static u32 ath9k_hw_mac_to_clks(struct ath_hal *ah, u32 usecs)
@@ -5924,7 +5935,7 @@ bool ath9k_hw_reset(struct ath_hal *ah, enum ath9k_opmode opmode,
5924 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, 5935 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
5925 AR_GPIO_JTAG_DISABLE); 5936 AR_GPIO_JTAG_DISABLE);
5926 5937
5927 if (ah->ah_caps.wireless_modes & ATH9K_MODE_SEL_11A) { 5938 if (test_bit(ATH9K_MODE_11A, ah->ah_caps.wireless_modes)) {
5928 if (IS_CHAN_5GHZ(chan)) 5939 if (IS_CHAN_5GHZ(chan))
5929 ath9k_hw_set_gpio(ah, 9, 0); 5940 ath9k_hw_set_gpio(ah, 9, 0);
5930 else 5941 else
@@ -8238,23 +8249,23 @@ const struct ath9k_rate_table *ath9k_hw_getratetable(struct ath_hal *ah,
8238{ 8249{
8239 struct ath9k_rate_table *rt; 8250 struct ath9k_rate_table *rt;
8240 switch (mode) { 8251 switch (mode) {
8241 case ATH9K_MODE_SEL_11A: 8252 case ATH9K_MODE_11A:
8242 rt = &ar5416_11a_table; 8253 rt = &ar5416_11a_table;
8243 break; 8254 break;
8244 case ATH9K_MODE_SEL_11B: 8255 case ATH9K_MODE_11B:
8245 rt = &ar5416_11b_table; 8256 rt = &ar5416_11b_table;
8246 break; 8257 break;
8247 case ATH9K_MODE_SEL_11G: 8258 case ATH9K_MODE_11G:
8248 rt = &ar5416_11g_table; 8259 rt = &ar5416_11g_table;
8249 break; 8260 break;
8250 case ATH9K_MODE_SEL_11NG_HT20: 8261 case ATH9K_MODE_11NG_HT20:
8251 case ATH9K_MODE_SEL_11NG_HT40PLUS: 8262 case ATH9K_MODE_11NG_HT40PLUS:
8252 case ATH9K_MODE_SEL_11NG_HT40MINUS: 8263 case ATH9K_MODE_11NG_HT40MINUS:
8253 rt = &ar5416_11ng_table; 8264 rt = &ar5416_11ng_table;
8254 break; 8265 break;
8255 case ATH9K_MODE_SEL_11NA_HT20: 8266 case ATH9K_MODE_11NA_HT20:
8256 case ATH9K_MODE_SEL_11NA_HT40PLUS: 8267 case ATH9K_MODE_11NA_HT40PLUS:
8257 case ATH9K_MODE_SEL_11NA_HT40MINUS: 8268 case ATH9K_MODE_11NA_HT40MINUS:
8258 rt = &ar5416_11na_table; 8269 rt = &ar5416_11na_table;
8259 break; 8270 break;
8260 default: 8271 default:
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
index 4cf0d26d1392..2888778040e4 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -507,7 +507,13 @@ static int ath9k_config(struct ieee80211_hw *hw,
507 } 507 }
508 508
509 sc->sc_ah->ah_channels[pos].chanmode = 509 sc->sc_ah->ah_channels[pos].chanmode =
510 (curchan->band == IEEE80211_BAND_2GHZ) ? CHANNEL_G : CHANNEL_A; 510 (curchan->band == IEEE80211_BAND_2GHZ) ?
511 CHANNEL_G : CHANNEL_A;
512
513 if (sc->sc_curaid && hw->conf.ht_conf.ht_supported)
514 sc->sc_ah->ah_channels[pos].chanmode =
515 ath_get_extchanmode(sc, curchan);
516
511 sc->sc_config.txpowlimit = 2 * conf->power_level; 517 sc->sc_config.txpowlimit = 2 * conf->power_level;
512 518
513 /* set h/w channel */ 519 /* set h/w channel */
@@ -1145,75 +1151,6 @@ enum ath9k_ht_macmode ath_cwm_macmode(struct ath_softc *sc)
1145 return sc->sc_ht_info.tx_chan_width; 1151 return sc->sc_ht_info.tx_chan_width;
1146} 1152}
1147 1153
1148void ath_setup_rate(struct ath_softc *sc,
1149 enum wireless_mode wMode,
1150 enum RATE_TYPE type,
1151 const struct ath9k_rate_table *rt)
1152{
1153 int i, maxrates, a = 0, b = 0;
1154 struct ieee80211_supported_band *band_2ghz;
1155 struct ieee80211_supported_band *band_5ghz;
1156 struct ieee80211_rate *rates_2ghz;
1157 struct ieee80211_rate *rates_5ghz;
1158
1159 if ((wMode >= WIRELESS_MODE_MAX) || (type != NORMAL_RATE))
1160 return;
1161
1162 band_2ghz = &sc->sbands[IEEE80211_BAND_2GHZ];
1163 band_5ghz = &sc->sbands[IEEE80211_BAND_5GHZ];
1164 rates_2ghz = sc->rates[IEEE80211_BAND_2GHZ];
1165 rates_5ghz = sc->rates[IEEE80211_BAND_5GHZ];
1166
1167 if (rt->rateCount > ATH_RATE_MAX)
1168 maxrates = ATH_RATE_MAX;
1169 else
1170 maxrates = rt->rateCount;
1171
1172 if ((band_2ghz->n_bitrates != 0) && (band_5ghz->n_bitrates != 0)) {
1173 DPRINTF(sc, ATH_DBG_CONFIG,
1174 "%s: Rates already setup\n", __func__);
1175 return;
1176 }
1177
1178 for (i = 0; i < maxrates; i++) {
1179 switch (wMode) {
1180 case WIRELESS_MODE_11b:
1181 case WIRELESS_MODE_11g:
1182 rates_2ghz[a].bitrate = rt->info[i].rateKbps / 100;
1183 rates_2ghz[a].hw_value = rt->info[i].rateCode;
1184 a++;
1185 band_2ghz->n_bitrates = a;
1186 break;
1187 case WIRELESS_MODE_11a:
1188 rates_5ghz[b].bitrate = rt->info[i].rateKbps / 100;
1189 rates_5ghz[b].hw_value = rt->info[i].rateCode;
1190 b++;
1191 band_5ghz->n_bitrates = b;
1192 break;
1193 default:
1194 break;
1195 }
1196 }
1197
1198 if (band_2ghz->n_bitrates) {
1199 for (i = 0; i < band_2ghz->n_bitrates; i++) {
1200 DPRINTF(sc, ATH_DBG_CONFIG,
1201 "%s: 2GHz Rate: %2dMbps, ratecode: %2d\n",
1202 __func__,
1203 rates_2ghz[i].bitrate / 10,
1204 rates_2ghz[i].hw_value);
1205 }
1206 } else if (band_5ghz->n_bitrates) {
1207 for (i = 0; i < band_5ghz->n_bitrates; i++) {
1208 DPRINTF(sc, ATH_DBG_CONFIG,
1209 "%s: 5Ghz Rate: %2dMbps, ratecode: %2d\n",
1210 __func__,
1211 rates_5ghz[i].bitrate / 10,
1212 rates_5ghz[i].hw_value);
1213 }
1214 }
1215}
1216
1217static int ath_detach(struct ath_softc *sc) 1154static int ath_detach(struct ath_softc *sc)
1218{ 1155{
1219 struct ieee80211_hw *hw = sc->hw; 1156 struct ieee80211_hw *hw = sc->hw;
@@ -1275,7 +1212,7 @@ static int ath_attach(u16 devid,
1275 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = 1212 hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
1276 &sc->sbands[IEEE80211_BAND_2GHZ]; 1213 &sc->sbands[IEEE80211_BAND_2GHZ];
1277 1214
1278 if (sc->sc_ah->ah_caps.wireless_modes & ATH9K_MODE_SEL_11A) { 1215 if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes)) {
1279 sc->sbands[IEEE80211_BAND_5GHZ].channels = 1216 sc->sbands[IEEE80211_BAND_5GHZ].channels =
1280 sc->channels[IEEE80211_BAND_5GHZ]; 1217 sc->channels[IEEE80211_BAND_5GHZ];
1281 sc->sbands[IEEE80211_BAND_5GHZ].bitrates = 1218 sc->sbands[IEEE80211_BAND_5GHZ].bitrates =
diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c
index d3132009d94d..73c460ad355f 100644
--- a/drivers/net/wireless/ath9k/rc.c
+++ b/drivers/net/wireless/ath9k/rc.c
@@ -484,37 +484,37 @@ static void ar5416_attach_ratetables(struct ath_rate_softc *sc)
484 /* 484 /*
485 * Attach rate tables. 485 * Attach rate tables.
486 */ 486 */
487 sc->hw_rate_table[WIRELESS_MODE_11b] = &ar5416_11b_ratetable; 487 sc->hw_rate_table[ATH9K_MODE_11B] = &ar5416_11b_ratetable;
488 sc->hw_rate_table[WIRELESS_MODE_11a] = &ar5416_11a_ratetable; 488 sc->hw_rate_table[ATH9K_MODE_11A] = &ar5416_11a_ratetable;
489 sc->hw_rate_table[WIRELESS_MODE_11g] = &ar5416_11g_ratetable; 489 sc->hw_rate_table[ATH9K_MODE_11G] = &ar5416_11g_ratetable;
490 490
491 sc->hw_rate_table[WIRELESS_MODE_11NA_HT20] = &ar5416_11na_ratetable; 491 sc->hw_rate_table[ATH9K_MODE_11NA_HT20] = &ar5416_11na_ratetable;
492 sc->hw_rate_table[WIRELESS_MODE_11NG_HT20] = &ar5416_11ng_ratetable; 492 sc->hw_rate_table[ATH9K_MODE_11NG_HT20] = &ar5416_11ng_ratetable;
493 sc->hw_rate_table[WIRELESS_MODE_11NA_HT40PLUS] = 493 sc->hw_rate_table[ATH9K_MODE_11NA_HT40PLUS] =
494 &ar5416_11na_ratetable; 494 &ar5416_11na_ratetable;
495 sc->hw_rate_table[WIRELESS_MODE_11NA_HT40MINUS] = 495 sc->hw_rate_table[ATH9K_MODE_11NA_HT40MINUS] =
496 &ar5416_11na_ratetable; 496 &ar5416_11na_ratetable;
497 sc->hw_rate_table[WIRELESS_MODE_11NG_HT40PLUS] = 497 sc->hw_rate_table[ATH9K_MODE_11NG_HT40PLUS] =
498 &ar5416_11ng_ratetable; 498 &ar5416_11ng_ratetable;
499 sc->hw_rate_table[WIRELESS_MODE_11NG_HT40MINUS] = 499 sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS] =
500 &ar5416_11ng_ratetable; 500 &ar5416_11ng_ratetable;
501} 501}
502 502
503static void ar5416_setquarter_ratetable(struct ath_rate_softc *sc) 503static void ar5416_setquarter_ratetable(struct ath_rate_softc *sc)
504{ 504{
505 sc->hw_rate_table[WIRELESS_MODE_11a] = &ar5416_11a_ratetable_Quarter; 505 sc->hw_rate_table[ATH9K_MODE_11A] = &ar5416_11a_ratetable_Quarter;
506 return; 506 return;
507} 507}
508 508
509static void ar5416_sethalf_ratetable(struct ath_rate_softc *sc) 509static void ar5416_sethalf_ratetable(struct ath_rate_softc *sc)
510{ 510{
511 sc->hw_rate_table[WIRELESS_MODE_11a] = &ar5416_11a_ratetable_Half; 511 sc->hw_rate_table[ATH9K_MODE_11A] = &ar5416_11a_ratetable_Half;
512 return; 512 return;
513} 513}
514 514
515static void ar5416_setfull_ratetable(struct ath_rate_softc *sc) 515static void ar5416_setfull_ratetable(struct ath_rate_softc *sc)
516{ 516{
517 sc->hw_rate_table[WIRELESS_MODE_11a] = &ar5416_11a_ratetable; 517 sc->hw_rate_table[ATH9K_MODE_11A] = &ar5416_11a_ratetable;
518 return; 518 return;
519} 519}
520 520
@@ -1123,9 +1123,9 @@ static void ath_rc_ratefind(struct ath_softc *sc,
1123 * So, set fourth rate in series to be same as third one for 1123 * So, set fourth rate in series to be same as third one for
1124 * above conditions. 1124 * above conditions.
1125 */ 1125 */
1126 if ((sc->sc_curmode == WIRELESS_MODE_11NG_HT20) || 1126 if ((sc->sc_curmode == ATH9K_MODE_11NG_HT20) ||
1127 (sc->sc_curmode == WIRELESS_MODE_11NG_HT40PLUS) || 1127 (sc->sc_curmode == ATH9K_MODE_11NG_HT40PLUS) ||
1128 (sc->sc_curmode == WIRELESS_MODE_11NG_HT40MINUS)) { 1128 (sc->sc_curmode == ATH9K_MODE_11NG_HT40MINUS)) {
1129 u8 dot11rate = rate_table->info[rix].dot11rate; 1129 u8 dot11rate = rate_table->info[rix].dot11rate;
1130 u8 phy = rate_table->info[rix].phy; 1130 u8 phy = rate_table->info[rix].phy;
1131 if (i == 4 && 1131 if (i == 4 &&
diff --git a/drivers/net/wireless/ath9k/rc.h b/drivers/net/wireless/ath9k/rc.h
index 8f6c28e65191..71aef9c75232 100644
--- a/drivers/net/wireless/ath9k/rc.h
+++ b/drivers/net/wireless/ath9k/rc.h
@@ -247,7 +247,7 @@ struct ath_rateset {
247/* per-device state */ 247/* per-device state */
248struct ath_rate_softc { 248struct ath_rate_softc {
249 /* phy tables that contain rate control data */ 249 /* phy tables that contain rate control data */
250 const void *hw_rate_table[WIRELESS_MODE_MAX]; 250 const void *hw_rate_table[ATH9K_MODE_MAX];
251 int fixedrix; /* -1 or index of fixed rate */ 251 int fixedrix; /* -1 or index of fixed rate */
252}; 252};
253 253
diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c
index 05e10c485fa4..62e28887ccd3 100644
--- a/drivers/net/wireless/ath9k/regd.c
+++ b/drivers/net/wireless/ath9k/regd.c
@@ -131,46 +131,45 @@ static bool ath9k_regd_is_ccode_valid(struct ath_hal *ah,
131 return false; 131 return false;
132} 132}
133 133
134static u32 134static void
135ath9k_regd_get_wmodes_nreg(struct ath_hal *ah, 135ath9k_regd_get_wmodes_nreg(struct ath_hal *ah,
136 struct country_code_to_enum_rd *country, 136 struct country_code_to_enum_rd *country,
137 struct regDomain *rd5GHz) 137 struct regDomain *rd5GHz,
138 unsigned long *modes_allowed)
138{ 139{
139 u32 modesAvail; 140 bitmap_copy(modes_allowed, ah->ah_caps.wireless_modes, ATH9K_MODE_MAX);
140 141
141 modesAvail = ah->ah_caps.wireless_modes; 142 if (test_bit(ATH9K_MODE_11G, ah->ah_caps.wireless_modes) &&
143 (!country->allow11g))
144 clear_bit(ATH9K_MODE_11G, modes_allowed);
142 145
143 if ((modesAvail & ATH9K_MODE_SEL_11G) && (!country->allow11g)) 146 if (test_bit(ATH9K_MODE_11A, ah->ah_caps.wireless_modes) &&
144 modesAvail &= ~ATH9K_MODE_SEL_11G;
145 if ((modesAvail & ATH9K_MODE_SEL_11A) &&
146 (ath9k_regd_is_chan_bm_zero(rd5GHz->chan11a))) 147 (ath9k_regd_is_chan_bm_zero(rd5GHz->chan11a)))
147 modesAvail &= ~ATH9K_MODE_SEL_11A; 148 clear_bit(ATH9K_MODE_11A, modes_allowed);
148 149
149 if ((modesAvail & ATH9K_MODE_SEL_11NG_HT20) 150 if (test_bit(ATH9K_MODE_11NG_HT20, ah->ah_caps.wireless_modes)
150 && (!country->allow11ng20)) 151 && (!country->allow11ng20))
151 modesAvail &= ~ATH9K_MODE_SEL_11NG_HT20; 152 clear_bit(ATH9K_MODE_11NG_HT20, modes_allowed);
152 153
153 if ((modesAvail & ATH9K_MODE_SEL_11NA_HT20) 154 if (test_bit(ATH9K_MODE_11NA_HT20, ah->ah_caps.wireless_modes)
154 && (!country->allow11na20)) 155 && (!country->allow11na20))
155 modesAvail &= ~ATH9K_MODE_SEL_11NA_HT20; 156 clear_bit(ATH9K_MODE_11NA_HT20, modes_allowed);
156 157
157 if ((modesAvail & ATH9K_MODE_SEL_11NG_HT40PLUS) && 158 if (test_bit(ATH9K_MODE_11NG_HT40PLUS, ah->ah_caps.wireless_modes) &&
158 (!country->allow11ng40)) 159 (!country->allow11ng40))
159 modesAvail &= ~ATH9K_MODE_SEL_11NG_HT40PLUS; 160 clear_bit(ATH9K_MODE_11NG_HT40PLUS, modes_allowed);
160 161
161 if ((modesAvail & ATH9K_MODE_SEL_11NG_HT40MINUS) && 162 if (test_bit(ATH9K_MODE_11NG_HT40MINUS, ah->ah_caps.wireless_modes) &&
162 (!country->allow11ng40)) 163 (!country->allow11ng40))
163 modesAvail &= ~ATH9K_MODE_SEL_11NG_HT40MINUS; 164 clear_bit(ATH9K_MODE_11NG_HT40MINUS, modes_allowed);
164 165
165 if ((modesAvail & ATH9K_MODE_SEL_11NA_HT40PLUS) && 166 if (test_bit(ATH9K_MODE_11NA_HT40PLUS, ah->ah_caps.wireless_modes) &&
166 (!country->allow11na40)) 167 (!country->allow11na40))
167 modesAvail &= ~ATH9K_MODE_SEL_11NA_HT40PLUS; 168 clear_bit(ATH9K_MODE_11NA_HT40PLUS, modes_allowed);
168 169
169 if ((modesAvail & ATH9K_MODE_SEL_11NA_HT40MINUS) && 170 if (test_bit(ATH9K_MODE_11NA_HT40MINUS, ah->ah_caps.wireless_modes) &&
170 (!country->allow11na40)) 171 (!country->allow11na40))
171 modesAvail &= ~ATH9K_MODE_SEL_11NA_HT40MINUS; 172 clear_bit(ATH9K_MODE_11NA_HT40MINUS, modes_allowed);
172
173 return modesAvail;
174} 173}
175 174
176bool ath9k_regd_is_public_safety_sku(struct ath_hal *ah) 175bool ath9k_regd_is_public_safety_sku(struct ath_hal *ah)
@@ -545,10 +544,10 @@ ath9k_regd_add_channel(struct ath_hal *ah,
545 } 544 }
546 } 545 }
547 546
548 if (cm->mode & (ATH9K_MODE_SEL_11A | 547 if ((cm->mode == ATH9K_MODE_11A) ||
549 ATH9K_MODE_SEL_11NA_HT20 | 548 (cm->mode == ATH9K_MODE_11NA_HT20) ||
550 ATH9K_MODE_SEL_11NA_HT40PLUS | 549 (cm->mode == ATH9K_MODE_11NA_HT40PLUS) ||
551 ATH9K_MODE_SEL_11NA_HT40MINUS)) { 550 (cm->mode == ATH9K_MODE_11NA_HT40MINUS)) {
552 if (rd->flags & (ADHOC_NO_11A | DISALLOW_ADHOC_11A)) 551 if (rd->flags & (ADHOC_NO_11A | DISALLOW_ADHOC_11A))
553 privFlags |= CHANNEL_DISALLOW_ADHOC; 552 privFlags |= CHANNEL_DISALLOW_ADHOC;
554 } 553 }
@@ -618,10 +617,9 @@ ath9k_regd_init_channels(struct ath_hal *ah,
618 u32 maxchans, 617 u32 maxchans,
619 u32 *nchans, u8 *regclassids, 618 u32 *nchans, u8 *regclassids,
620 u32 maxregids, u32 *nregids, u16 cc, 619 u32 maxregids, u32 *nregids, u16 cc,
621 u32 modeSelect, bool enableOutdoor, 620 bool enableOutdoor,
622 bool enableExtendedChannels) 621 bool enableExtendedChannels)
623{ 622{
624 u32 modesAvail;
625 u16 maxChan = 7000; 623 u16 maxChan = 7000;
626 struct country_code_to_enum_rd *country = NULL; 624 struct country_code_to_enum_rd *country = NULL;
627 struct regDomain rd5GHz, rd2GHz; 625 struct regDomain rd5GHz, rd2GHz;
@@ -631,11 +629,13 @@ ath9k_regd_init_channels(struct ath_hal *ah,
631 u8 ctl; 629 u8 ctl;
632 int regdmn; 630 int regdmn;
633 u16 chanSep; 631 u16 chanSep;
632 unsigned long *modes_avail;
633 DECLARE_BITMAP(modes_allowed, ATH9K_MODE_MAX);
634 634
635 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "%s: cc %u mode 0x%x%s%s\n", 635 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "%s: cc %u %s %s\n",
636 __func__, cc, modeSelect, 636 __func__, cc,
637 enableOutdoor ? " Enable outdoor" : " ", 637 enableOutdoor ? "Enable outdoor" : "",
638 enableExtendedChannels ? " Enable ecm" : ""); 638 enableExtendedChannels ? "Enable ecm" : "");
639 639
640 if (!ath9k_regd_is_ccode_valid(ah, cc)) { 640 if (!ath9k_regd_is_ccode_valid(ah, cc)) {
641 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, 641 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
@@ -726,9 +726,11 @@ ath9k_regd_init_channels(struct ath_hal *ah,
726 } 726 }
727 727
728 if (country == NULL) { 728 if (country == NULL) {
729 modesAvail = ah->ah_caps.wireless_modes; 729 modes_avail = ah->ah_caps.wireless_modes;
730 } else { 730 } else {
731 modesAvail = ath9k_regd_get_wmodes_nreg(ah, country, &rd5GHz); 731 ath9k_regd_get_wmodes_nreg(ah, country, &rd5GHz, modes_allowed);
732 modes_avail = modes_allowed;
733
732 if (!enableOutdoor) 734 if (!enableOutdoor)
733 maxChan = country->outdoorChanStart; 735 maxChan = country->outdoorChanStart;
734 } 736 }
@@ -745,19 +747,12 @@ ath9k_regd_init_channels(struct ath_hal *ah,
745 struct RegDmnFreqBand *fband = NULL, *freqs; 747 struct RegDmnFreqBand *fband = NULL, *freqs;
746 int8_t low_adj = 0, hi_adj = 0; 748 int8_t low_adj = 0, hi_adj = 0;
747 749
748 if ((cm->mode & modeSelect) == 0) { 750 if (!test_bit(cm->mode, modes_avail)) {
749 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, 751 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
750 "%s: skip mode 0x%x flags 0x%x\n", 752 "%s: !avail mode %d flags 0x%x\n",
751 __func__, cm->mode, cm->flags); 753 __func__, cm->mode, cm->flags);
752 continue; 754 continue;
753 } 755 }
754 if ((cm->mode & modesAvail) == 0) {
755 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
756 "%s: !avail mode 0x%x (0x%x) flags 0x%x\n",
757 __func__, modesAvail, cm->mode,
758 cm->flags);
759 continue;
760 }
761 if (!ath9k_get_channel_edges(ah, cm->flags, &c_lo, &c_hi)) { 756 if (!ath9k_get_channel_edges(ah, cm->flags, &c_lo, &c_hi)) {
762 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, 757 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
763 "%s: channels 0x%x not supported " 758 "%s: channels 0x%x not supported "
@@ -767,25 +762,25 @@ ath9k_regd_init_channels(struct ath_hal *ah,
767 } 762 }
768 763
769 switch (cm->mode) { 764 switch (cm->mode) {
770 case ATH9K_MODE_SEL_11A: 765 case ATH9K_MODE_11A:
771 case ATH9K_MODE_SEL_11NA_HT20: 766 case ATH9K_MODE_11NA_HT20:
772 case ATH9K_MODE_SEL_11NA_HT40PLUS: 767 case ATH9K_MODE_11NA_HT40PLUS:
773 case ATH9K_MODE_SEL_11NA_HT40MINUS: 768 case ATH9K_MODE_11NA_HT40MINUS:
774 rd = &rd5GHz; 769 rd = &rd5GHz;
775 channelBM = rd->chan11a; 770 channelBM = rd->chan11a;
776 freqs = &regDmn5GhzFreq[0]; 771 freqs = &regDmn5GhzFreq[0];
777 ctl = rd->conformanceTestLimit; 772 ctl = rd->conformanceTestLimit;
778 break; 773 break;
779 case ATH9K_MODE_SEL_11B: 774 case ATH9K_MODE_11B:
780 rd = &rd2GHz; 775 rd = &rd2GHz;
781 channelBM = rd->chan11b; 776 channelBM = rd->chan11b;
782 freqs = &regDmn2GhzFreq[0]; 777 freqs = &regDmn2GhzFreq[0];
783 ctl = rd->conformanceTestLimit | CTL_11B; 778 ctl = rd->conformanceTestLimit | CTL_11B;
784 break; 779 break;
785 case ATH9K_MODE_SEL_11G: 780 case ATH9K_MODE_11G:
786 case ATH9K_MODE_SEL_11NG_HT20: 781 case ATH9K_MODE_11NG_HT20:
787 case ATH9K_MODE_SEL_11NG_HT40PLUS: 782 case ATH9K_MODE_11NG_HT40PLUS:
788 case ATH9K_MODE_SEL_11NG_HT40MINUS: 783 case ATH9K_MODE_11NG_HT40MINUS:
789 rd = &rd2GHz; 784 rd = &rd2GHz;
790 channelBM = rd->chan11g; 785 channelBM = rd->chan11g;
791 freqs = &regDmn2Ghz11gFreq[0]; 786 freqs = &regDmn2Ghz11gFreq[0];
@@ -801,13 +796,13 @@ ath9k_regd_init_channels(struct ath_hal *ah,
801 if (ath9k_regd_is_chan_bm_zero(channelBM)) 796 if (ath9k_regd_is_chan_bm_zero(channelBM))
802 continue; 797 continue;
803 798
804 if ((cm->mode == ATH9K_MODE_SEL_11NA_HT40PLUS) || 799 if ((cm->mode == ATH9K_MODE_11NA_HT40PLUS) ||
805 (cm->mode == ATH9K_MODE_SEL_11NG_HT40PLUS)) { 800 (cm->mode == ATH9K_MODE_11NG_HT40PLUS)) {
806 hi_adj = -20; 801 hi_adj = -20;
807 } 802 }
808 803
809 if ((cm->mode == ATH9K_MODE_SEL_11NA_HT40MINUS) || 804 if ((cm->mode == ATH9K_MODE_11NA_HT40MINUS) ||
810 (cm->mode == ATH9K_MODE_SEL_11NG_HT40MINUS)) { 805 (cm->mode == ATH9K_MODE_11NG_HT40MINUS)) {
811 low_adj = 20; 806 low_adj = 20;
812 } 807 }
813 808
diff --git a/drivers/net/wireless/ath9k/regd.h b/drivers/net/wireless/ath9k/regd.h
index ae77496bfde3..0ecd344fbd98 100644
--- a/drivers/net/wireless/ath9k/regd.h
+++ b/drivers/net/wireless/ath9k/regd.h
@@ -117,11 +117,11 @@
117#define isUNII1OddChan(ch) \ 117#define isUNII1OddChan(ch) \
118 ((ch == 5170) || (ch == 5190) || (ch == 5210) || (ch == 5230)) 118 ((ch == 5170) || (ch == 5190) || (ch == 5210) || (ch == 5230))
119 119
120#define IS_HT40_MODE(_mode) \ 120#define IS_HT40_MODE(_mode) \
121 (((_mode == ATH9K_MODE_SEL_11NA_HT40PLUS || \ 121 (((_mode == ATH9K_MODE_11NA_HT40PLUS || \
122 _mode == ATH9K_MODE_SEL_11NG_HT40PLUS || \ 122 _mode == ATH9K_MODE_11NG_HT40PLUS || \
123 _mode == ATH9K_MODE_SEL_11NA_HT40MINUS || \ 123 _mode == ATH9K_MODE_11NA_HT40MINUS || \
124 _mode == ATH9K_MODE_SEL_11NG_HT40MINUS) ? true : false)) 124 _mode == ATH9K_MODE_11NG_HT40MINUS) ? true : false))
125 125
126#define CHAN_FLAGS (CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER) 126#define CHAN_FLAGS (CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER)
127 127
diff --git a/drivers/net/wireless/ath9k/regd_common.h b/drivers/net/wireless/ath9k/regd_common.h
index b3bfae4fc99c..9112c030b1e8 100644
--- a/drivers/net/wireless/ath9k/regd_common.h
+++ b/drivers/net/wireless/ath9k/regd_common.h
@@ -1893,15 +1893,15 @@ static struct regDomain regDomains[] = {
1893}; 1893};
1894 1894
1895static const struct cmode modes[] = { 1895static const struct cmode modes[] = {
1896 {ATH9K_MODE_SEL_11A, CHANNEL_A}, 1896 {ATH9K_MODE_11A, CHANNEL_A},
1897 {ATH9K_MODE_SEL_11B, CHANNEL_B}, 1897 {ATH9K_MODE_11B, CHANNEL_B},
1898 {ATH9K_MODE_SEL_11G, CHANNEL_G}, 1898 {ATH9K_MODE_11G, CHANNEL_G},
1899 {ATH9K_MODE_SEL_11NG_HT20, CHANNEL_G_HT20}, 1899 {ATH9K_MODE_11NG_HT20, CHANNEL_G_HT20},
1900 {ATH9K_MODE_SEL_11NG_HT40PLUS, CHANNEL_G_HT40PLUS}, 1900 {ATH9K_MODE_11NG_HT40PLUS, CHANNEL_G_HT40PLUS},
1901 {ATH9K_MODE_SEL_11NG_HT40MINUS, CHANNEL_G_HT40MINUS}, 1901 {ATH9K_MODE_11NG_HT40MINUS, CHANNEL_G_HT40MINUS},
1902 {ATH9K_MODE_SEL_11NA_HT20, CHANNEL_A_HT20}, 1902 {ATH9K_MODE_11NA_HT20, CHANNEL_A_HT20},
1903 {ATH9K_MODE_SEL_11NA_HT40PLUS, CHANNEL_A_HT40PLUS}, 1903 {ATH9K_MODE_11NA_HT40PLUS, CHANNEL_A_HT40PLUS},
1904 {ATH9K_MODE_SEL_11NA_HT40MINUS, CHANNEL_A_HT40MINUS}, 1904 {ATH9K_MODE_11NA_HT40MINUS, CHANNEL_A_HT40MINUS},
1905}; 1905};
1906 1906
1907static struct japan_bandcheck j_bandcheck[] = { 1907static struct japan_bandcheck j_bandcheck[] = {
diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c
index debd7f46d44a..157f830ee6b8 100644
--- a/drivers/net/wireless/ath9k/xmit.c
+++ b/drivers/net/wireless/ath9k/xmit.c
@@ -408,7 +408,7 @@ static int ath_tx_prepare(struct ath_softc *sc,
408 if (txctl->min_rate) 408 if (txctl->min_rate)
409 rcs[0].rix = ath_rate_findrateix(sc, txctl->min_rate); 409 rcs[0].rix = ath_rate_findrateix(sc, txctl->min_rate);
410 else 410 else
411 rcs[0].rix = sc->sc_minrateix; 411 rcs[0].rix = 0;
412 rcs[0].tries = ATH_MGT_TXMAXTRY; 412 rcs[0].tries = ATH_MGT_TXMAXTRY;
413 } 413 }
414 rix = rcs[0].rix; 414 rix = rcs[0].rix;