diff options
author | Stanislaw Gruszka <sgruszka@redhat.com> | 2010-03-29 06:18:35 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-03-31 14:46:38 -0400 |
commit | e61146e36b40fd9d346118c40285913236c329f3 (patch) | |
tree | d98781250a92062e519798b69b0e0e8966ae259c /drivers/net/wireless/iwlwifi/iwl-core.c | |
parent | e1b3ec1a2a336c328c336cfa5485a5f0484cc90d (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.c | 142 |
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 | */ |
226 | void iwl_activate_qos(struct iwl_priv *priv, u8 force) | 226 | static 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 | } |
254 | EXPORT_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 | */ | ||
264 | void 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 | } | ||
355 | EXPORT_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 | } |
2180 | EXPORT_SYMBOL(iwl_mac_beacon_update); | 2063 | EXPORT_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; |