aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-agn.c
diff options
context:
space:
mode:
authorSamuel Ortiz <samuel.ortiz@intel.com>2009-01-27 17:27:52 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-02-09 15:03:33 -0500
commit8ccde88a87a3dc906234b281a036fee9c7371949 (patch)
tree05bb74d5f11201e0a7c38169ecbab3509e18b686 /drivers/net/wireless/iwlwifi/iwl-agn.c
parentd14c7c1d6aef1175625ea72938b07cee072723dc (diff)
iwl3945: Getting rid of the *39_rxon iwl_priv fields
The iwl_rxon_cmd is really just a iwl3945_rxon_cmd structure extension. So, we can use the *_rxon fields from iwl_priv instead of the 3945 specific ones (*39_rxon). We have to then be careful when submitting REPLY_RXON host commands, since the command length as to be set according to the HW. As another precaution the reserved4 and reserved5 fields are cleared before being sent to the 3945. With the *39_rxon removal, a lot of duplicated code can be removed from the 3945 code base. Signed-off-by: Samuel Ortiz <samuel.ortiz@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/iwl-agn.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c358
1 files changed, 3 insertions, 355 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 6b7120a41ab2..c54a9bcbb2e1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -94,66 +94,6 @@ MODULE_ALIAS("iwl4965");
94 94
95/**************************************************************/ 95/**************************************************************/
96 96
97
98
99static void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt)
100{
101 struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
102
103 if (hw_decrypt)
104 rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK;
105 else
106 rxon->filter_flags |= RXON_FILTER_DIS_DECRYPT_MSK;
107
108}
109
110/**
111 * iwl_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed
112 * @priv: staging_rxon is compared to active_rxon
113 *
114 * If the RXON structure is changing enough to require a new tune,
115 * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that
116 * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required.
117 */
118static int iwl_full_rxon_required(struct iwl_priv *priv)
119{
120
121 /* These items are only settable from the full RXON command */
122 if (!(iwl_is_associated(priv)) ||
123 compare_ether_addr(priv->staging_rxon.bssid_addr,
124 priv->active_rxon.bssid_addr) ||
125 compare_ether_addr(priv->staging_rxon.node_addr,
126 priv->active_rxon.node_addr) ||
127 compare_ether_addr(priv->staging_rxon.wlap_bssid_addr,
128 priv->active_rxon.wlap_bssid_addr) ||
129 (priv->staging_rxon.dev_type != priv->active_rxon.dev_type) ||
130 (priv->staging_rxon.channel != priv->active_rxon.channel) ||
131 (priv->staging_rxon.air_propagation !=
132 priv->active_rxon.air_propagation) ||
133 (priv->staging_rxon.ofdm_ht_single_stream_basic_rates !=
134 priv->active_rxon.ofdm_ht_single_stream_basic_rates) ||
135 (priv->staging_rxon.ofdm_ht_dual_stream_basic_rates !=
136 priv->active_rxon.ofdm_ht_dual_stream_basic_rates) ||
137 (priv->staging_rxon.assoc_id != priv->active_rxon.assoc_id))
138 return 1;
139
140 /* flags, filter_flags, ofdm_basic_rates, and cck_basic_rates can
141 * be updated with the RXON_ASSOC command -- however only some
142 * flag transitions are allowed using RXON_ASSOC */
143
144 /* Check if we are not switching bands */
145 if ((priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) !=
146 (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK))
147 return 1;
148
149 /* Check if we are switching association toggle */
150 if ((priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) !=
151 (priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK))
152 return 1;
153
154 return 0;
155}
156
157/** 97/**
158 * iwl_commit_rxon - commit staging_rxon to hardware 98 * iwl_commit_rxon - commit staging_rxon to hardware
159 * 99 *
@@ -179,7 +119,7 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
179 * 5000, but will not damage 4965 */ 119 * 5000, but will not damage 4965 */
180 priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN; 120 priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN;
181 121
182 ret = iwl_agn_check_rxon_cmd(priv); 122 ret = iwl_check_rxon_cmd(priv);
183 if (ret) { 123 if (ret) {
184 IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n"); 124 IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
185 return -EINVAL; 125 return -EINVAL;
@@ -374,31 +314,6 @@ static unsigned int iwl_fill_beacon_frame(struct iwl_priv *priv,
374 return priv->ibss_beacon->len; 314 return priv->ibss_beacon->len;
375} 315}
376 316
377static u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv)
378{
379 int i;
380 int rate_mask;
381
382 /* Set rate mask*/
383 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
384 rate_mask = priv->active_rate_basic & IWL_CCK_RATES_MASK;
385 else
386 rate_mask = priv->active_rate_basic & IWL_OFDM_RATES_MASK;
387
388 /* Find lowest valid rate */
389 for (i = IWL_RATE_1M_INDEX; i != IWL_RATE_INVALID;
390 i = iwl_rates[i].next_ieee) {
391 if (rate_mask & (1 << i))
392 return iwl_rates[i].plcp;
393 }
394
395 /* No valid rate was found. Assign the lowest one */
396 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
397 return IWL_RATE_1M_PLCP;
398 else
399 return IWL_RATE_6M_PLCP;
400}
401
402static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv, 317static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
403 struct iwl_frame *frame, u8 rate) 318 struct iwl_frame *frame, u8 rate)
404{ 319{
@@ -771,111 +686,10 @@ static void iwl_setup_rxon_timing(struct iwl_priv *priv)
771 le16_to_cpu(priv->rxon_timing.atim_window)); 686 le16_to_cpu(priv->rxon_timing.atim_window));
772} 687}
773 688
774static void iwl_set_flags_for_band(struct iwl_priv *priv,
775 enum ieee80211_band band)
776{
777 if (band == IEEE80211_BAND_5GHZ) {
778 priv->staging_rxon.flags &=
779 ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK
780 | RXON_FLG_CCK_MSK);
781 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
782 } else {
783 /* Copied from iwl_post_associate() */
784 if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
785 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
786 else
787 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
788
789 if (priv->iw_mode == NL80211_IFTYPE_ADHOC)
790 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
791
792 priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK;
793 priv->staging_rxon.flags |= RXON_FLG_AUTO_DETECT_MSK;
794 priv->staging_rxon.flags &= ~RXON_FLG_CCK_MSK;
795 }
796}
797
798/*
799 * initialize rxon structure with default values from eeprom
800 */
801static void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode)
802{
803 const struct iwl_channel_info *ch_info;
804
805 memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon));
806
807 switch (mode) {
808 case NL80211_IFTYPE_AP:
809 priv->staging_rxon.dev_type = RXON_DEV_TYPE_AP;
810 break;
811
812 case NL80211_IFTYPE_STATION:
813 priv->staging_rxon.dev_type = RXON_DEV_TYPE_ESS;
814 priv->staging_rxon.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;
815 break;
816
817 case NL80211_IFTYPE_ADHOC:
818 priv->staging_rxon.dev_type = RXON_DEV_TYPE_IBSS;
819 priv->staging_rxon.flags = RXON_FLG_SHORT_PREAMBLE_MSK;
820 priv->staging_rxon.filter_flags = RXON_FILTER_BCON_AWARE_MSK |
821 RXON_FILTER_ACCEPT_GRP_MSK;
822 break;
823
824 case NL80211_IFTYPE_MONITOR:
825 priv->staging_rxon.dev_type = RXON_DEV_TYPE_SNIFFER;
826 priv->staging_rxon.filter_flags = RXON_FILTER_PROMISC_MSK |
827 RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_ACCEPT_GRP_MSK;
828 break;
829 default:
830 IWL_ERR(priv, "Unsupported interface type %d\n", mode);
831 break;
832 }
833
834#if 0
835 /* TODO: Figure out when short_preamble would be set and cache from
836 * that */
837 if (!hw_to_local(priv->hw)->short_preamble)
838 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
839 else
840 priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
841#endif
842
843 ch_info = iwl_get_channel_info(priv, priv->band,
844 le16_to_cpu(priv->active_rxon.channel));
845
846 if (!ch_info)
847 ch_info = &priv->channel_info[0];
848
849 /*
850 * in some case A channels are all non IBSS
851 * in this case force B/G channel
852 */
853 if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
854 !(is_channel_ibss(ch_info)))
855 ch_info = &priv->channel_info[0];
856
857 priv->staging_rxon.channel = cpu_to_le16(ch_info->channel);
858 priv->band = ch_info->band;
859
860 iwl_set_flags_for_band(priv, priv->band);
861
862 priv->staging_rxon.ofdm_basic_rates =
863 (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
864 priv->staging_rxon.cck_basic_rates =
865 (IWL_CCK_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
866
867 priv->staging_rxon.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED_MSK |
868 RXON_FLG_CHANNEL_MODE_PURE_40_MSK);
869 memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
870 memcpy(priv->staging_rxon.wlap_bssid_addr, priv->mac_addr, ETH_ALEN);
871 priv->staging_rxon.ofdm_ht_single_stream_basic_rates = 0xff;
872 priv->staging_rxon.ofdm_ht_dual_stream_basic_rates = 0xff;
873 iwl_set_rxon_chain(priv);
874}
875
876static int iwl_set_mode(struct iwl_priv *priv, int mode) 689static int iwl_set_mode(struct iwl_priv *priv, int mode)
877{ 690{
878 iwl_connection_init_rx_config(priv, mode); 691 iwl_connection_init_rx_config(priv, mode);
692 iwl_set_rxon_chain(priv);
879 memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); 693 memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
880 694
881 iwl_clear_stations_table(priv); 695 iwl_clear_stations_table(priv);
@@ -896,54 +710,6 @@ static int iwl_set_mode(struct iwl_priv *priv, int mode)
896 return 0; 710 return 0;
897} 711}
898 712
899static void iwl_set_rate(struct iwl_priv *priv)
900{
901 const struct ieee80211_supported_band *hw = NULL;
902 struct ieee80211_rate *rate;
903 int i;
904
905 hw = iwl_get_hw_mode(priv, priv->band);
906 if (!hw) {
907 IWL_ERR(priv, "Failed to set rate: unable to get hw mode\n");
908 return;
909 }
910
911 priv->active_rate = 0;
912 priv->active_rate_basic = 0;
913
914 for (i = 0; i < hw->n_bitrates; i++) {
915 rate = &(hw->bitrates[i]);
916 if (rate->hw_value < IWL_RATE_COUNT)
917 priv->active_rate |= (1 << rate->hw_value);
918 }
919
920 IWL_DEBUG_RATE("Set active_rate = %0x, active_rate_basic = %0x\n",
921 priv->active_rate, priv->active_rate_basic);
922
923 /*
924 * If a basic rate is configured, then use it (adding IWL_RATE_1M_MASK)
925 * otherwise set it to the default of all CCK rates and 6, 12, 24 for
926 * OFDM
927 */
928 if (priv->active_rate_basic & IWL_CCK_BASIC_RATES_MASK)
929 priv->staging_rxon.cck_basic_rates =
930 ((priv->active_rate_basic &
931 IWL_CCK_RATES_MASK) >> IWL_FIRST_CCK_RATE) & 0xF;
932 else
933 priv->staging_rxon.cck_basic_rates =
934 (IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
935
936 if (priv->active_rate_basic & IWL_OFDM_BASIC_RATES_MASK)
937 priv->staging_rxon.ofdm_basic_rates =
938 ((priv->active_rate_basic &
939 (IWL_OFDM_BASIC_RATES_MASK | IWL_RATE_6M_MASK)) >>
940 IWL_FIRST_OFDM_RATE) & 0xFF;
941 else
942 priv->staging_rxon.ofdm_basic_rates =
943 (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
944}
945
946
947/****************************************************************************** 713/******************************************************************************
948 * 714 *
949 * Generic RX handler implementations 715 * Generic RX handler implementations
@@ -999,19 +765,6 @@ static void iwl_rx_reply_error(struct iwl_priv *priv,
999 le32_to_cpu(pkt->u.err_resp.error_info)); 765 le32_to_cpu(pkt->u.err_resp.error_info));
1000} 766}
1001 767
1002#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
1003
1004static void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
1005{
1006 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
1007 struct iwl_rxon_cmd *rxon = (void *)&priv->active_rxon;
1008 struct iwl_csa_notification *csa = &(pkt->u.csa_notif);
1009 IWL_DEBUG_11H("CSA notif: channel %d, status %d\n",
1010 le16_to_cpu(csa->channel), le32_to_cpu(csa->status));
1011 rxon->channel = csa->channel;
1012 priv->staging_rxon.channel = csa->channel;
1013}
1014
1015static void iwl_rx_pm_sleep_notif(struct iwl_priv *priv, 768static void iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
1016 struct iwl_rx_mem_buffer *rxb) 769 struct iwl_rx_mem_buffer *rxb)
1017{ 770{
@@ -1370,27 +1123,6 @@ void iwl_rx_handle(struct iwl_priv *priv)
1370 iwl_rx_queue_restock(priv); 1123 iwl_rx_queue_restock(priv);
1371} 1124}
1372 1125
1373#ifdef CONFIG_IWLWIFI_DEBUG
1374static void iwl_print_rx_config_cmd(struct iwl_priv *priv)
1375{
1376 struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
1377
1378 IWL_DEBUG_RADIO("RX CONFIG:\n");
1379 iwl_print_hex_dump(priv, IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon));
1380 IWL_DEBUG_RADIO("u16 channel: 0x%x\n", le16_to_cpu(rxon->channel));
1381 IWL_DEBUG_RADIO("u32 flags: 0x%08X\n", le32_to_cpu(rxon->flags));
1382 IWL_DEBUG_RADIO("u32 filter_flags: 0x%08x\n",
1383 le32_to_cpu(rxon->filter_flags));
1384 IWL_DEBUG_RADIO("u8 dev_type: 0x%x\n", rxon->dev_type);
1385 IWL_DEBUG_RADIO("u8 ofdm_basic_rates: 0x%02x\n",
1386 rxon->ofdm_basic_rates);
1387 IWL_DEBUG_RADIO("u8 cck_basic_rates: 0x%02x\n", rxon->cck_basic_rates);
1388 IWL_DEBUG_RADIO("u8[6] node_addr: %pM\n", rxon->node_addr);
1389 IWL_DEBUG_RADIO("u8[6] bssid_addr: %pM\n", rxon->bssid_addr);
1390 IWL_DEBUG_RADIO("u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id));
1391}
1392#endif
1393
1394/* call this function to flush any scheduled tasklet */ 1126/* call this function to flush any scheduled tasklet */
1395static inline void iwl_synchronize_irq(struct iwl_priv *priv) 1127static inline void iwl_synchronize_irq(struct iwl_priv *priv)
1396{ 1128{
@@ -1399,45 +1131,6 @@ static inline void iwl_synchronize_irq(struct iwl_priv *priv)
1399 tasklet_kill(&priv->irq_tasklet); 1131 tasklet_kill(&priv->irq_tasklet);
1400} 1132}
1401 1133
1402/**
1403 * iwl_irq_handle_error - called for HW or SW error interrupt from card
1404 */
1405static void iwl_irq_handle_error(struct iwl_priv *priv)
1406{
1407 /* Set the FW error flag -- cleared on iwl_down */
1408 set_bit(STATUS_FW_ERROR, &priv->status);
1409
1410 /* Cancel currently queued command. */
1411 clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
1412
1413#ifdef CONFIG_IWLWIFI_DEBUG
1414 if (priv->debug_level & IWL_DL_FW_ERRORS) {
1415 iwl_dump_nic_error_log(priv);
1416 iwl_dump_nic_event_log(priv);
1417 iwl_print_rx_config_cmd(priv);
1418 }
1419#endif
1420
1421 wake_up_interruptible(&priv->wait_command_queue);
1422
1423 /* Keep the restart process from trying to send host
1424 * commands by clearing the INIT status bit */
1425 clear_bit(STATUS_READY, &priv->status);
1426
1427 if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) {
1428 IWL_DEBUG(IWL_DL_FW_ERRORS,
1429 "Restarting adapter due to uCode error.\n");
1430
1431 if (iwl_is_associated(priv)) {
1432 memcpy(&priv->recovery_rxon, &priv->active_rxon,
1433 sizeof(priv->recovery_rxon));
1434 priv->error_recovering = 1;
1435 }
1436 if (priv->cfg->mod_params->restart_fw)
1437 queue_work(priv->workqueue, &priv->restart);
1438 }
1439}
1440
1441static void iwl_error_recovery(struct iwl_priv *priv) 1134static void iwl_error_recovery(struct iwl_priv *priv)
1442{ 1135{
1443 unsigned long flags; 1136 unsigned long flags;
@@ -2010,6 +1703,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
2010 } else { 1703 } else {
2011 /* Initialize our rx_config data */ 1704 /* Initialize our rx_config data */
2012 iwl_connection_init_rx_config(priv, priv->iw_mode); 1705 iwl_connection_init_rx_config(priv, priv->iw_mode);
1706 iwl_set_rxon_chain(priv);
2013 memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); 1707 memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
2014 } 1708 }
2015 1709
@@ -2899,52 +2593,6 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw,
2899 return 0; 2593 return 0;
2900} 2594}
2901 2595
2902static void iwl_configure_filter(struct ieee80211_hw *hw,
2903 unsigned int changed_flags,
2904 unsigned int *total_flags,
2905 int mc_count, struct dev_addr_list *mc_list)
2906{
2907 struct iwl_priv *priv = hw->priv;
2908 __le32 *filter_flags = &priv->staging_rxon.filter_flags;
2909
2910 IWL_DEBUG_MAC80211("Enter: changed: 0x%x, total: 0x%x\n",
2911 changed_flags, *total_flags);
2912
2913 if (changed_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS)) {
2914 if (*total_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS))
2915 *filter_flags |= RXON_FILTER_PROMISC_MSK;
2916 else
2917 *filter_flags &= ~RXON_FILTER_PROMISC_MSK;
2918 }
2919 if (changed_flags & FIF_ALLMULTI) {
2920 if (*total_flags & FIF_ALLMULTI)
2921 *filter_flags |= RXON_FILTER_ACCEPT_GRP_MSK;
2922 else
2923 *filter_flags &= ~RXON_FILTER_ACCEPT_GRP_MSK;
2924 }
2925 if (changed_flags & FIF_CONTROL) {
2926 if (*total_flags & FIF_CONTROL)
2927 *filter_flags |= RXON_FILTER_CTL2HOST_MSK;
2928 else
2929 *filter_flags &= ~RXON_FILTER_CTL2HOST_MSK;
2930 }
2931 if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
2932 if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
2933 *filter_flags |= RXON_FILTER_BCON_AWARE_MSK;
2934 else
2935 *filter_flags &= ~RXON_FILTER_BCON_AWARE_MSK;
2936 }
2937
2938 /* We avoid iwl_commit_rxon here to commit the new filter flags
2939 * since mac80211 will call ieee80211_hw_config immediately.
2940 * (mc_list is not supported at this time). Otherwise, we need to
2941 * queue a background iwl_commit_rxon work.
2942 */
2943
2944 *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS |
2945 FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
2946}
2947
2948static void iwl_mac_remove_interface(struct ieee80211_hw *hw, 2596static void iwl_mac_remove_interface(struct ieee80211_hw *hw,
2949 struct ieee80211_if_init_conf *conf) 2597 struct ieee80211_if_init_conf *conf)
2950{ 2598{