diff options
author | John W. Linville <linville@tuxdriver.com> | 2010-04-15 16:21:34 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-04-15 16:21:34 -0400 |
commit | 5c01d5669356e13f0fb468944c1dd4c6a7e978ad (patch) | |
tree | fa43345288d7b25fac92b3b35360a177c4947313 /drivers/net/wireless/iwlwifi/iwl-core.c | |
parent | fea069152614cdeefba4b2bf80afcddb9c217fc8 (diff) | |
parent | a5e944f1d955f3819503348426763e21e0413ba6 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Conflicts:
Documentation/feature-removal-schedule.txt
drivers/net/wireless/ath/ath5k/phy.c
drivers/net/wireless/wl12xx/wl1271_main.c
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-core.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.c | 267 |
1 files changed, 30 insertions, 237 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 0ee8cc296e4..2a89747d347 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -66,7 +66,7 @@ MODULE_LICENSE("GPL"); | |||
66 | */ | 66 | */ |
67 | static bool bt_coex_active = true; | 67 | static bool bt_coex_active = true; |
68 | module_param(bt_coex_active, bool, S_IRUGO); | 68 | module_param(bt_coex_active, bool, S_IRUGO); |
69 | MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist\n"); | 69 | MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist"); |
70 | 70 | ||
71 | static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = { | 71 | static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = { |
72 | {COEX_CU_UNASSOC_IDLE_RP, COEX_CU_UNASSOC_IDLE_WP, | 72 | {COEX_CU_UNASSOC_IDLE_RP, COEX_CU_UNASSOC_IDLE_WP, |
@@ -141,30 +141,6 @@ const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = { | |||
141 | }; | 141 | }; |
142 | EXPORT_SYMBOL(iwl_rates); | 142 | EXPORT_SYMBOL(iwl_rates); |
143 | 143 | ||
144 | /** | ||
145 | * translate ucode response to mac80211 tx status control values | ||
146 | */ | ||
147 | void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags, | ||
148 | struct ieee80211_tx_info *info) | ||
149 | { | ||
150 | struct ieee80211_tx_rate *r = &info->control.rates[0]; | ||
151 | |||
152 | info->antenna_sel_tx = | ||
153 | ((rate_n_flags & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS); | ||
154 | if (rate_n_flags & RATE_MCS_HT_MSK) | ||
155 | r->flags |= IEEE80211_TX_RC_MCS; | ||
156 | if (rate_n_flags & RATE_MCS_GF_MSK) | ||
157 | r->flags |= IEEE80211_TX_RC_GREEN_FIELD; | ||
158 | if (rate_n_flags & RATE_MCS_HT40_MSK) | ||
159 | r->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; | ||
160 | if (rate_n_flags & RATE_MCS_DUP_MSK) | ||
161 | r->flags |= IEEE80211_TX_RC_DUP_DATA; | ||
162 | if (rate_n_flags & RATE_MCS_SGI_MSK) | ||
163 | r->flags |= IEEE80211_TX_RC_SHORT_GI; | ||
164 | r->idx = iwl_hwrate_to_mac80211_idx(rate_n_flags, info->band); | ||
165 | } | ||
166 | EXPORT_SYMBOL(iwl_hwrate_to_tx_control); | ||
167 | |||
168 | int iwl_hwrate_to_plcp_idx(u32 rate_n_flags) | 144 | int iwl_hwrate_to_plcp_idx(u32 rate_n_flags) |
169 | { | 145 | { |
170 | int idx = 0; | 146 | int idx = 0; |
@@ -196,27 +172,6 @@ int iwl_hwrate_to_plcp_idx(u32 rate_n_flags) | |||
196 | } | 172 | } |
197 | EXPORT_SYMBOL(iwl_hwrate_to_plcp_idx); | 173 | EXPORT_SYMBOL(iwl_hwrate_to_plcp_idx); |
198 | 174 | ||
199 | int iwl_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band) | ||
200 | { | ||
201 | int idx = 0; | ||
202 | int band_offset = 0; | ||
203 | |||
204 | /* HT rate format: mac80211 wants an MCS number, which is just LSB */ | ||
205 | if (rate_n_flags & RATE_MCS_HT_MSK) { | ||
206 | idx = (rate_n_flags & 0xff); | ||
207 | return idx; | ||
208 | /* Legacy rate format, search for match in table */ | ||
209 | } else { | ||
210 | if (band == IEEE80211_BAND_5GHZ) | ||
211 | band_offset = IWL_FIRST_OFDM_RATE; | ||
212 | for (idx = band_offset; idx < IWL_RATE_COUNT_LEGACY; idx++) | ||
213 | if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF)) | ||
214 | return idx - band_offset; | ||
215 | } | ||
216 | |||
217 | return -1; | ||
218 | } | ||
219 | |||
220 | u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant) | 175 | u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant) |
221 | { | 176 | { |
222 | int i; | 177 | int i; |
@@ -266,74 +221,16 @@ void iwl_hw_detect(struct iwl_priv *priv) | |||
266 | } | 221 | } |
267 | EXPORT_SYMBOL(iwl_hw_detect); | 222 | EXPORT_SYMBOL(iwl_hw_detect); |
268 | 223 | ||
269 | int iwl_hw_nic_init(struct iwl_priv *priv) | ||
270 | { | ||
271 | unsigned long flags; | ||
272 | struct iwl_rx_queue *rxq = &priv->rxq; | ||
273 | int ret; | ||
274 | |||
275 | /* nic_init */ | ||
276 | spin_lock_irqsave(&priv->lock, flags); | ||
277 | priv->cfg->ops->lib->apm_ops.init(priv); | ||
278 | |||
279 | /* Set interrupt coalescing calibration timer to default (512 usecs) */ | ||
280 | iwl_write8(priv, CSR_INT_COALESCING, IWL_HOST_INT_CALIB_TIMEOUT_DEF); | ||
281 | |||
282 | spin_unlock_irqrestore(&priv->lock, flags); | ||
283 | |||
284 | ret = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN); | ||
285 | |||
286 | priv->cfg->ops->lib->apm_ops.config(priv); | ||
287 | |||
288 | /* Allocate the RX queue, or reset if it is already allocated */ | ||
289 | if (!rxq->bd) { | ||
290 | ret = iwl_rx_queue_alloc(priv); | ||
291 | if (ret) { | ||
292 | IWL_ERR(priv, "Unable to initialize Rx queue\n"); | ||
293 | return -ENOMEM; | ||
294 | } | ||
295 | } else | ||
296 | iwl_rx_queue_reset(priv, rxq); | ||
297 | |||
298 | iwl_rx_replenish(priv); | ||
299 | |||
300 | iwl_rx_init(priv, rxq); | ||
301 | |||
302 | spin_lock_irqsave(&priv->lock, flags); | ||
303 | |||
304 | rxq->need_update = 1; | ||
305 | iwl_rx_queue_update_write_ptr(priv, rxq); | ||
306 | |||
307 | spin_unlock_irqrestore(&priv->lock, flags); | ||
308 | |||
309 | /* Allocate or reset and init all Tx and Command queues */ | ||
310 | if (!priv->txq) { | ||
311 | ret = iwl_txq_ctx_alloc(priv); | ||
312 | if (ret) | ||
313 | return ret; | ||
314 | } else | ||
315 | iwl_txq_ctx_reset(priv); | ||
316 | |||
317 | set_bit(STATUS_INIT, &priv->status); | ||
318 | |||
319 | return 0; | ||
320 | } | ||
321 | EXPORT_SYMBOL(iwl_hw_nic_init); | ||
322 | |||
323 | /* | 224 | /* |
324 | * QoS support | 225 | * QoS support |
325 | */ | 226 | */ |
326 | void iwl_activate_qos(struct iwl_priv *priv, u8 force) | 227 | static void iwl_update_qos(struct iwl_priv *priv) |
327 | { | 228 | { |
328 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 229 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
329 | return; | 230 | return; |
330 | 231 | ||
331 | priv->qos_data.def_qos_parm.qos_flags = 0; | 232 | priv->qos_data.def_qos_parm.qos_flags = 0; |
332 | 233 | ||
333 | if (priv->qos_data.qos_cap.q_AP.queue_request && | ||
334 | !priv->qos_data.qos_cap.q_AP.txop_request) | ||
335 | priv->qos_data.def_qos_parm.qos_flags |= | ||
336 | QOS_PARAM_FLG_TXOP_TYPE_MSK; | ||
337 | if (priv->qos_data.qos_active) | 234 | if (priv->qos_data.qos_active) |
338 | priv->qos_data.def_qos_parm.qos_flags |= | 235 | priv->qos_data.def_qos_parm.qos_flags |= |
339 | QOS_PARAM_FLG_UPDATE_EDCA_MSK; | 236 | QOS_PARAM_FLG_UPDATE_EDCA_MSK; |
@@ -341,118 +238,14 @@ void iwl_activate_qos(struct iwl_priv *priv, u8 force) | |||
341 | if (priv->current_ht_config.is_ht) | 238 | if (priv->current_ht_config.is_ht) |
342 | priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; | 239 | priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; |
343 | 240 | ||
344 | if (force || iwl_is_associated(priv)) { | 241 | IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n", |
345 | IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n", | 242 | priv->qos_data.qos_active, |
346 | priv->qos_data.qos_active, | 243 | priv->qos_data.def_qos_parm.qos_flags); |
347 | priv->qos_data.def_qos_parm.qos_flags); | ||
348 | |||
349 | iwl_send_cmd_pdu_async(priv, REPLY_QOS_PARAM, | ||
350 | sizeof(struct iwl_qosparam_cmd), | ||
351 | &priv->qos_data.def_qos_parm, NULL); | ||
352 | } | ||
353 | } | ||
354 | EXPORT_SYMBOL(iwl_activate_qos); | ||
355 | |||
356 | /* | ||
357 | * AC CWmin CW max AIFSN TXOP Limit TXOP Limit | ||
358 | * (802.11b) (802.11a/g) | ||
359 | * AC_BK 15 1023 7 0 0 | ||
360 | * AC_BE 15 1023 3 0 0 | ||
361 | * AC_VI 7 15 2 6.016ms 3.008ms | ||
362 | * AC_VO 3 7 2 3.264ms 1.504ms | ||
363 | */ | ||
364 | void iwl_reset_qos(struct iwl_priv *priv) | ||
365 | { | ||
366 | u16 cw_min = 15; | ||
367 | u16 cw_max = 1023; | ||
368 | u8 aifs = 2; | ||
369 | bool is_legacy = false; | ||
370 | unsigned long flags; | ||
371 | int i; | ||
372 | |||
373 | spin_lock_irqsave(&priv->lock, flags); | ||
374 | /* QoS always active in AP and ADHOC mode | ||
375 | * In STA mode wait for association | ||
376 | */ | ||
377 | if (priv->iw_mode == NL80211_IFTYPE_ADHOC || | ||
378 | priv->iw_mode == NL80211_IFTYPE_AP) | ||
379 | priv->qos_data.qos_active = 1; | ||
380 | else | ||
381 | priv->qos_data.qos_active = 0; | ||
382 | |||
383 | /* check for legacy mode */ | ||
384 | if ((priv->iw_mode == NL80211_IFTYPE_ADHOC && | ||
385 | (priv->active_rate & IWL_OFDM_RATES_MASK) == 0) || | ||
386 | (priv->iw_mode == NL80211_IFTYPE_STATION && | ||
387 | (priv->staging_rxon.flags & RXON_FLG_SHORT_SLOT_MSK) == 0)) { | ||
388 | cw_min = 31; | ||
389 | is_legacy = 1; | ||
390 | } | ||
391 | |||
392 | if (priv->qos_data.qos_active) | ||
393 | aifs = 3; | ||
394 | |||
395 | /* AC_BE */ | ||
396 | priv->qos_data.def_qos_parm.ac[0].cw_min = cpu_to_le16(cw_min); | ||
397 | priv->qos_data.def_qos_parm.ac[0].cw_max = cpu_to_le16(cw_max); | ||
398 | priv->qos_data.def_qos_parm.ac[0].aifsn = aifs; | ||
399 | priv->qos_data.def_qos_parm.ac[0].edca_txop = 0; | ||
400 | priv->qos_data.def_qos_parm.ac[0].reserved1 = 0; | ||
401 | |||
402 | if (priv->qos_data.qos_active) { | ||
403 | /* AC_BK */ | ||
404 | i = 1; | ||
405 | priv->qos_data.def_qos_parm.ac[i].cw_min = cpu_to_le16(cw_min); | ||
406 | priv->qos_data.def_qos_parm.ac[i].cw_max = cpu_to_le16(cw_max); | ||
407 | priv->qos_data.def_qos_parm.ac[i].aifsn = 7; | ||
408 | priv->qos_data.def_qos_parm.ac[i].edca_txop = 0; | ||
409 | priv->qos_data.def_qos_parm.ac[i].reserved1 = 0; | ||
410 | |||
411 | /* AC_VI */ | ||
412 | i = 2; | ||
413 | priv->qos_data.def_qos_parm.ac[i].cw_min = | ||
414 | cpu_to_le16((cw_min + 1) / 2 - 1); | ||
415 | priv->qos_data.def_qos_parm.ac[i].cw_max = | ||
416 | cpu_to_le16(cw_min); | ||
417 | priv->qos_data.def_qos_parm.ac[i].aifsn = 2; | ||
418 | if (is_legacy) | ||
419 | priv->qos_data.def_qos_parm.ac[i].edca_txop = | ||
420 | cpu_to_le16(6016); | ||
421 | else | ||
422 | priv->qos_data.def_qos_parm.ac[i].edca_txop = | ||
423 | cpu_to_le16(3008); | ||
424 | priv->qos_data.def_qos_parm.ac[i].reserved1 = 0; | ||
425 | |||
426 | /* AC_VO */ | ||
427 | i = 3; | ||
428 | priv->qos_data.def_qos_parm.ac[i].cw_min = | ||
429 | cpu_to_le16((cw_min + 1) / 4 - 1); | ||
430 | priv->qos_data.def_qos_parm.ac[i].cw_max = | ||
431 | cpu_to_le16((cw_min + 1) / 2 - 1); | ||
432 | priv->qos_data.def_qos_parm.ac[i].aifsn = 2; | ||
433 | priv->qos_data.def_qos_parm.ac[i].reserved1 = 0; | ||
434 | if (is_legacy) | ||
435 | priv->qos_data.def_qos_parm.ac[i].edca_txop = | ||
436 | cpu_to_le16(3264); | ||
437 | else | ||
438 | priv->qos_data.def_qos_parm.ac[i].edca_txop = | ||
439 | cpu_to_le16(1504); | ||
440 | } else { | ||
441 | for (i = 1; i < 4; i++) { | ||
442 | priv->qos_data.def_qos_parm.ac[i].cw_min = | ||
443 | cpu_to_le16(cw_min); | ||
444 | priv->qos_data.def_qos_parm.ac[i].cw_max = | ||
445 | cpu_to_le16(cw_max); | ||
446 | priv->qos_data.def_qos_parm.ac[i].aifsn = aifs; | ||
447 | priv->qos_data.def_qos_parm.ac[i].edca_txop = 0; | ||
448 | priv->qos_data.def_qos_parm.ac[i].reserved1 = 0; | ||
449 | } | ||
450 | } | ||
451 | IWL_DEBUG_QOS(priv, "set QoS to default \n"); | ||
452 | 244 | ||
453 | spin_unlock_irqrestore(&priv->lock, flags); | 245 | iwl_send_cmd_pdu_async(priv, REPLY_QOS_PARAM, |
246 | sizeof(struct iwl_qosparam_cmd), | ||
247 | &priv->qos_data.def_qos_parm, NULL); | ||
454 | } | 248 | } |
455 | EXPORT_SYMBOL(iwl_reset_qos); | ||
456 | 249 | ||
457 | #define MAX_BIT_RATE_40_MHZ 150 /* Mbps */ | 250 | #define MAX_BIT_RATE_40_MHZ 150 /* Mbps */ |
458 | #define MAX_BIT_RATE_20_MHZ 72 /* Mbps */ | 251 | #define MAX_BIT_RATE_20_MHZ 72 /* Mbps */ |
@@ -1092,12 +885,12 @@ void iwl_set_rxon_chain(struct iwl_priv *priv) | |||
1092 | rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS; | 885 | rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS; |
1093 | 886 | ||
1094 | /* copied from 'iwl_bg_request_scan()' */ | 887 | /* copied from 'iwl_bg_request_scan()' */ |
1095 | /* Force use of chains B and C (0x6) for Rx for 4965 | 888 | /* Force use of chains B and C (0x6) for Rx |
1096 | * Avoid A (0x1) because of its off-channel reception on A-band. | 889 | * Avoid A (0x1) for the device has off-channel reception on A-band. |
1097 | * MIMO is not used here, but value is required */ | 890 | * MIMO is not used here, but value is required */ |
1098 | if (iwl_is_monitor_mode(priv) && | 891 | if (iwl_is_monitor_mode(priv) && |
1099 | !(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) && | 892 | !(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) && |
1100 | ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965)) { | 893 | priv->cfg->off_channel_workaround) { |
1101 | rx_chain = ANT_ABC << RXON_RX_CHAIN_VALID_POS; | 894 | rx_chain = ANT_ABC << RXON_RX_CHAIN_VALID_POS; |
1102 | rx_chain |= ANT_BC << RXON_RX_CHAIN_FORCE_SEL_POS; | 895 | rx_chain |= ANT_BC << RXON_RX_CHAIN_FORCE_SEL_POS; |
1103 | rx_chain |= ANT_ABC << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS; | 896 | rx_chain |= ANT_ABC << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS; |
@@ -1584,10 +1377,11 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) | |||
1584 | int ret = 0; | 1377 | int ret = 0; |
1585 | s8 prev_tx_power = priv->tx_power_user_lmt; | 1378 | s8 prev_tx_power = priv->tx_power_user_lmt; |
1586 | 1379 | ||
1587 | if (tx_power < IWL_TX_POWER_TARGET_POWER_MIN) { | 1380 | if (tx_power < IWLAGN_TX_POWER_TARGET_POWER_MIN) { |
1588 | IWL_WARN(priv, "Requested user TXPOWER %d below lower limit %d.\n", | 1381 | IWL_WARN(priv, |
1382 | "Requested user TXPOWER %d below lower limit %d.\n", | ||
1589 | tx_power, | 1383 | tx_power, |
1590 | IWL_TX_POWER_TARGET_POWER_MIN); | 1384 | IWLAGN_TX_POWER_TARGET_POWER_MIN); |
1591 | return -EINVAL; | 1385 | return -EINVAL; |
1592 | } | 1386 | } |
1593 | 1387 | ||
@@ -1631,10 +1425,11 @@ irqreturn_t iwl_isr_legacy(int irq, void *data) | |||
1631 | struct iwl_priv *priv = data; | 1425 | struct iwl_priv *priv = data; |
1632 | u32 inta, inta_mask; | 1426 | u32 inta, inta_mask; |
1633 | u32 inta_fh; | 1427 | u32 inta_fh; |
1428 | unsigned long flags; | ||
1634 | if (!priv) | 1429 | if (!priv) |
1635 | return IRQ_NONE; | 1430 | return IRQ_NONE; |
1636 | 1431 | ||
1637 | spin_lock(&priv->lock); | 1432 | spin_lock_irqsave(&priv->lock, flags); |
1638 | 1433 | ||
1639 | /* Disable (but don't clear!) interrupts here to avoid | 1434 | /* Disable (but don't clear!) interrupts here to avoid |
1640 | * back-to-back ISRs and sporadic interrupts from our NIC. | 1435 | * back-to-back ISRs and sporadic interrupts from our NIC. |
@@ -1672,7 +1467,7 @@ irqreturn_t iwl_isr_legacy(int irq, void *data) | |||
1672 | tasklet_schedule(&priv->irq_tasklet); | 1467 | tasklet_schedule(&priv->irq_tasklet); |
1673 | 1468 | ||
1674 | unplugged: | 1469 | unplugged: |
1675 | spin_unlock(&priv->lock); | 1470 | spin_unlock_irqrestore(&priv->lock, flags); |
1676 | return IRQ_HANDLED; | 1471 | return IRQ_HANDLED; |
1677 | 1472 | ||
1678 | none: | 1473 | none: |
@@ -1680,7 +1475,7 @@ irqreturn_t iwl_isr_legacy(int irq, void *data) | |||
1680 | /* only Re-enable if diabled by irq */ | 1475 | /* only Re-enable if diabled by irq */ |
1681 | if (test_bit(STATUS_INT_ENABLED, &priv->status)) | 1476 | if (test_bit(STATUS_INT_ENABLED, &priv->status)) |
1682 | iwl_enable_interrupts(priv); | 1477 | iwl_enable_interrupts(priv); |
1683 | spin_unlock(&priv->lock); | 1478 | spin_unlock_irqrestore(&priv->lock, flags); |
1684 | return IRQ_NONE; | 1479 | return IRQ_NONE; |
1685 | } | 1480 | } |
1686 | EXPORT_SYMBOL(iwl_isr_legacy); | 1481 | EXPORT_SYMBOL(iwl_isr_legacy); |
@@ -1993,12 +1788,6 @@ int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, | |||
1993 | cpu_to_le16((params->txop * 32)); | 1788 | cpu_to_le16((params->txop * 32)); |
1994 | 1789 | ||
1995 | priv->qos_data.def_qos_parm.ac[q].reserved1 = 0; | 1790 | priv->qos_data.def_qos_parm.ac[q].reserved1 = 0; |
1996 | priv->qos_data.qos_active = 1; | ||
1997 | |||
1998 | if (priv->iw_mode == NL80211_IFTYPE_AP) | ||
1999 | iwl_activate_qos(priv, 1); | ||
2000 | else if (priv->assoc_id && iwl_is_associated(priv)) | ||
2001 | iwl_activate_qos(priv, 0); | ||
2002 | 1791 | ||
2003 | spin_unlock_irqrestore(&priv->lock, flags); | 1792 | spin_unlock_irqrestore(&priv->lock, flags); |
2004 | 1793 | ||
@@ -2013,7 +1802,7 @@ static void iwl_ht_conf(struct iwl_priv *priv, | |||
2013 | struct iwl_ht_config *ht_conf = &priv->current_ht_config; | 1802 | struct iwl_ht_config *ht_conf = &priv->current_ht_config; |
2014 | struct ieee80211_sta *sta; | 1803 | struct ieee80211_sta *sta; |
2015 | 1804 | ||
2016 | IWL_DEBUG_MAC80211(priv, "enter: \n"); | 1805 | IWL_DEBUG_MAC80211(priv, "enter:\n"); |
2017 | 1806 | ||
2018 | if (!ht_conf->is_ht) | 1807 | if (!ht_conf->is_ht) |
2019 | return; | 1808 | return; |
@@ -2269,11 +2058,8 @@ int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
2269 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 2058 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
2270 | spin_unlock_irqrestore(&priv->lock, flags); | 2059 | spin_unlock_irqrestore(&priv->lock, flags); |
2271 | 2060 | ||
2272 | iwl_reset_qos(priv); | ||
2273 | |||
2274 | priv->cfg->ops->lib->post_associate(priv); | 2061 | priv->cfg->ops->lib->post_associate(priv); |
2275 | 2062 | ||
2276 | |||
2277 | return 0; | 2063 | return 0; |
2278 | } | 2064 | } |
2279 | EXPORT_SYMBOL(iwl_mac_beacon_update); | 2065 | EXPORT_SYMBOL(iwl_mac_beacon_update); |
@@ -2495,6 +2281,15 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
2495 | iwl_set_tx_power(priv, conf->power_level, false); | 2281 | iwl_set_tx_power(priv, conf->power_level, false); |
2496 | } | 2282 | } |
2497 | 2283 | ||
2284 | if (changed & IEEE80211_CONF_CHANGE_QOS) { | ||
2285 | bool qos_active = !!(conf->flags & IEEE80211_CONF_QOS); | ||
2286 | |||
2287 | spin_lock_irqsave(&priv->lock, flags); | ||
2288 | priv->qos_data.qos_active = qos_active; | ||
2289 | iwl_update_qos(priv); | ||
2290 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2291 | } | ||
2292 | |||
2498 | if (!iwl_is_ready(priv)) { | 2293 | if (!iwl_is_ready(priv)) { |
2499 | IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); | 2294 | IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); |
2500 | goto out; | 2295 | goto out; |
@@ -2529,8 +2324,6 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw) | |||
2529 | memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_config)); | 2324 | memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_config)); |
2530 | spin_unlock_irqrestore(&priv->lock, flags); | 2325 | spin_unlock_irqrestore(&priv->lock, flags); |
2531 | 2326 | ||
2532 | iwl_reset_qos(priv); | ||
2533 | |||
2534 | spin_lock_irqsave(&priv->lock, flags); | 2327 | spin_lock_irqsave(&priv->lock, flags); |
2535 | priv->assoc_id = 0; | 2328 | priv->assoc_id = 0; |
2536 | priv->assoc_capability = 0; | 2329 | priv->assoc_capability = 0; |
@@ -2574,7 +2367,7 @@ int iwl_alloc_txq_mem(struct iwl_priv *priv) | |||
2574 | sizeof(struct iwl_tx_queue) * priv->cfg->num_of_queues, | 2367 | sizeof(struct iwl_tx_queue) * priv->cfg->num_of_queues, |
2575 | GFP_KERNEL); | 2368 | GFP_KERNEL); |
2576 | if (!priv->txq) { | 2369 | if (!priv->txq) { |
2577 | IWL_ERR(priv, "Not enough memory for txq \n"); | 2370 | IWL_ERR(priv, "Not enough memory for txq\n"); |
2578 | return -ENOMEM; | 2371 | return -ENOMEM; |
2579 | } | 2372 | } |
2580 | return 0; | 2373 | return 0; |