aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-core.c
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/iwl-core.c
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/iwl-core.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c142
1 files changed, 16 insertions, 126 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 1b4408a31bf..38d19c11c47 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;