diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00config.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00config.c | 164 |
1 files changed, 24 insertions, 140 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index 7910147157b5..3e4eee3ab7d2 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c | |||
@@ -86,13 +86,14 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, | |||
86 | erp.short_preamble = bss_conf->use_short_preamble; | 86 | erp.short_preamble = bss_conf->use_short_preamble; |
87 | erp.cts_protection = bss_conf->use_cts_prot; | 87 | erp.cts_protection = bss_conf->use_cts_prot; |
88 | 88 | ||
89 | erp.ack_timeout = PLCP + get_duration(ACK_SIZE, 10); | 89 | erp.slot_time = bss_conf->use_short_slot ? SHORT_SLOT_TIME : SLOT_TIME; |
90 | erp.ack_consume_time = SIFS + PLCP + get_duration(ACK_SIZE, 10); | 90 | erp.sifs = SIFS; |
91 | erp.pifs = bss_conf->use_short_slot ? SHORT_PIFS : PIFS; | ||
92 | erp.difs = bss_conf->use_short_slot ? SHORT_DIFS : DIFS; | ||
93 | erp.eifs = bss_conf->use_short_slot ? SHORT_EIFS : EIFS; | ||
91 | 94 | ||
92 | if (rt2x00dev->hw->conf.flags & IEEE80211_CONF_SHORT_SLOT_TIME) | 95 | erp.ack_timeout = PLCP + erp.difs + get_duration(ACK_SIZE, 10); |
93 | erp.ack_timeout += SHORT_DIFS; | 96 | erp.ack_consume_time = SIFS + PLCP + get_duration(ACK_SIZE, 10); |
94 | else | ||
95 | erp.ack_timeout += DIFS; | ||
96 | 97 | ||
97 | if (bss_conf->use_short_preamble) { | 98 | if (bss_conf->use_short_preamble) { |
98 | erp.ack_timeout += SHORT_PREAMBLE; | 99 | erp.ack_timeout += SHORT_PREAMBLE; |
@@ -102,16 +103,18 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, | |||
102 | erp.ack_consume_time += PREAMBLE; | 103 | erp.ack_consume_time += PREAMBLE; |
103 | } | 104 | } |
104 | 105 | ||
106 | erp.basic_rates = bss_conf->basic_rates; | ||
107 | |||
105 | rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp); | 108 | rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp); |
106 | } | 109 | } |
107 | 110 | ||
108 | void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, | 111 | void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, |
109 | enum antenna rx, enum antenna tx) | 112 | enum antenna rx, enum antenna tx) |
110 | { | 113 | { |
111 | struct rt2x00lib_conf libconf; | 114 | struct antenna_setup ant; |
112 | 115 | ||
113 | libconf.ant.rx = rx; | 116 | ant.rx = rx; |
114 | libconf.ant.tx = tx; | 117 | ant.tx = tx; |
115 | 118 | ||
116 | if (rx == rt2x00dev->link.ant.active.rx && | 119 | if (rx == rt2x00dev->link.ant.active.rx && |
117 | tx == rt2x00dev->link.ant.active.tx) | 120 | tx == rt2x00dev->link.ant.active.tx) |
@@ -129,111 +132,28 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
129 | * The latter is required since we need to recalibrate the | 132 | * The latter is required since we need to recalibrate the |
130 | * noise-sensitivity ratio for the new setup. | 133 | * noise-sensitivity ratio for the new setup. |
131 | */ | 134 | */ |
132 | rt2x00dev->ops->lib->config(rt2x00dev, &libconf, CONFIG_UPDATE_ANTENNA); | 135 | rt2x00dev->ops->lib->config_ant(rt2x00dev, &ant); |
136 | |||
133 | rt2x00lib_reset_link_tuner(rt2x00dev); | 137 | rt2x00lib_reset_link_tuner(rt2x00dev); |
134 | rt2x00_reset_link_ant_rssi(&rt2x00dev->link); | 138 | rt2x00_reset_link_ant_rssi(&rt2x00dev->link); |
135 | 139 | ||
136 | rt2x00dev->link.ant.active.rx = libconf.ant.rx; | 140 | memcpy(&rt2x00dev->link.ant.active, &ant, sizeof(ant)); |
137 | rt2x00dev->link.ant.active.tx = libconf.ant.tx; | ||
138 | 141 | ||
139 | if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) | 142 | if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) |
140 | rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK); | 143 | rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK); |
141 | } | 144 | } |
142 | 145 | ||
143 | static u32 rt2x00lib_get_basic_rates(struct ieee80211_supported_band *band) | ||
144 | { | ||
145 | const struct rt2x00_rate *rate; | ||
146 | unsigned int i; | ||
147 | u32 mask = 0; | ||
148 | |||
149 | for (i = 0; i < band->n_bitrates; i++) { | ||
150 | rate = rt2x00_get_rate(band->bitrates[i].hw_value); | ||
151 | if (rate->flags & DEV_RATE_BASIC) | ||
152 | mask |= rate->ratemask; | ||
153 | } | ||
154 | |||
155 | return mask; | ||
156 | } | ||
157 | |||
158 | void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, | 146 | void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, |
159 | struct ieee80211_conf *conf, const int force_config) | 147 | struct ieee80211_conf *conf, |
148 | unsigned int ieee80211_flags) | ||
160 | { | 149 | { |
161 | struct rt2x00lib_conf libconf; | 150 | struct rt2x00lib_conf libconf; |
162 | struct ieee80211_supported_band *band; | ||
163 | struct antenna_setup *default_ant = &rt2x00dev->default_ant; | ||
164 | struct antenna_setup *active_ant = &rt2x00dev->link.ant.active; | ||
165 | int flags = 0; | ||
166 | int short_slot_time; | ||
167 | |||
168 | /* | ||
169 | * In some situations we want to force all configurations | ||
170 | * to be reloaded (When resuming for instance). | ||
171 | */ | ||
172 | if (force_config) { | ||
173 | flags = CONFIG_UPDATE_ALL; | ||
174 | goto config; | ||
175 | } | ||
176 | |||
177 | /* | ||
178 | * Check which configuration options have been | ||
179 | * updated and should be send to the device. | ||
180 | */ | ||
181 | if (rt2x00dev->rx_status.band != conf->channel->band) | ||
182 | flags |= CONFIG_UPDATE_PHYMODE; | ||
183 | if (rt2x00dev->rx_status.freq != conf->channel->center_freq) | ||
184 | flags |= CONFIG_UPDATE_CHANNEL; | ||
185 | if (rt2x00dev->tx_power != conf->power_level) | ||
186 | flags |= CONFIG_UPDATE_TXPOWER; | ||
187 | |||
188 | /* | ||
189 | * Determining changes in the antenna setups request several checks: | ||
190 | * antenna_sel_{r,t}x = 0 | ||
191 | * -> Does active_{r,t}x match default_{r,t}x | ||
192 | * -> Is default_{r,t}x SW_DIVERSITY | ||
193 | * antenna_sel_{r,t}x = 1/2 | ||
194 | * -> Does active_{r,t}x match antenna_sel_{r,t}x | ||
195 | * The reason for not updating the antenna while SW diversity | ||
196 | * should be used is simple: Software diversity means that | ||
197 | * we should switch between the antenna's based on the | ||
198 | * quality. This means that the current antenna is good enough | ||
199 | * to work with untill the link tuner decides that an antenna | ||
200 | * switch should be performed. | ||
201 | */ | ||
202 | if (default_ant->rx != ANTENNA_SW_DIVERSITY && | ||
203 | default_ant->rx != active_ant->rx) | ||
204 | flags |= CONFIG_UPDATE_ANTENNA; | ||
205 | else if (active_ant->rx == ANTENNA_SW_DIVERSITY) | ||
206 | flags |= CONFIG_UPDATE_ANTENNA; | ||
207 | |||
208 | if (default_ant->tx != ANTENNA_SW_DIVERSITY && | ||
209 | default_ant->tx != active_ant->tx) | ||
210 | flags |= CONFIG_UPDATE_ANTENNA; | ||
211 | else if (active_ant->tx == ANTENNA_SW_DIVERSITY) | ||
212 | flags |= CONFIG_UPDATE_ANTENNA; | ||
213 | 151 | ||
214 | /* | ||
215 | * The following configuration options are never | ||
216 | * stored anywhere and will always be updated. | ||
217 | */ | ||
218 | flags |= CONFIG_UPDATE_SLOT_TIME; | ||
219 | flags |= CONFIG_UPDATE_BEACON_INT; | ||
220 | |||
221 | /* | ||
222 | * We have determined what options should be updated, | ||
223 | * now precalculate device configuration values depending | ||
224 | * on what configuration options need to be updated. | ||
225 | */ | ||
226 | config: | ||
227 | memset(&libconf, 0, sizeof(libconf)); | 152 | memset(&libconf, 0, sizeof(libconf)); |
228 | 153 | ||
229 | if (flags & CONFIG_UPDATE_PHYMODE) { | 154 | libconf.conf = conf; |
230 | band = &rt2x00dev->bands[conf->channel->band]; | ||
231 | |||
232 | libconf.band = conf->channel->band; | ||
233 | libconf.basic_rates = rt2x00lib_get_basic_rates(band); | ||
234 | } | ||
235 | 155 | ||
236 | if (flags & CONFIG_UPDATE_CHANNEL) { | 156 | if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL) { |
237 | memcpy(&libconf.rf, | 157 | memcpy(&libconf.rf, |
238 | &rt2x00dev->spec.channels[conf->channel->hw_value], | 158 | &rt2x00dev->spec.channels[conf->channel->hw_value], |
239 | sizeof(libconf.rf)); | 159 | sizeof(libconf.rf)); |
@@ -243,57 +163,21 @@ config: | |||
243 | sizeof(libconf.channel)); | 163 | sizeof(libconf.channel)); |
244 | } | 164 | } |
245 | 165 | ||
246 | if (flags & CONFIG_UPDATE_ANTENNA) { | ||
247 | if (default_ant->rx != ANTENNA_SW_DIVERSITY) | ||
248 | libconf.ant.rx = default_ant->rx; | ||
249 | else if (active_ant->rx == ANTENNA_SW_DIVERSITY) | ||
250 | libconf.ant.rx = ANTENNA_B; | ||
251 | else | ||
252 | libconf.ant.rx = active_ant->rx; | ||
253 | |||
254 | if (default_ant->tx != ANTENNA_SW_DIVERSITY) | ||
255 | libconf.ant.tx = default_ant->tx; | ||
256 | else if (active_ant->tx == ANTENNA_SW_DIVERSITY) | ||
257 | libconf.ant.tx = ANTENNA_B; | ||
258 | else | ||
259 | libconf.ant.tx = active_ant->tx; | ||
260 | } | ||
261 | |||
262 | if (flags & CONFIG_UPDATE_SLOT_TIME) { | ||
263 | short_slot_time = conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME; | ||
264 | |||
265 | libconf.slot_time = | ||
266 | short_slot_time ? SHORT_SLOT_TIME : SLOT_TIME; | ||
267 | libconf.sifs = SIFS; | ||
268 | libconf.pifs = short_slot_time ? SHORT_PIFS : PIFS; | ||
269 | libconf.difs = short_slot_time ? SHORT_DIFS : DIFS; | ||
270 | libconf.eifs = short_slot_time ? SHORT_EIFS : EIFS; | ||
271 | } | ||
272 | |||
273 | libconf.conf = conf; | ||
274 | |||
275 | /* | 166 | /* |
276 | * Start configuration. | 167 | * Start configuration. |
277 | */ | 168 | */ |
278 | rt2x00dev->ops->lib->config(rt2x00dev, &libconf, flags); | 169 | rt2x00dev->ops->lib->config(rt2x00dev, &libconf, ieee80211_flags); |
279 | 170 | ||
280 | /* | 171 | /* |
281 | * Some configuration changes affect the link quality | 172 | * Some configuration changes affect the link quality |
282 | * which means we need to reset the link tuner. | 173 | * which means we need to reset the link tuner. |
283 | */ | 174 | */ |
284 | if (flags & (CONFIG_UPDATE_CHANNEL | CONFIG_UPDATE_ANTENNA)) | 175 | if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL) |
285 | rt2x00lib_reset_link_tuner(rt2x00dev); | 176 | rt2x00lib_reset_link_tuner(rt2x00dev); |
286 | 177 | ||
287 | if (flags & CONFIG_UPDATE_PHYMODE) { | 178 | rt2x00dev->curr_band = conf->channel->band; |
288 | rt2x00dev->curr_band = conf->channel->band; | ||
289 | rt2x00dev->rx_status.band = conf->channel->band; | ||
290 | } | ||
291 | |||
292 | rt2x00dev->rx_status.freq = conf->channel->center_freq; | ||
293 | rt2x00dev->tx_power = conf->power_level; | 179 | rt2x00dev->tx_power = conf->power_level; |
294 | 180 | ||
295 | if (flags & CONFIG_UPDATE_ANTENNA) { | 181 | rt2x00dev->rx_status.band = conf->channel->band; |
296 | rt2x00dev->link.ant.active.rx = libconf.ant.rx; | 182 | rt2x00dev->rx_status.freq = conf->channel->center_freq; |
297 | rt2x00dev->link.ant.active.tx = libconf.ant.tx; | ||
298 | } | ||
299 | } | 183 | } |