diff options
author | Luis R. Rodriguez <lrodriguez@atheros.com> | 2009-01-22 18:16:48 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-01-29 16:01:20 -0500 |
commit | 5f8e077c0adc0dc7cfad64cdc05276e1961a1394 (patch) | |
tree | dc918d9eacab12998d8e67f259de32dbbb409e81 /drivers/net/wireless/ath9k/main.c | |
parent | 24ed1da1337b92e3b0a89f2c2b7cd33b9a8fcb62 (diff) |
ath9k: simplify regulatory code
Now that cfg80211 has its own regulatory infrastructure we can
condense ath9k's regulatory code considerably. We only keep data
we need to provide our own regulatory_hint(), reg_notifier() and
information necessary for calibration.
Atheros hardware supports 12 world regulatory domains, since these
are custom we apply them through the the new wiphy_apply_custom_regulatory().
Although we have 12 we can consolidate these into 5 structures based on
frequency and apply a different set of flags that differentiate them on
a case by case basis through the reg_notifier().
If CRDA is not found our own custom world regulatory domain is applied,
this is identical to cfg80211's except we enable passive scan on most
frequencies.
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath9k/main.c')
-rw-r--r-- | drivers/net/wireless/ath9k/main.c | 263 |
1 files changed, 142 insertions, 121 deletions
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index b494a0d7e8b5..561a2c3adbbe 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c | |||
@@ -28,6 +28,77 @@ MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards."); | |||
28 | MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards"); | 28 | MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards"); |
29 | MODULE_LICENSE("Dual BSD/GPL"); | 29 | MODULE_LICENSE("Dual BSD/GPL"); |
30 | 30 | ||
31 | /* We use the hw_value as an index into our private channel structure */ | ||
32 | |||
33 | #define CHAN2G(_freq, _idx) { \ | ||
34 | .center_freq = (_freq), \ | ||
35 | .hw_value = (_idx), \ | ||
36 | .max_power = 30, \ | ||
37 | } | ||
38 | |||
39 | #define CHAN5G(_freq, _idx) { \ | ||
40 | .band = IEEE80211_BAND_5GHZ, \ | ||
41 | .center_freq = (_freq), \ | ||
42 | .hw_value = (_idx), \ | ||
43 | .max_power = 30, \ | ||
44 | } | ||
45 | |||
46 | /* Some 2 GHz radios are actually tunable on 2312-2732 | ||
47 | * on 5 MHz steps, we support the channels which we know | ||
48 | * we have calibration data for all cards though to make | ||
49 | * this static */ | ||
50 | static struct ieee80211_channel ath9k_2ghz_chantable[] = { | ||
51 | CHAN2G(2412, 0), /* Channel 1 */ | ||
52 | CHAN2G(2417, 1), /* Channel 2 */ | ||
53 | CHAN2G(2422, 2), /* Channel 3 */ | ||
54 | CHAN2G(2427, 3), /* Channel 4 */ | ||
55 | CHAN2G(2432, 4), /* Channel 5 */ | ||
56 | CHAN2G(2437, 5), /* Channel 6 */ | ||
57 | CHAN2G(2442, 6), /* Channel 7 */ | ||
58 | CHAN2G(2447, 7), /* Channel 8 */ | ||
59 | CHAN2G(2452, 8), /* Channel 9 */ | ||
60 | CHAN2G(2457, 9), /* Channel 10 */ | ||
61 | CHAN2G(2462, 10), /* Channel 11 */ | ||
62 | CHAN2G(2467, 11), /* Channel 12 */ | ||
63 | CHAN2G(2472, 12), /* Channel 13 */ | ||
64 | CHAN2G(2484, 13), /* Channel 14 */ | ||
65 | }; | ||
66 | |||
67 | /* Some 5 GHz radios are actually tunable on XXXX-YYYY | ||
68 | * on 5 MHz steps, we support the channels which we know | ||
69 | * we have calibration data for all cards though to make | ||
70 | * this static */ | ||
71 | static struct ieee80211_channel ath9k_5ghz_chantable[] = { | ||
72 | /* _We_ call this UNII 1 */ | ||
73 | CHAN5G(5180, 14), /* Channel 36 */ | ||
74 | CHAN5G(5200, 15), /* Channel 40 */ | ||
75 | CHAN5G(5220, 16), /* Channel 44 */ | ||
76 | CHAN5G(5240, 17), /* Channel 48 */ | ||
77 | /* _We_ call this UNII 2 */ | ||
78 | CHAN5G(5260, 18), /* Channel 52 */ | ||
79 | CHAN5G(5280, 19), /* Channel 56 */ | ||
80 | CHAN5G(5300, 20), /* Channel 60 */ | ||
81 | CHAN5G(5320, 21), /* Channel 64 */ | ||
82 | /* _We_ call this "Middle band" */ | ||
83 | CHAN5G(5500, 22), /* Channel 100 */ | ||
84 | CHAN5G(5520, 23), /* Channel 104 */ | ||
85 | CHAN5G(5540, 24), /* Channel 108 */ | ||
86 | CHAN5G(5560, 25), /* Channel 112 */ | ||
87 | CHAN5G(5580, 26), /* Channel 116 */ | ||
88 | CHAN5G(5600, 27), /* Channel 120 */ | ||
89 | CHAN5G(5620, 28), /* Channel 124 */ | ||
90 | CHAN5G(5640, 29), /* Channel 128 */ | ||
91 | CHAN5G(5660, 30), /* Channel 132 */ | ||
92 | CHAN5G(5680, 31), /* Channel 136 */ | ||
93 | CHAN5G(5700, 32), /* Channel 140 */ | ||
94 | /* _We_ call this UNII 3 */ | ||
95 | CHAN5G(5745, 33), /* Channel 149 */ | ||
96 | CHAN5G(5765, 34), /* Channel 153 */ | ||
97 | CHAN5G(5785, 35), /* Channel 157 */ | ||
98 | CHAN5G(5805, 36), /* Channel 161 */ | ||
99 | CHAN5G(5825, 37), /* Channel 165 */ | ||
100 | }; | ||
101 | |||
31 | static void ath_cache_conf_rate(struct ath_softc *sc, | 102 | static void ath_cache_conf_rate(struct ath_softc *sc, |
32 | struct ieee80211_conf *conf) | 103 | struct ieee80211_conf *conf) |
33 | { | 104 | { |
@@ -152,75 +223,6 @@ static void ath_setup_rates(struct ath_softc *sc, enum ieee80211_band band) | |||
152 | } | 223 | } |
153 | } | 224 | } |
154 | 225 | ||
155 | static int ath_setup_channels(struct ath_softc *sc) | ||
156 | { | ||
157 | struct ath_hal *ah = sc->sc_ah; | ||
158 | int nchan, i, a = 0, b = 0; | ||
159 | u8 regclassids[ATH_REGCLASSIDS_MAX]; | ||
160 | u32 nregclass = 0; | ||
161 | struct ieee80211_supported_band *band_2ghz; | ||
162 | struct ieee80211_supported_band *band_5ghz; | ||
163 | struct ieee80211_channel *chan_2ghz; | ||
164 | struct ieee80211_channel *chan_5ghz; | ||
165 | struct ath9k_channel *c; | ||
166 | |||
167 | /* Fill in ah->ah_channels */ | ||
168 | if (!ath9k_regd_init_channels(ah, ATH_CHAN_MAX, (u32 *)&nchan, | ||
169 | regclassids, ATH_REGCLASSIDS_MAX, | ||
170 | &nregclass, CTRY_DEFAULT, false, 1)) { | ||
171 | u32 rd = ah->ah_currentRD; | ||
172 | DPRINTF(sc, ATH_DBG_FATAL, | ||
173 | "Unable to collect channel list; " | ||
174 | "regdomain likely %u country code %u\n", | ||
175 | rd, CTRY_DEFAULT); | ||
176 | return -EINVAL; | ||
177 | } | ||
178 | |||
179 | band_2ghz = &sc->sbands[IEEE80211_BAND_2GHZ]; | ||
180 | band_5ghz = &sc->sbands[IEEE80211_BAND_5GHZ]; | ||
181 | chan_2ghz = sc->channels[IEEE80211_BAND_2GHZ]; | ||
182 | chan_5ghz = sc->channels[IEEE80211_BAND_5GHZ]; | ||
183 | |||
184 | for (i = 0; i < nchan; i++) { | ||
185 | c = &ah->ah_channels[i]; | ||
186 | if (IS_CHAN_2GHZ(c)) { | ||
187 | chan_2ghz[a].band = IEEE80211_BAND_2GHZ; | ||
188 | chan_2ghz[a].center_freq = c->channel; | ||
189 | chan_2ghz[a].max_power = c->maxTxPower; | ||
190 | c->chan = &chan_2ghz[a]; | ||
191 | |||
192 | if (c->privFlags & CHANNEL_DISALLOW_ADHOC) | ||
193 | chan_2ghz[a].flags |= IEEE80211_CHAN_NO_IBSS; | ||
194 | if (c->channelFlags & CHANNEL_PASSIVE) | ||
195 | chan_2ghz[a].flags |= IEEE80211_CHAN_PASSIVE_SCAN; | ||
196 | |||
197 | band_2ghz->n_channels = ++a; | ||
198 | |||
199 | DPRINTF(sc, ATH_DBG_CONFIG, "2MHz channel: %d, " | ||
200 | "channelFlags: 0x%x\n", | ||
201 | c->channel, c->channelFlags); | ||
202 | } else if (IS_CHAN_5GHZ(c)) { | ||
203 | chan_5ghz[b].band = IEEE80211_BAND_5GHZ; | ||
204 | chan_5ghz[b].center_freq = c->channel; | ||
205 | chan_5ghz[b].max_power = c->maxTxPower; | ||
206 | c->chan = &chan_5ghz[a]; | ||
207 | |||
208 | if (c->privFlags & CHANNEL_DISALLOW_ADHOC) | ||
209 | chan_5ghz[b].flags |= IEEE80211_CHAN_NO_IBSS; | ||
210 | if (c->channelFlags & CHANNEL_PASSIVE) | ||
211 | chan_5ghz[b].flags |= IEEE80211_CHAN_PASSIVE_SCAN; | ||
212 | |||
213 | band_5ghz->n_channels = ++b; | ||
214 | |||
215 | DPRINTF(sc, ATH_DBG_CONFIG, "5MHz channel: %d, " | ||
216 | "channelFlags: 0x%x\n", | ||
217 | c->channel, c->channelFlags); | ||
218 | } | ||
219 | } | ||
220 | |||
221 | return 0; | ||
222 | } | ||
223 | |||
224 | /* | 226 | /* |
225 | * Set/change channels. If the channel is really being changed, it's done | 227 | * Set/change channels. If the channel is really being changed, it's done |
226 | * by reseting the chip. To accomplish this we must first cleanup any pending | 228 | * by reseting the chip. To accomplish this we must first cleanup any pending |
@@ -582,19 +584,6 @@ irqreturn_t ath_isr(int irq, void *dev) | |||
582 | return IRQ_HANDLED; | 584 | return IRQ_HANDLED; |
583 | } | 585 | } |
584 | 586 | ||
585 | static int ath_get_channel(struct ath_softc *sc, | ||
586 | struct ieee80211_channel *chan) | ||
587 | { | ||
588 | int i; | ||
589 | |||
590 | for (i = 0; i < sc->sc_ah->ah_nchan; i++) { | ||
591 | if (sc->sc_ah->ah_channels[i].channel == chan->center_freq) | ||
592 | return i; | ||
593 | } | ||
594 | |||
595 | return -1; | ||
596 | } | ||
597 | |||
598 | static u32 ath_get_extchanmode(struct ath_softc *sc, | 587 | static u32 ath_get_extchanmode(struct ath_softc *sc, |
599 | struct ieee80211_channel *chan, | 588 | struct ieee80211_channel *chan, |
600 | enum nl80211_channel_type channel_type) | 589 | enum nl80211_channel_type channel_type) |
@@ -1349,16 +1338,12 @@ static int ath_init(u16 devid, struct ath_softc *sc) | |||
1349 | for (i = 0; i < sc->sc_keymax; i++) | 1338 | for (i = 0; i < sc->sc_keymax; i++) |
1350 | ath9k_hw_keyreset(ah, (u16) i); | 1339 | ath9k_hw_keyreset(ah, (u16) i); |
1351 | 1340 | ||
1352 | /* Collect the channel list using the default country code */ | 1341 | if (ath9k_regd_init(sc->sc_ah)) |
1353 | |||
1354 | error = ath_setup_channels(sc); | ||
1355 | if (error) | ||
1356 | goto bad; | 1342 | goto bad; |
1357 | 1343 | ||
1358 | /* default to MONITOR mode */ | 1344 | /* default to MONITOR mode */ |
1359 | sc->sc_ah->ah_opmode = NL80211_IFTYPE_MONITOR; | 1345 | sc->sc_ah->ah_opmode = NL80211_IFTYPE_MONITOR; |
1360 | 1346 | ||
1361 | |||
1362 | /* Setup rate tables */ | 1347 | /* Setup rate tables */ |
1363 | 1348 | ||
1364 | ath_rate_attach(sc); | 1349 | ath_rate_attach(sc); |
@@ -1490,18 +1475,20 @@ static int ath_init(u16 devid, struct ath_softc *sc) | |||
1490 | 1475 | ||
1491 | /* setup channels and rates */ | 1476 | /* setup channels and rates */ |
1492 | 1477 | ||
1493 | sc->sbands[IEEE80211_BAND_2GHZ].channels = | 1478 | sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable; |
1494 | sc->channels[IEEE80211_BAND_2GHZ]; | ||
1495 | sc->sbands[IEEE80211_BAND_2GHZ].bitrates = | 1479 | sc->sbands[IEEE80211_BAND_2GHZ].bitrates = |
1496 | sc->rates[IEEE80211_BAND_2GHZ]; | 1480 | sc->rates[IEEE80211_BAND_2GHZ]; |
1497 | sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; | 1481 | sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; |
1482 | sc->sbands[IEEE80211_BAND_2GHZ].n_channels = | ||
1483 | ARRAY_SIZE(ath9k_2ghz_chantable); | ||
1498 | 1484 | ||
1499 | if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes)) { | 1485 | if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes)) { |
1500 | sc->sbands[IEEE80211_BAND_5GHZ].channels = | 1486 | sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable; |
1501 | sc->channels[IEEE80211_BAND_5GHZ]; | ||
1502 | sc->sbands[IEEE80211_BAND_5GHZ].bitrates = | 1487 | sc->sbands[IEEE80211_BAND_5GHZ].bitrates = |
1503 | sc->rates[IEEE80211_BAND_5GHZ]; | 1488 | sc->rates[IEEE80211_BAND_5GHZ]; |
1504 | sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ; | 1489 | sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ; |
1490 | sc->sbands[IEEE80211_BAND_5GHZ].n_channels = | ||
1491 | ARRAY_SIZE(ath9k_5ghz_chantable); | ||
1505 | } | 1492 | } |
1506 | 1493 | ||
1507 | if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_BT_COEX) | 1494 | if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_BT_COEX) |
@@ -1550,6 +1537,9 @@ int ath_attach(u16 devid, struct ath_softc *sc) | |||
1550 | BIT(NL80211_IFTYPE_STATION) | | 1537 | BIT(NL80211_IFTYPE_STATION) | |
1551 | BIT(NL80211_IFTYPE_ADHOC); | 1538 | BIT(NL80211_IFTYPE_ADHOC); |
1552 | 1539 | ||
1540 | hw->wiphy->reg_notifier = ath9k_reg_notifier; | ||
1541 | hw->wiphy->strict_regulatory = true; | ||
1542 | |||
1553 | hw->queues = 4; | 1543 | hw->queues = 4; |
1554 | hw->max_rates = 4; | 1544 | hw->max_rates = 4; |
1555 | hw->max_rate_tries = ATH_11N_TXMAXTRY; | 1545 | hw->max_rate_tries = ATH_11N_TXMAXTRY; |
@@ -1588,11 +1578,36 @@ int ath_attach(u16 devid, struct ath_softc *sc) | |||
1588 | goto detach; | 1578 | goto detach; |
1589 | #endif | 1579 | #endif |
1590 | 1580 | ||
1581 | if (ath9k_is_world_regd(sc->sc_ah)) { | ||
1582 | /* Anything applied here (prior to wiphy registratoin) gets | ||
1583 | * saved on the wiphy orig_* parameters */ | ||
1584 | const struct ieee80211_regdomain *regd = | ||
1585 | ath9k_world_regdomain(sc->sc_ah); | ||
1586 | hw->wiphy->custom_regulatory = true; | ||
1587 | hw->wiphy->strict_regulatory = false; | ||
1588 | wiphy_apply_custom_regulatory(sc->hw->wiphy, regd); | ||
1589 | ath9k_reg_apply_radar_flags(hw->wiphy); | ||
1590 | ath9k_reg_apply_world_flags(hw->wiphy, REGDOM_SET_BY_INIT); | ||
1591 | } else { | ||
1592 | /* This gets applied in the case of the absense of CRDA, | ||
1593 | * its our own custom world regulatory domain, similar to | ||
1594 | * cfg80211's but we enable passive scanning */ | ||
1595 | const struct ieee80211_regdomain *regd = | ||
1596 | ath9k_default_world_regdomain(); | ||
1597 | wiphy_apply_custom_regulatory(sc->hw->wiphy, regd); | ||
1598 | ath9k_reg_apply_radar_flags(hw->wiphy); | ||
1599 | ath9k_reg_apply_world_flags(hw->wiphy, REGDOM_SET_BY_INIT); | ||
1600 | } | ||
1601 | |||
1591 | error = ieee80211_register_hw(hw); | 1602 | error = ieee80211_register_hw(hw); |
1592 | 1603 | ||
1604 | if (!ath9k_is_world_regd(sc->sc_ah)) | ||
1605 | regulatory_hint(hw->wiphy, sc->sc_ah->alpha2); | ||
1606 | |||
1593 | /* Initialize LED control */ | 1607 | /* Initialize LED control */ |
1594 | ath_init_leds(sc); | 1608 | ath_init_leds(sc); |
1595 | 1609 | ||
1610 | |||
1596 | return 0; | 1611 | return 0; |
1597 | detach: | 1612 | detach: |
1598 | ath_detach(sc); | 1613 | ath_detach(sc); |
@@ -1818,6 +1833,37 @@ int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc) | |||
1818 | return qnum; | 1833 | return qnum; |
1819 | } | 1834 | } |
1820 | 1835 | ||
1836 | /* XXX: Remove me once we don't depend on ath9k_channel for all | ||
1837 | * this redundant data */ | ||
1838 | static void ath9k_update_ichannel(struct ath_softc *sc, | ||
1839 | struct ath9k_channel *ichan) | ||
1840 | { | ||
1841 | struct ieee80211_hw *hw = sc->hw; | ||
1842 | struct ieee80211_channel *chan = hw->conf.channel; | ||
1843 | struct ieee80211_conf *conf = &hw->conf; | ||
1844 | |||
1845 | ichan->channel = chan->center_freq; | ||
1846 | ichan->chan = chan; | ||
1847 | |||
1848 | if (chan->band == IEEE80211_BAND_2GHZ) { | ||
1849 | ichan->chanmode = CHANNEL_G; | ||
1850 | ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM; | ||
1851 | } else { | ||
1852 | ichan->chanmode = CHANNEL_A; | ||
1853 | ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM; | ||
1854 | } | ||
1855 | |||
1856 | sc->tx_chan_width = ATH9K_HT_MACMODE_20; | ||
1857 | |||
1858 | if (conf_is_ht(conf)) { | ||
1859 | if (conf_is_ht40(conf)) | ||
1860 | sc->tx_chan_width = ATH9K_HT_MACMODE_2040; | ||
1861 | |||
1862 | ichan->chanmode = ath_get_extchanmode(sc, chan, | ||
1863 | conf->channel_type); | ||
1864 | } | ||
1865 | } | ||
1866 | |||
1821 | /**********************/ | 1867 | /**********************/ |
1822 | /* mac80211 callbacks */ | 1868 | /* mac80211 callbacks */ |
1823 | /**********************/ | 1869 | /**********************/ |
@@ -1834,16 +1880,10 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1834 | 1880 | ||
1835 | /* setup initial channel */ | 1881 | /* setup initial channel */ |
1836 | 1882 | ||
1837 | pos = ath_get_channel(sc, curchan); | 1883 | pos = curchan->hw_value; |
1838 | if (pos == -1) { | ||
1839 | DPRINTF(sc, ATH_DBG_FATAL, "Invalid channel: %d\n", curchan->center_freq); | ||
1840 | return -EINVAL; | ||
1841 | } | ||
1842 | 1884 | ||
1843 | sc->tx_chan_width = ATH9K_HT_MACMODE_20; | ||
1844 | sc->sc_ah->ah_channels[pos].chanmode = | ||
1845 | (curchan->band == IEEE80211_BAND_2GHZ) ? CHANNEL_G : CHANNEL_A; | ||
1846 | init_channel = &sc->sc_ah->ah_channels[pos]; | 1885 | init_channel = &sc->sc_ah->ah_channels[pos]; |
1886 | ath9k_update_ichannel(sc, init_channel); | ||
1847 | 1887 | ||
1848 | /* Reset SERDES registers */ | 1888 | /* Reset SERDES registers */ |
1849 | ath9k_hw_configpcipowersave(sc->sc_ah, 0); | 1889 | ath9k_hw_configpcipowersave(sc->sc_ah, 0); |
@@ -2127,32 +2167,13 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
2127 | 2167 | ||
2128 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { | 2168 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { |
2129 | struct ieee80211_channel *curchan = hw->conf.channel; | 2169 | struct ieee80211_channel *curchan = hw->conf.channel; |
2130 | int pos; | 2170 | int pos = curchan->hw_value; |
2131 | 2171 | ||
2132 | DPRINTF(sc, ATH_DBG_CONFIG, "Set channel: %d MHz\n", | 2172 | DPRINTF(sc, ATH_DBG_CONFIG, "Set channel: %d MHz\n", |
2133 | curchan->center_freq); | 2173 | curchan->center_freq); |
2134 | 2174 | ||
2135 | pos = ath_get_channel(sc, curchan); | 2175 | /* XXX: remove me eventualy */ |
2136 | if (pos == -1) { | 2176 | ath9k_update_ichannel(sc, &sc->sc_ah->ah_channels[pos]); |
2137 | DPRINTF(sc, ATH_DBG_FATAL, "Invalid channel: %d\n", | ||
2138 | curchan->center_freq); | ||
2139 | mutex_unlock(&sc->mutex); | ||
2140 | return -EINVAL; | ||
2141 | } | ||
2142 | |||
2143 | sc->tx_chan_width = ATH9K_HT_MACMODE_20; | ||
2144 | sc->sc_ah->ah_channels[pos].chanmode = | ||
2145 | (curchan->band == IEEE80211_BAND_2GHZ) ? | ||
2146 | CHANNEL_G : CHANNEL_A; | ||
2147 | |||
2148 | if (conf_is_ht(conf)) { | ||
2149 | if (conf_is_ht40(conf)) | ||
2150 | sc->tx_chan_width = ATH9K_HT_MACMODE_2040; | ||
2151 | |||
2152 | sc->sc_ah->ah_channels[pos].chanmode = | ||
2153 | ath_get_extchanmode(sc, curchan, | ||
2154 | conf->channel_type); | ||
2155 | } | ||
2156 | 2177 | ||
2157 | ath_update_chainmask(sc, conf_is_ht(conf)); | 2178 | ath_update_chainmask(sc, conf_is_ht(conf)); |
2158 | 2179 | ||