aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi
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
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')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c145
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c32
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c174
7 files changed, 185 insertions, 175 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 519e8922d9f4..9a0fb80023ab 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -2008,6 +2008,150 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
2008 return rc; 2008 return rc;
2009} 2009}
2010 2010
2011/**
2012 * iwl3945_commit_rxon - commit staging_rxon to hardware
2013 *
2014 * The RXON command in staging_rxon is committed to the hardware and
2015 * the active_rxon structure is updated with the new data. This
2016 * function correctly transitions out of the RXON_ASSOC_MSK state if
2017 * a HW tune is required based on the RXON structure changes.
2018 */
2019static int iwl3945_commit_rxon(struct iwl_priv *priv)
2020{
2021 /* cast away the const for active_rxon in this function */
2022 struct iwl3945_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
2023 struct iwl3945_rxon_cmd *staging_rxon = (void *)&priv->staging_rxon;
2024 int rc = 0;
2025 bool new_assoc =
2026 !!(priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK);
2027
2028 if (!iwl_is_alive(priv))
2029 return -1;
2030
2031 /* always get timestamp with Rx frame */
2032 staging_rxon->flags |= RXON_FLG_TSF2HOST_MSK;
2033
2034 /* select antenna */
2035 staging_rxon->flags &=
2036 ~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK);
2037 staging_rxon->flags |= iwl3945_get_antenna_flags(priv);
2038
2039 rc = iwl_check_rxon_cmd(priv);
2040 if (rc) {
2041 IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
2042 return -EINVAL;
2043 }
2044
2045 /* If we don't need to send a full RXON, we can use
2046 * iwl3945_rxon_assoc_cmd which is used to reconfigure filter
2047 * and other flags for the current radio configuration. */
2048 if (!iwl_full_rxon_required(priv)) {
2049 rc = iwl_send_rxon_assoc(priv);
2050 if (rc) {
2051 IWL_ERR(priv, "Error setting RXON_ASSOC "
2052 "configuration (%d).\n", rc);
2053 return rc;
2054 }
2055
2056 memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
2057
2058 return 0;
2059 }
2060
2061 /* If we are currently associated and the new config requires
2062 * an RXON_ASSOC and the new config wants the associated mask enabled,
2063 * we must clear the associated from the active configuration
2064 * before we apply the new config */
2065 if (iwl_is_associated(priv) && new_assoc) {
2066 IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
2067 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2068
2069 /*
2070 * reserved4 and 5 could have been filled by the iwlcore code.
2071 * Let's clear them before pushing to the 3945.
2072 */
2073 active_rxon->reserved4 = 0;
2074 active_rxon->reserved5 = 0;
2075 rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
2076 sizeof(struct iwl3945_rxon_cmd),
2077 &priv->active_rxon);
2078
2079 /* If the mask clearing failed then we set
2080 * active_rxon back to what it was previously */
2081 if (rc) {
2082 active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK;
2083 IWL_ERR(priv, "Error clearing ASSOC_MSK on current "
2084 "configuration (%d).\n", rc);
2085 return rc;
2086 }
2087 }
2088
2089 IWL_DEBUG_INFO(priv, "Sending RXON\n"
2090 "* with%s RXON_FILTER_ASSOC_MSK\n"
2091 "* channel = %d\n"
2092 "* bssid = %pM\n",
2093 (new_assoc ? "" : "out"),
2094 le16_to_cpu(staging_rxon->channel),
2095 staging_rxon->bssid_addr);
2096
2097 /*
2098 * reserved4 and 5 could have been filled by the iwlcore code.
2099 * Let's clear them before pushing to the 3945.
2100 */
2101 staging_rxon->reserved4 = 0;
2102 staging_rxon->reserved5 = 0;
2103
2104 iwl_set_rxon_hwcrypto(priv, !priv->hw_params.sw_crypto);
2105
2106 /* Apply the new configuration */
2107 rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
2108 sizeof(struct iwl3945_rxon_cmd),
2109 staging_rxon);
2110 if (rc) {
2111 IWL_ERR(priv, "Error setting new configuration (%d).\n", rc);
2112 return rc;
2113 }
2114
2115 memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
2116
2117 iwl3945_clear_stations_table(priv);
2118
2119 /* If we issue a new RXON command which required a tune then we must
2120 * send a new TXPOWER command or we won't be able to Tx any frames */
2121 rc = priv->cfg->ops->lib->send_tx_power(priv);
2122 if (rc) {
2123 IWL_ERR(priv, "Error setting Tx power (%d).\n", rc);
2124 return rc;
2125 }
2126
2127 /* Add the broadcast address so we can send broadcast frames */
2128 if (iwl3945_add_station(priv, iwl_bcast_addr, 0, 0) ==
2129 IWL_INVALID_STATION) {
2130 IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n");
2131 return -EIO;
2132 }
2133
2134 /* If we have set the ASSOC_MSK and we are in BSS mode then
2135 * add the IWL_AP_ID to the station rate table */
2136 if (iwl_is_associated(priv) &&
2137 (priv->iw_mode == NL80211_IFTYPE_STATION))
2138 if (iwl3945_add_station(priv, priv->active_rxon.bssid_addr,
2139 1, 0)
2140 == IWL_INVALID_STATION) {
2141 IWL_ERR(priv, "Error adding AP address for transmit\n");
2142 return -EIO;
2143 }
2144
2145 /* Init the hardware's rate fallback order based on the band */
2146 rc = iwl3945_init_hw_rate_table(priv);
2147 if (rc) {
2148 IWL_ERR(priv, "Error setting HW rate table: %02X\n", rc);
2149 return -EIO;
2150 }
2151
2152 return 0;
2153}
2154
2011/* will add 3945 channel switch cmd handling later */ 2155/* will add 3945 channel switch cmd handling later */
2012int iwl3945_hw_channel_switch(struct iwl_priv *priv, u16 channel) 2156int iwl3945_hw_channel_switch(struct iwl_priv *priv, u16 channel)
2013{ 2157{
@@ -2775,6 +2919,7 @@ static int iwl3945_load_bsm(struct iwl_priv *priv)
2775 2919
2776static struct iwl_hcmd_ops iwl3945_hcmd = { 2920static struct iwl_hcmd_ops iwl3945_hcmd = {
2777 .rxon_assoc = iwl3945_send_rxon_assoc, 2921 .rxon_assoc = iwl3945_send_rxon_assoc,
2922 .commit_rxon = iwl3945_commit_rxon,
2778}; 2923};
2779 2924
2780static struct iwl_lib_ops iwl3945_lib = { 2925static struct iwl_lib_ops iwl3945_lib = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index 13b191f155ad..8e3e8161526a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -207,6 +207,7 @@ extern int iwl3945_send_add_station(struct iwl_priv *priv,
207 struct iwl3945_addsta_cmd *sta, u8 flags); 207 struct iwl3945_addsta_cmd *sta, u8 flags);
208extern u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *bssid, 208extern u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *bssid,
209 int is_ap, u8 flags); 209 int is_ap, u8 flags);
210extern void iwl3945_clear_stations_table(struct iwl_priv *priv);
210extern int iwl3945_power_init_handle(struct iwl_priv *priv); 211extern int iwl3945_power_init_handle(struct iwl_priv *priv);
211extern int iwl3945_eeprom_init(struct iwl_priv *priv); 212extern int iwl3945_eeprom_init(struct iwl_priv *priv);
212extern int iwl3945_calc_db_from_ratio(int sig_ratio); 213extern int iwl3945_calc_db_from_ratio(int sig_ratio);
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 37544afbebe6..053e42091124 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2271,6 +2271,7 @@ static void iwl4965_cancel_deferred_work(struct iwl_priv *priv)
2271 2271
2272static struct iwl_hcmd_ops iwl4965_hcmd = { 2272static struct iwl_hcmd_ops iwl4965_hcmd = {
2273 .rxon_assoc = iwl4965_send_rxon_assoc, 2273 .rxon_assoc = iwl4965_send_rxon_assoc,
2274 .commit_rxon = iwl_commit_rxon,
2274}; 2275};
2275 2276
2276static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = { 2277static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 837dbad80e5e..410cba221610 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -1474,6 +1474,7 @@ int iwl5000_calc_rssi(struct iwl_priv *priv,
1474 1474
1475struct iwl_hcmd_ops iwl5000_hcmd = { 1475struct iwl_hcmd_ops iwl5000_hcmd = {
1476 .rxon_assoc = iwl5000_send_rxon_assoc, 1476 .rxon_assoc = iwl5000_send_rxon_assoc,
1477 .commit_rxon = iwl_commit_rxon,
1477}; 1478};
1478 1479
1479struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = { 1480struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 124a477ebd99..50ef649b1c97 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -102,7 +102,7 @@ MODULE_ALIAS("iwl4965");
102 * function correctly transitions out of the RXON_ASSOC_MSK state if 102 * function correctly transitions out of the RXON_ASSOC_MSK state if
103 * a HW tune is required based on the RXON structure changes. 103 * a HW tune is required based on the RXON structure changes.
104 */ 104 */
105static int iwl_commit_rxon(struct iwl_priv *priv) 105int iwl_commit_rxon(struct iwl_priv *priv)
106{ 106{
107 /* cast away the const for active_rxon in this function */ 107 /* cast away the const for active_rxon in this function */
108 struct iwl_rxon_cmd *active_rxon = (void *)&priv->active_rxon; 108 struct iwl_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
@@ -247,7 +247,7 @@ void iwl_update_chain_flags(struct iwl_priv *priv)
247{ 247{
248 248
249 iwl_set_rxon_chain(priv); 249 iwl_set_rxon_chain(priv);
250 iwl_commit_rxon(priv); 250 iwlcore_commit_rxon(priv);
251} 251}
252 252
253static void iwl_clear_free_frames(struct iwl_priv *priv) 253static void iwl_clear_free_frames(struct iwl_priv *priv)
@@ -606,7 +606,7 @@ static int iwl_set_mode(struct iwl_priv *priv, int mode)
606 return -EAGAIN; 606 return -EAGAIN;
607 } 607 }
608 608
609 iwl_commit_rxon(priv); 609 iwlcore_commit_rxon(priv);
610 610
611 return 0; 611 return 0;
612} 612}
@@ -1000,7 +1000,7 @@ static void iwl_error_recovery(struct iwl_priv *priv)
1000 memcpy(&priv->staging_rxon, &priv->recovery_rxon, 1000 memcpy(&priv->staging_rxon, &priv->recovery_rxon,
1001 sizeof(priv->staging_rxon)); 1001 sizeof(priv->staging_rxon));
1002 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 1002 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
1003 iwl_commit_rxon(priv); 1003 iwlcore_commit_rxon(priv);
1004 1004
1005 iwl_rxon_add_station(priv, priv->bssid, 1); 1005 iwl_rxon_add_station(priv, priv->bssid, 1);
1006 1006
@@ -1509,7 +1509,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
1509 iwl_reset_run_time_calib(priv); 1509 iwl_reset_run_time_calib(priv);
1510 1510
1511 /* Configure the adapter for unassociated operation */ 1511 /* Configure the adapter for unassociated operation */
1512 iwl_commit_rxon(priv); 1512 iwlcore_commit_rxon(priv);
1513 1513
1514 /* At this point, the NIC is initialized and operational */ 1514 /* At this point, the NIC is initialized and operational */
1515 iwl_rf_kill_ct_config(priv); 1515 iwl_rf_kill_ct_config(priv);
@@ -1865,7 +1865,7 @@ void iwl_post_associate(struct iwl_priv *priv)
1865 conf = ieee80211_get_hw_conf(priv->hw); 1865 conf = ieee80211_get_hw_conf(priv->hw);
1866 1866
1867 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 1867 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
1868 iwl_commit_rxon(priv); 1868 iwlcore_commit_rxon(priv);
1869 1869
1870 iwl_setup_rxon_timing(priv); 1870 iwl_setup_rxon_timing(priv);
1871 ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, 1871 ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
@@ -1900,7 +1900,7 @@ void iwl_post_associate(struct iwl_priv *priv)
1900 1900
1901 } 1901 }
1902 1902
1903 iwl_commit_rxon(priv); 1903 iwlcore_commit_rxon(priv);
1904 1904
1905 switch (priv->iw_mode) { 1905 switch (priv->iw_mode) {
1906 case NL80211_IFTYPE_STATION: 1906 case NL80211_IFTYPE_STATION:
@@ -2211,7 +2211,7 @@ static int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
2211 2211
2212 if (memcmp(&priv->active_rxon, 2212 if (memcmp(&priv->active_rxon,
2213 &priv->staging_rxon, sizeof(priv->staging_rxon))) 2213 &priv->staging_rxon, sizeof(priv->staging_rxon)))
2214 iwl_commit_rxon(priv); 2214 iwlcore_commit_rxon(priv);
2215 else 2215 else
2216 IWL_DEBUG_INFO(priv, "No re-sending same RXON configuration.\n"); 2216 IWL_DEBUG_INFO(priv, "No re-sending same RXON configuration.\n");
2217 2217
@@ -2235,7 +2235,7 @@ static void iwl_config_ap(struct iwl_priv *priv)
2235 2235
2236 /* RXON - unassoc (to set timing command) */ 2236 /* RXON - unassoc (to set timing command) */
2237 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 2237 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2238 iwl_commit_rxon(priv); 2238 iwlcore_commit_rxon(priv);
2239 2239
2240 /* RXON Timing */ 2240 /* RXON Timing */
2241 iwl_setup_rxon_timing(priv); 2241 iwl_setup_rxon_timing(priv);
@@ -2271,7 +2271,7 @@ static void iwl_config_ap(struct iwl_priv *priv)
2271 } 2271 }
2272 /* restore RXON assoc */ 2272 /* restore RXON assoc */
2273 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; 2273 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
2274 iwl_commit_rxon(priv); 2274 iwlcore_commit_rxon(priv);
2275 spin_lock_irqsave(&priv->lock, flags); 2275 spin_lock_irqsave(&priv->lock, flags);
2276 iwl_activate_qos(priv, 1); 2276 iwl_activate_qos(priv, 1);
2277 spin_unlock_irqrestore(&priv->lock, flags); 2277 spin_unlock_irqrestore(&priv->lock, flags);
@@ -2365,7 +2365,7 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw,
2365 if (priv->iw_mode == NL80211_IFTYPE_AP) 2365 if (priv->iw_mode == NL80211_IFTYPE_AP)
2366 iwl_config_ap(priv); 2366 iwl_config_ap(priv);
2367 else { 2367 else {
2368 rc = iwl_commit_rxon(priv); 2368 rc = iwlcore_commit_rxon(priv);
2369 if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc) 2369 if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc)
2370 iwl_rxon_add_station( 2370 iwl_rxon_add_station(
2371 priv, priv->active_rxon.bssid_addr, 1); 2371 priv, priv->active_rxon.bssid_addr, 1);
@@ -2374,7 +2374,7 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw,
2374 } else { 2374 } else {
2375 iwl_scan_cancel_timeout(priv, 100); 2375 iwl_scan_cancel_timeout(priv, 100);
2376 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 2376 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2377 iwl_commit_rxon(priv); 2377 iwlcore_commit_rxon(priv);
2378 } 2378 }
2379 2379
2380 done: 2380 done:
@@ -2396,7 +2396,7 @@ static void iwl_mac_remove_interface(struct ieee80211_hw *hw,
2396 if (iwl_is_ready_rf(priv)) { 2396 if (iwl_is_ready_rf(priv)) {
2397 iwl_scan_cancel_timeout(priv, 100); 2397 iwl_scan_cancel_timeout(priv, 100);
2398 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 2398 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2399 iwl_commit_rxon(priv); 2399 iwlcore_commit_rxon(priv);
2400 } 2400 }
2401 if (priv->vif == conf->vif) { 2401 if (priv->vif == conf->vif) {
2402 priv->vif = NULL; 2402 priv->vif = NULL;
@@ -2623,7 +2623,7 @@ static void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
2623 if (priv->iw_mode != NL80211_IFTYPE_AP) { 2623 if (priv->iw_mode != NL80211_IFTYPE_AP) {
2624 iwl_scan_cancel_timeout(priv, 100); 2624 iwl_scan_cancel_timeout(priv, 100);
2625 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 2625 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2626 iwl_commit_rxon(priv); 2626 iwlcore_commit_rxon(priv);
2627 } 2627 }
2628 2628
2629 iwl_power_update_mode(priv, 0); 2629 iwl_power_update_mode(priv, 0);
@@ -2803,7 +2803,7 @@ static ssize_t store_flags(struct device *d,
2803 else { 2803 else {
2804 IWL_DEBUG_INFO(priv, "Commit rxon.flags = 0x%04X\n", flags); 2804 IWL_DEBUG_INFO(priv, "Commit rxon.flags = 0x%04X\n", flags);
2805 priv->staging_rxon.flags = cpu_to_le32(flags); 2805 priv->staging_rxon.flags = cpu_to_le32(flags);
2806 iwl_commit_rxon(priv); 2806 iwlcore_commit_rxon(priv);
2807 } 2807 }
2808 } 2808 }
2809 mutex_unlock(&priv->mutex); 2809 mutex_unlock(&priv->mutex);
@@ -2844,7 +2844,7 @@ static ssize_t store_filter_flags(struct device *d,
2844 "0x%04X\n", filter_flags); 2844 "0x%04X\n", filter_flags);
2845 priv->staging_rxon.filter_flags = 2845 priv->staging_rxon.filter_flags =
2846 cpu_to_le32(filter_flags); 2846 cpu_to_le32(filter_flags);
2847 iwl_commit_rxon(priv); 2847 iwlcore_commit_rxon(priv);
2848 } 2848 }
2849 } 2849 }
2850 mutex_unlock(&priv->mutex); 2850 mutex_unlock(&priv->mutex);
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 04473858b9b5..c7e05953cb75 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -85,6 +85,7 @@ struct iwl_cmd;
85 85
86struct iwl_hcmd_ops { 86struct iwl_hcmd_ops {
87 int (*rxon_assoc)(struct iwl_priv *priv); 87 int (*rxon_assoc)(struct iwl_priv *priv);
88 int (*commit_rxon)(struct iwl_priv *priv);
88}; 89};
89struct iwl_hcmd_utils_ops { 90struct iwl_hcmd_utils_ops {
90 u16 (*get_hcmd_size)(u8 cmd_id, u16 len); 91 u16 (*get_hcmd_size)(u8 cmd_id, u16 len);
@@ -259,6 +260,7 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
259 struct ieee80211_bss_conf *bss_conf, 260 struct ieee80211_bss_conf *bss_conf,
260 u32 changes); 261 u32 changes);
261int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb); 262int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb);
263int iwl_commit_rxon(struct iwl_priv *priv);
262 264
263/***************************************************** 265/*****************************************************
264 * RX handlers. 266 * RX handlers.
@@ -541,6 +543,10 @@ static inline int iwl_send_rxon_assoc(struct iwl_priv *priv)
541{ 543{
542 return priv->cfg->ops->hcmd->rxon_assoc(priv); 544 return priv->cfg->ops->hcmd->rxon_assoc(priv);
543} 545}
546static inline int iwlcore_commit_rxon(struct iwl_priv *priv)
547{
548 return priv->cfg->ops->hcmd->commit_rxon(priv);
549}
544 550
545static inline const struct ieee80211_supported_band *iwl_get_hw_mode( 551static inline const struct ieee80211_supported_band *iwl_get_hw_mode(
546 struct iwl_priv *priv, enum ieee80211_band band) 552 struct iwl_priv *priv, enum ieee80211_band band)
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);