aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl3945-base.c
diff options
context:
space:
mode:
authorAbhijeet Kolekar <abhijeet.kolekar@intel.com>2009-04-08 14:26:37 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-04-22 16:54:41 -0400
commite0158e61108bdadd70865c2149dc829a5c84dd73 (patch)
tree7ef8284cf26e6b3bc98ff8c47a407e1d87d8edaa /drivers/net/wireless/iwlwifi/iwl3945-base.c
parent9944b938f23fdd1ce2f5da190f771f176bb51eef (diff)
iwlwifi: add commit_rxon lib
Patch adds commit_rxon lib operation to iwlwifi and iwl3945 drivers. Signed-off-by: Abhijeet Kolekar <abhijeet.kolekar@intel.com> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl3945-base.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c174
1 files changed, 15 insertions, 159 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 857393a69016..e96a726dc5c9 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -149,7 +149,7 @@ out:
149 * 149 *
150 * NOTE: This does not clear or otherwise alter the device's station table. 150 * NOTE: This does not clear or otherwise alter the device's station table.
151 */ 151 */
152static void iwl3945_clear_stations_table(struct iwl_priv *priv) 152void iwl3945_clear_stations_table(struct iwl_priv *priv)
153{ 153{
154 unsigned long flags; 154 unsigned long flags;
155 155
@@ -270,150 +270,6 @@ __le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv)
270 return 0; /* "diversity" is default if error */ 270 return 0; /* "diversity" is default if error */
271} 271}
272 272
273/**
274 * iwl3945_commit_rxon - commit staging_rxon to hardware
275 *
276 * The RXON command in staging_rxon is committed to the hardware and
277 * the active_rxon structure is updated with the new data. This
278 * function correctly transitions out of the RXON_ASSOC_MSK state if
279 * a HW tune is required based on the RXON structure changes.
280 */
281static int iwl3945_commit_rxon(struct iwl_priv *priv)
282{
283 /* cast away the const for active_rxon in this function */
284 struct iwl3945_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
285 struct iwl3945_rxon_cmd *staging_rxon = (void *)&priv->staging_rxon;
286 int rc = 0;
287 bool new_assoc =
288 !!(priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK);
289
290 if (!iwl_is_alive(priv))
291 return -1;
292
293 /* always get timestamp with Rx frame */
294 staging_rxon->flags |= RXON_FLG_TSF2HOST_MSK;
295
296 /* select antenna */
297 staging_rxon->flags &=
298 ~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK);
299 staging_rxon->flags |= iwl3945_get_antenna_flags(priv);
300
301 rc = iwl_check_rxon_cmd(priv);
302 if (rc) {
303 IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
304 return -EINVAL;
305 }
306
307 /* If we don't need to send a full RXON, we can use
308 * iwl3945_rxon_assoc_cmd which is used to reconfigure filter
309 * and other flags for the current radio configuration. */
310 if (!iwl_full_rxon_required(priv)) {
311 rc = iwl_send_rxon_assoc(priv);
312 if (rc) {
313 IWL_ERR(priv, "Error setting RXON_ASSOC "
314 "configuration (%d).\n", rc);
315 return rc;
316 }
317
318 memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
319
320 return 0;
321 }
322
323 /* If we are currently associated and the new config requires
324 * an RXON_ASSOC and the new config wants the associated mask enabled,
325 * we must clear the associated from the active configuration
326 * before we apply the new config */
327 if (iwl_is_associated(priv) && new_assoc) {
328 IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
329 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
330
331 /*
332 * reserved4 and 5 could have been filled by the iwlcore code.
333 * Let's clear them before pushing to the 3945.
334 */
335 active_rxon->reserved4 = 0;
336 active_rxon->reserved5 = 0;
337 rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
338 sizeof(struct iwl3945_rxon_cmd),
339 &priv->active_rxon);
340
341 /* If the mask clearing failed then we set
342 * active_rxon back to what it was previously */
343 if (rc) {
344 active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK;
345 IWL_ERR(priv, "Error clearing ASSOC_MSK on current "
346 "configuration (%d).\n", rc);
347 return rc;
348 }
349 }
350
351 IWL_DEBUG_INFO(priv, "Sending RXON\n"
352 "* with%s RXON_FILTER_ASSOC_MSK\n"
353 "* channel = %d\n"
354 "* bssid = %pM\n",
355 (new_assoc ? "" : "out"),
356 le16_to_cpu(staging_rxon->channel),
357 staging_rxon->bssid_addr);
358
359 /*
360 * reserved4 and 5 could have been filled by the iwlcore code.
361 * Let's clear them before pushing to the 3945.
362 */
363 staging_rxon->reserved4 = 0;
364 staging_rxon->reserved5 = 0;
365
366 iwl_set_rxon_hwcrypto(priv, !priv->hw_params.sw_crypto);
367
368 /* Apply the new configuration */
369 rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
370 sizeof(struct iwl3945_rxon_cmd),
371 staging_rxon);
372 if (rc) {
373 IWL_ERR(priv, "Error setting new configuration (%d).\n", rc);
374 return rc;
375 }
376
377 memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
378
379 iwl3945_clear_stations_table(priv);
380
381 /* If we issue a new RXON command which required a tune then we must
382 * send a new TXPOWER command or we won't be able to Tx any frames */
383 rc = priv->cfg->ops->lib->send_tx_power(priv);
384 if (rc) {
385 IWL_ERR(priv, "Error setting Tx power (%d).\n", rc);
386 return rc;
387 }
388
389 /* Add the broadcast address so we can send broadcast frames */
390 if (iwl3945_add_station(priv, iwl_bcast_addr, 0, 0) ==
391 IWL_INVALID_STATION) {
392 IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n");
393 return -EIO;
394 }
395
396 /* If we have set the ASSOC_MSK and we are in BSS mode then
397 * add the IWL_AP_ID to the station rate table */
398 if (iwl_is_associated(priv) &&
399 (priv->iw_mode == NL80211_IFTYPE_STATION))
400 if (iwl3945_add_station(priv, priv->active_rxon.bssid_addr,
401 1, 0)
402 == IWL_INVALID_STATION) {
403 IWL_ERR(priv, "Error adding AP address for transmit\n");
404 return -EIO;
405 }
406
407 /* Init the hardware's rate fallback order based on the band */
408 rc = iwl3945_init_hw_rate_table(priv);
409 if (rc) {
410 IWL_ERR(priv, "Error setting HW rate table: %02X\n", rc);
411 return -EIO;
412 }
413
414 return 0;
415}
416
417static int iwl3945_set_ccmp_dynamic_key_info(struct iwl_priv *priv, 273static int iwl3945_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
418 struct ieee80211_key_conf *keyconf, 274 struct ieee80211_key_conf *keyconf,
419 u8 sta_id) 275 u8 sta_id)
@@ -745,7 +601,7 @@ static int iwl3945_set_mode(struct iwl_priv *priv, int mode)
745 return -EAGAIN; 601 return -EAGAIN;
746 } 602 }
747 603
748 iwl3945_commit_rxon(priv); 604 iwlcore_commit_rxon(priv);
749 605
750 return 0; 606 return 0;
751} 607}
@@ -2025,7 +1881,7 @@ static void iwl3945_error_recovery(struct iwl_priv *priv)
2025 memcpy(&priv->staging_rxon, &priv->recovery_rxon, 1881 memcpy(&priv->staging_rxon, &priv->recovery_rxon,
2026 sizeof(priv->staging_rxon)); 1882 sizeof(priv->staging_rxon));
2027 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 1883 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2028 iwl3945_commit_rxon(priv); 1884 iwlcore_commit_rxon(priv);
2029 1885
2030 iwl3945_add_station(priv, priv->bssid, 1, 0); 1886 iwl3945_add_station(priv, priv->bssid, 1, 0);
2031 1887
@@ -2881,7 +2737,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
2881 iwl_send_bt_config(priv); 2737 iwl_send_bt_config(priv);
2882 2738
2883 /* Configure the adapter for unassociated operation */ 2739 /* Configure the adapter for unassociated operation */
2884 iwl3945_commit_rxon(priv); 2740 iwlcore_commit_rxon(priv);
2885 2741
2886 iwl3945_reg_txpower_periodic(priv); 2742 iwl3945_reg_txpower_periodic(priv);
2887 2743
@@ -3430,7 +3286,7 @@ void iwl3945_post_associate(struct iwl_priv *priv)
3430 conf = ieee80211_get_hw_conf(priv->hw); 3286 conf = ieee80211_get_hw_conf(priv->hw);
3431 3287
3432 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 3288 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
3433 iwl3945_commit_rxon(priv); 3289 iwlcore_commit_rxon(priv);
3434 3290
3435 memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd)); 3291 memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd));
3436 iwl3945_setup_rxon_timing(priv); 3292 iwl3945_setup_rxon_timing(priv);
@@ -3463,7 +3319,7 @@ void iwl3945_post_associate(struct iwl_priv *priv)
3463 3319
3464 } 3320 }
3465 3321
3466 iwl3945_commit_rxon(priv); 3322 iwlcore_commit_rxon(priv);
3467 3323
3468 switch (priv->iw_mode) { 3324 switch (priv->iw_mode) {
3469 case NL80211_IFTYPE_STATION: 3325 case NL80211_IFTYPE_STATION:
@@ -3740,7 +3596,7 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed)
3740 3596
3741 if (memcmp(&priv->active_rxon, 3597 if (memcmp(&priv->active_rxon,
3742 &priv->staging_rxon, sizeof(priv->staging_rxon))) 3598 &priv->staging_rxon, sizeof(priv->staging_rxon)))
3743 iwl3945_commit_rxon(priv); 3599 iwlcore_commit_rxon(priv);
3744 else 3600 else
3745 IWL_DEBUG_INFO(priv, "Not re-sending same RXON configuration\n"); 3601 IWL_DEBUG_INFO(priv, "Not re-sending same RXON configuration\n");
3746 3602
@@ -3764,7 +3620,7 @@ static void iwl3945_config_ap(struct iwl_priv *priv)
3764 3620
3765 /* RXON - unassoc (to set timing command) */ 3621 /* RXON - unassoc (to set timing command) */
3766 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 3622 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
3767 iwl3945_commit_rxon(priv); 3623 iwlcore_commit_rxon(priv);
3768 3624
3769 /* RXON Timing */ 3625 /* RXON Timing */
3770 memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd)); 3626 memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd));
@@ -3800,7 +3656,7 @@ static void iwl3945_config_ap(struct iwl_priv *priv)
3800 } 3656 }
3801 /* restore RXON assoc */ 3657 /* restore RXON assoc */
3802 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; 3658 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
3803 iwl3945_commit_rxon(priv); 3659 iwlcore_commit_rxon(priv);
3804 iwl3945_add_station(priv, iwl_bcast_addr, 0, 0); 3660 iwl3945_add_station(priv, iwl_bcast_addr, 0, 0);
3805 } 3661 }
3806 iwl3945_send_beacon_cmd(priv); 3662 iwl3945_send_beacon_cmd(priv);
@@ -3891,7 +3747,7 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
3891 if (priv->iw_mode == NL80211_IFTYPE_AP) 3747 if (priv->iw_mode == NL80211_IFTYPE_AP)
3892 iwl3945_config_ap(priv); 3748 iwl3945_config_ap(priv);
3893 else { 3749 else {
3894 rc = iwl3945_commit_rxon(priv); 3750 rc = iwlcore_commit_rxon(priv);
3895 if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc) 3751 if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc)
3896 iwl3945_add_station(priv, 3752 iwl3945_add_station(priv,
3897 priv->active_rxon.bssid_addr, 1, 0); 3753 priv->active_rxon.bssid_addr, 1, 0);
@@ -3900,7 +3756,7 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
3900 } else { 3756 } else {
3901 iwl_scan_cancel_timeout(priv, 100); 3757 iwl_scan_cancel_timeout(priv, 100);
3902 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 3758 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
3903 iwl3945_commit_rxon(priv); 3759 iwlcore_commit_rxon(priv);
3904 } 3760 }
3905 3761
3906 done: 3762 done:
@@ -3922,7 +3778,7 @@ static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw,
3922 if (iwl_is_ready_rf(priv)) { 3778 if (iwl_is_ready_rf(priv)) {
3923 iwl_scan_cancel_timeout(priv, 100); 3779 iwl_scan_cancel_timeout(priv, 100);
3924 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 3780 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
3925 iwl3945_commit_rxon(priv); 3781 iwlcore_commit_rxon(priv);
3926 } 3782 }
3927 if (priv->vif == conf->vif) { 3783 if (priv->vif == conf->vif) {
3928 priv->vif = NULL; 3784 priv->vif = NULL;
@@ -4065,7 +3921,7 @@ static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw)
4065 if (priv->iw_mode != NL80211_IFTYPE_AP) { 3921 if (priv->iw_mode != NL80211_IFTYPE_AP) {
4066 iwl_scan_cancel_timeout(priv, 100); 3922 iwl_scan_cancel_timeout(priv, 100);
4067 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 3923 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
4068 iwl3945_commit_rxon(priv); 3924 iwlcore_commit_rxon(priv);
4069 } 3925 }
4070 3926
4071 /* Per mac80211.h: This is only used in IBSS mode... */ 3927 /* Per mac80211.h: This is only used in IBSS mode... */
@@ -4191,7 +4047,7 @@ static ssize_t store_flags(struct device *d,
4191 IWL_DEBUG_INFO(priv, "Committing rxon.flags = 0x%04X\n", 4047 IWL_DEBUG_INFO(priv, "Committing rxon.flags = 0x%04X\n",
4192 flags); 4048 flags);
4193 priv->staging_rxon.flags = cpu_to_le32(flags); 4049 priv->staging_rxon.flags = cpu_to_le32(flags);
4194 iwl3945_commit_rxon(priv); 4050 iwlcore_commit_rxon(priv);
4195 } 4051 }
4196 } 4052 }
4197 mutex_unlock(&priv->mutex); 4053 mutex_unlock(&priv->mutex);
@@ -4227,7 +4083,7 @@ static ssize_t store_filter_flags(struct device *d,
4227 "0x%04X\n", filter_flags); 4083 "0x%04X\n", filter_flags);
4228 priv->staging_rxon.filter_flags = 4084 priv->staging_rxon.filter_flags =
4229 cpu_to_le32(filter_flags); 4085 cpu_to_le32(filter_flags);
4230 iwl3945_commit_rxon(priv); 4086 iwlcore_commit_rxon(priv);
4231 } 4087 }
4232 } 4088 }
4233 mutex_unlock(&priv->mutex); 4089 mutex_unlock(&priv->mutex);