aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi
diff options
context:
space:
mode:
authorStanislaw Gruszka <sgruszka@redhat.com>2010-03-29 06:18:35 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-03-31 14:46:38 -0400
commite61146e36b40fd9d346118c40285913236c329f3 (patch)
treed98781250a92062e519798b69b0e0e8966ae259c /drivers/net/wireless/iwlwifi
parente1b3ec1a2a336c328c336cfa5485a5f0484cc90d (diff)
iwlwifi: manage QoS by mac stack
We activate/deactivate QoS and setup default queue parameters in iwlwifi driver. Mac stack do the same, so we do not need repeat that work here. Stack also will tell when disable QoS, this will fix driver when working with older APs, that do not have QoS implemented. Patch make "force = true" in iwl_active_qos() assuming we always want to do with QoS what mac stack wish. Patch also remove unused qos_cap bits, do not initialize qos_active = 0, as we have it initialized to zero by kzalloc. Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c15
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c142
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h21
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c7
5 files changed, 17 insertions, 171 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 3f0fd755a609..b431e9254c06 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -2531,7 +2531,6 @@ void iwl_post_associate(struct iwl_priv *priv)
2531{ 2531{
2532 struct ieee80211_conf *conf = NULL; 2532 struct ieee80211_conf *conf = NULL;
2533 int ret = 0; 2533 int ret = 0;
2534 unsigned long flags;
2535 2534
2536 if (priv->iw_mode == NL80211_IFTYPE_AP) { 2535 if (priv->iw_mode == NL80211_IFTYPE_AP) {
2537 IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__); 2536 IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__);
@@ -2612,10 +2611,6 @@ void iwl_post_associate(struct iwl_priv *priv)
2612 break; 2611 break;
2613 } 2612 }
2614 2613
2615 spin_lock_irqsave(&priv->lock, flags);
2616 iwl_activate_qos(priv, 0);
2617 spin_unlock_irqrestore(&priv->lock, flags);
2618
2619 /* the chain noise calibration will enabled PM upon completion 2614 /* the chain noise calibration will enabled PM upon completion
2620 * If chain noise has already been run, then we need to enable 2615 * If chain noise has already been run, then we need to enable
2621 * power management here */ 2616 * power management here */
@@ -2792,7 +2787,6 @@ static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
2792void iwl_config_ap(struct iwl_priv *priv) 2787void iwl_config_ap(struct iwl_priv *priv)
2793{ 2788{
2794 int ret = 0; 2789 int ret = 0;
2795 unsigned long flags;
2796 2790
2797 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 2791 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2798 return; 2792 return;
@@ -2844,10 +2838,6 @@ void iwl_config_ap(struct iwl_priv *priv)
2844 /* restore RXON assoc */ 2838 /* restore RXON assoc */
2845 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; 2839 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
2846 iwlcore_commit_rxon(priv); 2840 iwlcore_commit_rxon(priv);
2847 iwl_reset_qos(priv);
2848 spin_lock_irqsave(&priv->lock, flags);
2849 iwl_activate_qos(priv, 1);
2850 spin_unlock_irqrestore(&priv->lock, flags);
2851 iwl_add_bcast_station(priv); 2841 iwl_add_bcast_station(priv);
2852 } 2842 }
2853 iwl_send_beacon_cmd(priv); 2843 iwl_send_beacon_cmd(priv);
@@ -3382,11 +3372,6 @@ static int iwl_init_drv(struct iwl_priv *priv)
3382 3372
3383 iwl_init_scan_params(priv); 3373 iwl_init_scan_params(priv);
3384 3374
3385 iwl_reset_qos(priv);
3386
3387 priv->qos_data.qos_active = 0;
3388 priv->qos_data.qos_cap.val = 0;
3389
3390 /* Set the tx_power_user_lmt to the lowest power level 3375 /* Set the tx_power_user_lmt to the lowest power level
3391 * this value will get overwritten by channel max power avg 3376 * this value will get overwritten by channel max power avg
3392 * from eeprom */ 3377 * from eeprom */
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 1b4408a31bff..38d19c11c47e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -223,17 +223,13 @@ EXPORT_SYMBOL(iwl_hw_detect);
223/* 223/*
224 * QoS support 224 * QoS support
225*/ 225*/
226void iwl_activate_qos(struct iwl_priv *priv, u8 force) 226static void iwl_update_qos(struct iwl_priv *priv)
227{ 227{
228 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 228 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
229 return; 229 return;
230 230
231 priv->qos_data.def_qos_parm.qos_flags = 0; 231 priv->qos_data.def_qos_parm.qos_flags = 0;
232 232
233 if (priv->qos_data.qos_cap.q_AP.queue_request &&
234 !priv->qos_data.qos_cap.q_AP.txop_request)
235 priv->qos_data.def_qos_parm.qos_flags |=
236 QOS_PARAM_FLG_TXOP_TYPE_MSK;
237 if (priv->qos_data.qos_active) 233 if (priv->qos_data.qos_active)
238 priv->qos_data.def_qos_parm.qos_flags |= 234 priv->qos_data.def_qos_parm.qos_flags |=
239 QOS_PARAM_FLG_UPDATE_EDCA_MSK; 235 QOS_PARAM_FLG_UPDATE_EDCA_MSK;
@@ -241,118 +237,14 @@ void iwl_activate_qos(struct iwl_priv *priv, u8 force)
241 if (priv->current_ht_config.is_ht) 237 if (priv->current_ht_config.is_ht)
242 priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; 238 priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
243 239
244 if (force || iwl_is_associated(priv)) { 240 IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",
245 IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n", 241 priv->qos_data.qos_active,
246 priv->qos_data.qos_active, 242 priv->qos_data.def_qos_parm.qos_flags);
247 priv->qos_data.def_qos_parm.qos_flags);
248 243
249 iwl_send_cmd_pdu_async(priv, REPLY_QOS_PARAM, 244 iwl_send_cmd_pdu_async(priv, REPLY_QOS_PARAM,
250 sizeof(struct iwl_qosparam_cmd), 245 sizeof(struct iwl_qosparam_cmd),
251 &priv->qos_data.def_qos_parm, NULL); 246 &priv->qos_data.def_qos_parm, NULL);
252 }
253} 247}
254EXPORT_SYMBOL(iwl_activate_qos);
255
256/*
257 * AC CWmin CW max AIFSN TXOP Limit TXOP Limit
258 * (802.11b) (802.11a/g)
259 * AC_BK 15 1023 7 0 0
260 * AC_BE 15 1023 3 0 0
261 * AC_VI 7 15 2 6.016ms 3.008ms
262 * AC_VO 3 7 2 3.264ms 1.504ms
263 */
264void iwl_reset_qos(struct iwl_priv *priv)
265{
266 u16 cw_min = 15;
267 u16 cw_max = 1023;
268 u8 aifs = 2;
269 bool is_legacy = false;
270 unsigned long flags;
271 int i;
272
273 spin_lock_irqsave(&priv->lock, flags);
274 /* QoS always active in AP and ADHOC mode
275 * In STA mode wait for association
276 */
277 if (priv->iw_mode == NL80211_IFTYPE_ADHOC ||
278 priv->iw_mode == NL80211_IFTYPE_AP)
279 priv->qos_data.qos_active = 1;
280 else
281 priv->qos_data.qos_active = 0;
282
283 /* check for legacy mode */
284 if ((priv->iw_mode == NL80211_IFTYPE_ADHOC &&
285 (priv->active_rate & IWL_OFDM_RATES_MASK) == 0) ||
286 (priv->iw_mode == NL80211_IFTYPE_STATION &&
287 (priv->staging_rxon.flags & RXON_FLG_SHORT_SLOT_MSK) == 0)) {
288 cw_min = 31;
289 is_legacy = 1;
290 }
291
292 if (priv->qos_data.qos_active)
293 aifs = 3;
294
295 /* AC_BE */
296 priv->qos_data.def_qos_parm.ac[0].cw_min = cpu_to_le16(cw_min);
297 priv->qos_data.def_qos_parm.ac[0].cw_max = cpu_to_le16(cw_max);
298 priv->qos_data.def_qos_parm.ac[0].aifsn = aifs;
299 priv->qos_data.def_qos_parm.ac[0].edca_txop = 0;
300 priv->qos_data.def_qos_parm.ac[0].reserved1 = 0;
301
302 if (priv->qos_data.qos_active) {
303 /* AC_BK */
304 i = 1;
305 priv->qos_data.def_qos_parm.ac[i].cw_min = cpu_to_le16(cw_min);
306 priv->qos_data.def_qos_parm.ac[i].cw_max = cpu_to_le16(cw_max);
307 priv->qos_data.def_qos_parm.ac[i].aifsn = 7;
308 priv->qos_data.def_qos_parm.ac[i].edca_txop = 0;
309 priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
310
311 /* AC_VI */
312 i = 2;
313 priv->qos_data.def_qos_parm.ac[i].cw_min =
314 cpu_to_le16((cw_min + 1) / 2 - 1);
315 priv->qos_data.def_qos_parm.ac[i].cw_max =
316 cpu_to_le16(cw_min);
317 priv->qos_data.def_qos_parm.ac[i].aifsn = 2;
318 if (is_legacy)
319 priv->qos_data.def_qos_parm.ac[i].edca_txop =
320 cpu_to_le16(6016);
321 else
322 priv->qos_data.def_qos_parm.ac[i].edca_txop =
323 cpu_to_le16(3008);
324 priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
325
326 /* AC_VO */
327 i = 3;
328 priv->qos_data.def_qos_parm.ac[i].cw_min =
329 cpu_to_le16((cw_min + 1) / 4 - 1);
330 priv->qos_data.def_qos_parm.ac[i].cw_max =
331 cpu_to_le16((cw_min + 1) / 2 - 1);
332 priv->qos_data.def_qos_parm.ac[i].aifsn = 2;
333 priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
334 if (is_legacy)
335 priv->qos_data.def_qos_parm.ac[i].edca_txop =
336 cpu_to_le16(3264);
337 else
338 priv->qos_data.def_qos_parm.ac[i].edca_txop =
339 cpu_to_le16(1504);
340 } else {
341 for (i = 1; i < 4; i++) {
342 priv->qos_data.def_qos_parm.ac[i].cw_min =
343 cpu_to_le16(cw_min);
344 priv->qos_data.def_qos_parm.ac[i].cw_max =
345 cpu_to_le16(cw_max);
346 priv->qos_data.def_qos_parm.ac[i].aifsn = aifs;
347 priv->qos_data.def_qos_parm.ac[i].edca_txop = 0;
348 priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
349 }
350 }
351 IWL_DEBUG_QOS(priv, "set QoS to default \n");
352
353 spin_unlock_irqrestore(&priv->lock, flags);
354}
355EXPORT_SYMBOL(iwl_reset_qos);
356 248
357#define MAX_BIT_RATE_40_MHZ 150 /* Mbps */ 249#define MAX_BIT_RATE_40_MHZ 150 /* Mbps */
358#define MAX_BIT_RATE_20_MHZ 72 /* Mbps */ 250#define MAX_BIT_RATE_20_MHZ 72 /* Mbps */
@@ -1894,12 +1786,6 @@ int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
1894 cpu_to_le16((params->txop * 32)); 1786 cpu_to_le16((params->txop * 32));
1895 1787
1896 priv->qos_data.def_qos_parm.ac[q].reserved1 = 0; 1788 priv->qos_data.def_qos_parm.ac[q].reserved1 = 0;
1897 priv->qos_data.qos_active = 1;
1898
1899 if (priv->iw_mode == NL80211_IFTYPE_AP)
1900 iwl_activate_qos(priv, 1);
1901 else if (priv->assoc_id && iwl_is_associated(priv))
1902 iwl_activate_qos(priv, 0);
1903 1789
1904 spin_unlock_irqrestore(&priv->lock, flags); 1790 spin_unlock_irqrestore(&priv->lock, flags);
1905 1791
@@ -2170,11 +2056,8 @@ int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
2170 IWL_DEBUG_MAC80211(priv, "leave\n"); 2056 IWL_DEBUG_MAC80211(priv, "leave\n");
2171 spin_unlock_irqrestore(&priv->lock, flags); 2057 spin_unlock_irqrestore(&priv->lock, flags);
2172 2058
2173 iwl_reset_qos(priv);
2174
2175 priv->cfg->ops->lib->post_associate(priv); 2059 priv->cfg->ops->lib->post_associate(priv);
2176 2060
2177
2178 return 0; 2061 return 0;
2179} 2062}
2180EXPORT_SYMBOL(iwl_mac_beacon_update); 2063EXPORT_SYMBOL(iwl_mac_beacon_update);
@@ -2396,6 +2279,15 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
2396 iwl_set_tx_power(priv, conf->power_level, false); 2279 iwl_set_tx_power(priv, conf->power_level, false);
2397 } 2280 }
2398 2281
2282 if (changed & IEEE80211_CONF_CHANGE_QOS) {
2283 bool qos_active = !!(conf->flags & IEEE80211_CONF_QOS);
2284
2285 spin_lock_irqsave(&priv->lock, flags);
2286 priv->qos_data.qos_active = qos_active;
2287 iwl_update_qos(priv);
2288 spin_unlock_irqrestore(&priv->lock, flags);
2289 }
2290
2399 if (!iwl_is_ready(priv)) { 2291 if (!iwl_is_ready(priv)) {
2400 IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); 2292 IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
2401 goto out; 2293 goto out;
@@ -2430,8 +2322,6 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
2430 memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_config)); 2322 memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_config));
2431 spin_unlock_irqrestore(&priv->lock, flags); 2323 spin_unlock_irqrestore(&priv->lock, flags);
2432 2324
2433 iwl_reset_qos(priv);
2434
2435 spin_lock_irqsave(&priv->lock, flags); 2325 spin_lock_irqsave(&priv->lock, flags);
2436 priv->assoc_id = 0; 2326 priv->assoc_id = 0;
2437 priv->assoc_capability = 0; 2327 priv->assoc_capability = 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 9d7a68f07882..bc04b43cad36 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -316,8 +316,7 @@ struct iwl_cfg {
316struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg, 316struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg,
317 struct ieee80211_ops *hw_ops); 317 struct ieee80211_ops *hw_ops);
318void iwl_hw_detect(struct iwl_priv *priv); 318void iwl_hw_detect(struct iwl_priv *priv);
319void iwl_reset_qos(struct iwl_priv *priv); 319void iwl_activate_qos(struct iwl_priv *priv);
320void iwl_activate_qos(struct iwl_priv *priv, u8 force);
321int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, 320int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
322 const struct ieee80211_tx_queue_params *params); 321 const struct ieee80211_tx_queue_params *params);
323void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt); 322void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 46a574080160..7f38d2d9b575 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -476,30 +476,9 @@ struct iwl_ht_config {
476 u8 non_GF_STA_present; 476 u8 non_GF_STA_present;
477}; 477};
478 478
479union iwl_qos_capabity {
480 struct {
481 u8 edca_count:4; /* bit 0-3 */
482 u8 q_ack:1; /* bit 4 */
483 u8 queue_request:1; /* bit 5 */
484 u8 txop_request:1; /* bit 6 */
485 u8 reserved:1; /* bit 7 */
486 } q_AP;
487 struct {
488 u8 acvo_APSD:1; /* bit 0 */
489 u8 acvi_APSD:1; /* bit 1 */
490 u8 ac_bk_APSD:1; /* bit 2 */
491 u8 ac_be_APSD:1; /* bit 3 */
492 u8 q_ack:1; /* bit 4 */
493 u8 max_len:2; /* bit 5-6 */
494 u8 more_data_ack:1; /* bit 7 */
495 } q_STA;
496 u8 val;
497};
498
499/* QoS structures */ 479/* QoS structures */
500struct iwl_qos_info { 480struct iwl_qos_info {
501 int qos_active; 481 int qos_active;
502 union iwl_qos_capabity qos_cap;
503 struct iwl_qosparam_cmd def_qos_parm; 482 struct iwl_qosparam_cmd def_qos_parm;
504}; 483};
505 484
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 4995134d7e4a..24c240d53f5c 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -3140,8 +3140,6 @@ void iwl3945_post_associate(struct iwl_priv *priv)
3140 break; 3140 break;
3141 } 3141 }
3142 3142
3143 iwl_activate_qos(priv, 0);
3144
3145 /* we have just associated, don't start scan too early */ 3143 /* we have just associated, don't start scan too early */
3146 priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN; 3144 priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN;
3147} 3145}
@@ -3889,11 +3887,6 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
3889 priv->iw_mode = NL80211_IFTYPE_STATION; 3887 priv->iw_mode = NL80211_IFTYPE_STATION;
3890 priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; 3888 priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;
3891 3889
3892 iwl_reset_qos(priv);
3893
3894 priv->qos_data.qos_active = 0;
3895 priv->qos_data.qos_cap.val = 0;
3896
3897 priv->tx_power_user_lmt = IWL_DEFAULT_TX_POWER; 3890 priv->tx_power_user_lmt = IWL_DEFAULT_TX_POWER;
3898 3891
3899 if (eeprom->version < EEPROM_3945_EEPROM_VERSION) { 3892 if (eeprom->version < EEPROM_3945_EEPROM_VERSION) {