diff options
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 0ee8cc296e48..2a89747d3473 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; |
