aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2011-07-22 17:51:16 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-07-22 17:51:16 -0400
commit41bf37117b47fc5ce2aae91f6a108e7e42e0b046 (patch)
treed5c8f24075313edfe548256dd931527f1569921e /drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
parent415b3334a21aa67806c52d1acf4e72e14f7f402f (diff)
parent6e6e8c510a84fe3237ef02b954e58cca6a3f4b1a (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn-rxon.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rxon.c115
1 files changed, 105 insertions, 10 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
index dc64f2515357..d42ef1763a71 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
@@ -40,7 +40,7 @@ static int iwlagn_disable_bss(struct iwl_priv *priv,
40 int ret; 40 int ret;
41 41
42 send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; 42 send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
43 ret = trans_send_cmd_pdu(priv, ctx->rxon_cmd, 43 ret = trans_send_cmd_pdu(&priv->trans, ctx->rxon_cmd,
44 CMD_SYNC, sizeof(*send), send); 44 CMD_SYNC, sizeof(*send), send);
45 45
46 send->filter_flags = old_filter; 46 send->filter_flags = old_filter;
@@ -66,7 +66,7 @@ static int iwlagn_disable_pan(struct iwl_priv *priv,
66 66
67 send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; 67 send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
68 send->dev_type = RXON_DEV_TYPE_P2P; 68 send->dev_type = RXON_DEV_TYPE_P2P;
69 ret = trans_send_cmd_pdu(priv, ctx->rxon_cmd, 69 ret = trans_send_cmd_pdu(&priv->trans, ctx->rxon_cmd,
70 CMD_SYNC, sizeof(*send), send); 70 CMD_SYNC, sizeof(*send), send);
71 71
72 send->filter_flags = old_filter; 72 send->filter_flags = old_filter;
@@ -92,7 +92,7 @@ static int iwlagn_disconn_pan(struct iwl_priv *priv,
92 int ret; 92 int ret;
93 93
94 send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; 94 send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
95 ret = trans_send_cmd_pdu(priv, ctx->rxon_cmd, CMD_SYNC, 95 ret = trans_send_cmd_pdu(&priv->trans, ctx->rxon_cmd, CMD_SYNC,
96 sizeof(*send), send); 96 sizeof(*send), send);
97 97
98 send->filter_flags = old_filter; 98 send->filter_flags = old_filter;
@@ -121,7 +121,7 @@ static void iwlagn_update_qos(struct iwl_priv *priv,
121 ctx->qos_data.qos_active, 121 ctx->qos_data.qos_active,
122 ctx->qos_data.def_qos_parm.qos_flags); 122 ctx->qos_data.def_qos_parm.qos_flags);
123 123
124 ret = trans_send_cmd_pdu(priv, ctx->qos_cmd, CMD_SYNC, 124 ret = trans_send_cmd_pdu(&priv->trans, ctx->qos_cmd, CMD_SYNC,
125 sizeof(struct iwl_qosparam_cmd), 125 sizeof(struct iwl_qosparam_cmd),
126 &ctx->qos_data.def_qos_parm); 126 &ctx->qos_data.def_qos_parm);
127 if (ret) 127 if (ret)
@@ -180,7 +180,7 @@ static int iwlagn_send_rxon_assoc(struct iwl_priv *priv,
180 ctx->staging.ofdm_ht_triple_stream_basic_rates; 180 ctx->staging.ofdm_ht_triple_stream_basic_rates;
181 rxon_assoc.acquisition_data = ctx->staging.acquisition_data; 181 rxon_assoc.acquisition_data = ctx->staging.acquisition_data;
182 182
183 ret = trans_send_cmd_pdu(priv, ctx->rxon_assoc_cmd, 183 ret = trans_send_cmd_pdu(&priv->trans, ctx->rxon_assoc_cmd,
184 CMD_ASYNC, sizeof(rxon_assoc), &rxon_assoc); 184 CMD_ASYNC, sizeof(rxon_assoc), &rxon_assoc);
185 return ret; 185 return ret;
186} 186}
@@ -266,7 +266,7 @@ static int iwlagn_rxon_connect(struct iwl_priv *priv,
266 * Associated RXON doesn't clear the station table in uCode, 266 * Associated RXON doesn't clear the station table in uCode,
267 * so we don't need to restore stations etc. after this. 267 * so we don't need to restore stations etc. after this.
268 */ 268 */
269 ret = trans_send_cmd_pdu(priv, ctx->rxon_cmd, CMD_SYNC, 269 ret = trans_send_cmd_pdu(&priv->trans, ctx->rxon_cmd, CMD_SYNC,
270 sizeof(struct iwl_rxon_cmd), &ctx->staging); 270 sizeof(struct iwl_rxon_cmd), &ctx->staging);
271 if (ret) { 271 if (ret) {
272 IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); 272 IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
@@ -303,6 +303,98 @@ static int iwlagn_rxon_connect(struct iwl_priv *priv,
303 return 0; 303 return 0;
304} 304}
305 305
306int iwlagn_set_pan_params(struct iwl_priv *priv)
307{
308 struct iwl_wipan_params_cmd cmd;
309 struct iwl_rxon_context *ctx_bss, *ctx_pan;
310 int slot0 = 300, slot1 = 0;
311 int ret;
312
313 if (priv->valid_contexts == BIT(IWL_RXON_CTX_BSS))
314 return 0;
315
316 BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
317
318 lockdep_assert_held(&priv->mutex);
319
320 ctx_bss = &priv->contexts[IWL_RXON_CTX_BSS];
321 ctx_pan = &priv->contexts[IWL_RXON_CTX_PAN];
322
323 /*
324 * If the PAN context is inactive, then we don't need
325 * to update the PAN parameters, the last thing we'll
326 * have done before it goes inactive is making the PAN
327 * parameters be WLAN-only.
328 */
329 if (!ctx_pan->is_active)
330 return 0;
331
332 memset(&cmd, 0, sizeof(cmd));
333
334 /* only 2 slots are currently allowed */
335 cmd.num_slots = 2;
336
337 cmd.slots[0].type = 0; /* BSS */
338 cmd.slots[1].type = 1; /* PAN */
339
340 if (priv->hw_roc_channel) {
341 /* both contexts must be used for this to happen */
342 slot1 = priv->hw_roc_duration;
343 slot0 = IWL_MIN_SLOT_TIME;
344 } else if (ctx_bss->vif && ctx_pan->vif) {
345 int bcnint = ctx_pan->beacon_int;
346 int dtim = ctx_pan->vif->bss_conf.dtim_period ?: 1;
347
348 /* should be set, but seems unused?? */
349 cmd.flags |= cpu_to_le16(IWL_WIPAN_PARAMS_FLG_SLOTTED_MODE);
350
351 if (ctx_pan->vif->type == NL80211_IFTYPE_AP &&
352 bcnint &&
353 bcnint != ctx_bss->beacon_int) {
354 IWL_ERR(priv,
355 "beacon intervals don't match (%d, %d)\n",
356 ctx_bss->beacon_int, ctx_pan->beacon_int);
357 } else
358 bcnint = max_t(int, bcnint,
359 ctx_bss->beacon_int);
360 if (!bcnint)
361 bcnint = DEFAULT_BEACON_INTERVAL;
362 slot0 = bcnint / 2;
363 slot1 = bcnint - slot0;
364
365 if (test_bit(STATUS_SCAN_HW, &priv->status) ||
366 (!ctx_bss->vif->bss_conf.idle &&
367 !ctx_bss->vif->bss_conf.assoc)) {
368 slot0 = dtim * bcnint * 3 - IWL_MIN_SLOT_TIME;
369 slot1 = IWL_MIN_SLOT_TIME;
370 } else if (!ctx_pan->vif->bss_conf.idle &&
371 !ctx_pan->vif->bss_conf.assoc) {
372 slot1 = bcnint * 3 - IWL_MIN_SLOT_TIME;
373 slot0 = IWL_MIN_SLOT_TIME;
374 }
375 } else if (ctx_pan->vif) {
376 slot0 = 0;
377 slot1 = max_t(int, 1, ctx_pan->vif->bss_conf.dtim_period) *
378 ctx_pan->beacon_int;
379 slot1 = max_t(int, DEFAULT_BEACON_INTERVAL, slot1);
380
381 if (test_bit(STATUS_SCAN_HW, &priv->status)) {
382 slot0 = slot1 * 3 - IWL_MIN_SLOT_TIME;
383 slot1 = IWL_MIN_SLOT_TIME;
384 }
385 }
386
387 cmd.slots[0].width = cpu_to_le16(slot0);
388 cmd.slots[1].width = cpu_to_le16(slot1);
389
390 ret = trans_send_cmd_pdu(&priv->trans, REPLY_WIPAN_PARAMS, CMD_SYNC,
391 sizeof(cmd), &cmd);
392 if (ret)
393 IWL_ERR(priv, "Error setting PAN parameters (%d)\n", ret);
394
395 return ret;
396}
397
306/** 398/**
307 * iwlagn_commit_rxon - commit staging_rxon to hardware 399 * iwlagn_commit_rxon - commit staging_rxon to hardware
308 * 400 *
@@ -345,8 +437,8 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
345 /* always get timestamp with Rx frame */ 437 /* always get timestamp with Rx frame */
346 ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK; 438 ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;
347 439
348 if (ctx->ctxid == IWL_RXON_CTX_PAN && priv->_agn.hw_roc_channel) { 440 if (ctx->ctxid == IWL_RXON_CTX_PAN && priv->hw_roc_channel) {
349 struct ieee80211_channel *chan = priv->_agn.hw_roc_channel; 441 struct ieee80211_channel *chan = priv->hw_roc_channel;
350 442
351 iwl_set_rxon_channel(priv, chan, ctx); 443 iwl_set_rxon_channel(priv, chan, ctx);
352 iwl_set_flags_for_band(priv, ctx, chan->band, NULL); 444 iwl_set_flags_for_band(priv, ctx, chan->band, NULL);
@@ -694,8 +786,8 @@ static void iwlagn_chain_noise_reset(struct iwl_priv *priv)
694 786
695 memset(&cmd, 0, sizeof(cmd)); 787 memset(&cmd, 0, sizeof(cmd));
696 iwl_set_calib_hdr(&cmd.hdr, 788 iwl_set_calib_hdr(&cmd.hdr,
697 priv->_agn.phy_calib_chain_noise_reset_cmd); 789 priv->phy_calib_chain_noise_reset_cmd);
698 ret = trans_send_cmd_pdu(priv, 790 ret = trans_send_cmd_pdu(&priv->trans,
699 REPLY_PHY_CALIBRATION_CMD, 791 REPLY_PHY_CALIBRATION_CMD,
700 CMD_SYNC, sizeof(cmd), &cmd); 792 CMD_SYNC, sizeof(cmd), &cmd);
701 if (ret) 793 if (ret)
@@ -762,6 +854,9 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
762 iwl_wake_any_queue(priv, ctx); 854 iwl_wake_any_queue(priv, ctx);
763 } 855 }
764 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 856 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
857
858 if (ctx->ctxid == IWL_RXON_CTX_BSS)
859 priv->have_rekey_data = false;
765 } 860 }
766 861
767 iwlagn_bt_coex_rssi_monitor(priv); 862 iwlagn_bt_coex_rssi_monitor(priv);