···11+mac80211_hwsim - software simulator of 802.11 radio(s) for mac8021122+Copyright (c) 2008, Jouni Malinen <j@w1.fi>33+44+This program is free software; you can redistribute it and/or modify55+it under the terms of the GNU General Public License version 2 as66+published by the Free Software Foundation.77+88+99+Introduction1010+1111+mac80211_hwsim is a Linux kernel module that can be used to simulate1212+arbitrary number of IEEE 802.11 radios for mac80211. It can be used to1313+test most of the mac80211 functionality and user space tools (e.g.,1414+hostapd and wpa_supplicant) in a way that matches very closely with1515+the normal case of using real WLAN hardware. From the mac80211 view1616+point, mac80211_hwsim is yet another hardware driver, i.e., no changes1717+to mac80211 are needed to use this testing tool.1818+1919+The main goal for mac80211_hwsim is to make it easier for developers2020+to test their code and work with new features to mac80211, hostapd,2121+and wpa_supplicant. The simulated radios do not have the limitations2222+of real hardware, so it is easy to generate an arbitrary test setup2323+and always reproduce the same setup for future tests. In addition,2424+since all radio operation is simulated, any channel can be used in2525+tests regardless of regulatory rules.2626+2727+mac80211_hwsim kernel module has a parameter 'radios' that can be used2828+to select how many radios are simulated (default 2). This allows2929+configuration of both very simply setups (e.g., just a single access3030+point and a station) or large scale tests (multiple access points with3131+hundreds of stations).3232+3333+mac80211_hwsim works by tracking the current channel of each virtual3434+radio and copying all transmitted frames to all other radios that are3535+currently enabled and on the same channel as the transmitting3636+radio. Software encryption in mac80211 is used so that the frames are3737+actually encrypted over the virtual air interface to allow more3838+complete testing of encryption.3939+4040+A global monitoring netdev, hwsim#, is created independent of4141+mac80211. This interface can be used to monitor all transmitted frames4242+regardless of channel.4343+4444+4545+Simple example4646+4747+This example shows how to use mac80211_hwsim to simulate two radios:4848+one to act as an access point and the other as a station that4949+associates with the AP. hostapd and wpa_supplicant are used to take5050+care of WPA2-PSK authentication. In addition, hostapd is also5151+processing access point side of association.5252+5353+Please note that the current Linux kernel does not enable AP mode, so a5454+simple patch is needed to enable AP mode selection:5555+http://johannes.sipsolutions.net/patches/kernel/all/LATEST/006-allow-ap-vlan-modes.patch5656+5757+5858+# Build mac80211_hwsim as part of kernel configuration5959+6060+# Load the module6161+modprobe mac80211_hwsim6262+6363+# Run hostapd (AP) for wlan06464+hostapd hostapd.conf6565+6666+# Run wpa_supplicant (station) for wlan16767+wpa_supplicant -Dwext -iwlan1 -c wpa_supplicant.conf
···673673674674 Thanks to Infineon-ADMtek for their support of this driver.675675676676+config MAC80211_HWSIM677677+ tristate "Simulated radio testing tool for mac80211"678678+ depends on MAC80211 && WLAN_80211679679+ ---help---680680+ This driver is a developer testing tool that can be used to test681681+ IEEE 802.11 networking stack (mac80211) functionality. This is not682682+ needed for normal wireless LAN usage and is only for testing. See683683+ Documentation/networking/mac80211_hwsim for more information on how684684+ to use this tool.685685+686686+ To compile this driver as a module, choose M here: the module will be687687+ called mac80211_hwsim. If unsure, say N.688688+676689source "drivers/net/wireless/p54/Kconfig"677690source "drivers/net/wireless/ath5k/Kconfig"678691source "drivers/net/wireless/iwlwifi/Kconfig"
···1414 bool1515 default n16161717-config IWLWIFI_RUN_TIME_CALIB1818- bool1919- depends on IWLCORE2020- default n2121- ---help---2222- This option will enable run time calibration for the iwlwifi driver.2323- These calibrations are Sensitivity and Chain Noise.2424-2525-2617config IWLWIFI_RFKILL2718 boolean "IWLWIFI RF kill support"2819 depends on IWLCORE···4554 say M here and read <file:Documentation/kbuild/modules.txt>. The4655 module will be called iwl4965.ko.47564848-config IWL4965_HT4949- bool "Enable 802.11n HT features in iwl4965 driver"5050- depends on EXPERIMENTAL5151- depends on IWL49655252- ---help---5353- This option enables IEEE 802.11n High Throughput features5454- for the iwl4965 driver.5555-5657config IWL4965_LEDS5758 bool "Enable LEDS features in iwl4965 driver"5859 depends on IWL4965···5875 depends on IWL49655976 ---help---6077 This option will enable spectrum measurement for the iwl4965 driver.6161-6262-config IWL4965_RUN_TIME_CALIB6363- bool "Enable run time Calibration for 4965 NIC"6464- select IWLWIFI_RUN_TIME_CALIB6565- depends on IWL49656666- default y6767- ---help---6868- This option will enable run time calibration for the iwl4965 driver.6969- These calibrations are Sensitivity and Chain Noise. If unsure, say yes70787179config IWLWIFI_DEBUG7280 bool "Enable full debugging output in iwl4965 driver"···91117 ---help---92118 This option enables support for Intel Wireless WiFi Link 5000AGN Family93119 Dependency on 4965 is temporary9494-9595-config IWL5000_RUN_TIME_CALIB9696- bool "Enable run time Calibration for 5000 NIC"9797- select IWLWIFI_RUN_TIME_CALIB9898- depends on IWL50009999- default y100100- ---help---101101- This option will enable run time calibration for the iwl5000 driver.102102- These calibrations are Sensitivity and Chain Noise. If unsure, say yes103103-104120105121config IWLWIFI_DEBUGFS106122 bool "Iwlwifi debugfs support"
···3838#include "../net/mac80211/rate.h"39394040#include "iwl-dev.h"4141+#include "iwl-sta.h"4142#include "iwl-core.h"4243#include "iwl-helpers.h"4344···106105 struct iwl4965_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */107106};108107109109-#ifdef CONFIG_IWL4965_HT110110-111108struct iwl4965_traffic_load {112109 unsigned long time_stamp; /* age of the oldest statistics */113110 u32 packet_count[TID_QUEUE_MAX_SIZE]; /* packet count in this time···116117 * been used since the last cleanup */117118 u8 head; /* start of the circular buffer */118119};119119-120120-#endif /* CONFIG_IWL4965_HT */121120122121/**123122 * struct iwl4965_lq_sta -- driver's rate scaling private structure···154157155158 struct iwl_link_quality_cmd lq;156159 struct iwl4965_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */157157-#ifdef CONFIG_IWL4965_HT158160 struct iwl4965_traffic_load load[TID_MAX_LOAD_COUNT];159161 u8 tx_agg_tid_en;160160-#endif161162#ifdef CONFIG_MAC80211_DEBUGFS162163 struct dentry *rs_sta_dbgfs_scale_table_file;163164 struct dentry *rs_sta_dbgfs_stats_table_file;164164-#ifdef CONFIG_IWL4965_HT165165 struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file;166166-#endif167166 u32 dbg_fixed_rate;168167#endif169168 struct iwl_priv *drv;···249256 return ((ant_type & valid_antenna) == ant_type);250257}251258252252-#ifdef CONFIG_IWL4965_HT253259/*254260 * removes the old data from the statistics. All data that is older than255261 * TID_MAX_TIME_DIFF, will be deleted.···274282 * increment traffic load value for tid and also remove275283 * any old values if passed the certain time period276284 */277277-static void rs_tl_add_packet(struct iwl4965_lq_sta *lq_data,278278- struct ieee80211_hdr *hdr)285285+static u8 rs_tl_add_packet(struct iwl4965_lq_sta *lq_data,286286+ struct ieee80211_hdr *hdr)279287{280288 u32 curr_time = jiffies_to_msecs(jiffies);281289 u32 time_diff;282290 s32 index;283291 struct iwl4965_traffic_load *tl = NULL;284284- u16 fc = le16_to_cpu(hdr->frame_control);292292+ __le16 fc = hdr->frame_control;285293 u8 tid;286294287287- if (ieee80211_is_qos_data(fc)) {288288- u8 *qc = ieee80211_get_qos_ctrl(hdr, ieee80211_get_hdrlen(fc));295295+ if (ieee80211_is_data_qos(fc)) {296296+ u8 *qc = ieee80211_get_qos_ctl(hdr);289297 tid = qc[0] & 0xf;290298 } else291291- return;299299+ return MAX_TID_COUNT;292300293301 tl = &lq_data->load[tid];294302···301309 tl->queue_count = 1;302310 tl->head = 0;303311 tl->packet_count[0] = 1;304304- return;312312+ return MAX_TID_COUNT;305313 }306314307315 time_diff = TIME_WRAP_AROUND(tl->time_stamp, curr_time);···318326319327 if ((index + 1) > tl->queue_count)320328 tl->queue_count = index + 1;329329+330330+ return tid;321331}322332323333/*···382388 for (tid = 0; tid < TID_MAX_LOAD_COUNT; tid++)383389 rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta);384390}385385-386386-#endif /* CONFIG_IWLWIFI_HT */387391388392static inline int get_num_of_ant_from_rate(u32 rate_n_flags)389393{···537545 u8 num_of_ant = get_num_of_ant_from_rate(rate_n_flags);538546 u8 mcs;539547540540- *rate_idx = iwl4965_hwrate_to_plcp_idx(rate_n_flags);548548+ *rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags);541549542550 if (*rate_idx == IWL_RATE_INVALID) {543551 *rate_idx = -1;···618626619627/* FIXME:RS: in 4965 we don't use greenfield at all */620628/* FIXME:RS: don't use greenfield for now in TX */621621-/* #ifdef CONFIG_IWL4965_HT */622629#if 0623630static inline u8 rs_use_green(struct iwl_priv *priv, struct ieee80211_conf *conf)624631{···625634 priv->current_ht_config.is_green_field &&626635 !priv->current_ht_config.non_GF_STA_present);627636}628628-#else637637+#endif629638static inline u8 rs_use_green(struct iwl_priv *priv, struct ieee80211_conf *conf)630639{631640 return 0;632641}633633-#endif /* CONFIG_IWL4965_HT */634642635643/**636644 * rs_get_supported_rates - get the available rates···794804 struct iwl4965_scale_tbl_info tbl_type;795805 struct iwl4965_scale_tbl_info *curr_tbl, *search_tbl;796806 u8 active_index = 0;797797- u16 fc = le16_to_cpu(hdr->frame_control);807807+ __le16 fc = hdr->frame_control;798808 s32 tpt = 0;799809800810 IWL_DEBUG_RATE_LIMIT("get frame ack response, update rate scale window\n");···10401050 tbl->expected_tpt = expected_tpt_G;10411051}1042105210431043-#ifdef CONFIG_IWL4965_HT10441053/*10451054 * Find starting rate for new "search" high-throughput mode of modulation.10461055 * Goal is to find lowest expected rate (under perfect conditions) that is···1141115211421153 return new_rate;11431154}11441144-#endif /* CONFIG_IWL4965_HT */1145115511461156/*11471157 * Set up search table for MIMO11481158 */11491149-#ifdef CONFIG_IWL4965_HT11501159static int rs_switch_to_mimo2(struct iwl_priv *priv,11511160 struct iwl4965_lq_sta *lq_sta,11521161 struct ieee80211_conf *conf,···12081221 tbl->current_rate, is_green);12091222 return 0;12101223}12111211-#else12121212-static int rs_switch_to_mimo2(struct iwl_priv *priv,12131213- struct iwl4965_lq_sta *lq_sta,12141214- struct ieee80211_conf *conf,12151215- struct sta_info *sta,12161216- struct iwl4965_scale_tbl_info *tbl, int index)12171217-{12181218- return -1;12191219-}12201220-#endif /*CONFIG_IWL4965_HT */1221122412221225/*12231226 * Set up search table for SISO···12181241 struct sta_info *sta,12191242 struct iwl4965_scale_tbl_info *tbl, int index)12201243{12211221-#ifdef CONFIG_IWL4965_HT12221244 u16 rate_mask;12231245 u8 is_green = lq_sta->is_green;12241246 s32 rate;···12671291 IWL_DEBUG_RATE("LQ: Switch to new mcs %X index is green %X\n",12681292 tbl->current_rate, is_green);12691293 return 0;12701270-#else12711271- return -1;12721272-#endif /*CONFIG_IWL4965_HT */12731294}1274129512751296/*···16511678 int high_tpt = IWL_INVALID_VALUE;16521679 u32 fail_count;16531680 s8 scale_action = 0;16541654- u16 fc, rate_mask;16811681+ __le16 fc;16821682+ u16 rate_mask;16551683 u8 update_lq = 0;16561684 struct iwl4965_lq_sta *lq_sta;16571685 struct iwl4965_scale_tbl_info *tbl, *tbl1;···16631689 u8 done_search = 0;16641690 u16 high_low;16651691 s32 sr;16661666-#ifdef CONFIG_IWL4965_HT16671692 u8 tid = MAX_TID_COUNT;16681668-#endif1669169316701694 IWL_DEBUG_RATE("rate scale calculate new rate for skb\n");1671169516721672- fc = le16_to_cpu(hdr->frame_control);16961696+ fc = hdr->frame_control;16731697 if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1)) {16741698 /* Send management frames and broadcast/multicast data using16751699 * lowest rate. */···16841712 }16851713 lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv;1686171416871687-#ifdef CONFIG_IWL4965_HT16881688- rs_tl_add_packet(lq_sta, hdr);16891689-#endif17151715+ tid = rs_tl_add_packet(lq_sta, hdr);17161716+16901717 /*16911718 * Select rate-scale / modulation-mode table to work with in16921719 * the rest of this function: "search" if searching for better···18131842 tbl = &(lq_sta->lq_info[active_tbl]);1814184318151844 /* Revert to "active" rate and throughput info */18161816- index = iwl4965_hwrate_to_plcp_idx(18171817- tbl->current_rate);18451845+ index = iwl_hwrate_to_plcp_idx(tbl->current_rate);18181846 current_tpt = lq_sta->last_tpt;1819184718201848 /* Need to set up a new rate table in uCode */···19671997 rs_rate_scale_clear_window(&(tbl->win[i]));1968199819691999 /* Use new "search" start rate */19701970- index = iwl4965_hwrate_to_plcp_idx(19711971- tbl->current_rate);20002000+ index = iwl_hwrate_to_plcp_idx(tbl->current_rate);1972200119732002 IWL_DEBUG_RATE("Switch current mcs: %X index: %d\n",19742003 tbl->current_rate, index);···19822013 * before next round of mode comparisons. */19832014 tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]);19842015 if (is_legacy(tbl1->lq_type) &&19851985-#ifdef CONFIG_IWL4965_HT19862016 (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)) &&19871987-#endif19882017 (lq_sta->action_counter >= 1)) {19892018 lq_sta->action_counter = 0;19902019 IWL_DEBUG_RATE("LQ: STAY in legacy table\n");···19942027 * mode for a while before next round of mode comparisons. */19952028 if (lq_sta->enable_counter &&19962029 (lq_sta->action_counter >= IWL_ACTION_LIMIT)) {19971997-#ifdef CONFIG_IWL4965_HT19982030 if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) &&19992031 (lq_sta->tx_agg_tid_en & (1 << tid)) &&20002032 (tid != MAX_TID_COUNT)) {20012033 IWL_DEBUG_RATE("try to aggregate tid %d\n", tid);20022034 rs_tl_turn_on_agg(priv, tid, lq_sta, sta);20032035 }20042004-#endif /*CONFIG_IWL4965_HT */20052036 lq_sta->action_counter = 0;20062037 rs_set_stay_in_table(priv, 0, lq_sta);20072038 }···21012136 struct ieee80211_conf *conf = &local->hw.conf;21022137 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;21032138 struct sta_info *sta;21042104- u16 fc;21392139+ __le16 fc;21052140 struct iwl_priv *priv = (struct iwl_priv *)priv_rate;21062141 struct iwl4965_lq_sta *lq_sta;21072142···2113214821142149 /* Send management frames and broadcast/multicast data using lowest21152150 * rate. */21162116- fc = le16_to_cpu(hdr->frame_control);21512151+ fc = hdr->frame_control;21172152 if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) ||21182153 !sta || !sta->rate_ctrl_priv) {21192154 sel->rate_idx = rate_lowest_index(local, sband, sta);···22442279 lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000);22452280 lq_sta->active_rate_basic = priv->active_rate_basic;22462281 lq_sta->band = priv->band;22472247-#ifdef CONFIG_IWL4965_HT22482282 /*22492283 * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3),22502284 * supp_rates[] does not; shift to convert format, force 9 MBits off.22512285 */22522252- lq_sta->active_siso_rate =22532253- priv->current_ht_config.supp_mcs_set[0] << 1;22542254- lq_sta->active_siso_rate |=22552255- priv->current_ht_config.supp_mcs_set[0] & 0x1;22862286+ lq_sta->active_siso_rate = conf->ht_conf.supp_mcs_set[0] << 1;22872287+ lq_sta->active_siso_rate |= conf->ht_conf.supp_mcs_set[0] & 0x1;22562288 lq_sta->active_siso_rate &= ~((u16)0x2);22572289 lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE;2258229022592291 /* Same here */22602260- lq_sta->active_mimo2_rate =22612261- priv->current_ht_config.supp_mcs_set[1] << 1;22622262- lq_sta->active_mimo2_rate |=22632263- priv->current_ht_config.supp_mcs_set[1] & 0x1;22922292+ lq_sta->active_mimo2_rate = conf->ht_conf.supp_mcs_set[1] << 1;22932293+ lq_sta->active_mimo2_rate |= conf->ht_conf.supp_mcs_set[1] & 0x1;22642294 lq_sta->active_mimo2_rate &= ~((u16)0x2);22652295 lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE;2266229622672267- lq_sta->active_mimo3_rate =22682268- priv->current_ht_config.supp_mcs_set[2] << 1;22692269- lq_sta->active_mimo3_rate |=22702270- priv->current_ht_config.supp_mcs_set[2] & 0x1;22972297+ lq_sta->active_mimo3_rate = conf->ht_conf.supp_mcs_set[2] << 1;22982298+ lq_sta->active_mimo3_rate |= conf->ht_conf.supp_mcs_set[2] & 0x1;22712299 lq_sta->active_mimo3_rate &= ~((u16)0x2);22722300 lq_sta->active_mimo3_rate <<= IWL_FIRST_OFDM_RATE;22732301···2275231722762318 /* as default allow aggregation for all tids */22772319 lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID;22782278-#endif /*CONFIG_IWL4965_HT*/22792320#ifdef CONFIG_MAC80211_DEBUGFS22802321 lq_sta->drv = priv;22812322#endif···25922635 lq_sta->rs_sta_dbgfs_stats_table_file =25932636 debugfs_create_file("rate_stats_table", 0600, dir,25942637 lq_sta, &rs_sta_dbgfs_stats_table_ops);25952595-#ifdef CONFIG_IWL4965_HT25962638 lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file =25972639 debugfs_create_u8("tx_agg_tid_enable", 0600, dir,25982640 &lq_sta->tx_agg_tid_en);25992599-#endif2600264126012642}26022643···26032648 struct iwl4965_lq_sta *lq_sta = priv_sta;26042649 debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file);26052650 debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file);26062606-#ifdef CONFIG_IWL4965_HT26072651 debugfs_remove(lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file);26082608-#endif26092652}26102653#endif26112654
-2
drivers/net/wireless/iwlwifi/iwl-4965-rs.h
···286286 return rate;287287}288288289289-extern int iwl4965_hwrate_to_plcp_idx(u32 rate_n_flags);290290-291289/**292290 * iwl4965_fill_rs_info - Fill an output text buffer with the rate representation293291 *
+90-292
drivers/net/wireless/iwlwifi/iwl-4965.c
···4646#include "iwl-calib.h"4747#include "iwl-sta.h"48484949+static int iwl4965_send_tx_power(struct iwl_priv *priv);5050+static int iwl4965_hw_get_temperature(const struct iwl_priv *priv);5151+4952/* module parameters */5053static struct iwl_mod_params iwl4965_mod_params = {5154 .num_of_queues = IWL49_NUM_QUEUES,···284281 }285282286283 /* Calculate temperature */287287- priv->temperature = iwl4965_get_temperature(priv);284284+ priv->temperature = iwl4965_hw_get_temperature(priv);288285289286 /* Send pointers to protocol/runtime uCode image ... init code will290287 * load and launch runtime uCode, which will send us another "Alive"···306303{307304 return (rxon_flags & RXON_FLG_CHANNEL_MODE_PURE_40_MSK) ||308305 (rxon_flags & RXON_FLG_CHANNEL_MODE_MIXED_MSK);309309-}310310-311311-int iwl4965_hwrate_to_plcp_idx(u32 rate_n_flags)312312-{313313- int idx = 0;314314-315315- /* 4965 HT rate format */316316- if (rate_n_flags & RATE_MCS_HT_MSK) {317317- idx = (rate_n_flags & 0xff);318318-319319- if (idx >= IWL_RATE_MIMO2_6M_PLCP)320320- idx = idx - IWL_RATE_MIMO2_6M_PLCP;321321-322322- idx += IWL_FIRST_OFDM_RATE;323323- /* skip 9M not supported in ht*/324324- if (idx >= IWL_RATE_9M_INDEX)325325- idx += 1;326326- if ((idx >= IWL_FIRST_OFDM_RATE) && (idx <= IWL_LAST_OFDM_RATE))327327- return idx;328328-329329- /* 4965 legacy rate format, search for match in table */330330- } else {331331- for (idx = 0; idx < ARRAY_SIZE(iwl_rates); idx++)332332- if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF))333333- return idx;334334- }335335-336336- return -1;337337-}338338-339339-/**340340- * translate ucode response to mac80211 tx status control values341341- */342342-void iwl4965_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,343343- struct ieee80211_tx_info *control)344344-{345345- int rate_index;346346-347347- control->antenna_sel_tx =348348- ((rate_n_flags & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS);349349- if (rate_n_flags & RATE_MCS_HT_MSK)350350- control->flags |= IEEE80211_TX_CTL_OFDM_HT;351351- if (rate_n_flags & RATE_MCS_GF_MSK)352352- control->flags |= IEEE80211_TX_CTL_GREEN_FIELD;353353- if (rate_n_flags & RATE_MCS_FAT_MSK)354354- control->flags |= IEEE80211_TX_CTL_40_MHZ_WIDTH;355355- if (rate_n_flags & RATE_MCS_DUP_MSK)356356- control->flags |= IEEE80211_TX_CTL_DUP_DATA;357357- if (rate_n_flags & RATE_MCS_SGI_MSK)358358- control->flags |= IEEE80211_TX_CTL_SHORT_GI;359359- rate_index = iwl4965_hwrate_to_plcp_idx(rate_n_flags);360360- if (control->band == IEEE80211_BAND_5GHZ)361361- rate_index -= IWL_FIRST_OFDM_RATE;362362- control->tx_rate_idx = rate_index;363306}364307365308/*···557608558609#define REG_RECALIB_PERIOD (60)559610560560-/**561561- * iwl4965_bg_statistics_periodic - Timer callback to queue statistics562562- *563563- * This callback is provided in order to send a statistics request.564564- *565565- * This timer function is continually reset to execute within566566- * REG_RECALIB_PERIOD seconds since the last STATISTICS_NOTIFICATION567567- * was received. We need to ensure we receive the statistics in order568568- * to update the temperature used for calibrating the TXPOWER.569569- */570570-static void iwl4965_bg_statistics_periodic(unsigned long data)571571-{572572- struct iwl_priv *priv = (struct iwl_priv *)data;573573-574574- if (test_bit(STATUS_EXIT_PENDING, &priv->status))575575- return;576576-577577- iwl_send_statistics_request(priv, CMD_ASYNC);578578-}579579-580580-void iwl4965_rf_kill_ct_config(struct iwl_priv *priv)581581-{582582- struct iwl4965_ct_kill_config cmd;583583- unsigned long flags;584584- int ret = 0;585585-586586- spin_lock_irqsave(&priv->lock, flags);587587- iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,588588- CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);589589- spin_unlock_irqrestore(&priv->lock, flags);590590-591591- cmd.critical_temperature_R =592592- cpu_to_le32(priv->hw_params.ct_kill_threshold);593593-594594- ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD,595595- sizeof(cmd), &cmd);596596- if (ret)597597- IWL_ERROR("REPLY_CT_KILL_CONFIG_CMD failed\n");598598- else599599- IWL_DEBUG_INFO("REPLY_CT_KILL_CONFIG_CMD succeeded, "600600- "critical temperature is %d\n",601601- cmd.critical_temperature_R);602602-}603603-604604-#ifdef CONFIG_IWL4965_RUN_TIME_CALIB605605-606611/* Reset differential Rx gains in NIC to prepare for chain noise calibration.607612 * Called after every association, but this runs only once!608613 * ... once chain noise is calibrated the first time, it's good forever. */···644741 data->beacon_count = 0;645742}646743647647-static void iwl4965_bg_sensitivity_work(struct work_struct *work)648648-{649649- struct iwl_priv *priv = container_of(work, struct iwl_priv,650650- sensitivity_work);651651-652652- mutex_lock(&priv->mutex);653653-654654- if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||655655- test_bit(STATUS_SCANNING, &priv->status)) {656656- mutex_unlock(&priv->mutex);657657- return;658658- }659659-660660- if (priv->start_calib) {661661- iwl_chain_noise_calibration(priv, &priv->statistics);662662-663663- iwl_sensitivity_calibration(priv, &priv->statistics);664664- }665665-666666- mutex_unlock(&priv->mutex);667667- return;668668-}669669-#endif /*CONFIG_IWL4965_RUN_TIME_CALIB*/670670-671744static void iwl4965_bg_txpower_work(struct work_struct *work)672745{673746 struct iwl_priv *priv = container_of(work, struct iwl_priv,···662783 /* Regardless of if we are assocaited, we must reconfigure the663784 * TX power since frames can be sent on non-radar channels while664785 * not associated */665665- iwl4965_hw_reg_send_txpower(priv);786786+ iwl4965_send_tx_power(priv);666787667788 /* Update last_temperature to keep is_calib_needed from running668789 * when it isn't needed... */···722843 IWL_TX_FIFO_HCCA_2723844};724845725725-int iwl4965_alive_notify(struct iwl_priv *priv)846846+static int iwl4965_alive_notify(struct iwl_priv *priv)726847{727848 u32 a;728849 int i = 0;···799920 return ret;800921}801922802802-#ifdef CONFIG_IWL4965_RUN_TIME_CALIB803923static struct iwl_sensitivity_ranges iwl4965_sensitivity = {804924 .min_nrg_cck = 97,805925 .max_nrg_cck = 0,···821943 .nrg_th_cck = 100,822944 .nrg_th_ofdm = 100,823945};824824-#endif825946826947/**827948 * iwl4965_hw_set_hw_params828949 *829950 * Called when initializing driver830951 */831831-int iwl4965_hw_set_hw_params(struct iwl_priv *priv)952952+static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)832953{833954834955 if ((priv->cfg->mod_params->num_of_queues > IWL49_NUM_QUEUES) ||···838961 }839962840963 priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues;964964+ priv->hw_params.first_ampdu_q = IWL49_FIRST_AMPDU_QUEUE;841965 priv->hw_params.sw_crypto = priv->cfg->mod_params->sw_crypto;842966 priv->hw_params.max_rxq_size = RX_QUEUE_SIZE;843967 priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;···861983 priv->hw_params.valid_rx_ant = ANT_A | ANT_B;862984 priv->hw_params.ct_kill_threshold = CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD);863985864864-#ifdef CONFIG_IWL4965_RUN_TIME_CALIB865986 priv->hw_params.sens = &iwl4965_sensitivity;866866-#endif867987868988 return 0;869989}···8761000 sizeof(struct iwl4965_powertable_cmd),8771001 cmd, NULL);8781002 return ret;879879-}880880-int iwl4965_hw_reg_set_txpower(struct iwl_priv *priv, s8 power)881881-{882882- IWL_ERROR("TODO: Implement iwl4965_hw_reg_set_txpower!\n");883883- return -EINVAL;8841003}88510048861005static s32 iwl4965_math_div_round(s32 num, s32 denom, s32 *res)···9251054 comp = 0;92610559271056 return comp;928928-}929929-930930-static const struct iwl_channel_info *931931-iwl4965_get_channel_txpower_info(struct iwl_priv *priv,932932- enum ieee80211_band band, u16 channel)933933-{934934- const struct iwl_channel_info *ch_info;935935-936936- ch_info = iwl_get_channel_info(priv, band, channel);937937-938938- if (!is_channel_valid(ch_info))939939- return NULL;940940-941941- return ch_info;9421057}94310589441059static s32 iwl4965_get_tx_atten_grp(u16 channel)···13501493 s32 factory_actual_pwr[2];13511494 s32 power_index;1352149513531353- /* Sanity check requested level (dBm) */13541354- if (priv->user_txpower_limit < IWL_TX_POWER_TARGET_POWER_MIN) {13551355- IWL_WARNING("Requested user TXPOWER %d below limit.\n",13561356- priv->user_txpower_limit);13571357- return -EINVAL;13581358- }13591359- if (priv->user_txpower_limit > IWL_TX_POWER_TARGET_POWER_MAX) {13601360- IWL_WARNING("Requested user TXPOWER %d above limit.\n",13611361- priv->user_txpower_limit);13621362- return -EINVAL;13631363- }13641364-13651496 /* user_txpower_limit is in dBm, convert to half-dBm (half-dB units13661497 * are used for indexing into txpower table) */13671367- user_target_power = 2 * priv->user_txpower_limit;14981498+ user_target_power = 2 * priv->tx_power_user_lmt;1368149913691500 /* Get current (RXON) channel, band, width */13701370- ch_info =13711371- iwl4965_get_channel_txpower_info(priv, priv->band, channel);13721372-13731501 IWL_DEBUG_TXPOWER("chan %d band %d is_fat %d\n", channel, band,13741502 is_fat);1375150313761376- if (!ch_info)15041504+ ch_info = iwl_get_channel_info(priv, priv->band, channel);15051505+15061506+ if (!is_channel_valid(ch_info))13771507 return -EINVAL;1378150813791509 /* get txatten group, used to select 1) thermal txpower adjustment···15611717}1562171815631719/**15641564- * iwl4965_hw_reg_send_txpower - Configure the TXPOWER level user limit17201720+ * iwl4965_send_tx_power - Configure the TXPOWER level user limit15651721 *15661722 * Uses the active RXON for channel, band, and characteristics (fat, high)15671567- * The power limit is taken from priv->user_txpower_limit.17231723+ * The power limit is taken from priv->tx_power_user_lmt.15681724 */15691569-int iwl4965_hw_reg_send_txpower(struct iwl_priv *priv)17251725+static int iwl4965_send_tx_power(struct iwl_priv *priv)15701726{15711727 struct iwl4965_txpowertable_cmd cmd = { 0 };15721728 int ret;···16921848 return le32_to_cpu(s->rb_closed) & 0xFFF;16931849}1694185016951695-int iwl4965_hw_get_temperature(struct iwl_priv *priv)16961696-{16971697- return priv->temperature;16981698-}16991699-17001851unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv,17011852 struct iwl_frame *frame, u8 rate)17021853{···1714187517151876 if ((rate == IWL_RATE_1M_PLCP) || (rate >= IWL_RATE_2M_PLCP))17161877 tx_beacon_cmd->tx.rate_n_flags =17171717- iwl4965_hw_set_rate_n_flags(rate, RATE_MCS_CCK_MSK);18781878+ iwl_hw_set_rate_n_flags(rate, RATE_MCS_CCK_MSK);17181879 else17191880 tx_beacon_cmd->tx.rate_n_flags =17201720- iwl4965_hw_set_rate_n_flags(rate, 0);18811881+ iwl_hw_set_rate_n_flags(rate, 0);1721188217221883 tx_beacon_cmd->tx.tx_flags = (TX_CMD_FLG_SEQ_CTL_MSK |17231884 TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK);···17891950}1790195117911952/**17921792- * iwl4965_get_temperature - return the calibrated temperature (in Kelvin)19531953+ * iwl4965_hw_get_temperature - return the calibrated temperature (in Kelvin)17931954 * @statistics: Provides the temperature reading from the uCode17941955 *17951956 * A return of <0 indicates bogus data in the statistics17961957 */17971797-int iwl4965_get_temperature(const struct iwl_priv *priv)19581958+static int iwl4965_hw_get_temperature(const struct iwl_priv *priv)17981959{17991960 s32 temperature;18001961 s32 vt;···18291990 vt = sign_extend(18301991 le32_to_cpu(priv->statistics.general.temperature), 23);1831199218321832- IWL_DEBUG_TEMP("Calib values R[1-3]: %d %d %d R4: %d\n",18331833- R1, R2, R3, vt);19931993+ IWL_DEBUG_TEMP("Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt);1834199418351995 if (R3 == R1) {18361996 IWL_ERROR("Calibration conflict R1 == R3\n");···18402002 * Add offset to center the adjustment around 0 degrees Centigrade. */18412003 temperature = TEMPERATURE_CALIB_A_VAL * (vt - R2);18422004 temperature /= (R3 - R1);18431843- temperature = (temperature * 97) / 100 +18441844- TEMPERATURE_CALIB_KELVIN_OFFSET;20052005+ temperature = (temperature * 97) / 100 + TEMPERATURE_CALIB_KELVIN_OFFSET;1845200618461846- IWL_DEBUG_TEMP("Calibrated temperature: %dK, %dC\n", temperature,18471847- KELVIN_TO_CELSIUS(temperature));20072007+ IWL_DEBUG_TEMP("Calibrated temperature: %dK, %dC\n",20082008+ temperature, KELVIN_TO_CELSIUS(temperature));1848200918492010 return temperature;18502011}···19602123 if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) &&19612124 (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) {19622125 iwl4965_rx_calc_noise(priv);19631963-#ifdef CONFIG_IWL4965_RUN_TIME_CALIB19641964- queue_work(priv->workqueue, &priv->sensitivity_work);19651965-#endif21262126+ queue_work(priv->workqueue, &priv->run_time_calib_work);19662127 }1967212819682129 iwl_leds_background(priv);···19712136 if (!change)19722137 return;1973213819741974- temp = iwl4965_get_temperature(priv);21392139+ temp = iwl4965_hw_get_temperature(priv);19752140 if (temp < 0)19762141 return;19772142···19902155 priv->temperature = temp;19912156 set_bit(STATUS_TEMPERATURE, &priv->status);1992215719931993- if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) &&19941994- iwl4965_is_temp_calib_needed(priv))21582158+ if (!priv->disable_tx_power_cal &&21592159+ unlikely(!test_bit(STATUS_SCANNING, &priv->status)) &&21602160+ iwl4965_is_temp_calib_needed(priv))19952161 queue_work(priv->workqueue, &priv->txpower_work);19962162}19972163···23882552 u32 print_dump = 0; /* set to 1 to dump all frames' contents */23892553 u32 hundred = 0;23902554 u32 dataframe = 0;23912391- u16 fc;25552555+ __le16 fc;23922556 u16 seq_ctl;23932557 u16 channel;23942558 u16 phy_flags;···24112575 return;2412257624132577 /* MAC header */24142414- fc = le16_to_cpu(header->frame_control);25782578+ fc = header->frame_control;24152579 seq_ctl = le16_to_cpu(header->seq_ctrl);2416258024172581 /* metadata */···2436260024372601 /* if data frame is to us and all is good,24382602 * (optionally) print summary for only 1 out of every 100 */24392439- if (to_us && (fc & ~IEEE80211_FCTL_PROTECTED) ==24402440- (IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) {26032603+ if (to_us && (fc & ~cpu_to_le16(IEEE80211_FCTL_PROTECTED)) ==26042604+ cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) {24412605 dataframe = 1;24422606 if (!group100)24432607 print_summary = 1; /* print each frame */···2461262524622626 if (hundred)24632627 title = "100Frames";24642464- else if (fc & IEEE80211_FCTL_RETRY)26282628+ else if (ieee80211_has_retry(fc))24652629 title = "Retry";24662466- else if (ieee80211_is_assoc_response(fc))26302630+ else if (ieee80211_is_assoc_resp(fc))24672631 title = "AscRsp";24682468- else if (ieee80211_is_reassoc_response(fc))26322632+ else if (ieee80211_is_reassoc_resp(fc))24692633 title = "RasRsp";24702470- else if (ieee80211_is_probe_response(fc)) {26342634+ else if (ieee80211_is_probe_resp(fc)) {24712635 title = "PrbRsp";24722636 print_dump = 1; /* dump frame contents */24732637 } else if (ieee80211_is_beacon(fc)) {···24842648 else24852649 title = "Frame";2486265024872487- rate_idx = iwl4965_hwrate_to_plcp_idx(rate_sym);26512651+ rate_idx = iwl_hwrate_to_plcp_idx(rate_sym);24882652 if (unlikely(rate_idx == -1))24892653 bitrate = 0;24902654 else···24962660 if (dataframe)24972661 IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, "24982662 "len=%u, rssi=%d, chnl=%d, rate=%u, \n",24992499- title, fc, header->addr1[5],26632663+ title, le16_to_cpu(fc), header->addr1[5],25002664 length, rssi, channel, bitrate);25012665 else {25022666 /* src/dst addresses assume managed mode */25032667 IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, "25042668 "src=0x%02x, rssi=%u, tim=%lu usec, "25052669 "phy=0x%02x, chnl=%d\n",25062506- title, fc, header->addr1[5],26702670+ title, le16_to_cpu(fc), header->addr1[5],25072671 header->addr3[5], rssi,25082672 tsf_low - priv->scan_start_tsf,25092673 phy_flags, channel);···25492713 rx_status.band = (rx_start->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?25502714 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;25512715 rx_status.rate_idx =25522552- iwl4965_hwrate_to_plcp_idx(le32_to_cpu(rx_start->rate_n_flags));27162716+ iwl_hwrate_to_plcp_idx(le32_to_cpu(rx_start->rate_n_flags));25532717 if (rx_status.band == IEEE80211_BAND_5GHZ)25542718 rx_status.rate_idx -= IWL_FIRST_OFDM_RATE;25552719···26552819 break;2656282026572821 case IEEE80211_FTYPE_CTL:26582658-#ifdef CONFIG_IWL4965_HT26592822 switch (fc & IEEE80211_FCTL_STYPE) {26602823 case IEEE80211_STYPE_BACK_REQ:26612824 IWL_DEBUG_HT("IEEE80211_STYPE_BACK_REQ arrived\n");···26642829 default:26652830 break;26662831 }26672667-#endif26682832 break;2669283326702834 case IEEE80211_FTYPE_DATA: {···2696286226972863 }26982864}26992699-27002700-#ifdef CONFIG_IWL4965_HT2701286527022866/**27032867 * iwl4965_tx_status_reply_compressed_ba - Update tx status from block-ack···27582926 info->flags |= IEEE80211_TX_STAT_AMPDU;27592927 info->status.ampdu_ack_map = successes;27602928 info->status.ampdu_ack_len = agg->frame_count;27612761- iwl4965_hwrate_to_tx_control(priv, agg->rate_n_flags, info);29292929+ iwl_hwrate_to_tx_control(priv, agg->rate_n_flags, info);2762293027632931 IWL_DEBUG_TX_REPLY("Bitmap %llx\n", (unsigned long long)bitmap);27642932···27802948}2781294927822950/**27832783- * txq_id must be greater than IWL_BACK_QUEUE_FIRST_ID29512951+ * txq_id must be greater than IWL49_FIRST_AMPDU_QUEUE27842952 * priv->lock must be held by the caller27852953 */27862954static int iwl4965_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,···27882956{27892957 int ret = 0;2790295827912791- if (IWL_BACK_QUEUE_FIRST_ID > txq_id) {29592959+ if (IWL49_FIRST_AMPDU_QUEUE > txq_id) {27922960 IWL_WARNING("queue number too small: %d, must be > %d\n",27932793- txq_id, IWL_BACK_QUEUE_FIRST_ID);29612961+ txq_id, IWL49_FIRST_AMPDU_QUEUE);27942962 return -EINVAL;27952963 }27962964···28783046 if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) {28793047 /* calculate mac80211 ampdu sw queue to wake */28803048 int ampdu_q =28812881- scd_flow - IWL_BACK_QUEUE_FIRST_ID + priv->hw->queues;30493049+ scd_flow - priv->hw_params.first_ampdu_q + priv->hw->queues;28823050 int freed = iwl_tx_queue_reclaim(priv, scd_flow, index);28833051 priv->stations[ba_resp->sta_id].28843052 tid[ba_resp->tid].tfds_in_queue -= freed;···29233091/**29243092 * iwl4965_tx_queue_agg_enable - Set up & enable aggregation for selected queue29253093 *29262926- * NOTE: txq_id must be greater than IWL_BACK_QUEUE_FIRST_ID,30943094+ * NOTE: txq_id must be greater than IWL49_FIRST_AMPDU_QUEUE,29273095 * i.e. it must be one of the higher queues used for aggregation29283096 */29293097static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id,···29333101 int ret;29343102 u16 ra_tid;2935310329362936- if (IWL_BACK_QUEUE_FIRST_ID > txq_id)31043104+ if (IWL49_FIRST_AMPDU_QUEUE > txq_id)29373105 IWL_WARNING("queue number too small: %d, must be > %d\n",29382938- txq_id, IWL_BACK_QUEUE_FIRST_ID);31063106+ txq_id, IWL49_FIRST_AMPDU_QUEUE);2939310729403108 ra_tid = BUILD_RAxTID(sta_id, tid);29413109···29863154 return 0;29873155}2988315629892989-#endif /* CONFIG_IWL4965_HT */29902990-29912991-29922992-#ifdef CONFIG_IWL4965_HT29933157static int iwl4965_rx_agg_start(struct iwl_priv *priv,29943158 const u8 *addr, int tid, u16 ssn)29953159{···30593231 }30603232 return 0;30613233}30623062-#endif /* CONFIG_IWL4965_HT */30633063-3064323430653235static u16 iwl4965_get_hcmd_size(u8 cmd_id, u16 len)30663236{···30883262 return (u16)sizeof(struct iwl4965_addsta_cmd);30893263}3090326430913091-#ifdef CONFIG_IWL4965_HT30923265static inline u32 iwl4965_get_scd_ssn(struct iwl4965_tx_resp *tx_resp)30933266{30943094- __le32 *scd_ssn = (__le32 *)((u32 *)&tx_resp->status +30953095- tx_resp->frame_count);30963096- return le32_to_cpu(*scd_ssn) & MAX_SN;30973097-32673267+ return le32_to_cpup(&tx_resp->u.status + tx_resp->frame_count) & MAX_SN;30983268}3099326931003270/**···30983276 */30993277static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,31003278 struct iwl_ht_agg *agg,31013101- struct iwl4965_tx_resp_agg *tx_resp,31023102- u16 start_idx)32793279+ struct iwl4965_tx_resp *tx_resp,32803280+ int txq_id, u16 start_idx)31033281{31043282 u16 status;31053105- struct agg_tx_status *frame_status = &tx_resp->status;32833283+ struct agg_tx_status *frame_status = tx_resp->u.agg_status;31063284 struct ieee80211_tx_info *info = NULL;31073285 struct ieee80211_hdr *hdr = NULL;31083108- int i, sh;31093109- int txq_id, idx;32863286+ u32 rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);32873287+ int i, sh, idx;31103288 u16 seq;31113111-31123289 if (agg->wait_for_ba)31133290 IWL_DEBUG_TX_REPLY("got tx response w/o block-ack\n");3114329131153292 agg->frame_count = tx_resp->frame_count;31163293 agg->start_idx = start_idx;31173117- agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);32943294+ agg->rate_n_flags = rate_n_flags;31183295 agg->bitmap = 0;3119329631203297 /* # frames attempted by Tx command */31213298 if (agg->frame_count == 1) {31223299 /* Only one frame was attempted; no block-ack will arrive */31233300 status = le16_to_cpu(frame_status[0].status);31243124- seq = le16_to_cpu(frame_status[0].sequence);31253125- idx = SEQ_TO_INDEX(seq);31263126- txq_id = SEQ_TO_QUEUE(seq);33013301+ idx = start_idx;3127330231283303 /* FIXME: code repetition */31293304 IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n",···31313312 info->flags &= ~IEEE80211_TX_CTL_AMPDU;31323313 info->flags |= iwl_is_tx_success(status)?31333314 IEEE80211_TX_STAT_ACK : 0;31343134- iwl4965_hwrate_to_tx_control(priv,31353135- le32_to_cpu(tx_resp->rate_n_flags),31363136- info);33153315+ iwl_hwrate_to_tx_control(priv, rate_n_flags, info);31373316 /* FIXME: code repetition end */3138331731393318 IWL_DEBUG_TX_REPLY("1 Frame 0x%x failure :%d\n",31403319 status & 0xff, tx_resp->failure_frame);31413141- IWL_DEBUG_TX_REPLY("Rate Info rate_n_flags=%x\n",31423142- iwl4965_hw_get_rate_n_flags(tx_resp->rate_n_flags));33203320+ IWL_DEBUG_TX_REPLY("Rate Info rate_n_flags=%x\n", rate_n_flags);3143332131443322 agg->wait_for_ba = 0;31453323 } else {···3194337831953379 agg->bitmap = bitmap;31963380 agg->start_idx = start;31973197- agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);31983381 IWL_DEBUG_TX_REPLY("Frames %d start_idx=%d bitmap=0x%llx\n",31993382 agg->frame_count, agg->start_idx,32003383 (unsigned long long)agg->bitmap);···32033388 }32043389 return 0;32053390}32063206-#endif3207339132083392/**32093393 * iwl4965_rx_reply_tx - Handle standard (non-aggregation) Tx response···32173403 struct iwl_tx_queue *txq = &priv->txq[txq_id];32183404 struct ieee80211_tx_info *info;32193405 struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0];32203220- u32 status = le32_to_cpu(tx_resp->status);32213221-#ifdef CONFIG_IWL4965_HT34063406+ u32 status = le32_to_cpu(tx_resp->u.status);32223407 int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION;32233223- u16 fc;34083408+ __le16 fc;32243409 struct ieee80211_hdr *hdr;32253410 u8 *qc = NULL;32263226-#endif3227341132283412 if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {32293413 IWL_ERROR("Read index for DMA queue txq_id (%d) index %d "···32343422 info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]);32353423 memset(&info->status, 0, sizeof(info->status));3236342432373237-#ifdef CONFIG_IWL4965_HT32383425 hdr = iwl_tx_queue_get_hdr(priv, txq_id, index);32393239- fc = le16_to_cpu(hdr->frame_control);32403240- if (ieee80211_is_qos_data(fc)) {32413241- qc = ieee80211_get_qos_ctrl(hdr, ieee80211_get_hdrlen(fc));34263426+ fc = hdr->frame_control;34273427+ if (ieee80211_is_data_qos(fc)) {34283428+ qc = ieee80211_get_qos_ctl(hdr);32423429 tid = qc[0] & 0xf;32433430 }32443431···3256344532573446 agg = &priv->stations[sta_id].tid[tid].agg;3258344732593259- iwl4965_tx_status_reply_tx(priv, agg,32603260- (struct iwl4965_tx_resp_agg *)tx_resp, index);34483448+ iwl4965_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index);3261344932623450 if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status)) {32633451 /* TODO: send BAR */···32743464 txq_id >= 0 && priv->mac80211_registered &&32753465 agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) {32763466 /* calculate mac80211 ampdu sw queue to wake */32773277- ampdu_q = txq_id - IWL_BACK_QUEUE_FIRST_ID +34673467+ ampdu_q = txq_id - IWL49_FIRST_AMPDU_QUEUE +32783468 priv->hw->queues;32793469 if (agg->state == IWL_AGG_OFF)32803470 ieee80211_wake_queue(priv->hw, txq_id);···32843474 iwl_txq_check_empty(priv, sta_id, tid, txq_id);32853475 }32863476 } else {32873287-#endif /* CONFIG_IWL4965_HT */34773477+ info->status.retry_count = tx_resp->failure_frame;34783478+ info->flags |=34793479+ iwl_is_tx_success(status) ? IEEE80211_TX_STAT_ACK : 0;34803480+ iwl_hwrate_to_tx_control(priv,34813481+ le32_to_cpu(tx_resp->rate_n_flags),34823482+ info);3288348332893289- info->status.retry_count = tx_resp->failure_frame;32903290- info->flags |= iwl_is_tx_success(status) ? IEEE80211_TX_STAT_ACK : 0;32913291- iwl4965_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags),32923292- info);34843484+ IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags "34853485+ "0x%x retries %d\n", txq_id,34863486+ iwl_get_tx_fail_reason(status),34873487+ status, le32_to_cpu(tx_resp->rate_n_flags),34883488+ tx_resp->failure_frame);3293348932943294- IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags 0x%x "32953295- "retries %d\n", txq_id, iwl_get_tx_fail_reason(status),32963296- status, le32_to_cpu(tx_resp->rate_n_flags),32973297- tx_resp->failure_frame);34903490+ IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);3298349132993299- IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);33003300-#ifdef CONFIG_IWL4965_HT33013301- if (index != -1) {33023302- int freed = iwl_tx_queue_reclaim(priv, txq_id, index);33033303- if (tid != MAX_TID_COUNT)34923492+ if (index != -1) {34933493+ int freed = iwl_tx_queue_reclaim(priv, txq_id, index);34943494+ if (tid != MAX_TID_COUNT)33043495 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;33053305- if (iwl_queue_space(&txq->q) > txq->q.low_mark &&34963496+ if (iwl_queue_space(&txq->q) > txq->q.low_mark &&33063497 (txq_id >= 0) && priv->mac80211_registered)33073498 ieee80211_wake_queue(priv->hw, txq_id);33083308- if (tid != MAX_TID_COUNT)34993499+ if (tid != MAX_TID_COUNT)33093500 iwl_txq_check_empty(priv, sta_id, tid, txq_id);35013501+ }33103502 }33113311- }33123312-#endif /* CONFIG_IWL4965_HT */3313350333143504 if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))33153505 IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n");···33233513 priv->rx_handlers[REPLY_RX] = iwl4965_rx_reply_rx;33243514 /* Tx response */33253515 priv->rx_handlers[REPLY_TX] = iwl4965_rx_reply_tx;33263326-33273327-#ifdef CONFIG_IWL4965_HT35163516+ /* block ack */33283517 priv->rx_handlers[REPLY_COMPRESSED_BA] = iwl4965_rx_reply_compressed_ba;33293329-#endif /* CONFIG_IWL4965_HT */33303518}3331351933323332-void iwl4965_hw_setup_deferred_work(struct iwl_priv *priv)35203520+static void iwl4965_setup_deferred_work(struct iwl_priv *priv)33333521{33343522 INIT_WORK(&priv->txpower_work, iwl4965_bg_txpower_work);33353335-#ifdef CONFIG_IWL4965_RUN_TIME_CALIB33363336- INIT_WORK(&priv->sensitivity_work, iwl4965_bg_sensitivity_work);33373337-#endif33383338- init_timer(&priv->statistics_periodic);33393339- priv->statistics_periodic.data = (unsigned long)priv;33403340- priv->statistics_periodic.function = iwl4965_bg_statistics_periodic;33413523}3342352433433343-void iwl4965_hw_cancel_deferred_work(struct iwl_priv *priv)35253525+static void iwl4965_cancel_deferred_work(struct iwl_priv *priv)33443526{33453345- del_timer_sync(&priv->statistics_periodic);33463346-33473347- cancel_delayed_work(&priv->init_alive_start);35273527+ cancel_work_sync(&priv->txpower_work);33483528}3349352933503530···33453545static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {33463546 .get_hcmd_size = iwl4965_get_hcmd_size,33473547 .build_addsta_hcmd = iwl4965_build_addsta_hcmd,33483348-#ifdef CONFIG_IWL4965_RUN_TIME_CALIB33493548 .chain_noise_reset = iwl4965_chain_noise_reset,33503549 .gain_computation = iwl4965_gain_computation,33513351-#endif33523550};3353355133543552static struct iwl_lib_ops iwl4965_lib = {···33563558 .shared_mem_rx_idx = iwl4965_shared_mem_rx_idx,33573559 .txq_update_byte_cnt_tbl = iwl4965_txq_update_byte_cnt_tbl,33583560 .txq_set_sched = iwl4965_txq_set_sched,33593359-#ifdef CONFIG_IWL4965_HT33603561 .txq_agg_enable = iwl4965_txq_agg_enable,33613562 .txq_agg_disable = iwl4965_txq_agg_disable,33623362-#endif33633563 .rx_handler_setup = iwl4965_rx_handler_setup,35643564+ .setup_deferred_work = iwl4965_setup_deferred_work,35653565+ .cancel_deferred_work = iwl4965_cancel_deferred_work,33643566 .is_valid_rtc_data_addr = iwl4965_hw_valid_rtc_data_addr,33653567 .alive_notify = iwl4965_alive_notify,33663568 .init_alive_start = iwl4965_init_alive_start,···33883590 .check_version = iwl4965_eeprom_check_version,33893591 .query_addr = iwlcore_eeprom_query_addr,33903592 },33913391- .radio_kill_sw = iwl4965_radio_kill_sw,33923593 .set_power = iwl4965_set_power,35943594+ .send_tx_power = iwl4965_send_tx_power,33933595 .update_chain_flags = iwl4965_update_chain_flags,33943596};33953597
···4141#include "iwl-dev.h"4242#include "iwl-core.h"4343#include "iwl-io.h"4444+#include "iwl-sta.h"4445#include "iwl-helpers.h"4546#include "iwl-5000-hw.h"4647···301300302301}303302304304-#ifdef CONFIG_IWL5000_RUN_TIME_CALIB305305-306303static void iwl5000_gain_computation(struct iwl_priv *priv,307304 u32 average_noise[NUM_RX_CHAINS],308305 u16 min_average_noise_antenna_i,···353354 data->beacon_count = 0;354355}355356356356-357357static void iwl5000_chain_noise_reset(struct iwl_priv *priv)358358{359359 struct iwl_chain_noise_data *data = &priv->chain_noise_data;···390392 .nrg_th_cck = 95,391393 .nrg_th_ofdm = 95,392394};393393-394394-#endif /* CONFIG_IWL5000_RUN_TIME_CALIB */395395-396396-397395398396static const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv,399397 size_t offset)···826832 }827833828834 priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues;835835+ priv->hw_params.first_ampdu_q = IWL50_FIRST_AMPDU_QUEUE;829836 priv->hw_params.sw_crypto = priv->cfg->mod_params->sw_crypto;830837 priv->hw_params.max_rxq_size = RX_QUEUE_SIZE;831838 priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;···842847 priv->hw_params.max_bsm_size = BSM_SRAM_SIZE;843848 priv->hw_params.fat_channel = BIT(IEEE80211_BAND_2GHZ) |844849 BIT(IEEE80211_BAND_5GHZ);845845-#ifdef CONFIG_IWL5000_RUN_TIME_CALIB846850 priv->hw_params.sens = &iwl5000_sensitivity;847847-#endif848851849852 switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {850853 case CSR_HW_REV_TYPE_5100:···977984 }978985}979986987987+static int iwl5000_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid,988988+ u16 txq_id)989989+{990990+ u32 tbl_dw_addr;991991+ u32 tbl_dw;992992+ u16 scd_q2ratid;993993+994994+ scd_q2ratid = ra_tid & IWL_SCD_QUEUE_RA_TID_MAP_RATID_MSK;995995+996996+ tbl_dw_addr = priv->scd_base_addr +997997+ IWL50_SCD_TRANSLATE_TBL_OFFSET_QUEUE(txq_id);998998+999999+ tbl_dw = iwl_read_targ_mem(priv, tbl_dw_addr);10001000+10011001+ if (txq_id & 0x1)10021002+ tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF);10031003+ else10041004+ tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000);10051005+10061006+ iwl_write_targ_mem(priv, tbl_dw_addr, tbl_dw);10071007+10081008+ return 0;10091009+}10101010+static void iwl5000_tx_queue_stop_scheduler(struct iwl_priv *priv, u16 txq_id)10111011+{10121012+ /* Simply stop the queue, but don't change any configuration;10131013+ * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */10141014+ iwl_write_prph(priv,10151015+ IWL50_SCD_QUEUE_STATUS_BITS(txq_id),10161016+ (0 << IWL50_SCD_QUEUE_STTS_REG_POS_ACTIVE)|10171017+ (1 << IWL50_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));10181018+}10191019+10201020+static int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id,10211021+ int tx_fifo, int sta_id, int tid, u16 ssn_idx)10221022+{10231023+ unsigned long flags;10241024+ int ret;10251025+ u16 ra_tid;10261026+10271027+ if (IWL50_FIRST_AMPDU_QUEUE > txq_id)10281028+ IWL_WARNING("queue number too small: %d, must be > %d\n",10291029+ txq_id, IWL50_FIRST_AMPDU_QUEUE);10301030+10311031+ ra_tid = BUILD_RAxTID(sta_id, tid);10321032+10331033+ /* Modify device's station table to Tx this TID */10341034+ iwl_sta_modify_enable_tid_tx(priv, sta_id, tid);10351035+10361036+ spin_lock_irqsave(&priv->lock, flags);10371037+ ret = iwl_grab_nic_access(priv);10381038+ if (ret) {10391039+ spin_unlock_irqrestore(&priv->lock, flags);10401040+ return ret;10411041+ }10421042+10431043+ /* Stop this Tx queue before configuring it */10441044+ iwl5000_tx_queue_stop_scheduler(priv, txq_id);10451045+10461046+ /* Map receiver-address / traffic-ID to this queue */10471047+ iwl5000_tx_queue_set_q2ratid(priv, ra_tid, txq_id);10481048+10491049+ /* Set this queue as a chain-building queue */10501050+ iwl_set_bits_prph(priv, IWL50_SCD_QUEUECHAIN_SEL, (1<<txq_id));10511051+10521052+ /* enable aggregations for the queue */10531053+ iwl_set_bits_prph(priv, IWL50_SCD_AGGR_SEL, (1<<txq_id));10541054+10551055+ /* Place first TFD at index corresponding to start sequence number.10561056+ * Assumes that ssn_idx is valid (!= 0xFFF) */10571057+ priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff);10581058+ priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff);10591059+ iwl5000_set_wr_ptrs(priv, txq_id, ssn_idx);10601060+10611061+ /* Set up Tx window size and frame limit for this queue */10621062+ iwl_write_targ_mem(priv, priv->scd_base_addr +10631063+ IWL50_SCD_CONTEXT_QUEUE_OFFSET(txq_id) +10641064+ sizeof(u32),10651065+ ((SCD_WIN_SIZE <<10661066+ IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &10671067+ IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |10681068+ ((SCD_FRAME_LIMIT <<10691069+ IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &10701070+ IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));10711071+10721072+ iwl_set_bits_prph(priv, IWL50_SCD_INTERRUPT_MASK, (1 << txq_id));10731073+10741074+ /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */10751075+ iwl5000_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1);10761076+10771077+ iwl_release_nic_access(priv);10781078+ spin_unlock_irqrestore(&priv->lock, flags);10791079+10801080+ return 0;10811081+}10821082+10831083+static int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,10841084+ u16 ssn_idx, u8 tx_fifo)10851085+{10861086+ int ret;10871087+10881088+ if (IWL50_FIRST_AMPDU_QUEUE > txq_id) {10891089+ IWL_WARNING("queue number too small: %d, must be > %d\n",10901090+ txq_id, IWL50_FIRST_AMPDU_QUEUE);10911091+ return -EINVAL;10921092+ }10931093+10941094+ ret = iwl_grab_nic_access(priv);10951095+ if (ret)10961096+ return ret;10971097+10981098+ iwl5000_tx_queue_stop_scheduler(priv, txq_id);10991099+11001100+ iwl_clear_bits_prph(priv, IWL50_SCD_AGGR_SEL, (1 << txq_id));11011101+11021102+ priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff);11031103+ priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff);11041104+ /* supposes that ssn_idx is valid (!= 0xFFF) */11051105+ iwl5000_set_wr_ptrs(priv, txq_id, ssn_idx);11061106+11071107+ iwl_clear_bits_prph(priv, IWL50_SCD_INTERRUPT_MASK, (1 << txq_id));11081108+ iwl_txq_ctx_deactivate(priv, txq_id);11091109+ iwl5000_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0);11101110+11111111+ iwl_release_nic_access(priv);11121112+11131113+ return 0;11141114+}11151115+9801116static u16 iwl5000_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)9811117{9821118 u16 size = (u16)sizeof(struct iwl_addsta_cmd);···1126100411271005static inline u32 iwl5000_get_scd_ssn(struct iwl5000_tx_resp *tx_resp)11281006{11291129- __le32 *scd_ssn = (__le32 *)((u32 *)&tx_resp->status +11301130- tx_resp->frame_count);11311131- return le32_to_cpu(*scd_ssn) & MAX_SN;11321132-10071007+ return le32_to_cpup((__le32*)&tx_resp->status +10081008+ tx_resp->frame_count) & MAX_SN;11331009}1134101011351011static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,11361012 struct iwl_ht_agg *agg,11371013 struct iwl5000_tx_resp *tx_resp,11381138- u16 start_idx)10141014+ int txq_id, u16 start_idx)11391015{11401016 u16 status;11411017 struct agg_tx_status *frame_status = &tx_resp->status;11421018 struct ieee80211_tx_info *info = NULL;11431019 struct ieee80211_hdr *hdr = NULL;11441144- int i, sh;11451145- int txq_id, idx;10201020+ u32 rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);10211021+ int i, sh, idx;11461022 u16 seq;1147102311481024 if (agg->wait_for_ba)···1148102811491029 agg->frame_count = tx_resp->frame_count;11501030 agg->start_idx = start_idx;11511151- agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);10311031+ agg->rate_n_flags = rate_n_flags;11521032 agg->bitmap = 0;1153103311541034 /* # frames attempted by Tx command */11551035 if (agg->frame_count == 1) {11561036 /* Only one frame was attempted; no block-ack will arrive */11571037 status = le16_to_cpu(frame_status[0].status);11581158- seq = le16_to_cpu(frame_status[0].sequence);11591159- idx = SEQ_TO_INDEX(seq);11601160- txq_id = SEQ_TO_QUEUE(seq);10381038+ idx = start_idx;1161103911621040 /* FIXME: code repetition */11631041 IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n",···11661048 info->flags &= ~IEEE80211_TX_CTL_AMPDU;11671049 info->flags |= iwl_is_tx_success(status)?11681050 IEEE80211_TX_STAT_ACK : 0;11691169- iwl4965_hwrate_to_tx_control(priv,11701170- le32_to_cpu(tx_resp->rate_n_flags),11711171- info);10511051+ iwl_hwrate_to_tx_control(priv, rate_n_flags, info);10521052+11721053 /* FIXME: code repetition end */1173105411741055 IWL_DEBUG_TX_REPLY("1 Frame 0x%x failure :%d\n",11751056 status & 0xff, tx_resp->failure_frame);11761176- IWL_DEBUG_TX_REPLY("Rate Info rate_n_flags=%x\n",11771177- iwl4965_hw_get_rate_n_flags(tx_resp->rate_n_flags));10571057+ IWL_DEBUG_TX_REPLY("Rate Info rate_n_flags=%x\n", rate_n_flags);1178105811791059 agg->wait_for_ba = 0;11801060 } else {···1230111412311115 agg->bitmap = bitmap;12321116 agg->start_idx = start;12331233- agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);12341117 IWL_DEBUG_TX_REPLY("Frames %d start_idx=%d bitmap=0x%llx\n",12351118 agg->frame_count, agg->start_idx,12361119 (unsigned long long)agg->bitmap);···12511136 struct ieee80211_tx_info *info;12521137 struct iwl5000_tx_resp *tx_resp = (void *)&pkt->u.raw[0];12531138 u32 status = le16_to_cpu(tx_resp->status.status);12541254-#ifdef CONFIG_IWL4965_HT12551139 int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION;12561256- u16 fc;12571140 struct ieee80211_hdr *hdr;12581141 u8 *qc = NULL;12591259-#endif1260114212611143 if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {12621144 IWL_ERROR("Read index for DMA queue txq_id (%d) index %d "···12661154 info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]);12671155 memset(&info->status, 0, sizeof(info->status));1268115612691269-#ifdef CONFIG_IWL4965_HT12701157 hdr = iwl_tx_queue_get_hdr(priv, txq_id, index);12711271- fc = le16_to_cpu(hdr->frame_control);12721272- if (ieee80211_is_qos_data(fc)) {12731273- qc = ieee80211_get_qos_ctrl(hdr, ieee80211_get_hdrlen(fc));11581158+ if (ieee80211_is_data_qos(hdr->frame_control)) {11591159+ qc = ieee80211_get_qos_ctl(hdr);12741160 tid = qc[0] & 0xf;12751161 }12761162···1287117712881178 agg = &priv->stations[sta_id].tid[tid].agg;1289117912901290- iwl5000_tx_status_reply_tx(priv, agg, tx_resp, index);11801180+ iwl5000_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index);1291118112921182 if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status)) {12931183 /* TODO: send BAR */···13051195 txq_id >= 0 && priv->mac80211_registered &&13061196 agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) {13071197 /* calculate mac80211 ampdu sw queue to wake */13081308- ampdu_q = txq_id - IWL_BACK_QUEUE_FIRST_ID +11981198+ ampdu_q = txq_id - IWL50_FIRST_AMPDU_QUEUE +13091199 priv->hw->queues;13101200 if (agg->state == IWL_AGG_OFF)13111201 ieee80211_wake_queue(priv->hw, txq_id);···13151205 iwl_txq_check_empty(priv, sta_id, tid, txq_id);13161206 }13171207 } else {13181318-#endif /* CONFIG_IWL4965_HT */12081208+ info->status.retry_count = tx_resp->failure_frame;12091209+ info->flags =12101210+ iwl_is_tx_success(status) ? IEEE80211_TX_STAT_ACK : 0;12111211+ iwl_hwrate_to_tx_control(priv,12121212+ le32_to_cpu(tx_resp->rate_n_flags),12131213+ info);1319121413201320- info->status.retry_count = tx_resp->failure_frame;13211321- info->flags = iwl_is_tx_success(status) ? IEEE80211_TX_STAT_ACK : 0;13221322- iwl4965_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags),13231323- info);12151215+ IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags "12161216+ "0x%x retries %d\n", txq_id,12171217+ iwl_get_tx_fail_reason(status),12181218+ status, le32_to_cpu(tx_resp->rate_n_flags),12191219+ tx_resp->failure_frame);1324122013251325- IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags 0x%x "13261326- "retries %d\n", txq_id, iwl_get_tx_fail_reason(status),13271327- status, le32_to_cpu(tx_resp->rate_n_flags),13281328- tx_resp->failure_frame);13291329-13301330- IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);13311331-#ifdef CONFIG_IWL4965_HT13321332- if (index != -1) {13331333- int freed = iwl_tx_queue_reclaim(priv, txq_id, index);13341334- if (tid != MAX_TID_COUNT)12211221+ IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);12221222+ if (index != -1) {12231223+ int freed = iwl_tx_queue_reclaim(priv, txq_id, index);12241224+ if (tid != MAX_TID_COUNT)13351225 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;13361336- if (iwl_queue_space(&txq->q) > txq->q.low_mark &&12261226+ if (iwl_queue_space(&txq->q) > txq->q.low_mark &&13371227 (txq_id >= 0) && priv->mac80211_registered)13381228 ieee80211_wake_queue(priv->hw, txq_id);13391339- if (tid != MAX_TID_COUNT)12291229+ if (tid != MAX_TID_COUNT)13401230 iwl_txq_check_empty(priv, sta_id, tid, txq_id);12311231+ }13411232 }13421342- }13431343-#endif /* CONFIG_IWL4965_HT */1344123313451234 if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))13461235 IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n");···13491240static u16 iwl5000_get_hcmd_size(u8 cmd_id, u16 len)13501241{13511242 return len;12431243+}12441244+12451245+static void iwl5000_setup_deferred_work(struct iwl_priv *priv)12461246+{12471247+ /* in 5000 the tx power calibration is done in uCode */12481248+ priv->disable_tx_power_cal = 1;13521249}1353125013541251static void iwl5000_rx_handler_setup(struct iwl_priv *priv)···1420130514211306 return ret;14221307}13081308+static int iwl5000_send_tx_power(struct iwl_priv *priv)13091309+{13101310+ struct iwl5000_tx_power_dbm_cmd tx_power_cmd;13111311+13121312+ /* half dBm need to multiply */13131313+ tx_power_cmd.global_lmt = (s8)(2 * priv->tx_power_user_lmt);13141314+ tx_power_cmd.flags = 0;13151315+ tx_power_cmd.srv_chan_lmt = IWL50_TX_POWER_AUTO;13161316+ return iwl_send_cmd_pdu_async(priv, REPLY_TX_POWER_DBM_CMD,13171317+ sizeof(tx_power_cmd), &tx_power_cmd,13181318+ NULL);13191319+}13201320+1423132114241322static struct iwl_hcmd_ops iwl5000_hcmd = {14251323 .rxon_assoc = iwl5000_send_rxon_assoc,···14411313static struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {14421314 .get_hcmd_size = iwl5000_get_hcmd_size,14431315 .build_addsta_hcmd = iwl5000_build_addsta_hcmd,14441444-#ifdef CONFIG_IWL5000_RUN_TIME_CALIB14451316 .gain_computation = iwl5000_gain_computation,14461317 .chain_noise_reset = iwl5000_chain_noise_reset,14471447-#endif14481318};1449131914501320static struct iwl_lib_ops iwl5000_lib = {···14531327 .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl,14541328 .txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl,14551329 .txq_set_sched = iwl5000_txq_set_sched,13301330+ .txq_agg_enable = iwl5000_txq_agg_enable,13311331+ .txq_agg_disable = iwl5000_txq_agg_disable,14561332 .rx_handler_setup = iwl5000_rx_handler_setup,13331333+ .setup_deferred_work = iwl5000_setup_deferred_work,14571334 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,14581335 .load_ucode = iwl5000_load_ucode,14591336 .init_alive_start = iwl5000_init_alive_start,14601337 .alive_notify = iwl5000_alive_notify,13381338+ .send_tx_power = iwl5000_send_tx_power,14611339 .apm_ops = {14621340 .init = iwl5000_apm_init,14631341 .reset = iwl5000_apm_reset,
-4
drivers/net/wireless/iwlwifi/iwl-calib.c
···6060 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.6161 *****************************************************************************/62626363-#include <linux/kernel.h>6463#include <net/mac80211.h>65646665#include "iwl-dev.h"6766#include "iwl-core.h"6867#include "iwl-calib.h"6969-#include "iwl-eeprom.h"70687169/* "false alarms" are signals that our DSP tries to lock onto,7270 * but then determines that they are either noise, or transmissions···433435 data = &(priv->sensitivity_data);434436435437 if (ranges == NULL)436436- /* can happen if IWLWIFI_RUN_TIME_CALIB is selected437437- * but no IWLXXXX_RUN_TIME_CALIB for specific is selected */438438 return;439439440440 memset(data, 0, sizeof(struct iwl_sensitivity_data));
···2929 * Please use iwl-4965-hw.h for hardware-related definitions.3030 */31313232-#ifndef __iwl_4965_h__3333-#define __iwl_4965_h__3232+#ifndef __iwl_dev_h__3333+#define __iwl_dev_h__34343535#include <linux/pci.h> /* for struct pci_device_id */3636#include <linux/kernel.h>···157157 s64 last_radar_time;158158};159159160160-/* current Tx power values to use, one for each rate for each channel.161161- * requested power is limited by:162162- * -- regulatory EEPROM limits for this channel163163- * -- hardware capabilities (clip-powers)164164- * -- spectrum management165165- * -- user preference (e.g. iwconfig)166166- * when requested power is set, base power index must also be set. */167167-struct iwl4965_channel_power_info {168168- struct iwl4965_tx_power tpc; /* actual radio and DSP gain settings */169169- s8 power_table_index; /* actual (compenst'd) index into gain table */170170- s8 base_power_index; /* gain index for power at factory temp. */171171- s8 requested_power; /* power (dBm) requested for this chnl/rate */172172-};173173-174174-/* current scan Tx power values to use, one for each scan rate for each175175- * channel. */176176-struct iwl4965_scan_power_info {177177- struct iwl4965_tx_power tpc; /* actual radio and DSP gain settings */178178- s8 power_table_index; /* actual (compenst'd) index into gain table */179179- s8 requested_power; /* scan pwr (dBm) requested for chnl/rate */180180-};181181-182182-/* For fat_extension_channel */183183-enum {184184- HT_IE_EXT_CHANNEL_NONE = 0,185185- HT_IE_EXT_CHANNEL_ABOVE,186186- HT_IE_EXT_CHANNEL_INVALID,187187- HT_IE_EXT_CHANNEL_BELOW,188188- HT_IE_EXT_CHANNEL_MAX189189-};190190-191160/*192161 * One for each channel, holds all channel setup data193162 * Some of the fields (e.g. eeprom and flags/max_power_avg) are redundant194163 * with one another!195164 */196196-#define IWL4965_MAX_RATE (33)197197-198165struct iwl_channel_info {199166 struct iwl4965_channel_tgd_info tgd;200167 struct iwl4965_channel_tgh_info tgh;···180213 u8 band_index; /* 0-4, maps channel to band1/2/3/4/5 */181214 enum ieee80211_band band;182215183183- /* Radio/DSP gain settings for each "normal" data Tx rate.184184- * These include, in addition to RF and DSP gain, a few fields for185185- * remembering/modifying gain settings (indexes). */186186- struct iwl4965_channel_power_info power_info[IWL4965_MAX_RATE];187187-188216 /* FAT channel info */189217 s8 fat_max_power_avg; /* (dBm) regul. eeprom, normal Tx, any rate */190218 s8 fat_curr_txpow; /* (dBm) regulatory/spectrum/user (not h/w) */···187225 s8 fat_scan_power; /* (dBm) eeprom, direct scans, any rate */188226 u8 fat_flags; /* flags copied from EEPROM */189227 u8 fat_extension_channel; /* HT_IE_EXT_CHANNEL_* */190190-191191- /* Radio/DSP gain settings for each scan rate, for directed scans. */192192- struct iwl4965_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES];193228};194229195230struct iwl4965_clip_group {···360401#define IWL_INVALID_RATE 0xFF361402#define IWL_INVALID_VALUE -1362403363363-#ifdef CONFIG_IWL4965_HT364404/**365405 * struct iwl_ht_agg -- aggregation status while waiting for block-ack366406 * @txq_id: Tx queue used for Tx attempt···388430 u8 state;389431};390432391391-#endif /* CONFIG_IWL4965_HT */392433393434struct iwl_tid_data {394435 u16 seq_number;395436 u16 tfds_in_queue;396396-#ifdef CONFIG_IWL4965_HT397437 struct iwl_ht_agg agg;398398-#endif /* CONFIG_IWL4965_HT */399438};400439401440struct iwl_hw_key {···480525};481526482527/* uCode file layout */483483-struct iwl4965_ucode {528528+struct iwl_ucode {484529 __le32 ver; /* major/minor/subminor */485530 __le32 inst_size; /* bytes of runtime instructions */486531 __le32 data_size; /* bytes of runtime data */···542587 * @max_xxx_size: for ucode uses543588 * @ct_kill_threshold: temperature threshold544589 * @struct iwl_sensitivity_ranges: range of sensitivity values590590+ * @first_ampdu_q: first HW queue available for ampdu545591 */546592struct iwl_hw_params {547593 u16 max_txq_num;···562606 u32 max_data_size;563607 u32 max_bsm_size;564608 u32 ct_kill_threshold; /* value in hw-dependent units */565565-#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB566609 const struct iwl_sensitivity_ranges *sens;567567-#endif610610+ u8 first_ampdu_q;568611};569612570613#define HT_SHORT_GI_20MHZ (1 << 0)···593638 u8 flags, struct ieee80211_ht_info *ht_info);594639extern int iwl4965_is_network_packet(struct iwl_priv *priv,595640 struct ieee80211_hdr *header);596596-extern int iwl4965_power_init_handle(struct iwl_priv *priv);597597-extern void iwl4965_handle_data_packet_monitor(struct iwl_priv *priv,598598- struct iwl_rx_mem_buffer *rxb,599599- void *data, short len,600600- struct ieee80211_rx_status *stats,601601- u16 phy_flags);602641extern int iwl4965_is_duplicate_packet(struct iwl_priv *priv,603642 struct ieee80211_hdr *header);604604-extern int iwl4965_calc_db_from_ratio(int sig_ratio);605643extern int iwl4965_calc_sig_qual(int rssi_dbm, int noise_dbm);606644extern unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv,607645 struct ieee80211_hdr *hdr,···602654extern void iwl4965_update_chain_flags(struct iwl_priv *priv);603655int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src);604656605605-int iwl4965_init_geos(struct iwl_priv *priv);606606-void iwl4965_free_geos(struct iwl_priv *priv);607607-608657extern const u8 iwl_bcast_addr[ETH_ALEN];609609-int iwl4965_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd);610610-611611-/*612612- * Currently used by iwl-3945-rs... look at restructuring so that it doesn't613613- * call this... todo... fix that.614614-*/615615-extern u8 iwl4965_sync_station(struct iwl_priv *priv, int sta_id,616616- u16 tx_rate, u8 flags);617658618659/******************************************************************************619660 *···620683 * iwl4965_mac_ <-- mac80211 callback621684 *622685 ****************************************************************************/623623-extern void iwl4965_hw_setup_deferred_work(struct iwl_priv *priv);624624-extern void iwl4965_hw_cancel_deferred_work(struct iwl_priv *priv);625625-extern int iwl4965_hw_set_hw_params(struct iwl_priv *priv);626686extern int iwl_rxq_stop(struct iwl_priv *priv);627687extern void iwl_txq_ctx_stop(struct iwl_priv *priv);628628-extern int iwl4965_hw_get_temperature(struct iwl_priv *priv);629688extern unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv,630689 struct iwl_frame *frame, u8 rate);631631-extern void iwl4965_hw_build_tx_cmd_rate(struct iwl_priv *priv,632632- struct iwl_cmd *cmd,633633- struct ieee80211_tx_info *info,634634- struct ieee80211_hdr *hdr,635635- int sta_id, int tx_id);636636-extern int iwl4965_hw_reg_send_txpower(struct iwl_priv *priv);637637-extern int iwl4965_hw_reg_set_txpower(struct iwl_priv *priv, s8 power);638690extern void iwl4965_hw_rx_statistics(struct iwl_priv *priv,639691 struct iwl_rx_mem_buffer *rxb);640692extern void iwl4965_disable_events(struct iwl_priv *priv);641641-extern int iwl4965_get_temperature(const struct iwl_priv *priv);642693extern void iwl4965_rx_reply_rx(struct iwl_priv *priv,643694 struct iwl_rx_mem_buffer *rxb);644644-645645-/**646646- * iwl_find_station - Find station id for a given BSSID647647- * @bssid: MAC address of station ID to find648648- *649649- * NOTE: This should not be hardware specific but the code has650650- * not yet been merged into a single common layer for managing the651651- * station tables.652652- */653653-extern u8 iwl_find_station(struct iwl_priv *priv, const u8 *bssid);654695655696extern int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel);656697extern int iwl_queue_space(const struct iwl_queue *q);···653738654739struct iwl_priv;655740656656-extern void iwl4965_radio_kill_sw(struct iwl_priv *priv, int disable_radio);657741/*658742 * Forward declare iwl-4965.c functions for iwl-base.c659743 */660660-extern int iwl4965_tx_queue_update_wr_ptr(struct iwl_priv *priv,661661- struct iwl_tx_queue *txq,662662- u16 byte_cnt);663663-extern int iwl4965_alive_notify(struct iwl_priv *priv);664664-extern void iwl4965_update_rate_scaling(struct iwl_priv *priv, u8 mode);665744extern void iwl4965_rf_kill_ct_config(struct iwl_priv *priv);666666-extern void iwl4965_hwrate_to_tx_control(struct iwl_priv *priv,667667- u32 rate_n_flags,668668- struct ieee80211_tx_info *info);669745670670-#ifdef CONFIG_IWL4965_HT671671-extern void iwl4965_init_ht_hw_capab(const struct iwl_priv *priv,672672- struct ieee80211_ht_info *ht_info,673673- enum ieee80211_band band);674674-void iwl4965_set_rxon_ht(struct iwl_priv *priv,675675- struct iwl_ht_info *ht_info);676746int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw,677747 enum ieee80211_ampdu_mlme_action action,678748 const u8 *addr, u16 tid, u16 *ssn);679749int iwl4965_check_empty_hw_queue(struct iwl_priv *priv, int sta_id,680750 u8 tid, int txq_id);681681-#else682682-static inline void iwl4965_init_ht_hw_capab(const struct iwl_priv *priv,683683- struct ieee80211_ht_info *ht_info,684684- enum ieee80211_band band) {}685751686686-#endif /*CONFIG_IWL4965_HT */687752/* Structures, enum, and defines specific to the 4965 */688753689754#define IWL_KW_SIZE 0x1000 /*4k */···686791#define IWL_OPERATION_MODE_HT_ONLY 1687792#define IWL_OPERATION_MODE_MIXED 2688793#define IWL_OPERATION_MODE_20MHZ 3689689-690690-#define IWL_EXT_CHANNEL_OFFSET_NONE 0691691-#define IWL_EXT_CHANNEL_OFFSET_ABOVE 1692692-#define IWL_EXT_CHANNEL_OFFSET_RESERVE1 2693693-#define IWL_EXT_CHANNEL_OFFSET_BELOW 3694794695795#define IWL_TX_CRC_SIZE 4696796#define IWL_TX_DELIMITER_SIZE 4···782892 UCODE_RT783893};784894785785-#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB786895/* Sensitivity calib data */787896struct iwl_sensitivity_data {788897 u32 auto_corr_ofdm;···823934 u8 delta_gain_code[NUM_RX_CHAINS];824935 u8 radio_write;825936};826826-#endif /* CONFIG_IWLWIFI_RUN_TIME_CALIB */827937828938#define EEPROM_SEM_TIMEOUT 10 /* milliseconds */829939#define EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */···8941006 int one_direct_scan;8951007 u8 direct_ssid_len;8961008 u8 direct_ssid[IW_ESSID_MAX_SIZE];897897- struct iwl4965_scan_cmd *scan;10091009+ struct iwl_scan_cmd *scan;10101010+ u32 scan_tx_ant[IEEE80211_NUM_BANDS];89810118991012 /* spinlock */9001013 spinlock_t lock; /* protect general shared data */···9561067 u8 assoc_station_added;9571068 u8 use_ant_b_for_management_frame; /* Tx antenna selection */9581069 u8 start_calib;959959-#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB9601070 struct iwl_sensitivity_data sensitivity_data;9611071 struct iwl_chain_noise_data chain_noise_data;9621072 __le16 sensitivity_tbl[HD_TABLE_SIZE];963963-#endif /*CONFIG_IWLWIFI_RUN_TIME_CALIB*/9641073965965-#ifdef CONFIG_IWL4965_HT9661074 struct iwl_ht_info current_ht_config;967967-#endif9681075 u8 last_phy_res[100];96910769701077 /* Rate scaling data */···1082119710831198 struct delayed_work init_alive_start;10841199 struct delayed_work alive_start;10851085- struct delayed_work activity_timer;10861086- struct delayed_work thermal_periodic;10871087- struct delayed_work gather_stats;10881200 struct delayed_work scan_check;10891201 struct delayed_work post_associate;10901090-10911091-#define IWL_DEFAULT_TX_POWER 0x0F10921092- s8 user_txpower_limit;10931093- s8 max_channel_txpower_limit;12021202+ /* TX Power */12031203+ s8 tx_power_user_lmt;12041204+ s8 tx_power_channel_lmt;1094120510951206#ifdef CONFIG_PM10961207 u32 pm_state[16];···11041223#endif /* CONFIG_IWLWIFI_DEBUG */1105122411061225 struct work_struct txpower_work;11071107-#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB11081226 u32 disable_sens_cal;11091227 u32 disable_chain_noise_cal;11101110-#endif /* CONFIG_IWLWIFI_RUN_TIME_CALIB */11111111-#ifdef CONFIG_IWL4965_RUN_TIME_CALIB11121112- struct work_struct sensitivity_work;11131113-#endif /* CONFIG_IWL4965_RUN_TIME_CALIB */12281228+ u32 disable_tx_power_cal;12291229+ struct work_struct run_time_calib_work;11141230 struct timer_list statistics_periodic;11151231}; /*iwl_priv */11161232···11281250#endif112912511130125211311131-#ifdef CONFIG_IWL4965_HT11321132-static inline int iwl_get_ra_sta_id(struct iwl_priv *priv,11331133- struct ieee80211_hdr *hdr)11341134-{11351135- if (priv->iw_mode == IEEE80211_IF_TYPE_STA) {11361136- return IWL_AP_ID;11371137- } else {11381138- u8 *da = ieee80211_get_DA(hdr);11391139- return iwl_find_station(priv, da);11401140- }11411141-}11421142-11431253static inline struct ieee80211_hdr *iwl_tx_queue_get_hdr(struct iwl_priv *priv,11441254 int txq_id, int idx)11451255{···11361270 txb[idx].skb[0]->data;11371271 return NULL;11381272}11391139-#endif114012731141127411421275static inline int iwl_is_associated(struct iwl_priv *priv)···1197133211981333/* Requires full declaration of iwl_priv before including */1199133412001200-#endif /* __iwl4965_4965_h__ */13351335+#endif /* __iwl_dev_h__ */
+19-12
drivers/net/wireless/iwlwifi/iwl-eeprom.c
···382382 if (!is_channel_valid(ch_info))383383 return -1;384384385385- IWL_DEBUG_INFO("FAT Ch. %d [%sGHz] %s%s%s%s%s(0x%02x"386386- " %ddBm): Ad-Hoc %ssupported\n",385385+ IWL_DEBUG_INFO("FAT Ch. %d [%sGHz] %s%s%s%s%s(0x%02x %ddBm):"386386+ " Ad-Hoc %ssupported\n",387387 ch_info->channel,388388 is_channel_a_band(ch_info) ?389389 "5.2" : "2.4",···470470 /* Copy the run-time flags so they are there even on471471 * invalid channels */472472 ch_info->flags = eeprom_ch_info[ch].flags;473473+ /* First write that fat is not enabled, and then enable474474+ * one by one */475475+ ch_info->fat_extension_channel =476476+ (IEEE80211_CHAN_NO_FAT_ABOVE |477477+ IEEE80211_CHAN_NO_FAT_BELOW);473478474479 if (!(is_channel_valid(ch_info))) {475480 IWL_DEBUG_INFO("Ch. %d Flags %x [%sGHz] - "···493488 ch_info->scan_power = eeprom_ch_info[ch].max_power_avg;494489 ch_info->min_power = 0;495490496496- IWL_DEBUG_INFO("Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x"497497- " %ddBm): Ad-Hoc %ssupported\n",491491+ IWL_DEBUG_INFO("Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x %ddBm):"492492+ " Ad-Hoc %ssupported\n",498493 ch_info->channel,499494 is_channel_a_band(ch_info) ?500495 "5.2" : "2.4",···515510 /* Set the user_txpower_limit to the highest power516511 * supported by any channel */517512 if (eeprom_ch_info[ch].max_power_avg >518518- priv->user_txpower_limit)519519- priv->user_txpower_limit =513513+ priv->tx_power_user_lmt)514514+ priv->tx_power_user_lmt =520515 eeprom_ch_info[ch].max_power_avg;521516522517 ch_info++;···539534 for (ch = 0; ch < eeprom_ch_count; ch++) {540535541536 if ((band == 6) &&542542- ((eeprom_ch_index[ch] == 5) ||543543- (eeprom_ch_index[ch] == 6) ||544544- (eeprom_ch_index[ch] == 7)))545545- fat_extension_chan = HT_IE_EXT_CHANNEL_MAX;537537+ ((eeprom_ch_index[ch] == 5) ||538538+ (eeprom_ch_index[ch] == 6) ||539539+ (eeprom_ch_index[ch] == 7)))540540+ /* both are allowed: above and below */541541+ fat_extension_chan = 0;546542 else547547- fat_extension_chan = HT_IE_EXT_CHANNEL_ABOVE;543543+ fat_extension_chan =544544+ IEEE80211_CHAN_NO_FAT_BELOW;548545549546 /* Set up driver's info for lower half */550547 iwl_set_fat_chan_info(priv, ieeeband,···558551 iwl_set_fat_chan_info(priv, ieeeband,559552 (eeprom_ch_index[ch] + 4),560553 &(eeprom_ch_info[ch]),561561- HT_IE_EXT_CHANNEL_BELOW);554554+ IEEE80211_CHAN_NO_FAT_ABOVE);562555 }563556 }564557
-111
drivers/net/wireless/iwlwifi/iwl-helpers.h
···139139#define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo))))140140141141142142-#define IEEE80211_CHAN_W_RADAR_DETECT 0x00000010143143-144142static inline struct ieee80211_conf *ieee80211_get_hw_conf(145143 struct ieee80211_hw *hw)146144{147145 return &hw->conf;148148-}149149-150150-#define QOS_CONTROL_LEN 2151151-152152-153153-static inline int ieee80211_is_management(u16 fc)154154-{155155- return (fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT;156156-}157157-158158-static inline int ieee80211_is_control(u16 fc)159159-{160160- return (fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL;161161-}162162-163163-static inline int ieee80211_is_data(u16 fc)164164-{165165- return (fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA;166166-}167167-168168-static inline int ieee80211_is_back_request(u16 fc)169169-{170170- return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) &&171171- ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BACK_REQ);172172-}173173-174174-static inline int ieee80211_is_probe_response(u16 fc)175175-{176176- return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&177177- ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP);178178-}179179-180180-static inline int ieee80211_is_probe_request(u16 fc)181181-{182182- return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&183183- ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_REQ);184184-}185185-186186-static inline int ieee80211_is_beacon(u16 fc)187187-{188188- return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&189189- ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON);190190-}191191-192192-static inline int ieee80211_is_atim(u16 fc)193193-{194194- return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&195195- ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ATIM);196196-}197197-198198-static inline int ieee80211_is_assoc_request(u16 fc)199199-{200200- return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&201201- ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ);202202-}203203-204204-static inline int ieee80211_is_assoc_response(u16 fc)205205-{206206- return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&207207- ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_RESP);208208-}209209-210210-static inline int ieee80211_is_auth(u16 fc)211211-{212212- return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&213213- ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ);214214-}215215-216216-static inline int ieee80211_is_deauth(u16 fc)217217-{218218- return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&219219- ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ);220220-}221221-222222-static inline int ieee80211_is_disassoc(u16 fc)223223-{224224- return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&225225- ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ);226226-}227227-228228-static inline int ieee80211_is_reassoc_request(u16 fc)229229-{230230- return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&231231- ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_REQ);232232-}233233-234234-static inline int ieee80211_is_reassoc_response(u16 fc)235235-{236236- return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&237237- ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_RESP);238238-}239239-240240-static inline int ieee80211_is_qos_data(u16 fc)241241-{242242- return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) &&243243- ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_QOS_DATA);244244-}245245-/**246246- * ieee80211_get_qos_ctrl - get pointer to the QoS control field247247- *248248- * This function returns the pointer to 802.11 header QoS field (2 bytes)249249- * This function doesn't check whether hdr is a QoS hdr, use with care250250- * @hdr: struct ieee80211_hdr *hdr251251- * @hdr_len: header length252252- */253253-254254-static inline u8 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr, int hdr_len)255255-{256256- return ((u8 *) hdr + hdr_len - QOS_CONTROL_LEN);257146}258147259148static inline int iwl_check_bits(unsigned long field, unsigned long mask)
+2-2
drivers/net/wireless/iwlwifi/iwl-rfkill.c
···55555656 switch (state) {5757 case RFKILL_STATE_ON:5858- priv->cfg->ops->lib->radio_kill_sw(priv, 0);5858+ iwl_radio_kill_sw_enable_radio(priv);5959 /* if HW rf-kill is set dont allow ON state */6060 if (iwl_is_rfkill(priv))6161 err = -EBUSY;6262 break;6363 case RFKILL_STATE_OFF:6464- priv->cfg->ops->lib->radio_kill_sw(priv, 1);6464+ iwl_radio_kill_sw_disable_radio(priv);6565 if (!iwl_is_rfkill(priv))6666 err = -EBUSY;6767 break;
···11+/******************************************************************************22+ *33+ * GPL LICENSE SUMMARY44+ *55+ * Copyright(c) 2008 Intel Corporation. All rights reserved.66+ *77+ * This program is free software; you can redistribute it and/or modify88+ * it under the terms of version 2 of the GNU General Public License as99+ * published by the Free Software Foundation.1010+ *1111+ * This program is distributed in the hope that it will be useful, but1212+ * WITHOUT ANY WARRANTY; without even the implied warranty of1313+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU1414+ * General Public License for more details.1515+ *1616+ * You should have received a copy of the GNU General Public License1717+ * along with this program; if not, write to the Free Software1818+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,1919+ * USA2020+ *2121+ * The full GNU General Public License is included in this distribution2222+ * in the file called LICENSE.GPL.2323+ *2424+ * Contact Information:2525+ * Tomas Winkler <tomas.winkler@intel.com>2626+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-64972727+ *****************************************************************************/2828+#include <net/mac80211.h>2929+#include <linux/etherdevice.h>3030+3131+#include "iwl-eeprom.h"3232+#include "iwl-dev.h"3333+#include "iwl-core.h"3434+#include "iwl-sta.h"3535+#include "iwl-io.h"3636+#include "iwl-helpers.h"3737+3838+/* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after3939+ * sending probe req. This should be set long enough to hear probe responses4040+ * from more than one AP. */4141+#define IWL_ACTIVE_DWELL_TIME_24 (20) /* all times in msec */4242+#define IWL_ACTIVE_DWELL_TIME_52 (10)4343+4444+/* For faster active scanning, scan will move to the next channel if fewer than4545+ * PLCP_QUIET_THRESH packets are heard on this channel within4646+ * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell4747+ * time if it's a quiet channel (nothing responded to our probe, and there's4848+ * no other traffic).4949+ * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */5050+#define IWL_PLCP_QUIET_THRESH __constant_cpu_to_le16(1) /* packets */5151+#define IWL_ACTIVE_QUIET_TIME __constant_cpu_to_le16(5) /* msec */5252+5353+/* For passive scan, listen PASSIVE_DWELL_TIME (msec) on each channel.5454+ * Must be set longer than active dwell time.5555+ * For the most reliable scan, set > AP beacon interval (typically 100msec). */5656+#define IWL_PASSIVE_DWELL_TIME_24 (20) /* all times in msec */5757+#define IWL_PASSIVE_DWELL_TIME_52 (10)5858+#define IWL_PASSIVE_DWELL_BASE (100)5959+#define IWL_CHANNEL_TUNE_TIME 56060+6161+static int scan_tx_ant[3] = {6262+ RATE_MCS_ANT_A_MSK, RATE_MCS_ANT_B_MSK, RATE_MCS_ANT_C_MSK6363+};6464+6565+static int iwl_is_empty_essid(const char *essid, int essid_len)6666+{6767+ /* Single white space is for Linksys APs */6868+ if (essid_len == 1 && essid[0] == ' ')6969+ return 1;7070+7171+ /* Otherwise, if the entire essid is 0, we assume it is hidden */7272+ while (essid_len) {7373+ essid_len--;7474+ if (essid[essid_len] != '\0')7575+ return 0;7676+ }7777+7878+ return 1;7979+}8080+8181+8282+8383+const char *iwl_escape_essid(const char *essid, u8 essid_len)8484+{8585+ static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];8686+ const char *s = essid;8787+ char *d = escaped;8888+8989+ if (iwl_is_empty_essid(essid, essid_len)) {9090+ memcpy(escaped, "<hidden>", sizeof("<hidden>"));9191+ return escaped;9292+ }9393+9494+ essid_len = min(essid_len, (u8) IW_ESSID_MAX_SIZE);9595+ while (essid_len--) {9696+ if (*s == '\0') {9797+ *d++ = '\\';9898+ *d++ = '0';9999+ s++;100100+ } else101101+ *d++ = *s++;102102+ }103103+ *d = '\0';104104+ return escaped;105105+}106106+EXPORT_SYMBOL(iwl_escape_essid);107107+108108+/**109109+ * iwl_scan_cancel - Cancel any currently executing HW scan110110+ *111111+ * NOTE: priv->mutex is not required before calling this function112112+ */113113+int iwl_scan_cancel(struct iwl_priv *priv)114114+{115115+ if (!test_bit(STATUS_SCAN_HW, &priv->status)) {116116+ clear_bit(STATUS_SCANNING, &priv->status);117117+ return 0;118118+ }119119+120120+ if (test_bit(STATUS_SCANNING, &priv->status)) {121121+ if (!test_bit(STATUS_SCAN_ABORTING, &priv->status)) {122122+ IWL_DEBUG_SCAN("Queuing scan abort.\n");123123+ set_bit(STATUS_SCAN_ABORTING, &priv->status);124124+ queue_work(priv->workqueue, &priv->abort_scan);125125+126126+ } else127127+ IWL_DEBUG_SCAN("Scan abort already in progress.\n");128128+129129+ return test_bit(STATUS_SCANNING, &priv->status);130130+ }131131+132132+ return 0;133133+}134134+EXPORT_SYMBOL(iwl_scan_cancel);135135+/**136136+ * iwl_scan_cancel_timeout - Cancel any currently executing HW scan137137+ * @ms: amount of time to wait (in milliseconds) for scan to abort138138+ *139139+ * NOTE: priv->mutex must be held before calling this function140140+ */141141+int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms)142142+{143143+ unsigned long now = jiffies;144144+ int ret;145145+146146+ ret = iwl_scan_cancel(priv);147147+ if (ret && ms) {148148+ mutex_unlock(&priv->mutex);149149+ while (!time_after(jiffies, now + msecs_to_jiffies(ms)) &&150150+ test_bit(STATUS_SCANNING, &priv->status))151151+ msleep(1);152152+ mutex_lock(&priv->mutex);153153+154154+ return test_bit(STATUS_SCANNING, &priv->status);155155+ }156156+157157+ return ret;158158+}159159+EXPORT_SYMBOL(iwl_scan_cancel_timeout);160160+161161+static int iwl_send_scan_abort(struct iwl_priv *priv)162162+{163163+ int ret = 0;164164+ struct iwl_rx_packet *res;165165+ struct iwl_host_cmd cmd = {166166+ .id = REPLY_SCAN_ABORT_CMD,167167+ .meta.flags = CMD_WANT_SKB,168168+ };169169+170170+ /* If there isn't a scan actively going on in the hardware171171+ * then we are in between scan bands and not actually172172+ * actively scanning, so don't send the abort command */173173+ if (!test_bit(STATUS_SCAN_HW, &priv->status)) {174174+ clear_bit(STATUS_SCAN_ABORTING, &priv->status);175175+ return 0;176176+ }177177+178178+ ret = iwl_send_cmd_sync(priv, &cmd);179179+ if (ret) {180180+ clear_bit(STATUS_SCAN_ABORTING, &priv->status);181181+ return ret;182182+ }183183+184184+ res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;185185+ if (res->u.status != CAN_ABORT_STATUS) {186186+ /* The scan abort will return 1 for success or187187+ * 2 for "failure". A failure condition can be188188+ * due to simply not being in an active scan which189189+ * can occur if we send the scan abort before we190190+ * the microcode has notified us that a scan is191191+ * completed. */192192+ IWL_DEBUG_INFO("SCAN_ABORT returned %d.\n", res->u.status);193193+ clear_bit(STATUS_SCAN_ABORTING, &priv->status);194194+ clear_bit(STATUS_SCAN_HW, &priv->status);195195+ }196196+197197+ dev_kfree_skb_any(cmd.meta.u.skb);198198+199199+ return ret;200200+}201201+202202+203203+/* Service response to REPLY_SCAN_CMD (0x80) */204204+static void iwl_rx_reply_scan(struct iwl_priv *priv,205205+ struct iwl_rx_mem_buffer *rxb)206206+{207207+#ifdef CONFIG_IWLWIFI_DEBUG208208+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;209209+ struct iwl_scanreq_notification *notif =210210+ (struct iwl_scanreq_notification *)pkt->u.raw;211211+212212+ IWL_DEBUG_RX("Scan request status = 0x%x\n", notif->status);213213+#endif214214+}215215+216216+/* Service SCAN_START_NOTIFICATION (0x82) */217217+static void iwl_rx_scan_start_notif(struct iwl_priv *priv,218218+ struct iwl_rx_mem_buffer *rxb)219219+{220220+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;221221+ struct iwl_scanstart_notification *notif =222222+ (struct iwl_scanstart_notification *)pkt->u.raw;223223+ priv->scan_start_tsf = le32_to_cpu(notif->tsf_low);224224+ IWL_DEBUG_SCAN("Scan start: "225225+ "%d [802.11%s] "226226+ "(TSF: 0x%08X:%08X) - %d (beacon timer %u)\n",227227+ notif->channel,228228+ notif->band ? "bg" : "a",229229+ notif->tsf_high,230230+ notif->tsf_low, notif->status, notif->beacon_timer);231231+}232232+233233+/* Service SCAN_RESULTS_NOTIFICATION (0x83) */234234+static void iwl_rx_scan_results_notif(struct iwl_priv *priv,235235+ struct iwl_rx_mem_buffer *rxb)236236+{237237+#ifdef CONFIG_IWLWIFI_DEBUG238238+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;239239+ struct iwl_scanresults_notification *notif =240240+ (struct iwl_scanresults_notification *)pkt->u.raw;241241+242242+ IWL_DEBUG_SCAN("Scan ch.res: "243243+ "%d [802.11%s] "244244+ "(TSF: 0x%08X:%08X) - %d "245245+ "elapsed=%lu usec (%dms since last)\n",246246+ notif->channel,247247+ notif->band ? "bg" : "a",248248+ le32_to_cpu(notif->tsf_high),249249+ le32_to_cpu(notif->tsf_low),250250+ le32_to_cpu(notif->statistics[0]),251251+ le32_to_cpu(notif->tsf_low) - priv->scan_start_tsf,252252+ jiffies_to_msecs(elapsed_jiffies253253+ (priv->last_scan_jiffies, jiffies)));254254+#endif255255+256256+ priv->last_scan_jiffies = jiffies;257257+ priv->next_scan_jiffies = 0;258258+}259259+260260+/* Service SCAN_COMPLETE_NOTIFICATION (0x84) */261261+static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,262262+ struct iwl_rx_mem_buffer *rxb)263263+{264264+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;265265+ struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw;266266+267267+ IWL_DEBUG_SCAN("Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n",268268+ scan_notif->scanned_channels,269269+ scan_notif->tsf_low,270270+ scan_notif->tsf_high, scan_notif->status);271271+272272+ /* The HW is no longer scanning */273273+ clear_bit(STATUS_SCAN_HW, &priv->status);274274+275275+ /* The scan completion notification came in, so kill that timer... */276276+ cancel_delayed_work(&priv->scan_check);277277+278278+ IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n",279279+ (priv->scan_bands == 2) ? "2.4" : "5.2",280280+ jiffies_to_msecs(elapsed_jiffies281281+ (priv->scan_pass_start, jiffies)));282282+283283+ /* Remove this scanned band from the list284284+ * of pending bands to scan */285285+ priv->scan_bands--;286286+287287+ /* If a request to abort was given, or the scan did not succeed288288+ * then we reset the scan state machine and terminate,289289+ * re-queuing another scan if one has been requested */290290+ if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {291291+ IWL_DEBUG_INFO("Aborted scan completed.\n");292292+ clear_bit(STATUS_SCAN_ABORTING, &priv->status);293293+ } else {294294+ /* If there are more bands on this scan pass reschedule */295295+ if (priv->scan_bands > 0)296296+ goto reschedule;297297+ }298298+299299+ priv->last_scan_jiffies = jiffies;300300+ priv->next_scan_jiffies = 0;301301+ IWL_DEBUG_INFO("Setting scan to off\n");302302+303303+ clear_bit(STATUS_SCANNING, &priv->status);304304+305305+ IWL_DEBUG_INFO("Scan took %dms\n",306306+ jiffies_to_msecs(elapsed_jiffies(priv->scan_start, jiffies)));307307+308308+ queue_work(priv->workqueue, &priv->scan_completed);309309+310310+ return;311311+312312+reschedule:313313+ priv->scan_pass_start = jiffies;314314+ queue_work(priv->workqueue, &priv->request_scan);315315+}316316+317317+void iwl_setup_rx_scan_handlers(struct iwl_priv *priv)318318+{319319+ /* scan handlers */320320+ priv->rx_handlers[REPLY_SCAN_CMD] = iwl_rx_reply_scan;321321+ priv->rx_handlers[SCAN_START_NOTIFICATION] = iwl_rx_scan_start_notif;322322+ priv->rx_handlers[SCAN_RESULTS_NOTIFICATION] =323323+ iwl_rx_scan_results_notif;324324+ priv->rx_handlers[SCAN_COMPLETE_NOTIFICATION] =325325+ iwl_rx_scan_complete_notif;326326+}327327+EXPORT_SYMBOL(iwl_setup_rx_scan_handlers);328328+329329+static inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv,330330+ enum ieee80211_band band)331331+{332332+ if (band == IEEE80211_BAND_5GHZ)333333+ return IWL_ACTIVE_DWELL_TIME_52;334334+ else335335+ return IWL_ACTIVE_DWELL_TIME_24;336336+}337337+338338+static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,339339+ enum ieee80211_band band)340340+{341341+ u16 active = iwl_get_active_dwell_time(priv, band);342342+ u16 passive = (band != IEEE80211_BAND_5GHZ) ?343343+ IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 :344344+ IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52;345345+346346+ if (iwl_is_associated(priv)) {347347+ /* If we're associated, we clamp the maximum passive348348+ * dwell time to be 98% of the beacon interval (minus349349+ * 2 * channel tune time) */350350+ passive = priv->beacon_int;351351+ if ((passive > IWL_PASSIVE_DWELL_BASE) || !passive)352352+ passive = IWL_PASSIVE_DWELL_BASE;353353+ passive = (passive * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2;354354+ }355355+356356+ if (passive <= active)357357+ passive = active + 1;358358+359359+ return passive;360360+}361361+362362+static int iwl_get_channels_for_scan(struct iwl_priv *priv,363363+ enum ieee80211_band band,364364+ u8 is_active, u8 direct_mask,365365+ struct iwl_scan_channel *scan_ch)366366+{367367+ const struct ieee80211_channel *channels = NULL;368368+ const struct ieee80211_supported_band *sband;369369+ const struct iwl_channel_info *ch_info;370370+ u16 passive_dwell = 0;371371+ u16 active_dwell = 0;372372+ int added, i;373373+374374+ sband = iwl_get_hw_mode(priv, band);375375+ if (!sband)376376+ return 0;377377+378378+ channels = sband->channels;379379+380380+ active_dwell = iwl_get_active_dwell_time(priv, band);381381+ passive_dwell = iwl_get_passive_dwell_time(priv, band);382382+383383+ for (i = 0, added = 0; i < sband->n_channels; i++) {384384+ if (channels[i].flags & IEEE80211_CHAN_DISABLED)385385+ continue;386386+387387+ scan_ch->channel =388388+ ieee80211_frequency_to_channel(channels[i].center_freq);389389+390390+ ch_info = iwl_get_channel_info(priv, band, scan_ch->channel);391391+ if (!is_channel_valid(ch_info)) {392392+ IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n",393393+ scan_ch->channel);394394+ continue;395395+ }396396+397397+ if (!is_active || is_channel_passive(ch_info) ||398398+ (channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN))399399+ scan_ch->type = 0;400400+ else401401+ scan_ch->type = 1;402402+403403+ if (scan_ch->type & 1)404404+ scan_ch->type |= (direct_mask << 1);405405+406406+ scan_ch->active_dwell = cpu_to_le16(active_dwell);407407+ scan_ch->passive_dwell = cpu_to_le16(passive_dwell);408408+409409+ /* Set txpower levels to defaults */410410+ scan_ch->dsp_atten = 110;411411+412412+ if (band == IEEE80211_BAND_5GHZ)413413+ scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;414414+ else {415415+ scan_ch->tx_gain = ((1 << 5) | (5 << 3));416416+ /* NOTE: if we were doing 6Mb OFDM for scans we'd use417417+ * power level:418418+ * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3;419419+ */420420+ }421421+422422+ IWL_DEBUG_SCAN("Scanning %d [%s %d]\n",423423+ scan_ch->channel,424424+ (scan_ch->type & 1) ? "ACTIVE" : "PASSIVE",425425+ (scan_ch->type & 1) ?426426+ active_dwell : passive_dwell);427427+428428+ scan_ch++;429429+ added++;430430+ }431431+432432+ IWL_DEBUG_SCAN("total channels to scan %d \n", added);433433+ return added;434434+}435435+436436+void iwl_init_scan_params(struct iwl_priv *priv)437437+{438438+ if (!priv->scan_tx_ant[IEEE80211_BAND_5GHZ])439439+ priv->scan_tx_ant[IEEE80211_BAND_5GHZ] = RATE_MCS_ANT_INIT_IND;440440+ if (!priv->scan_tx_ant[IEEE80211_BAND_2GHZ])441441+ priv->scan_tx_ant[IEEE80211_BAND_2GHZ] = RATE_MCS_ANT_INIT_IND;442442+}443443+444444+int iwl_scan_initiate(struct iwl_priv *priv)445445+{446446+ if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {447447+ IWL_ERROR("APs don't scan.\n");448448+ return 0;449449+ }450450+451451+ if (!iwl_is_ready_rf(priv)) {452452+ IWL_DEBUG_SCAN("Aborting scan due to not ready.\n");453453+ return -EIO;454454+ }455455+456456+ if (test_bit(STATUS_SCANNING, &priv->status)) {457457+ IWL_DEBUG_SCAN("Scan already in progress.\n");458458+ return -EAGAIN;459459+ }460460+461461+ if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {462462+ IWL_DEBUG_SCAN("Scan request while abort pending. "463463+ "Queuing.\n");464464+ return -EAGAIN;465465+ }466466+467467+ IWL_DEBUG_INFO("Starting scan...\n");468468+ priv->scan_bands = 2;469469+ set_bit(STATUS_SCANNING, &priv->status);470470+ priv->scan_start = jiffies;471471+ priv->scan_pass_start = priv->scan_start;472472+473473+ queue_work(priv->workqueue, &priv->request_scan);474474+475475+ return 0;476476+}477477+EXPORT_SYMBOL(iwl_scan_initiate);478478+479479+#define IWL_SCAN_CHECK_WATCHDOG (7 * HZ)480480+481481+static void iwl_bg_scan_check(struct work_struct *data)482482+{483483+ struct iwl_priv *priv =484484+ container_of(data, struct iwl_priv, scan_check.work);485485+486486+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))487487+ return;488488+489489+ mutex_lock(&priv->mutex);490490+ if (test_bit(STATUS_SCANNING, &priv->status) ||491491+ test_bit(STATUS_SCAN_ABORTING, &priv->status)) {492492+ IWL_DEBUG(IWL_DL_SCAN, "Scan completion watchdog resetting "493493+ "adapter (%dms)\n",494494+ jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG));495495+496496+ if (!test_bit(STATUS_EXIT_PENDING, &priv->status))497497+ iwl_send_scan_abort(priv);498498+ }499499+ mutex_unlock(&priv->mutex);500500+}501501+/**502502+ * iwl_supported_rate_to_ie - fill in the supported rate in IE field503503+ *504504+ * return : set the bit for each supported rate insert in ie505505+ */506506+static u16 iwl_supported_rate_to_ie(u8 *ie, u16 supported_rate,507507+ u16 basic_rate, int *left)508508+{509509+ u16 ret_rates = 0, bit;510510+ int i;511511+ u8 *cnt = ie;512512+ u8 *rates = ie + 1;513513+514514+ for (bit = 1, i = 0; i < IWL_RATE_COUNT; i++, bit <<= 1) {515515+ if (bit & supported_rate) {516516+ ret_rates |= bit;517517+ rates[*cnt] = iwl_rates[i].ieee |518518+ ((bit & basic_rate) ? 0x80 : 0x00);519519+ (*cnt)++;520520+ (*left)--;521521+ if ((*left <= 0) ||522522+ (*cnt >= IWL_SUPPORTED_RATES_IE_LEN))523523+ break;524524+ }525525+ }526526+527527+ return ret_rates;528528+}529529+530530+531531+static void iwl_ht_cap_to_ie(const struct ieee80211_supported_band *sband,532532+ u8 *pos, int *left)533533+{534534+ struct ieee80211_ht_cap *ht_cap;535535+536536+ if (!sband || !sband->ht_info.ht_supported)537537+ return;538538+539539+ if (*left < sizeof(struct ieee80211_ht_cap))540540+ return;541541+542542+ *pos++ = sizeof(struct ieee80211_ht_cap);543543+ ht_cap = (struct ieee80211_ht_cap *) pos;544544+545545+ ht_cap->cap_info = cpu_to_le16(sband->ht_info.cap);546546+ memcpy(ht_cap->supp_mcs_set, sband->ht_info.supp_mcs_set, 16);547547+ ht_cap->ampdu_params_info =548548+ (sband->ht_info.ampdu_factor & IEEE80211_HT_CAP_AMPDU_FACTOR) |549549+ ((sband->ht_info.ampdu_density << 2) &550550+ IEEE80211_HT_CAP_AMPDU_DENSITY);551551+ *left -= sizeof(struct ieee80211_ht_cap);552552+}553553+554554+/**555555+ * iwl_fill_probe_req - fill in all required fields and IE for probe request556556+ */557557+558558+static u16 iwl_fill_probe_req(struct iwl_priv *priv,559559+ enum ieee80211_band band,560560+ struct ieee80211_mgmt *frame,561561+ int left)562562+{563563+ int len = 0;564564+ u8 *pos = NULL;565565+ u16 active_rates, ret_rates, cck_rates, active_rate_basic;566566+ const struct ieee80211_supported_band *sband =567567+ iwl_get_hw_mode(priv, band);568568+569569+570570+ /* Make sure there is enough space for the probe request,571571+ * two mandatory IEs and the data */572572+ left -= 24;573573+ if (left < 0)574574+ return 0;575575+576576+ frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);577577+ memcpy(frame->da, iwl_bcast_addr, ETH_ALEN);578578+ memcpy(frame->sa, priv->mac_addr, ETH_ALEN);579579+ memcpy(frame->bssid, iwl_bcast_addr, ETH_ALEN);580580+ frame->seq_ctrl = 0;581581+582582+ len += 24;583583+584584+ /* ...next IE... */585585+ pos = &frame->u.probe_req.variable[0];586586+587587+ /* fill in our indirect SSID IE */588588+ left -= 2;589589+ if (left < 0)590590+ return 0;591591+ *pos++ = WLAN_EID_SSID;592592+ *pos++ = 0;593593+594594+ len += 2;595595+596596+ /* fill in supported rate */597597+ left -= 2;598598+ if (left < 0)599599+ return 0;600600+601601+ *pos++ = WLAN_EID_SUPP_RATES;602602+ *pos = 0;603603+604604+ /* exclude 60M rate */605605+ active_rates = priv->rates_mask;606606+ active_rates &= ~IWL_RATE_60M_MASK;607607+608608+ active_rate_basic = active_rates & IWL_BASIC_RATES_MASK;609609+610610+ cck_rates = IWL_CCK_RATES_MASK & active_rates;611611+ ret_rates = iwl_supported_rate_to_ie(pos, cck_rates,612612+ active_rate_basic, &left);613613+ active_rates &= ~ret_rates;614614+615615+ ret_rates = iwl_supported_rate_to_ie(pos, active_rates,616616+ active_rate_basic, &left);617617+ active_rates &= ~ret_rates;618618+619619+ len += 2 + *pos;620620+ pos += (*pos) + 1;621621+622622+ if (active_rates == 0)623623+ goto fill_end;624624+625625+ /* fill in supported extended rate */626626+ /* ...next IE... */627627+ left -= 2;628628+ if (left < 0)629629+ return 0;630630+ /* ... fill it in... */631631+ *pos++ = WLAN_EID_EXT_SUPP_RATES;632632+ *pos = 0;633633+ iwl_supported_rate_to_ie(pos, active_rates, active_rate_basic, &left);634634+ if (*pos > 0) {635635+ len += 2 + *pos;636636+ pos += (*pos) + 1;637637+ } else {638638+ pos--;639639+ }640640+641641+ fill_end:642642+643643+ left -= 2;644644+ if (left < 0)645645+ return 0;646646+647647+ *pos++ = WLAN_EID_HT_CAPABILITY;648648+ *pos = 0;649649+ iwl_ht_cap_to_ie(sband, pos, &left);650650+ if (*pos > 0)651651+ len += 2 + *pos;652652+653653+ return (u16)len;654654+}655655+656656+static u32 iwl_scan_tx_ant(struct iwl_priv *priv, enum ieee80211_band band)657657+{658658+ int i, ind;659659+660660+ ind = priv->scan_tx_ant[band];661661+ for (i = 0; i < priv->hw_params.tx_chains_num; i++) {662662+ ind = (ind+1) >= priv->hw_params.tx_chains_num ? 0 : ind+1;663663+ if (priv->hw_params.valid_tx_ant & (1 << ind)) {664664+ priv->scan_tx_ant[band] = ind;665665+ break;666666+ }667667+ }668668+669669+ return scan_tx_ant[ind];670670+}671671+672672+673673+static void iwl_bg_request_scan(struct work_struct *data)674674+{675675+ struct iwl_priv *priv =676676+ container_of(data, struct iwl_priv, request_scan);677677+ struct iwl_host_cmd cmd = {678678+ .id = REPLY_SCAN_CMD,679679+ .len = sizeof(struct iwl_scan_cmd),680680+ .meta.flags = CMD_SIZE_HUGE,681681+ };682682+ struct iwl_scan_cmd *scan;683683+ struct ieee80211_conf *conf = NULL;684684+ int ret = 0;685685+ u32 tx_ant;686686+ u16 cmd_len;687687+ enum ieee80211_band band;688688+ u8 direct_mask;689689+ u8 rx_chain = 0x7; /* bitmap: ABC chains */690690+691691+ conf = ieee80211_get_hw_conf(priv->hw);692692+693693+ mutex_lock(&priv->mutex);694694+695695+ if (!iwl_is_ready(priv)) {696696+ IWL_WARNING("request scan called when driver not ready.\n");697697+ goto done;698698+ }699699+700700+ /* Make sure the scan wasn't cancelled before this queued work701701+ * was given the chance to run... */702702+ if (!test_bit(STATUS_SCANNING, &priv->status))703703+ goto done;704704+705705+ /* This should never be called or scheduled if there is currently706706+ * a scan active in the hardware. */707707+ if (test_bit(STATUS_SCAN_HW, &priv->status)) {708708+ IWL_DEBUG_INFO("Multiple concurrent scan requests in parallel. "709709+ "Ignoring second request.\n");710710+ ret = -EIO;711711+ goto done;712712+ }713713+714714+ if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {715715+ IWL_DEBUG_SCAN("Aborting scan due to device shutdown\n");716716+ goto done;717717+ }718718+719719+ if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {720720+ IWL_DEBUG_HC("Scan request while abort pending. Queuing.\n");721721+ goto done;722722+ }723723+724724+ if (iwl_is_rfkill(priv)) {725725+ IWL_DEBUG_HC("Aborting scan due to RF Kill activation\n");726726+ goto done;727727+ }728728+729729+ if (!test_bit(STATUS_READY, &priv->status)) {730730+ IWL_DEBUG_HC("Scan request while uninitialized. Queuing.\n");731731+ goto done;732732+ }733733+734734+ if (!priv->scan_bands) {735735+ IWL_DEBUG_HC("Aborting scan due to no requested bands\n");736736+ goto done;737737+ }738738+739739+ if (!priv->scan) {740740+ priv->scan = kmalloc(sizeof(struct iwl_scan_cmd) +741741+ IWL_MAX_SCAN_SIZE, GFP_KERNEL);742742+ if (!priv->scan) {743743+ ret = -ENOMEM;744744+ goto done;745745+ }746746+ }747747+ scan = priv->scan;748748+ memset(scan, 0, sizeof(struct iwl_scan_cmd) + IWL_MAX_SCAN_SIZE);749749+750750+ scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;751751+ scan->quiet_time = IWL_ACTIVE_QUIET_TIME;752752+753753+ if (iwl_is_associated(priv)) {754754+ u16 interval = 0;755755+ u32 extra;756756+ u32 suspend_time = 100;757757+ u32 scan_suspend_time = 100;758758+ unsigned long flags;759759+760760+ IWL_DEBUG_INFO("Scanning while associated...\n");761761+762762+ spin_lock_irqsave(&priv->lock, flags);763763+ interval = priv->beacon_int;764764+ spin_unlock_irqrestore(&priv->lock, flags);765765+766766+ scan->suspend_time = 0;767767+ scan->max_out_time = cpu_to_le32(200 * 1024);768768+ if (!interval)769769+ interval = suspend_time;770770+771771+ extra = (suspend_time / interval) << 22;772772+ scan_suspend_time = (extra |773773+ ((suspend_time % interval) * 1024));774774+ scan->suspend_time = cpu_to_le32(scan_suspend_time);775775+ IWL_DEBUG_SCAN("suspend_time 0x%X beacon interval %d\n",776776+ scan_suspend_time, interval);777777+ }778778+779779+ /* We should add the ability for user to lock to PASSIVE ONLY */780780+ if (priv->one_direct_scan) {781781+ IWL_DEBUG_SCAN("Start direct scan for '%s'\n",782782+ iwl_escape_essid(priv->direct_ssid,783783+ priv->direct_ssid_len));784784+ scan->direct_scan[0].id = WLAN_EID_SSID;785785+ scan->direct_scan[0].len = priv->direct_ssid_len;786786+ memcpy(scan->direct_scan[0].ssid,787787+ priv->direct_ssid, priv->direct_ssid_len);788788+ direct_mask = 1;789789+ } else if (!iwl_is_associated(priv) && priv->essid_len) {790790+ IWL_DEBUG_SCAN("Start direct scan for '%s' (not associated)\n",791791+ iwl_escape_essid(priv->essid, priv->essid_len));792792+ scan->direct_scan[0].id = WLAN_EID_SSID;793793+ scan->direct_scan[0].len = priv->essid_len;794794+ memcpy(scan->direct_scan[0].ssid, priv->essid, priv->essid_len);795795+ direct_mask = 1;796796+ } else {797797+ IWL_DEBUG_SCAN("Start indirect scan.\n");798798+ direct_mask = 0;799799+ }800800+801801+ scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;802802+ scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id;803803+ scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;804804+805805+806806+ switch (priv->scan_bands) {807807+ case 2:808808+ band = IEEE80211_BAND_2GHZ;809809+ scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;810810+ tx_ant = iwl_scan_tx_ant(priv, band);811811+ if (priv->active_rxon.flags & RXON_FLG_CHANNEL_MODE_PURE_40_MSK)812812+ scan->tx_cmd.rate_n_flags =813813+ iwl_hw_set_rate_n_flags(IWL_RATE_6M_PLCP,814814+ tx_ant);815815+ else816816+ scan->tx_cmd.rate_n_flags =817817+ iwl_hw_set_rate_n_flags(IWL_RATE_1M_PLCP,818818+ tx_ant |819819+ RATE_MCS_CCK_MSK);820820+ scan->good_CRC_th = 0;821821+ break;822822+823823+ case 1:824824+ band = IEEE80211_BAND_5GHZ;825825+ tx_ant = iwl_scan_tx_ant(priv, band);826826+ scan->tx_cmd.rate_n_flags =827827+ iwl_hw_set_rate_n_flags(IWL_RATE_6M_PLCP,828828+ tx_ant);829829+ scan->good_CRC_th = IWL_GOOD_CRC_TH;830830+831831+ /* Force use of chains B and C (0x6) for scan Rx for 4965832832+ * Avoid A (0x1) because of its off-channel reception on A-band.833833+ * MIMO is not used here, but value is required */834834+ if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965)835835+ rx_chain = 0x6;836836+837837+ break;838838+ default:839839+ IWL_WARNING("Invalid scan band count\n");840840+ goto done;841841+ }842842+843843+ scan->rx_chain = RXON_RX_CHAIN_DRIVER_FORCE_MSK |844844+ cpu_to_le16((0x7 << RXON_RX_CHAIN_VALID_POS) |845845+ (rx_chain << RXON_RX_CHAIN_FORCE_SEL_POS) |846846+ (0x7 << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS));847847+848848+ cmd_len = iwl_fill_probe_req(priv, band,849849+ (struct ieee80211_mgmt *)scan->data,850850+ IWL_MAX_SCAN_SIZE - sizeof(*scan));851851+852852+ scan->tx_cmd.len = cpu_to_le16(cmd_len);853853+854854+ if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR)855855+ scan->filter_flags = RXON_FILTER_PROMISC_MSK;856856+857857+ scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK |858858+ RXON_FILTER_BCON_AWARE_MSK);859859+860860+ if (direct_mask)861861+ scan->channel_count =862862+ iwl_get_channels_for_scan(priv, band, 1, /* active */863863+ direct_mask,864864+ (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);865865+ else866866+ scan->channel_count =867867+ iwl_get_channels_for_scan(priv, band, 0, /* passive */868868+ direct_mask,869869+ (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);870870+ if (scan->channel_count == 0) {871871+ IWL_DEBUG_SCAN("channel count %d\n", scan->channel_count);872872+ goto done;873873+ }874874+875875+ cmd.len += le16_to_cpu(scan->tx_cmd.len) +876876+ scan->channel_count * sizeof(struct iwl_scan_channel);877877+ cmd.data = scan;878878+ scan->len = cpu_to_le16(cmd.len);879879+880880+ set_bit(STATUS_SCAN_HW, &priv->status);881881+ ret = iwl_send_cmd_sync(priv, &cmd);882882+ if (ret)883883+ goto done;884884+885885+ queue_delayed_work(priv->workqueue, &priv->scan_check,886886+ IWL_SCAN_CHECK_WATCHDOG);887887+888888+ mutex_unlock(&priv->mutex);889889+ return;890890+891891+ done:892892+ /* inform mac80211 scan aborted */893893+ queue_work(priv->workqueue, &priv->scan_completed);894894+ mutex_unlock(&priv->mutex);895895+}896896+897897+static void iwl_bg_abort_scan(struct work_struct *work)898898+{899899+ struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan);900900+901901+ if (!iwl_is_ready(priv))902902+ return;903903+904904+ mutex_lock(&priv->mutex);905905+906906+ set_bit(STATUS_SCAN_ABORTING, &priv->status);907907+ iwl_send_scan_abort(priv);908908+909909+ mutex_unlock(&priv->mutex);910910+}911911+912912+void iwl_setup_scan_deferred_work(struct iwl_priv *priv)913913+{914914+ /* FIXME: move here when resolved PENDING915915+ * INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed); */916916+ INIT_WORK(&priv->request_scan, iwl_bg_request_scan);917917+ INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan);918918+ INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check);919919+}920920+EXPORT_SYMBOL(iwl_setup_scan_deferred_work);921921+
+31-22
drivers/net/wireless/iwlwifi/iwl-sta.c
···3030#include <net/mac80211.h>3131#include <linux/etherdevice.h>32323333-#include "iwl-eeprom.h"3433#include "iwl-dev.h"3534#include "iwl-core.h"3635#include "iwl-sta.h"3737-#include "iwl-io.h"3836#include "iwl-helpers.h"39374038···7274}7375EXPORT_SYMBOL(iwl_find_station);74767777+int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)7878+{7979+ if (priv->iw_mode == IEEE80211_IF_TYPE_STA) {8080+ return IWL_AP_ID;8181+ } else {8282+ u8 *da = ieee80211_get_DA(hdr);8383+ return iwl_find_station(priv, da);8484+ }8585+}8686+EXPORT_SYMBOL(iwl_get_ra_sta_id);8787+7588static int iwl_add_sta_callback(struct iwl_priv *priv,7689 struct iwl_cmd *cmd, struct sk_buff *skb)7790{···113104 /* We didn't cache the SKB; let the caller free it */114105 return 1;115106}116116-117117-118107119108int iwl_send_add_sta(struct iwl_priv *priv,120109 struct iwl_addsta_cmd *sta, u8 flags)···163156}164157EXPORT_SYMBOL(iwl_send_add_sta);165158166166-#ifdef CONFIG_IWL4965_HT167167-168159static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,169160 struct ieee80211_ht_info *sta_ht_inf)170161{···207202 done:208203 return;209204}210210-#else211211-static inline void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,212212- struct ieee80211_ht_info *sta_ht_info)213213-{214214-}215215-#endif216205217206/**218207 * iwl_add_station_flags - Add station to tables in driver and device···278279279280}280281EXPORT_SYMBOL(iwl_add_station_flags);281281-282282283283static int iwl_sta_ucode_deactivate(struct iwl_priv *priv, const char *addr)284284{···382384383385 return ret;384386}387387+385388/**386389 * iwl_remove_station - Remove driver's knowledge of station.387387- *388390 */389391u8 iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap)390392{···424426 return 0;425427}426428EXPORT_SYMBOL(iwl_remove_station);427427-int iwl_get_free_ucode_key_index(struct iwl_priv *priv)429429+static int iwl_get_free_ucode_key_index(struct iwl_priv *priv)428430{429431 int i;430432···494496 priv->default_wep_key--;495497 memset(&priv->wep_keys[keyconf->keyidx], 0, sizeof(priv->wep_keys[0]));496498 ret = iwl_send_static_wepkey_cmd(priv, 1);499499+ IWL_DEBUG_WEP("Remove default WEP key: idx=%d ret=%d\n",500500+ keyconf->keyidx, ret);497501 spin_unlock_irqrestore(&priv->sta_lock, flags);498502499503 return ret;···507507{508508 int ret;509509 unsigned long flags;510510+511511+ if (keyconf->keylen != WEP_KEY_LEN_128 &&512512+ keyconf->keylen != WEP_KEY_LEN_64) {513513+ IWL_DEBUG_WEP("Bad WEP key length %d\n", keyconf->keylen);514514+ return -EINVAL;515515+ }510516511517 keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV;512518 keyconf->hw_key_idx = HW_KEY_DEFAULT;···530524 keyconf->keylen);531525532526 ret = iwl_send_static_wepkey_cmd(priv, 0);527527+ IWL_DEBUG_WEP("Set default WEP key: len=%d idx=%d ret=%d\n",528528+ keyconf->keylen, keyconf->keyidx, ret);533529 spin_unlock_irqrestore(&priv->sta_lock, flags);534530535531 return ret;···678670 key_flags = le16_to_cpu(priv->stations[sta_id].sta.key.key_flags);679671 keyidx = (key_flags >> STA_KEY_FLG_KEYID_POS) & 0x3;680672673673+ IWL_DEBUG_WEP("Remove dynamic key: idx=%d sta=%d\n",674674+ keyconf->keyidx, sta_id);675675+681676 if (keyconf->keyidx != keyidx) {682677 /* We need to remove a key with index different that the one683678 * in the uCode. This means that the key we need to remove has···705694 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;706695 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;707696708708- IWL_DEBUG_INFO("hwcrypto: clear ucode station key info\n");709697 ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);710698 spin_unlock_irqrestore(&priv->sta_lock, flags);711699 return ret;···733723 IWL_ERROR("Unknown alg: %s alg = %d\n", __func__, keyconf->alg);734724 ret = -EINVAL;735725 }726726+727727+ IWL_DEBUG_WEP("Set dynamic key: alg= %d len=%d idx=%d sta=%d ret=%d\n",728728+ keyconf->alg, keyconf->keylen, keyconf->keyidx,729729+ sta_id, ret);736730737731 return ret;738732}···830816 rate_flags |= RATE_MCS_ANT_B_MSK; /*FIXME:RS*/831817832818 link_cmd.rs_table[i].rate_n_flags =833833- iwl4965_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags);819819+ iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags);834820 r = iwl4965_get_prev_ieee_rate(r);835821 }836822···856842 u8 sta_id;857843858844 /* Add station to device's station table */859859-#ifdef CONFIG_IWL4965_HT860845 struct ieee80211_conf *conf = &priv->hw->conf;861846 struct ieee80211_ht_info *cur_ht_config = &conf->ht_conf;862847···865852 sta_id = iwl_add_station_flags(priv, addr, is_ap,866853 0, cur_ht_config);867854 else868868-#endif /* CONFIG_IWL4965_HT */869855 sta_id = iwl_add_station_flags(priv, addr, is_ap,870856 0, NULL);871857···874862 return sta_id;875863}876864EXPORT_SYMBOL(iwl_rxon_add_station);877877-878865879866/**880867 * iwl_get_sta_id - Find station's index within station table···932921}933922EXPORT_SYMBOL(iwl_get_sta_id);934923935935-936924/**937925 * iwl_sta_modify_enable_tid_tx - Enable Tx for this TID in station table938926 */···949939 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);950940}951941EXPORT_SYMBOL(iwl_sta_modify_enable_tid_tx);952952-953942
+11-5
drivers/net/wireless/iwlwifi/iwl-sta.h
···3232#define HW_KEY_DYNAMIC 03333#define HW_KEY_DEFAULT 134343535-int iwl_get_free_ucode_key_index(struct iwl_priv *priv);3535+/**3636+ * iwl_find_station - Find station id for a given BSSID3737+ * @bssid: MAC address of station ID to find3838+ */3939+u8 iwl_find_station(struct iwl_priv *priv, const u8 *bssid);4040+3641int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty);3742int iwl_remove_default_wep_key(struct iwl_priv *priv,3838- struct ieee80211_key_conf *key);4343+ struct ieee80211_key_conf *key);3944int iwl_set_default_wep_key(struct iwl_priv *priv,4040- struct ieee80211_key_conf *key);4545+ struct ieee80211_key_conf *key);4146int iwl_set_dynamic_key(struct iwl_priv *priv,4242- struct ieee80211_key_conf *key, u8 sta_id);4747+ struct ieee80211_key_conf *key, u8 sta_id);4348int iwl_remove_dynamic_key(struct iwl_priv *priv,4444- struct ieee80211_key_conf *key, u8 sta_id);4949+ struct ieee80211_key_conf *key, u8 sta_id);4550int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap);4651u8 iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap);4752int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr);4853void iwl_sta_modify_enable_tid_tx(struct iwl_priv *priv, int sta_id, int tid);5454+int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr);4955#endif /* __iwl_sta_h__ */
+27-38
drivers/net/wireless/iwlwifi/iwl-tx.c
···3636#include "iwl-io.h"3737#include "iwl-helpers.h"38383939-#ifdef CONFIG_IWL4965_HT4040-4139static const u16 default_tid_to_tx_fifo[] = {4240 IWL_TX_FIFO_AC1,4341 IWL_TX_FIFO_AC0,···5557 IWL_TX_FIFO_NONE,5658 IWL_TX_FIFO_AC35759};5858-5959-#endif /*CONFIG_IWL4965_HT */6060-616062616362/**···569574 struct ieee80211_hdr *hdr,570575 int is_unicast, u8 std_id)571576{572572- u16 fc = le16_to_cpu(hdr->frame_control);577577+ __le16 fc = hdr->frame_control;573578 __le32 tx_flags = tx_cmd->tx_flags;574579575580 tx_cmd->stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;576581 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {577582 tx_flags |= TX_CMD_FLG_ACK_MSK;578578- if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT)583583+ if (ieee80211_is_mgmt(fc))579584 tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;580580- if (ieee80211_is_probe_response(fc) &&585585+ if (ieee80211_is_probe_resp(fc) &&581586 !(le16_to_cpu(hdr->seq_ctrl) & 0xf))582587 tx_flags |= TX_CMD_FLG_TSF_MSK;583588 } else {···585590 tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;586591 }587592588588- if (ieee80211_is_back_request(fc))593593+ if (ieee80211_is_back_req(fc))589594 tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK;590595591596592597 tx_cmd->sta_id = std_id;593593- if (ieee80211_get_morefrag(hdr))598598+ if (ieee80211_has_morefrags(fc))594599 tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK;595600596596- if (ieee80211_is_qos_data(fc)) {597597- u8 *qc = ieee80211_get_qos_ctrl(hdr, ieee80211_get_hdrlen(fc));601601+ if (ieee80211_is_data_qos(fc)) {602602+ u8 *qc = ieee80211_get_qos_ctl(hdr);598603 tx_cmd->tid_tspec = qc[0] & 0xf;599604 tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK;600605 } else {···613618 tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;614619615620 tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK);616616- if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) {617617- if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ ||618618- (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_REQ)621621+ if (ieee80211_is_mgmt(fc)) {622622+ if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc))619623 tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(3);620624 else621625 tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(2);···633639static void iwl_tx_cmd_build_rate(struct iwl_priv *priv,634640 struct iwl_tx_cmd *tx_cmd,635641 struct ieee80211_tx_info *info,636636- u16 fc, int sta_id,642642+ __le16 fc, int sta_id,637643 int is_hcca)638644{639645 u8 rts_retry_limit = 0;···654660 rate_flags |= RATE_MCS_CCK_MSK;655661656662657657- if (ieee80211_is_probe_response(fc)) {663663+ if (ieee80211_is_probe_resp(fc)) {658664 data_retry_limit = 3;659665 if (data_retry_limit < rts_retry_limit)660666 rts_retry_limit = data_retry_limit;···669675 tx_cmd->initial_rate_index = 0;670676 tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK;671677 } else {672672- switch (fc & IEEE80211_FCTL_STYPE) {673673- case IEEE80211_STYPE_AUTH:674674- case IEEE80211_STYPE_DEAUTH:675675- case IEEE80211_STYPE_ASSOC_REQ:676676- case IEEE80211_STYPE_REASSOC_REQ:678678+ switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {679679+ case cpu_to_le16(IEEE80211_STYPE_AUTH):680680+ case cpu_to_le16(IEEE80211_STYPE_DEAUTH):681681+ case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):682682+ case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):677683 if (tx_cmd->tx_flags & TX_CMD_FLG_RTS_MSK) {678684 tx_cmd->tx_flags &= ~TX_CMD_FLG_RTS_MSK;679685 tx_cmd->tx_flags |= TX_CMD_FLG_CTS_MSK;···695701696702 tx_cmd->rts_retry_limit = rts_retry_limit;697703 tx_cmd->data_retry_limit = data_retry_limit;698698- tx_cmd->rate_n_flags = iwl4965_hw_set_rate_n_flags(rate_plcp, rate_flags);704704+ tx_cmd->rate_n_flags = iwl_hw_set_rate_n_flags(rate_plcp, rate_flags);699705}700706701707static void iwl_tx_cmd_build_hwcrypto(struct iwl_priv *priv,···770776 u16 seq_number = 0;771777 u8 id, hdr_len, unicast;772778 u8 sta_id;773773- u16 fc;779779+ __le16 fc;774780 u8 wait_write_ptr = 0;775781 u8 tid = 0;776782 u8 *qc = NULL;···797803 unicast = !is_multicast_ether_addr(hdr->addr1);798804 id = 0;799805800800- fc = le16_to_cpu(hdr->frame_control);806806+ fc = hdr->frame_control;801807802808#ifdef CONFIG_IWLWIFI_DEBUG803809 if (ieee80211_is_auth(fc))804810 IWL_DEBUG_TX("Sending AUTH frame\n");805805- else if (ieee80211_is_assoc_request(fc))811811+ else if (ieee80211_is_assoc_req(fc))806812 IWL_DEBUG_TX("Sending ASSOC frame\n");807807- else if (ieee80211_is_reassoc_request(fc))813813+ else if (ieee80211_is_reassoc_req(fc))808814 IWL_DEBUG_TX("Sending REASSOC frame\n");809815#endif810816811817 /* drop all data frame if we are not associated */812812- if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) &&818818+ if (ieee80211_is_data(fc) &&813819 (!iwl_is_associated(priv) ||814820 ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id) ||815821 !priv->assoc_station_added)) {···819825820826 spin_unlock_irqrestore(&priv->lock, flags);821827822822- hdr_len = ieee80211_get_hdrlen(fc);828828+ hdr_len = ieee80211_get_hdrlen(le16_to_cpu(fc));823829824830 /* Find (or create) index into station table for destination station */825831 sta_id = iwl_get_sta_id(priv, hdr);···833839834840 IWL_DEBUG_TX("station Id %d\n", sta_id);835841836836- if (ieee80211_is_qos_data(fc)) {837837- qc = ieee80211_get_qos_ctrl(hdr, hdr_len);842842+ if (ieee80211_is_data_qos(fc)) {843843+ qc = ieee80211_get_qos_ctl(hdr);838844 tid = qc[0] & 0xf;839845 seq_number = priv->stations[sta_id].tid[tid].seq_number &840846 IEEE80211_SCTL_SEQ;···842848 (hdr->seq_ctrl &843849 __constant_cpu_to_le16(IEEE80211_SCTL_FRAG));844850 seq_number += 0x10;845845-#ifdef CONFIG_IWL4965_HT846851 /* aggregation is on for this <sta,tid> */847852 if (info->flags & IEEE80211_TX_CTL_AMPDU)848853 txq_id = priv->stations[sta_id].tid[tid].agg.txq_id;849854 priv->stations[sta_id].tid[tid].tfds_in_queue++;850850-#endif /* CONFIG_IWL4965_HT */851855 }852856853857 /* Descriptor for chosen Tx queue */···937945 /* set is_hcca to 0; it probably will never be implemented */938946 iwl_tx_cmd_build_rate(priv, tx_cmd, info, fc, sta_id, 0);939947940940- iwl_update_tx_stats(priv, fc, len);948948+ iwl_update_tx_stats(priv, le16_to_cpu(fc), len);941949942950 scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) +943951 offsetof(struct iwl_tx_cmd, scratch);944952 tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);945953 tx_cmd->dram_msb_ptr = iwl_get_dma_hi_address(scratch_phys);946954947947- if (!ieee80211_get_morefrag(hdr)) {955955+ if (!ieee80211_has_morefrags(hdr->frame_control)) {948956 txq->need_update = 1;949957 if (qc)950958 priv->stations[sta_id].tid[tid].seq_number = seq_number;···11881196}11891197EXPORT_SYMBOL(iwl_tx_cmd_complete);1190119811911191-11921192-#ifdef CONFIG_IWL4965_HT11931199/*11941200 * Find first available (lowest unused) Tx Queue, mark it "active".11951201 * Called only when finding queue for aggregation.···13491359 return 0;13501360}13511361EXPORT_SYMBOL(iwl_txq_check_empty);13521352-#endif /* CONFIG_IWL4965_HT */1353136213541363#ifdef CONFIG_IWLWIF_DEBUG13551364#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
+20-20
drivers/net/wireless/iwlwifi/iwl3945-base.c
···24312431 struct ieee80211_hdr *hdr,24322432 int is_unicast, u8 std_id)24332433{24342434- u16 fc = le16_to_cpu(hdr->frame_control);24342434+ __le16 fc = hdr->frame_control;24352435 __le32 tx_flags = cmd->cmd.tx.tx_flags;2436243624372437 cmd->cmd.tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;24382438 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {24392439 tx_flags |= TX_CMD_FLG_ACK_MSK;24402440- if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT)24402440+ if (ieee80211_is_mgmt(fc))24412441 tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;24422442- if (ieee80211_is_probe_response(fc) &&24422442+ if (ieee80211_is_probe_resp(fc) &&24432443 !(le16_to_cpu(hdr->seq_ctrl) & 0xf))24442444 tx_flags |= TX_CMD_FLG_TSF_MSK;24452445 } else {···24482448 }2449244924502450 cmd->cmd.tx.sta_id = std_id;24512451- if (ieee80211_get_morefrag(hdr))24512451+ if (ieee80211_has_morefrags(fc))24522452 tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK;2453245324542454- if (ieee80211_is_qos_data(fc)) {24552455- u8 *qc = ieee80211_get_qos_ctrl(hdr, ieee80211_get_hdrlen(fc));24542454+ if (ieee80211_is_data_qos(fc)) {24552455+ u8 *qc = ieee80211_get_qos_ctl(hdr);24562456 cmd->cmd.tx.tid_tspec = qc[0] & 0xf;24572457 tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK;24582458 } else {···24712471 tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;2472247224732473 tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK);24742474- if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) {24752475- if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ ||24762476- (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_REQ)24742474+ if (ieee80211_is_mgmt(fc)) {24752475+ if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc))24772476 cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(3);24782477 else24792478 cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(2);···25632564 u8 sta_id;25642565 u8 tid = 0;25652566 u16 seq_number = 0;25662566- u16 fc;25672567+ __le16 fc;25672568 u8 wait_write_ptr = 0;25682569 u8 *qc = NULL;25692570 unsigned long flags;···25882589 unicast = !is_multicast_ether_addr(hdr->addr1);25892590 id = 0;2590259125912591- fc = le16_to_cpu(hdr->frame_control);25922592+ fc = hdr->frame_control;2592259325932594#ifdef CONFIG_IWL3945_DEBUG25942595 if (ieee80211_is_auth(fc))25952596 IWL_DEBUG_TX("Sending AUTH frame\n");25962596- else if (ieee80211_is_assoc_request(fc))25972597+ else if (ieee80211_is_assoc_req(fc))25972598 IWL_DEBUG_TX("Sending ASSOC frame\n");25982598- else if (ieee80211_is_reassoc_request(fc))25992599+ else if (ieee80211_is_reassoc_req(fc))25992600 IWL_DEBUG_TX("Sending REASSOC frame\n");26002601#endif2601260226022603 /* drop all data frame if we are not associated */26032604 if ((!iwl3945_is_associated(priv) ||26042605 ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id)) &&26052605- ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) {26062606+ ieee80211_is_data(fc)) {26062607 IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n");26072608 goto drop_unlock;26082609 }2609261026102611 spin_unlock_irqrestore(&priv->lock, flags);2611261226122612- hdr_len = ieee80211_get_hdrlen(fc);26132613+ hdr_len = ieee80211_get_hdrlen(le16_to_cpu(fc));2613261426142615 /* Find (or create) index into station table for destination station */26152616 sta_id = iwl3945_get_sta_id(priv, hdr);···2623262426242625 IWL_DEBUG_RATE("station Id %d\n", sta_id);2625262626262626- if (ieee80211_is_qos_data(fc)) {26272627- qc = ieee80211_get_qos_ctrl(hdr, hdr_len);26272627+ if (ieee80211_is_data_qos(fc)) {26282628+ qc = ieee80211_get_qos_ctl(hdr);26282629 tid = qc[0] & 0xf;26292630 seq_number = priv->stations[sta_id].tid[tid].seq_number &26302631 IEEE80211_SCTL_SEQ;···27312732 out_cmd->cmd.tx.tx_flags &= ~TX_CMD_FLG_ANT_A_MSK;27322733 out_cmd->cmd.tx.tx_flags &= ~TX_CMD_FLG_ANT_B_MSK;2733273427342734- if (!ieee80211_get_morefrag(hdr)) {27352735+ if (!ieee80211_has_morefrags(hdr->frame_control)) {27352736 txq->need_update = 1;27362737 if (qc) {27372738 priv->stations[sta_id].tid[tid].seq_number = seq_number;···27452746 sizeof(out_cmd->cmd.tx));2746274727472748 iwl3945_print_hex_dump(IWL_DL_TX, (u8 *)out_cmd->cmd.tx.hdr,27482748- ieee80211_get_hdrlen(fc));27492749+ ieee80211_get_hdrlen(le16_to_cpu(fc)));2749275027502751 /* Tell device the write index *just past* this latest filled TFD */27512752 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);···28742875 return;28752876 }2876287728772877- queue_work(priv->workqueue, &priv->restart);28782878+ if (priv->is_open)28792879+ queue_work(priv->workqueue, &priv->restart);28782880 return;28792881}28802882
+197-1050
drivers/net/wireless/iwlwifi/iwl4965-base.c
···8787MODULE_AUTHOR(DRV_COPYRIGHT);8888MODULE_LICENSE("GPL");89899090-static int iwl4965_is_empty_essid(const char *essid, int essid_len)9191-{9292- /* Single white space is for Linksys APs */9393- if (essid_len == 1 && essid[0] == ' ')9494- return 1;9595-9696- /* Otherwise, if the entire essid is 0, we assume it is hidden */9797- while (essid_len) {9898- essid_len--;9999- if (essid[essid_len] != '\0')100100- return 0;101101- }102102-103103- return 1;104104-}105105-106106-static const char *iwl4965_escape_essid(const char *essid, u8 essid_len)107107-{108108- static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];109109- const char *s = essid;110110- char *d = escaped;111111-112112- if (iwl4965_is_empty_essid(essid, essid_len)) {113113- memcpy(escaped, "<hidden>", sizeof("<hidden>"));114114- return escaped;115115- }116116-117117- essid_len = min(essid_len, (u8) IW_ESSID_MAX_SIZE);118118- while (essid_len--) {119119- if (*s == '\0') {120120- *d++ = '\\';121121- *d++ = '0';122122- s++;123123- } else124124- *d++ = *s++;125125- }126126- *d = '\0';127127- return escaped;128128-}129129-13090/*************** STATION TABLE MANAGEMENT ****13191 * mac80211 should be examined to determine if sta_info is duplicating13292 * the functionality provided here···327367328368 /* If we issue a new RXON command which required a tune then we must329369 * send a new TXPOWER command or we won't be able to Tx any frames */330330- rc = iwl4965_hw_reg_send_txpower(priv);370370+ rc = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);331371 if (rc) {332332- IWL_ERROR("Error setting Tx power (%d).\n", rc);372372+ IWL_ERROR("Error sending TX power (%d).\n", rc);333373 return rc;334374 }335375···377417378418 return iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG,379419 sizeof(struct iwl4965_bt_cmd), &bt_cmd);380380-}381381-382382-static int iwl4965_send_scan_abort(struct iwl_priv *priv)383383-{384384- int ret = 0;385385- struct iwl_rx_packet *res;386386- struct iwl_host_cmd cmd = {387387- .id = REPLY_SCAN_ABORT_CMD,388388- .meta.flags = CMD_WANT_SKB,389389- };390390-391391- /* If there isn't a scan actively going on in the hardware392392- * then we are in between scan bands and not actually393393- * actively scanning, so don't send the abort command */394394- if (!test_bit(STATUS_SCAN_HW, &priv->status)) {395395- clear_bit(STATUS_SCAN_ABORTING, &priv->status);396396- return 0;397397- }398398-399399- ret = iwl_send_cmd_sync(priv, &cmd);400400- if (ret) {401401- clear_bit(STATUS_SCAN_ABORTING, &priv->status);402402- return ret;403403- }404404-405405- res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;406406- if (res->u.status != CAN_ABORT_STATUS) {407407- /* The scan abort will return 1 for success or408408- * 2 for "failure". A failure condition can be409409- * due to simply not being in an active scan which410410- * can occur if we send the scan abort before we411411- * the microcode has notified us that a scan is412412- * completed. */413413- IWL_DEBUG_INFO("SCAN_ABORT returned %d.\n", res->u.status);414414- clear_bit(STATUS_SCAN_ABORTING, &priv->status);415415- clear_bit(STATUS_SCAN_HW, &priv->status);416416- }417417-418418- dev_kfree_skb_any(cmd.meta.u.skb);419419-420420- return ret;421421-}422422-423423-/*424424- * CARD_STATE_CMD425425- *426426- * Use: Sets the device's internal card state to enable, disable, or halt427427- *428428- * When in the 'enable' state the card operates as normal.429429- * When in the 'disable' state, the card enters into a low power mode.430430- * When in the 'halt' state, the card is shut down and must be fully431431- * restarted to come back on.432432- */433433-static int iwl4965_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag)434434-{435435- struct iwl_host_cmd cmd = {436436- .id = REPLY_CARD_STATE_CMD,437437- .len = sizeof(u32),438438- .data = &flags,439439- .meta.flags = meta_flag,440440- };441441-442442- return iwl_send_cmd(priv, &cmd);443420}444421445422static void iwl_clear_free_frames(struct iwl_priv *priv)···502605 *503606 ******************************************************************************/504607505505-/**506506- * iwl4965_supported_rate_to_ie - fill in the supported rate in IE field507507- *508508- * return : set the bit for each supported rate insert in ie509509- */510510-static u16 iwl4965_supported_rate_to_ie(u8 *ie, u16 supported_rate,511511- u16 basic_rate, int *left)512512-{513513- u16 ret_rates = 0, bit;514514- int i;515515- u8 *cnt = ie;516516- u8 *rates = ie + 1;517517-518518- for (bit = 1, i = 0; i < IWL_RATE_COUNT; i++, bit <<= 1) {519519- if (bit & supported_rate) {520520- ret_rates |= bit;521521- rates[*cnt] = iwl_rates[i].ieee |522522- ((bit & basic_rate) ? 0x80 : 0x00);523523- (*cnt)++;524524- (*left)--;525525- if ((*left <= 0) ||526526- (*cnt >= IWL_SUPPORTED_RATES_IE_LEN))527527- break;528528- }529529- }530530-531531- return ret_rates;532532-}533533-534534-#ifdef CONFIG_IWL4965_HT535608static void iwl4965_ht_conf(struct iwl_priv *priv,536609 struct ieee80211_bss_conf *bss_conf)537610{···532665 iwl_conf->extension_chan_offset =533666 ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_SEC_OFFSET;534667 /* If no above or below channel supplied disable FAT channel */535535- if (iwl_conf->extension_chan_offset != IWL_EXT_CHANNEL_OFFSET_ABOVE &&536536- iwl_conf->extension_chan_offset != IWL_EXT_CHANNEL_OFFSET_BELOW)668668+ if (iwl_conf->extension_chan_offset != IEEE80211_HT_IE_CHA_SEC_ABOVE &&669669+ iwl_conf->extension_chan_offset != IEEE80211_HT_IE_CHA_SEC_BELOW) {670670+ iwl_conf->extension_chan_offset = IEEE80211_HT_IE_CHA_SEC_NONE;537671 iwl_conf->supported_chan_width = 0;672672+ }538673539674 iwl_conf->tx_mimo_ps_mode =540675 (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2);···552683553684 IWL_DEBUG_MAC80211("control channel %d\n", iwl_conf->control_channel);554685 IWL_DEBUG_MAC80211("leave\n");555555-}556556-557557-static void iwl_ht_cap_to_ie(const struct ieee80211_supported_band *sband,558558- u8 *pos, int *left)559559-{560560- struct ieee80211_ht_cap *ht_cap;561561-562562- if (!sband || !sband->ht_info.ht_supported)563563- return;564564-565565- if (*left < sizeof(struct ieee80211_ht_cap))566566- return;567567-568568- *pos++ = sizeof(struct ieee80211_ht_cap);569569- ht_cap = (struct ieee80211_ht_cap *) pos;570570-571571- ht_cap->cap_info = cpu_to_le16(sband->ht_info.cap);572572- memcpy(ht_cap->supp_mcs_set, sband->ht_info.supp_mcs_set, 16);573573- ht_cap->ampdu_params_info =574574- (sband->ht_info.ampdu_factor & IEEE80211_HT_CAP_AMPDU_FACTOR) |575575- ((sband->ht_info.ampdu_density << 2) &576576- IEEE80211_HT_CAP_AMPDU_DENSITY);577577- *left -= sizeof(struct ieee80211_ht_cap);578578-}579579-#else580580-static inline void iwl4965_ht_conf(struct iwl_priv *priv,581581- struct ieee80211_bss_conf *bss_conf)582582-{583583-}584584-static void iwl_ht_cap_to_ie(const struct ieee80211_supported_band *sband,585585- u8 *pos, int *left)586586-{587587-}588588-#endif589589-590590-591591-/**592592- * iwl4965_fill_probe_req - fill in all required fields and IE for probe request593593- */594594-static u16 iwl4965_fill_probe_req(struct iwl_priv *priv,595595- enum ieee80211_band band,596596- struct ieee80211_mgmt *frame,597597- int left, int is_direct)598598-{599599- int len = 0;600600- u8 *pos = NULL;601601- u16 active_rates, ret_rates, cck_rates, active_rate_basic;602602- const struct ieee80211_supported_band *sband =603603- iwl_get_hw_mode(priv, band);604604-605605- /* Make sure there is enough space for the probe request,606606- * two mandatory IEs and the data */607607- left -= 24;608608- if (left < 0)609609- return 0;610610- len += 24;611611-612612- frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);613613- memcpy(frame->da, iwl_bcast_addr, ETH_ALEN);614614- memcpy(frame->sa, priv->mac_addr, ETH_ALEN);615615- memcpy(frame->bssid, iwl_bcast_addr, ETH_ALEN);616616- frame->seq_ctrl = 0;617617-618618- /* fill in our indirect SSID IE */619619- /* ...next IE... */620620-621621- left -= 2;622622- if (left < 0)623623- return 0;624624- len += 2;625625- pos = &(frame->u.probe_req.variable[0]);626626- *pos++ = WLAN_EID_SSID;627627- *pos++ = 0;628628-629629- /* fill in our direct SSID IE... */630630- if (is_direct) {631631- /* ...next IE... */632632- left -= 2 + priv->essid_len;633633- if (left < 0)634634- return 0;635635- /* ... fill it in... */636636- *pos++ = WLAN_EID_SSID;637637- *pos++ = priv->essid_len;638638- memcpy(pos, priv->essid, priv->essid_len);639639- pos += priv->essid_len;640640- len += 2 + priv->essid_len;641641- }642642-643643- /* fill in supported rate */644644- /* ...next IE... */645645- left -= 2;646646- if (left < 0)647647- return 0;648648-649649- /* ... fill it in... */650650- *pos++ = WLAN_EID_SUPP_RATES;651651- *pos = 0;652652-653653- /* exclude 60M rate */654654- active_rates = priv->rates_mask;655655- active_rates &= ~IWL_RATE_60M_MASK;656656-657657- active_rate_basic = active_rates & IWL_BASIC_RATES_MASK;658658-659659- cck_rates = IWL_CCK_RATES_MASK & active_rates;660660- ret_rates = iwl4965_supported_rate_to_ie(pos, cck_rates,661661- active_rate_basic, &left);662662- active_rates &= ~ret_rates;663663-664664- ret_rates = iwl4965_supported_rate_to_ie(pos, active_rates,665665- active_rate_basic, &left);666666- active_rates &= ~ret_rates;667667-668668- len += 2 + *pos;669669- pos += (*pos) + 1;670670- if (active_rates == 0)671671- goto fill_end;672672-673673- /* fill in supported extended rate */674674- /* ...next IE... */675675- left -= 2;676676- if (left < 0)677677- return 0;678678- /* ... fill it in... */679679- *pos++ = WLAN_EID_EXT_SUPP_RATES;680680- *pos = 0;681681- iwl4965_supported_rate_to_ie(pos, active_rates,682682- active_rate_basic, &left);683683- if (*pos > 0)684684- len += 2 + *pos;685685-686686- fill_end:687687- /* fill in HT IE */688688- left -= 2;689689- if (left < 0)690690- return 0;691691-692692- *pos++ = WLAN_EID_HT_CAPABILITY;693693- *pos = 0;694694-695695- iwl_ht_cap_to_ie(sband, pos, &left);696696-697697- if (*pos > 0)698698- len += 2 + *pos;699699- return (u16)len;700686}701687702688/*···586862 priv->qos_data.def_qos_parm.qos_flags |=587863 QOS_PARAM_FLG_UPDATE_EDCA_MSK;588864589589-#ifdef CONFIG_IWL4965_HT590865 if (priv->current_ht_config.is_ht)591866 priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;592592-#endif /* CONFIG_IWL4965_HT */593867594868 spin_unlock_irqrestore(&priv->lock, flags);595869···631909 return 1;632910}633911634634-635635-636636-/**637637- * iwl4965_scan_cancel - Cancel any currently executing HW scan638638- *639639- * NOTE: priv->mutex is not required before calling this function640640- */641641-static int iwl4965_scan_cancel(struct iwl_priv *priv)642642-{643643- if (!test_bit(STATUS_SCAN_HW, &priv->status)) {644644- clear_bit(STATUS_SCANNING, &priv->status);645645- return 0;646646- }647647-648648- if (test_bit(STATUS_SCANNING, &priv->status)) {649649- if (!test_bit(STATUS_SCAN_ABORTING, &priv->status)) {650650- IWL_DEBUG_SCAN("Queuing scan abort.\n");651651- set_bit(STATUS_SCAN_ABORTING, &priv->status);652652- queue_work(priv->workqueue, &priv->abort_scan);653653-654654- } else655655- IWL_DEBUG_SCAN("Scan abort already in progress.\n");656656-657657- return test_bit(STATUS_SCANNING, &priv->status);658658- }659659-660660- return 0;661661-}662662-663663-/**664664- * iwl4965_scan_cancel_timeout - Cancel any currently executing HW scan665665- * @ms: amount of time to wait (in milliseconds) for scan to abort666666- *667667- * NOTE: priv->mutex must be held before calling this function668668- */669669-static int iwl4965_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms)670670-{671671- unsigned long now = jiffies;672672- int ret;673673-674674- ret = iwl4965_scan_cancel(priv);675675- if (ret && ms) {676676- mutex_unlock(&priv->mutex);677677- while (!time_after(jiffies, now + msecs_to_jiffies(ms)) &&678678- test_bit(STATUS_SCANNING, &priv->status))679679- msleep(1);680680- mutex_lock(&priv->mutex);681681-682682- return test_bit(STATUS_SCANNING, &priv->status);683683- }684684-685685- return ret;686686-}687687-688912static void iwl4965_sequence_reset(struct iwl_priv *priv)689913{690914 /* Reset ieee stats */···642974 priv->last_frag_num = -1;643975 priv->last_packet_time = 0;644976645645- iwl4965_scan_cancel(priv);977977+ iwl_scan_cancel(priv);646978}647979648980#define MAX_UCODE_BEACON_INTERVAL 4096···7161048 le32_to_cpu(priv->rxon_timing.beacon_init_val),7171049 le16_to_cpu(priv->rxon_timing.atim_window));7181050}719719-720720-static int iwl4965_scan_initiate(struct iwl_priv *priv)721721-{722722- if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {723723- IWL_ERROR("APs don't scan.\n");724724- return 0;725725- }726726-727727- if (!iwl_is_ready_rf(priv)) {728728- IWL_DEBUG_SCAN("Aborting scan due to not ready.\n");729729- return -EIO;730730- }731731-732732- if (test_bit(STATUS_SCANNING, &priv->status)) {733733- IWL_DEBUG_SCAN("Scan already in progress.\n");734734- return -EAGAIN;735735- }736736-737737- if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {738738- IWL_DEBUG_SCAN("Scan request while abort pending. "739739- "Queuing.\n");740740- return -EAGAIN;741741- }742742-743743- IWL_DEBUG_INFO("Starting scan...\n");744744- priv->scan_bands = 2;745745- set_bit(STATUS_SCANNING, &priv->status);746746- priv->scan_start = jiffies;747747- priv->scan_pass_start = priv->scan_start;748748-749749- queue_work(priv->workqueue, &priv->request_scan);750750-751751- return 0;752752-}753753-75410517551052static void iwl_set_flags_for_band(struct iwl_priv *priv,7561053 enum ieee80211_band band)···82111888221189static int iwl4965_set_mode(struct iwl_priv *priv, int mode)8231190{824824- if (mode == IEEE80211_IF_TYPE_IBSS) {825825- const struct iwl_channel_info *ch_info;826826-827827- ch_info = iwl_get_channel_info(priv,828828- priv->band,829829- le16_to_cpu(priv->staging_rxon.channel));830830-831831- if (!ch_info || !is_channel_ibss(ch_info)) {832832- IWL_ERROR("channel %d not IBSS channel\n",833833- le16_to_cpu(priv->staging_rxon.channel));834834- return -EINVAL;835835- }836836- }837837-8381191 priv->iw_mode = mode;11921192+11931193+ /* init channel/phymode to values given at driver init */11941194+ iwl_set_rxon_channel(priv, IEEE80211_BAND_2GHZ, 6);83911958401196 iwl4965_connection_init_rx_config(priv);8411197 memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);···8361214 return -EAGAIN;83712158381216 cancel_delayed_work(&priv->scan_check);839839- if (iwl4965_scan_cancel_timeout(priv, 100)) {12171217+ if (iwl_scan_cancel_timeout(priv, 100)) {8401218 IWL_WARNING("Aborted scan still in progress after 100ms\n");8411219 IWL_DEBUG_MAC80211("leaving - scan abort failed.\n");8421220 return -EAGAIN;···8921270 else8931271 priv->staging_rxon.ofdm_basic_rates =8941272 (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;895895-}896896-897897-void iwl4965_radio_kill_sw(struct iwl_priv *priv, int disable_radio)898898-{899899- unsigned long flags;900900-901901- if (!!disable_radio == test_bit(STATUS_RF_KILL_SW, &priv->status))902902- return;903903-904904- IWL_DEBUG_RF_KILL("Manual SW RF KILL set to: RADIO %s\n",905905- disable_radio ? "OFF" : "ON");906906-907907- if (disable_radio) {908908- iwl4965_scan_cancel(priv);909909- /* FIXME: This is a workaround for AP */910910- if (priv->iw_mode != IEEE80211_IF_TYPE_AP) {911911- spin_lock_irqsave(&priv->lock, flags);912912- iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,913913- CSR_UCODE_SW_BIT_RFKILL);914914- spin_unlock_irqrestore(&priv->lock, flags);915915- /* call the host command only if no hw rf-kill set */916916- if (!test_bit(STATUS_RF_KILL_HW, &priv->status) &&917917- iwl_is_ready(priv))918918- iwl4965_send_card_state(priv,919919- CARD_STATE_CMD_DISABLE,920920- 0);921921- set_bit(STATUS_RF_KILL_SW, &priv->status);922922-923923- /* make sure mac80211 stop sending Tx frame */924924- if (priv->mac80211_registered)925925- ieee80211_stop_queues(priv->hw);926926- }927927- return;928928- }929929-930930- spin_lock_irqsave(&priv->lock, flags);931931- iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);932932-933933- clear_bit(STATUS_RF_KILL_SW, &priv->status);934934- spin_unlock_irqrestore(&priv->lock, flags);935935-936936- /* wake up ucode */937937- msleep(10);938938-939939- spin_lock_irqsave(&priv->lock, flags);940940- iwl_read32(priv, CSR_UCODE_DRV_GP1);941941- if (!iwl_grab_nic_access(priv))942942- iwl_release_nic_access(priv);943943- spin_unlock_irqrestore(&priv->lock, flags);944944-945945- if (test_bit(STATUS_RF_KILL_HW, &priv->status)) {946946- IWL_DEBUG_RF_KILL("Can not turn radio back on - "947947- "disabled by HW switch\n");948948- return;949949- }950950-951951- queue_work(priv->workqueue, &priv->restart);952952- return;9531273}95412749551275#define IWL_PACKET_RETRY_TIME HZ···12251661 iwl4965_send_beacon_cmd(priv);12261662}1227166316641664+/**16651665+ * iwl4965_bg_statistics_periodic - Timer callback to queue statistics16661666+ *16671667+ * This callback is provided in order to send a statistics request.16681668+ *16691669+ * This timer function is continually reset to execute within16701670+ * REG_RECALIB_PERIOD seconds since the last STATISTICS_NOTIFICATION16711671+ * was received. We need to ensure we receive the statistics in order16721672+ * to update the temperature used for calibrating the TXPOWER.16731673+ */16741674+static void iwl4965_bg_statistics_periodic(unsigned long data)16751675+{16761676+ struct iwl_priv *priv = (struct iwl_priv *)data;16771677+16781678+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))16791679+ return;16801680+16811681+ iwl_send_statistics_request(priv, CMD_ASYNC);16821682+}16831683+12281684static void iwl4965_rx_beacon_notif(struct iwl_priv *priv,12291685 struct iwl_rx_mem_buffer *rxb)12301686{12311687#ifdef CONFIG_IWLWIFI_DEBUG12321688 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;12331689 struct iwl4965_beacon_notif *beacon = &(pkt->u.beacon_status);12341234- u8 rate = iwl4965_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags);16901690+ u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags);1235169112361692 IWL_DEBUG_RX("beacon status %x retries %d iss %d "12371693 "tsf %d %d rate %d\n",12381238- le32_to_cpu(beacon->beacon_notify_hdr.status) & TX_STATUS_MSK,16941694+ le32_to_cpu(beacon->beacon_notify_hdr.u.status) & TX_STATUS_MSK,12391695 beacon->beacon_notify_hdr.failure_frame,12401696 le32_to_cpu(beacon->ibss_mgr_status),12411697 le32_to_cpu(beacon->high_tsf),···12651681 if ((priv->iw_mode == IEEE80211_IF_TYPE_AP) &&12661682 (!test_bit(STATUS_EXIT_PENDING, &priv->status)))12671683 queue_work(priv->workqueue, &priv->beacon_update);12681268-}12691269-12701270-/* Service response to REPLY_SCAN_CMD (0x80) */12711271-static void iwl4965_rx_reply_scan(struct iwl_priv *priv,12721272- struct iwl_rx_mem_buffer *rxb)12731273-{12741274-#ifdef CONFIG_IWLWIFI_DEBUG12751275- struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;12761276- struct iwl4965_scanreq_notification *notif =12771277- (struct iwl4965_scanreq_notification *)pkt->u.raw;12781278-12791279- IWL_DEBUG_RX("Scan request status = 0x%x\n", notif->status);12801280-#endif12811281-}12821282-12831283-/* Service SCAN_START_NOTIFICATION (0x82) */12841284-static void iwl4965_rx_scan_start_notif(struct iwl_priv *priv,12851285- struct iwl_rx_mem_buffer *rxb)12861286-{12871287- struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;12881288- struct iwl4965_scanstart_notification *notif =12891289- (struct iwl4965_scanstart_notification *)pkt->u.raw;12901290- priv->scan_start_tsf = le32_to_cpu(notif->tsf_low);12911291- IWL_DEBUG_SCAN("Scan start: "12921292- "%d [802.11%s] "12931293- "(TSF: 0x%08X:%08X) - %d (beacon timer %u)\n",12941294- notif->channel,12951295- notif->band ? "bg" : "a",12961296- notif->tsf_high,12971297- notif->tsf_low, notif->status, notif->beacon_timer);12981298-}12991299-13001300-/* Service SCAN_RESULTS_NOTIFICATION (0x83) */13011301-static void iwl4965_rx_scan_results_notif(struct iwl_priv *priv,13021302- struct iwl_rx_mem_buffer *rxb)13031303-{13041304- struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;13051305- struct iwl4965_scanresults_notification *notif =13061306- (struct iwl4965_scanresults_notification *)pkt->u.raw;13071307-13081308- IWL_DEBUG_SCAN("Scan ch.res: "13091309- "%d [802.11%s] "13101310- "(TSF: 0x%08X:%08X) - %d "13111311- "elapsed=%lu usec (%dms since last)\n",13121312- notif->channel,13131313- notif->band ? "bg" : "a",13141314- le32_to_cpu(notif->tsf_high),13151315- le32_to_cpu(notif->tsf_low),13161316- le32_to_cpu(notif->statistics[0]),13171317- le32_to_cpu(notif->tsf_low) - priv->scan_start_tsf,13181318- jiffies_to_msecs(elapsed_jiffies13191319- (priv->last_scan_jiffies, jiffies)));13201320-13211321- priv->last_scan_jiffies = jiffies;13221322- priv->next_scan_jiffies = 0;13231323-}13241324-13251325-/* Service SCAN_COMPLETE_NOTIFICATION (0x84) */13261326-static void iwl4965_rx_scan_complete_notif(struct iwl_priv *priv,13271327- struct iwl_rx_mem_buffer *rxb)13281328-{13291329- struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;13301330- struct iwl4965_scancomplete_notification *scan_notif = (void *)pkt->u.raw;13311331-13321332- IWL_DEBUG_SCAN("Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n",13331333- scan_notif->scanned_channels,13341334- scan_notif->tsf_low,13351335- scan_notif->tsf_high, scan_notif->status);13361336-13371337- /* The HW is no longer scanning */13381338- clear_bit(STATUS_SCAN_HW, &priv->status);13391339-13401340- /* The scan completion notification came in, so kill that timer... */13411341- cancel_delayed_work(&priv->scan_check);13421342-13431343- IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n",13441344- (priv->scan_bands == 2) ? "2.4" : "5.2",13451345- jiffies_to_msecs(elapsed_jiffies13461346- (priv->scan_pass_start, jiffies)));13471347-13481348- /* Remove this scanned band from the list13491349- * of pending bands to scan */13501350- priv->scan_bands--;13511351-13521352- /* If a request to abort was given, or the scan did not succeed13531353- * then we reset the scan state machine and terminate,13541354- * re-queuing another scan if one has been requested */13551355- if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {13561356- IWL_DEBUG_INFO("Aborted scan completed.\n");13571357- clear_bit(STATUS_SCAN_ABORTING, &priv->status);13581358- } else {13591359- /* If there are more bands on this scan pass reschedule */13601360- if (priv->scan_bands > 0)13611361- goto reschedule;13621362- }13631363-13641364- priv->last_scan_jiffies = jiffies;13651365- priv->next_scan_jiffies = 0;13661366- IWL_DEBUG_INFO("Setting scan to off\n");13671367-13681368- clear_bit(STATUS_SCANNING, &priv->status);13691369-13701370- IWL_DEBUG_INFO("Scan took %dms\n",13711371- jiffies_to_msecs(elapsed_jiffies(priv->scan_start, jiffies)));13721372-13731373- queue_work(priv->workqueue, &priv->scan_completed);13741374-13751375- return;13761376-13771377-reschedule:13781378- priv->scan_pass_start = jiffies;13791379- queue_work(priv->workqueue, &priv->request_scan);13801684}1381168513821686/* Handle notification from uCode that card's power state is changing···13271855 clear_bit(STATUS_RF_KILL_SW, &priv->status);1328185613291857 if (!(flags & RXON_CARD_DISABLED))13301330- iwl4965_scan_cancel(priv);18581858+ iwl_scan_cancel(priv);1331185913321860 if ((test_bit(STATUS_RF_KILL_HW, &status) !=13331861 test_bit(STATUS_RF_KILL_HW, &priv->status)) ||···13771905 */13781906 priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl4965_hw_rx_statistics;13791907 priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl4965_hw_rx_statistics;13801380- /* scan handlers */13811381- priv->rx_handlers[REPLY_SCAN_CMD] = iwl4965_rx_reply_scan;13821382- priv->rx_handlers[SCAN_START_NOTIFICATION] = iwl4965_rx_scan_start_notif;13831383- priv->rx_handlers[SCAN_RESULTS_NOTIFICATION] =13841384- iwl4965_rx_scan_results_notif;13851385- priv->rx_handlers[SCAN_COMPLETE_NOTIFICATION] =13861386- iwl4965_rx_scan_complete_notif;19081908+19091909+ iwl_setup_rx_scan_handlers(priv);19101910+13871911 /* status change handler */13881912 priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl4965_rx_card_state_notif;13891913···15162048 /* Backtrack one entry */15172049 priv->rxq.read = i;15182050 iwl_rx_queue_restock(priv);15191519-}15201520-/* Convert linear signal-to-noise ratio into dB */15211521-static u8 ratio2dB[100] = {15221522-/* 0 1 2 3 4 5 6 7 8 9 */15231523- 0, 0, 6, 10, 12, 14, 16, 17, 18, 19, /* 00 - 09 */15241524- 20, 21, 22, 22, 23, 23, 24, 25, 26, 26, /* 10 - 19 */15251525- 26, 26, 26, 27, 27, 28, 28, 28, 29, 29, /* 20 - 29 */15261526- 29, 30, 30, 30, 31, 31, 31, 31, 32, 32, /* 30 - 39 */15271527- 32, 32, 32, 33, 33, 33, 33, 33, 34, 34, /* 40 - 49 */15281528- 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, /* 50 - 59 */15291529- 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, /* 60 - 69 */15301530- 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, /* 70 - 79 */15311531- 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, /* 80 - 89 */15321532- 39, 39, 39, 39, 39, 40, 40, 40, 40, 40 /* 90 - 99 */15331533-};15341534-15351535-/* Calculates a relative dB value from a ratio of linear15361536- * (i.e. not dB) signal levels.15371537- * Conversion assumes that levels are voltages (20*log), not powers (10*log). */15381538-int iwl4965_calc_db_from_ratio(int sig_ratio)15391539-{15401540- /* 1000:1 or higher just report as 60 dB */15411541- if (sig_ratio >= 1000)15421542- return 60;15431543-15441544- /* 100:1 or higher, divide by 10 and use table,15451545- * add 20 dB to make up for divide by 10 */15461546- if (sig_ratio >= 100)15471547- return (20 + (int)ratio2dB[sig_ratio/10]);15481548-15491549- /* We shouldn't see this */15501550- if (sig_ratio < 1)15511551- return 0;15521552-15531553- /* Use table for ratios 1:1 - 99:1 */15541554- return (int)ratio2dB[sig_ratio];15552051}1556205215572053#define PERFECT_RSSI (-20) /* dBm */···18912459 return IRQ_NONE;18922460}1893246118941894-/* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after18951895- * sending probe req. This should be set long enough to hear probe responses18961896- * from more than one AP. */18971897-#define IWL_ACTIVE_DWELL_TIME_24 (20) /* all times in msec */18981898-#define IWL_ACTIVE_DWELL_TIME_52 (10)18991899-19001900-/* For faster active scanning, scan will move to the next channel if fewer than19011901- * PLCP_QUIET_THRESH packets are heard on this channel within19021902- * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell19031903- * time if it's a quiet channel (nothing responded to our probe, and there's19041904- * no other traffic).19051905- * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */19061906-#define IWL_PLCP_QUIET_THRESH __constant_cpu_to_le16(1) /* packets */19071907-#define IWL_ACTIVE_QUIET_TIME __constant_cpu_to_le16(5) /* msec */19081908-19091909-/* For passive scan, listen PASSIVE_DWELL_TIME (msec) on each channel.19101910- * Must be set longer than active dwell time.19111911- * For the most reliable scan, set > AP beacon interval (typically 100msec). */19121912-#define IWL_PASSIVE_DWELL_TIME_24 (20) /* all times in msec */19131913-#define IWL_PASSIVE_DWELL_TIME_52 (10)19141914-#define IWL_PASSIVE_DWELL_BASE (100)19151915-#define IWL_CHANNEL_TUNE_TIME 519161916-19171917-static inline u16 iwl4965_get_active_dwell_time(struct iwl_priv *priv,19181918- enum ieee80211_band band)19191919-{19201920- if (band == IEEE80211_BAND_5GHZ)19211921- return IWL_ACTIVE_DWELL_TIME_52;19221922- else19231923- return IWL_ACTIVE_DWELL_TIME_24;19241924-}19251925-19261926-static u16 iwl4965_get_passive_dwell_time(struct iwl_priv *priv,19271927- enum ieee80211_band band)19281928-{19291929- u16 active = iwl4965_get_active_dwell_time(priv, band);19301930- u16 passive = (band != IEEE80211_BAND_5GHZ) ?19311931- IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 :19321932- IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52;19331933-19341934- if (iwl_is_associated(priv)) {19351935- /* If we're associated, we clamp the maximum passive19361936- * dwell time to be 98% of the beacon interval (minus19371937- * 2 * channel tune time) */19381938- passive = priv->beacon_int;19391939- if ((passive > IWL_PASSIVE_DWELL_BASE) || !passive)19401940- passive = IWL_PASSIVE_DWELL_BASE;19411941- passive = (passive * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2;19421942- }19431943-19441944- if (passive <= active)19451945- passive = active + 1;19461946-19471947- return passive;19481948-}19491949-19501950-static int iwl4965_get_channels_for_scan(struct iwl_priv *priv,19511951- enum ieee80211_band band,19521952- u8 is_active, u8 direct_mask,19531953- struct iwl4965_scan_channel *scan_ch)19541954-{19551955- const struct ieee80211_channel *channels = NULL;19561956- const struct ieee80211_supported_band *sband;19571957- const struct iwl_channel_info *ch_info;19581958- u16 passive_dwell = 0;19591959- u16 active_dwell = 0;19601960- int added, i;19611961-19621962- sband = iwl_get_hw_mode(priv, band);19631963- if (!sband)19641964- return 0;19651965-19661966- channels = sband->channels;19671967-19681968- active_dwell = iwl4965_get_active_dwell_time(priv, band);19691969- passive_dwell = iwl4965_get_passive_dwell_time(priv, band);19701970-19711971- for (i = 0, added = 0; i < sband->n_channels; i++) {19721972- if (channels[i].flags & IEEE80211_CHAN_DISABLED)19731973- continue;19741974-19751975- scan_ch->channel = ieee80211_frequency_to_channel(channels[i].center_freq);19761976-19771977- ch_info = iwl_get_channel_info(priv, band,19781978- scan_ch->channel);19791979- if (!is_channel_valid(ch_info)) {19801980- IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n",19811981- scan_ch->channel);19821982- continue;19831983- }19841984-19851985- if (!is_active || is_channel_passive(ch_info) ||19861986- (channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN))19871987- scan_ch->type = 0; /* passive */19881988- else19891989- scan_ch->type = 1; /* active */19901990-19911991- if (scan_ch->type & 1)19921992- scan_ch->type |= (direct_mask << 1);19931993-19941994- scan_ch->active_dwell = cpu_to_le16(active_dwell);19951995- scan_ch->passive_dwell = cpu_to_le16(passive_dwell);19961996-19971997- /* Set txpower levels to defaults */19981998- scan_ch->tpc.dsp_atten = 110;19991999- /* scan_pwr_info->tpc.dsp_atten; */20002000-20012001- /*scan_pwr_info->tpc.tx_gain; */20022002- if (band == IEEE80211_BAND_5GHZ)20032003- scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3;20042004- else {20052005- scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3));20062006- /* NOTE: if we were doing 6Mb OFDM for scans we'd use20072007- * power level:20082008- * scan_ch->tpc.tx_gain = ((1 << 5) | (2 << 3)) | 3;20092009- */20102010- }20112011-20122012- IWL_DEBUG_SCAN("Scanning %d [%s %d]\n",20132013- scan_ch->channel,20142014- (scan_ch->type & 1) ? "ACTIVE" : "PASSIVE",20152015- (scan_ch->type & 1) ?20162016- active_dwell : passive_dwell);20172017-20182018- scan_ch++;20192019- added++;20202020- }20212021-20222022- IWL_DEBUG_SCAN("total channels to scan %d \n", added);20232023- return added;20242024-}20252025-20262462/******************************************************************************20272463 *20282464 * uCode download functions···19212621 */19222622static int iwl4965_read_ucode(struct iwl_priv *priv)19232623{19241924- struct iwl4965_ucode *ucode;26242624+ struct iwl_ucode *ucode;19252625 int ret;19262626 const struct firmware *ucode_raw;19272627 const char *name = priv->cfg->fw_name;···21492849 /* After the ALIVE response, we can send host commands to 4965 uCode */21502850 set_bit(STATUS_ALIVE, &priv->status);2151285121522152- /* Clear out the uCode error bit if it is set */21532153- clear_bit(STATUS_FW_ERROR, &priv->status);21542154-21552852 if (iwl_is_rfkill(priv))21562853 return;21572854···21792882 iwl4965_commit_rxon(priv);2180288321812884 /* At this point, the NIC is initialized and operational */21822182- iwl4965_rf_kill_ct_config(priv);28852885+ iwl_rf_kill_ct_config(priv);2183288621842887 iwl_leds_register(priv);21852888···21902893 if (priv->error_recovering)21912894 iwl4965_error_recovery(priv);2192289521932193- iwlcore_low_level_notify(priv, IWLCORE_START_EVT);28962896+ iwl_power_update_mode(priv, 1);21942897 ieee80211_notify_mac(priv->hw, IEEE80211_NOTIFY_RE_ASSOC);28982898+28992899+ if (test_and_clear_bit(STATUS_MODE_PENDING, &priv->status))29002900+ iwl4965_set_mode(priv, priv->iw_mode);29012901+21952902 return;2196290321972904 restart:21982905 queue_work(priv->workqueue, &priv->restart);21992906}2200290722012201-static void iwl4965_cancel_deferred_work(struct iwl_priv *priv);29082908+static void iwl_cancel_deferred_work(struct iwl_priv *priv);2202290922032910static void __iwl4965_down(struct iwl_priv *priv)22042911{···22152914 set_bit(STATUS_EXIT_PENDING, &priv->status);2216291522172916 iwl_leds_unregister(priv);22182218-22192219- iwlcore_low_level_notify(priv, IWLCORE_STOP_EVT);2220291722212918 iwlcore_clear_stations_table(priv);22222919···23043005 __iwl4965_down(priv);23053006 mutex_unlock(&priv->mutex);2306300723072307- iwl4965_cancel_deferred_work(priv);30083008+ iwl_cancel_deferred_work(priv);23083009}2309301023103011#define MAX_HW_RESTARTS 5···23173018 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {23183019 IWL_WARNING("Exit pending; will not bring the NIC up\n");23193020 return -EIO;23202320- }23212321-23222322- if (test_bit(STATUS_RF_KILL_SW, &priv->status)) {23232323- IWL_WARNING("Radio disabled by SW RF kill (module "23242324- "parameter)\n");23252325- iwl_rfkill_set_hw_state(priv);23262326- return -ENODEV;23273021 }2328302223293023 if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) {···23723080 priv->ucode_data.len);2373308123743082 /* We return success when we resume from suspend and rf_kill is on. */23752375- if (test_bit(STATUS_RF_KILL_HW, &priv->status))30833083+ if (test_bit(STATUS_RF_KILL_HW, &priv->status) ||30843084+ test_bit(STATUS_RF_KILL_SW, &priv->status))23763085 return 0;2377308623783087 for (i = 0; i < MAX_HW_RESTARTS; i++) {···23903097 continue;23913098 }2392309931003100+ /* Clear out the uCode error bit if it is set */31013101+ clear_bit(STATUS_FW_ERROR, &priv->status);31023102+23933103 /* start card; "initialize" will load runtime ucode */23943104 iwl4965_nic_start(priv);23953105···2403310724043108 set_bit(STATUS_EXIT_PENDING, &priv->status);24053109 __iwl4965_down(priv);31103110+ clear_bit(STATUS_EXIT_PENDING, &priv->status);2406311124073112 /* tried to restart and config the device for as long as our24083113 * patience could withstand */···24833186{24843187 struct iwl_priv *priv = container_of(work,24853188 struct iwl_priv, set_monitor);31893189+ int ret;2486319024873191 IWL_DEBUG(IWL_DL_STATE, "setting monitor mode\n");2488319224893193 mutex_lock(&priv->mutex);2490319424912491- if (!iwl_is_ready(priv))24922492- IWL_DEBUG(IWL_DL_STATE, "leave - not ready\n");24932493- else24942494- if (iwl4965_set_mode(priv, IEEE80211_IF_TYPE_MNTR) != 0)24952495- IWL_ERROR("iwl4965_set_mode() failed\n");31953195+ ret = iwl4965_set_mode(priv, IEEE80211_IF_TYPE_MNTR);31963196+31973197+ if (ret) {31983198+ if (ret == -EAGAIN)31993199+ IWL_DEBUG(IWL_DL_STATE, "leave - not ready\n");32003200+ else32013201+ IWL_ERROR("iwl4965_set_mode() failed ret = %d\n", ret);32023202+ }2496320324973204 mutex_unlock(&priv->mutex);24983205}2499320625002500-#define IWL_SCAN_CHECK_WATCHDOG (7 * HZ)25012501-25022502-static void iwl4965_bg_scan_check(struct work_struct *data)32073207+static void iwl_bg_run_time_calib_work(struct work_struct *work)25033208{25042504- struct iwl_priv *priv =25052505- container_of(data, struct iwl_priv, scan_check.work);32093209+ struct iwl_priv *priv = container_of(work, struct iwl_priv,32103210+ run_time_calib_work);2506321125072507- if (test_bit(STATUS_EXIT_PENDING, &priv->status))32123212+ mutex_lock(&priv->mutex);32133213+32143214+ if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||32153215+ test_bit(STATUS_SCANNING, &priv->status)) {32163216+ mutex_unlock(&priv->mutex);25083217 return;25092509-25102510- mutex_lock(&priv->mutex);25112511- if (test_bit(STATUS_SCANNING, &priv->status) ||25122512- test_bit(STATUS_SCAN_ABORTING, &priv->status)) {25132513- IWL_DEBUG(IWL_DL_SCAN, "Scan completion watchdog resetting "25142514- "adapter (%dms)\n",25152515- jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG));25162516-25172517- if (!test_bit(STATUS_EXIT_PENDING, &priv->status))25182518- iwl4965_send_scan_abort(priv);25192519- }25202520- mutex_unlock(&priv->mutex);25212521-}25222522-25232523-static void iwl4965_bg_request_scan(struct work_struct *data)25242524-{25252525- struct iwl_priv *priv =25262526- container_of(data, struct iwl_priv, request_scan);25272527- struct iwl_host_cmd cmd = {25282528- .id = REPLY_SCAN_CMD,25292529- .len = sizeof(struct iwl4965_scan_cmd),25302530- .meta.flags = CMD_SIZE_HUGE,25312531- };25322532- struct iwl4965_scan_cmd *scan;25332533- struct ieee80211_conf *conf = NULL;25342534- u16 cmd_len;25352535- enum ieee80211_band band;25362536- u8 direct_mask;25372537- int ret = 0;25382538-25392539- conf = ieee80211_get_hw_conf(priv->hw);25402540-25412541- mutex_lock(&priv->mutex);25422542-25432543- if (!iwl_is_ready(priv)) {25442544- IWL_WARNING("request scan called when driver not ready.\n");25452545- goto done;25463218 }2547321925482548- /* Make sure the scan wasn't cancelled before this queued work25492549- * was given the chance to run... */25502550- if (!test_bit(STATUS_SCANNING, &priv->status))25512551- goto done;32203220+ if (priv->start_calib) {32213221+ iwl_chain_noise_calibration(priv, &priv->statistics);2552322225532553- /* This should never be called or scheduled if there is currently25542554- * a scan active in the hardware. */25552555- if (test_bit(STATUS_SCAN_HW, &priv->status)) {25562556- IWL_DEBUG_INFO("Multiple concurrent scan requests in parallel. "25572557- "Ignoring second request.\n");25582558- ret = -EIO;25592559- goto done;32233223+ iwl_sensitivity_calibration(priv, &priv->statistics);25603224 }25612561-25622562- if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {25632563- IWL_DEBUG_SCAN("Aborting scan due to device shutdown\n");25642564- goto done;25652565- }25662566-25672567- if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {25682568- IWL_DEBUG_HC("Scan request while abort pending. Queuing.\n");25692569- goto done;25702570- }25712571-25722572- if (iwl_is_rfkill(priv)) {25732573- IWL_DEBUG_HC("Aborting scan due to RF Kill activation\n");25742574- goto done;25752575- }25762576-25772577- if (!test_bit(STATUS_READY, &priv->status)) {25782578- IWL_DEBUG_HC("Scan request while uninitialized. Queuing.\n");25792579- goto done;25802580- }25812581-25822582- if (!priv->scan_bands) {25832583- IWL_DEBUG_HC("Aborting scan due to no requested bands\n");25842584- goto done;25852585- }25862586-25872587- if (!priv->scan) {25882588- priv->scan = kmalloc(sizeof(struct iwl4965_scan_cmd) +25892589- IWL_MAX_SCAN_SIZE, GFP_KERNEL);25902590- if (!priv->scan) {25912591- ret = -ENOMEM;25922592- goto done;25932593- }25942594- }25952595- scan = priv->scan;25962596- memset(scan, 0, sizeof(struct iwl4965_scan_cmd) + IWL_MAX_SCAN_SIZE);25972597-25982598- scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;25992599- scan->quiet_time = IWL_ACTIVE_QUIET_TIME;26002600-26012601- if (iwl_is_associated(priv)) {26022602- u16 interval = 0;26032603- u32 extra;26042604- u32 suspend_time = 100;26052605- u32 scan_suspend_time = 100;26062606- unsigned long flags;26072607-26082608- IWL_DEBUG_INFO("Scanning while associated...\n");26092609-26102610- spin_lock_irqsave(&priv->lock, flags);26112611- interval = priv->beacon_int;26122612- spin_unlock_irqrestore(&priv->lock, flags);26132613-26142614- scan->suspend_time = 0;26152615- scan->max_out_time = cpu_to_le32(200 * 1024);26162616- if (!interval)26172617- interval = suspend_time;26182618-26192619- extra = (suspend_time / interval) << 22;26202620- scan_suspend_time = (extra |26212621- ((suspend_time % interval) * 1024));26222622- scan->suspend_time = cpu_to_le32(scan_suspend_time);26232623- IWL_DEBUG_SCAN("suspend_time 0x%X beacon interval %d\n",26242624- scan_suspend_time, interval);26252625- }26262626-26272627- /* We should add the ability for user to lock to PASSIVE ONLY */26282628- if (priv->one_direct_scan) {26292629- IWL_DEBUG_SCAN26302630- ("Kicking off one direct scan for '%s'\n",26312631- iwl4965_escape_essid(priv->direct_ssid,26322632- priv->direct_ssid_len));26332633- scan->direct_scan[0].id = WLAN_EID_SSID;26342634- scan->direct_scan[0].len = priv->direct_ssid_len;26352635- memcpy(scan->direct_scan[0].ssid,26362636- priv->direct_ssid, priv->direct_ssid_len);26372637- direct_mask = 1;26382638- } else if (!iwl_is_associated(priv) && priv->essid_len) {26392639- IWL_DEBUG_SCAN26402640- ("Kicking off one direct scan for '%s' when not associated\n",26412641- iwl4965_escape_essid(priv->essid, priv->essid_len));26422642- scan->direct_scan[0].id = WLAN_EID_SSID;26432643- scan->direct_scan[0].len = priv->essid_len;26442644- memcpy(scan->direct_scan[0].ssid, priv->essid, priv->essid_len);26452645- direct_mask = 1;26462646- } else {26472647- IWL_DEBUG_SCAN("Kicking off one indirect scan.\n");26482648- direct_mask = 0;26492649- }26502650-26512651- scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;26522652- scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id;26532653- scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;26542654-26552655-26562656- switch (priv->scan_bands) {26572657- case 2:26582658- scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;26592659- scan->tx_cmd.rate_n_flags =26602660- iwl4965_hw_set_rate_n_flags(IWL_RATE_1M_PLCP,26612661- RATE_MCS_ANT_B_MSK|RATE_MCS_CCK_MSK);26622662-26632663- scan->good_CRC_th = 0;26642664- band = IEEE80211_BAND_2GHZ;26652665- break;26662666-26672667- case 1:26682668- scan->tx_cmd.rate_n_flags =26692669- iwl4965_hw_set_rate_n_flags(IWL_RATE_6M_PLCP,26702670- RATE_MCS_ANT_B_MSK);26712671- scan->good_CRC_th = IWL_GOOD_CRC_TH;26722672- band = IEEE80211_BAND_5GHZ;26732673- break;26742674-26752675- default:26762676- IWL_WARNING("Invalid scan band count\n");26772677- goto done;26782678- }26792679-26802680- /* We don't build a direct scan probe request; the uCode will do26812681- * that based on the direct_mask added to each channel entry */26822682- cmd_len = iwl4965_fill_probe_req(priv, band,26832683- (struct ieee80211_mgmt *)scan->data,26842684- IWL_MAX_SCAN_SIZE - sizeof(*scan), 0);26852685-26862686- scan->tx_cmd.len = cpu_to_le16(cmd_len);26872687- /* select Rx chains */26882688-26892689- /* Force use of chains B and C (0x6) for scan Rx.26902690- * Avoid A (0x1) because of its off-channel reception on A-band.26912691- * MIMO is not used here, but value is required to make uCode happy. */26922692- scan->rx_chain = RXON_RX_CHAIN_DRIVER_FORCE_MSK |26932693- cpu_to_le16((0x7 << RXON_RX_CHAIN_VALID_POS) |26942694- (0x6 << RXON_RX_CHAIN_FORCE_SEL_POS) |26952695- (0x7 << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS));26962696-26972697- if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR)26982698- scan->filter_flags = RXON_FILTER_PROMISC_MSK;26992699-27002700- if (direct_mask)27012701- scan->channel_count =27022702- iwl4965_get_channels_for_scan(27032703- priv, band, 1, /* active */27042704- direct_mask,27052705- (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);27062706- else27072707- scan->channel_count =27082708- iwl4965_get_channels_for_scan(27092709- priv, band, 0, /* passive */27102710- direct_mask,27112711- (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);27122712-27132713- scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK |27142714- RXON_FILTER_BCON_AWARE_MSK);27152715- cmd.len += le16_to_cpu(scan->tx_cmd.len) +27162716- scan->channel_count * sizeof(struct iwl4965_scan_channel);27172717- cmd.data = scan;27182718- scan->len = cpu_to_le16(cmd.len);27192719-27202720- set_bit(STATUS_SCAN_HW, &priv->status);27212721- ret = iwl_send_cmd_sync(priv, &cmd);27222722- if (ret)27232723- goto done;27242724-27252725- queue_delayed_work(priv->workqueue, &priv->scan_check,27262726- IWL_SCAN_CHECK_WATCHDOG);2727322527283226 mutex_unlock(&priv->mutex);27293227 return;27302730-27312731- done:27322732- /* inform mac80211 scan aborted */27332733- queue_work(priv->workqueue, &priv->scan_completed);27342734- mutex_unlock(&priv->mutex);27353228}2736322927373230static void iwl4965_bg_up(struct work_struct *data)···25853498 if (!priv->vif || !priv->is_open)25863499 return;2587350025882588- iwl4965_scan_cancel_timeout(priv, 200);35013501+ iwl_scan_cancel_timeout(priv, 200);2589350225903503 conf = ieee80211_get_hw_conf(priv->hw);25913504···2602351526033516 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;2604351726052605-#ifdef CONFIG_IWL4965_HT26063518 if (priv->current_ht_config.is_ht)26073519 iwl_set_rxon_ht(priv, &priv->current_ht_config);26082608-#endif /* CONFIG_IWL4965_HT*/35203520+26093521 iwl_set_rxon_chain(priv);26103522 priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id);26113523···2636355026373551 case IEEE80211_IF_TYPE_IBSS:2638355226392639- /* clear out the station table */26402640- iwlcore_clear_stations_table(priv);35533553+ /* assume default assoc id */35543554+ priv->assoc_id = 1;2641355526422642- iwl_rxon_add_station(priv, iwl_bcast_addr, 0);26433556 iwl_rxon_add_station(priv, priv->bssid, 0);26443557 iwl4965_rate_scale_init(priv->hw, IWL_STA_ID);26453558 iwl4965_send_beacon_cmd(priv);···2679359426803595}2681359626822682-static void iwl4965_bg_abort_scan(struct work_struct *work)26832683-{26842684- struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan);26852685-26862686- if (!iwl_is_ready(priv))26872687- return;26882688-26892689- mutex_lock(&priv->mutex);26902690-26912691- set_bit(STATUS_SCAN_ABORTING, &priv->status);26922692- iwl4965_send_scan_abort(priv);26932693-26942694- mutex_unlock(&priv->mutex);26952695-}26962696-26973597static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf);2698359826992699-static void iwl4965_bg_scan_completed(struct work_struct *work)35993599+static void iwl_bg_scan_completed(struct work_struct *work)27003600{27013601 struct iwl_priv *priv =27023602 container_of(work, struct iwl_priv, scan_completed);2703360327042704- IWL_DEBUG(IWL_DL_SCAN, "SCAN complete scan\n");36043604+ IWL_DEBUG_SCAN("SCAN complete scan\n");2705360527063606 if (test_bit(STATUS_EXIT_PENDING, &priv->status))27073607 return;···26993629 /* Since setting the TXPOWER may have been deferred while27003630 * performing the scan, fire one off */27013631 mutex_lock(&priv->mutex);27022702- iwl4965_hw_reg_send_txpower(priv);36323632+ iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);27033633 mutex_unlock(&priv->mutex);27043634}27053635···28083738 * RXON_FILTER_ASSOC_MSK BIT28093739 */28103740 mutex_lock(&priv->mutex);28112811- iwl4965_scan_cancel_timeout(priv, 100);37413741+ iwl_scan_cancel_timeout(priv, 100);28123742 cancel_delayed_work(&priv->post_associate);28133743 mutex_unlock(&priv->mutex);28143744 }···28713801 memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);28723802 }2873380328742874- if (iwl_is_ready(priv))28752875- iwl4965_set_mode(priv, conf->type);38043804+ if (iwl4965_set_mode(priv, conf->type) == -EAGAIN)38053805+ /* we are not ready, will run again when ready */38063806+ set_bit(STATUS_MODE_PENDING, &priv->status);2876380728773808 mutex_unlock(&priv->mutex);28783809···2901383029023831 priv->add_radiotap = !!(conf->flags & IEEE80211_CONF_RADIOTAP);2903383238333833+ if (conf->radio_enabled && iwl_radio_kill_sw_enable_radio(priv)) {38343834+ IWL_DEBUG_MAC80211("leave - RF-KILL - waiting for uCode\n");38353835+ goto out;38363836+ }38373837+38383838+ if (!conf->radio_enabled)38393839+ iwl_radio_kill_sw_disable_radio(priv);38403840+29043841 if (!iwl_is_ready(priv)) {29053842 IWL_DEBUG_MAC80211("leave - not ready\n");29063843 ret = -EIO;···29313852 goto out;29323853 }2933385438553855+ if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS &&38563856+ !is_channel_ibss(ch_info)) {38573857+ IWL_ERROR("channel %d in band %d not IBSS channel\n",38583858+ conf->channel->hw_value, conf->channel->band);38593859+ ret = -EINVAL;38603860+ goto out;38613861+ }38623862+29343863 spin_lock_irqsave(&priv->lock, flags);2935386429362936-#ifdef CONFIG_IWL4965_HT29373865 /* if we are switching from ht to 2.4 clear flags29383866 * from any ht related info since 2.4 does not29393867 * support ht */···29503864#endif29513865 )29523866 priv->staging_rxon.flags = 0;29532953-#endif /* CONFIG_IWL4965_HT */2954386729553868 iwl_set_rxon_channel(priv, conf->channel->band, channel);29563869···29693884 }29703885#endif2971388629722972- if (priv->cfg->ops->lib->radio_kill_sw)29732973- priv->cfg->ops->lib->radio_kill_sw(priv, !conf->radio_enabled);29742974-29753887 if (!conf->radio_enabled) {29763888 IWL_DEBUG_MAC80211("leave - radio disabled\n");29773889 goto out;···29793897 ret = -EIO;29803898 goto out;29813899 }39003900+39013901+ IWL_DEBUG_MAC80211("TX Power old=%d new=%d\n",39023902+ priv->tx_power_user_lmt, conf->power_level);39033903+39043904+ iwl_set_tx_power(priv, conf->power_level, false);2982390529833906 iwl4965_set_rate(priv);29843907···31214034 !is_multicast_ether_addr(conf->bssid)) {31224035 /* If there is currently a HW scan going on in the background31234036 * then we need to cancel it else the RXON below will fail. */31243124- if (iwl4965_scan_cancel_timeout(priv, 100)) {40374037+ if (iwl_scan_cancel_timeout(priv, 100)) {31254038 IWL_WARNING("Aborted scan still in progress "31264039 "after 100ms\n");31274040 IWL_DEBUG_MAC80211("leaving - scan abort failed.\n");···31464059 }3147406031484061 } else {31493149- iwl4965_scan_cancel_timeout(priv, 100);40624062+ iwl_scan_cancel_timeout(priv, 100);31504063 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;31514064 iwl4965_commit_rxon(priv);31524065 }···32044117 mutex_lock(&priv->mutex);3205411832064119 if (iwl_is_ready_rf(priv)) {32073207- iwl4965_scan_cancel_timeout(priv, 100);41204120+ iwl_scan_cancel_timeout(priv, 100);32084121 cancel_delayed_work(&priv->post_associate);32094122 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;32104123 iwl4965_commit_rxon(priv);···33184231 }33194232 if (len) {33204233 IWL_DEBUG_SCAN("direct scan for %s [%d]\n ",33213321- iwl4965_escape_essid(ssid, len), (int)len);42344234+ iwl_escape_essid(ssid, len), (int)len);3322423533234236 priv->one_direct_scan = 1;33244237 priv->direct_ssid_len = (u8)···33274240 } else33284241 priv->one_direct_scan = 0;3329424233303330- rc = iwl4965_scan_initiate(priv);42434243+ rc = iwl_scan_initiate(priv);3331424433324245 IWL_DEBUG_MAC80211("leave\n");33334246···33584271 return;33594272 }3360427333613361- iwl4965_scan_cancel_timeout(priv, 100);42744274+ iwl_scan_cancel_timeout(priv, 100);3362427533634276 key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK);33644277 key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);···34164329 }3417433034184331 mutex_lock(&priv->mutex);34193419- iwl4965_scan_cancel_timeout(priv, 100);43324332+ iwl_scan_cancel_timeout(priv, 100);34204333 mutex_unlock(&priv->mutex);3421433434224335 /* If we are getting WEP group key and we didn't receive any key mapping···35764489 IWL_DEBUG_MAC80211("enter\n");3577449035784491 priv->lq_mngr.lq_ready = 0;35793579-#ifdef CONFIG_IWL4965_HT35804492 spin_lock_irqsave(&priv->lock, flags);35814493 memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info));35824494 spin_unlock_irqrestore(&priv->lock, flags);35833583-#endif /* CONFIG_IWL4965_HT */3584449535854496 iwl_reset_qos(priv);35864497···36124527 * clear RXON_FILTER_ASSOC_MSK bit36134528 */36144529 if (priv->iw_mode != IEEE80211_IF_TYPE_AP) {36153615- iwl4965_scan_cancel_timeout(priv, 100);45304530+ iwl_scan_cancel_timeout(priv, 100);36164531 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;36174532 iwl4965_commit_rxon(priv);36184533 }···3668458336694584 iwl_reset_qos(priv);3670458536713671- queue_work(priv->workqueue, &priv->post_associate.work);45864586+ iwl4965_post_associate(priv);3672458736734588 mutex_unlock(&priv->mutex);36744589···37504665 if (!iwl_is_alive(priv))37514666 return -EAGAIN;3752466737533753- return sprintf(buf, "%d\n", iwl4965_hw_get_temperature(priv));46684668+ return sprintf(buf, "%d\n", priv->temperature);37544669}3755467037564671static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL);···37684683 struct device_attribute *attr, char *buf)37694684{37704685 struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;37713771- return sprintf(buf, "%d\n", priv->user_txpower_limit);46864686+ return sprintf(buf, "%d\n", priv->tx_power_user_lmt);37724687}3773468837744689static ssize_t store_tx_power(struct device *d,···37844699 printk(KERN_INFO DRV_NAME37854700 ": %s is not in decimal form.\n", buf);37864701 else37873787- iwl4965_hw_reg_set_txpower(priv, val);47024702+ iwl_set_tx_power(priv, val, false);3788470337894704 return count;37904705}···38094724 mutex_lock(&priv->mutex);38104725 if (le32_to_cpu(priv->staging_rxon.flags) != flags) {38114726 /* Cancel any currently running scans... */38123812- if (iwl4965_scan_cancel_timeout(priv, 100))47274727+ if (iwl_scan_cancel_timeout(priv, 100))38134728 IWL_WARNING("Could not cancel scan.\n");38144729 else {38154730 IWL_DEBUG_INFO("Committing rxon.flags = 0x%04X\n",···38444759 mutex_lock(&priv->mutex);38454760 if (le32_to_cpu(priv->staging_rxon.filter_flags) != filter_flags) {38464761 /* Cancel any currently running scans... */38473847- if (iwl4965_scan_cancel_timeout(priv, 100))47624762+ if (iwl_scan_cancel_timeout(priv, 100))38484763 IWL_WARNING("Could not cancel scan.\n");38494764 else {38504765 IWL_DEBUG_INFO("Committing rxon.filter_flags = "···40424957static ssize_t show_channels(struct device *d,40434958 struct device_attribute *attr, char *buf)40444959{40454045- /* all this shit doesn't belong into sysfs anyway */40464046- return 0;49604960+49614961+ struct iwl_priv *priv = dev_get_drvdata(d);49624962+ struct ieee80211_channel *channels = NULL;49634963+ const struct ieee80211_supported_band *supp_band = NULL;49644964+ int len = 0, i;49654965+ int count = 0;49664966+49674967+ if (!test_bit(STATUS_GEO_CONFIGURED, &priv->status))49684968+ return -EAGAIN;49694969+49704970+ supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_2GHZ);49714971+ channels = supp_band->channels;49724972+ count = supp_band->n_channels;49734973+49744974+ len += sprintf(&buf[len],49754975+ "Displaying %d channels in 2.4GHz band "49764976+ "(802.11bg):\n", count);49774977+49784978+ for (i = 0; i < count; i++)49794979+ len += sprintf(&buf[len], "%d: %ddBm: BSS%s%s, %s.\n",49804980+ ieee80211_frequency_to_channel(49814981+ channels[i].center_freq),49824982+ channels[i].max_power,49834983+ channels[i].flags & IEEE80211_CHAN_RADAR ?49844984+ " (IEEE 802.11h required)" : "",49854985+ (!(channels[i].flags & IEEE80211_CHAN_NO_IBSS)49864986+ || (channels[i].flags &49874987+ IEEE80211_CHAN_RADAR)) ? "" :49884988+ ", IBSS",49894989+ channels[i].flags &49904990+ IEEE80211_CHAN_PASSIVE_SCAN ?49914991+ "passive only" : "active/passive");49924992+49934993+ supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_5GHZ);49944994+ channels = supp_band->channels;49954995+ count = supp_band->n_channels;49964996+49974997+ len += sprintf(&buf[len], "Displaying %d channels in 5.2GHz band "49984998+ "(802.11a):\n", count);49994999+50005000+ for (i = 0; i < count; i++)50015001+ len += sprintf(&buf[len], "%d: %ddBm: BSS%s%s, %s.\n",50025002+ ieee80211_frequency_to_channel(50035003+ channels[i].center_freq),50045004+ channels[i].max_power,50055005+ channels[i].flags & IEEE80211_CHAN_RADAR ?50065006+ " (IEEE 802.11h required)" : "",50075007+ ((channels[i].flags & IEEE80211_CHAN_NO_IBSS)50085008+ || (channels[i].flags &50095009+ IEEE80211_CHAN_RADAR)) ? "" :50105010+ ", IBSS",50115011+ channels[i].flags &50125012+ IEEE80211_CHAN_PASSIVE_SCAN ?50135013+ "passive only" : "active/passive");50145014+50155015+ return len;40475016}4048501740495018static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL);···41575018 *41585019 *****************************************************************************/4159502041604160-static void iwl4965_setup_deferred_work(struct iwl_priv *priv)50215021+static void iwl_setup_deferred_work(struct iwl_priv *priv)41615022{41625023 priv->workqueue = create_workqueue(DRV_NAME);41635024···41665027 INIT_WORK(&priv->up, iwl4965_bg_up);41675028 INIT_WORK(&priv->restart, iwl4965_bg_restart);41685029 INIT_WORK(&priv->rx_replenish, iwl4965_bg_rx_replenish);41694169- INIT_WORK(&priv->scan_completed, iwl4965_bg_scan_completed);41704170- INIT_WORK(&priv->request_scan, iwl4965_bg_request_scan);41714171- INIT_WORK(&priv->abort_scan, iwl4965_bg_abort_scan);41725030 INIT_WORK(&priv->rf_kill, iwl4965_bg_rf_kill);41735031 INIT_WORK(&priv->beacon_update, iwl4965_bg_beacon_update);41745032 INIT_WORK(&priv->set_monitor, iwl4965_bg_set_monitor);50335033+ INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work);41755034 INIT_DELAYED_WORK(&priv->post_associate, iwl4965_bg_post_associate);41765035 INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start);41775036 INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start);41784178- INIT_DELAYED_WORK(&priv->scan_check, iwl4965_bg_scan_check);4179503741804180- iwl4965_hw_setup_deferred_work(priv);50385038+ /* FIXME : remove when resolved PENDING */50395039+ INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed);50405040+ iwl_setup_scan_deferred_work(priv);50415041+50425042+ if (priv->cfg->ops->lib->setup_deferred_work)50435043+ priv->cfg->ops->lib->setup_deferred_work(priv);50445044+50455045+ init_timer(&priv->statistics_periodic);50465046+ priv->statistics_periodic.data = (unsigned long)priv;50475047+ priv->statistics_periodic.function = iwl4965_bg_statistics_periodic;4181504841825049 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))41835050 iwl4965_irq_tasklet, (unsigned long)priv);41845051}4185505241864186-static void iwl4965_cancel_deferred_work(struct iwl_priv *priv)50535053+static void iwl_cancel_deferred_work(struct iwl_priv *priv)41875054{41884188- iwl4965_hw_cancel_deferred_work(priv);50555055+ if (priv->cfg->ops->lib->cancel_deferred_work)50565056+ priv->cfg->ops->lib->cancel_deferred_work(priv);4189505741905058 cancel_delayed_work_sync(&priv->init_alive_start);41915059 cancel_delayed_work(&priv->scan_check);41925060 cancel_delayed_work(&priv->alive_start);41935061 cancel_delayed_work(&priv->post_associate);41945062 cancel_work_sync(&priv->beacon_update);50635063+ del_timer_sync(&priv->statistics_periodic);41955064}4196506541975066static struct attribute *iwl4965_sysfs_entries[] = {···42475100 .reset_tsf = iwl4965_mac_reset_tsf,42485101 .beacon_update = iwl4965_mac_beacon_update,42495102 .bss_info_changed = iwl4965_bss_info_changed,42504250-#ifdef CONFIG_IWL4965_HT42515103 .ampdu_action = iwl4965_mac_ampdu_action,42524252-#endif /* CONFIG_IWL4965_HT */42535104 .hw_scan = iwl4965_mac_hw_scan42545105};42555106···44115266 }441252674413526844144414- iwl4965_setup_deferred_work(priv);52695269+ iwl_setup_deferred_work(priv);44155270 iwl4965_setup_rx_handlers(priv);4416527144175272 /********************···44325287 if (err)44335288 IWL_ERROR("failed to create debugfs files\n");4434528944354435- /* notify iwlcore to init */44364436- iwlcore_low_level_notify(priv, IWLCORE_INIT_EVT);52905290+ err = iwl_rfkill_init(priv);52915291+ if (err)52925292+ IWL_ERROR("Unable to initialize RFKILL system. "52935293+ "Ignoring error: %d\n", err);52945294+ iwl_power_initialize(priv);44375295 return 0;4438529644395297 out_remove_sysfs:···44995351 }45005352 }4501535345024502- iwlcore_low_level_notify(priv, IWLCORE_REMOVE_EVT);45034503-53545354+ iwl_rfkill_unregister(priv);45045355 iwl4965_dealloc_ucode_pci(priv);4505535645065357 if (priv->rxq.bd)
+122-40
drivers/net/wireless/libertas/if_cs.c
···159159160160161161162162-/* First the bitmasks for the host/card interrupt/status registers: */162162+/*163163+ * First the bitmasks for the host/card interrupt/status registers:164164+ */163165#define IF_CS_BIT_TX 0x0001164166#define IF_CS_BIT_RX 0x0002165167#define IF_CS_BIT_COMMAND 0x0004···169167#define IF_CS_BIT_EVENT 0x0010170168#define IF_CS_BIT_MASK 0x001f171169172172-/* And now the individual registers and assorted masks */170170+171171+172172+/*173173+ * It's not really clear to me what the host status register is for. It174174+ * needs to be set almost in union with "host int cause". The following175175+ * bits from above are used:176176+ *177177+ * IF_CS_BIT_TX driver downloaded a data packet178178+ * IF_CS_BIT_RX driver got a data packet179179+ * IF_CS_BIT_COMMAND driver downloaded a command180180+ * IF_CS_BIT_RESP not used (has some meaning with powerdown)181181+ * IF_CS_BIT_EVENT driver read a host event182182+ */173183#define IF_CS_HOST_STATUS 0x00000000174184185185+/*186186+ * With the host int cause register can the host (that is, Linux) cause187187+ * an interrupt in the firmware, to tell the firmware about those events:188188+ *189189+ * IF_CS_BIT_TX a data packet has been downloaded190190+ * IF_CS_BIT_RX a received data packet has retrieved191191+ * IF_CS_BIT_COMMAND a firmware block or a command has been downloaded192192+ * IF_CS_BIT_RESP not used (has some meaning with powerdown)193193+ * IF_CS_BIT_EVENT a host event (link lost etc) has been retrieved194194+ */175195#define IF_CS_HOST_INT_CAUSE 0x00000002176196197197+/*198198+ * The host int mask register is used to enable/disable interrupt. However,199199+ * I have the suspicion that disabled interrupts are lost.200200+ */177201#define IF_CS_HOST_INT_MASK 0x00000004178202179179-#define IF_CS_HOST_WRITE 0x00000016180180-#define IF_CS_HOST_WRITE_LEN 0x00000014181181-182182-#define IF_CS_HOST_CMD 0x0000001A183183-#define IF_CS_HOST_CMD_LEN 0x00000018184184-203203+/*204204+ * Used to send or receive data packets:205205+ */206206+#define IF_CS_WRITE 0x00000016207207+#define IF_CS_WRITE_LEN 0x00000014185208#define IF_CS_READ 0x00000010186209#define IF_CS_READ_LEN 0x00000024187210188188-#define IF_CS_CARD_CMD 0x00000012189189-#define IF_CS_CARD_CMD_LEN 0x00000030211211+/*212212+ * Used to send commands (and to send firmware block) and to213213+ * receive command responses:214214+ */215215+#define IF_CS_CMD 0x0000001A216216+#define IF_CS_CMD_LEN 0x00000018217217+#define IF_CS_RESP 0x00000012218218+#define IF_CS_RESP_LEN 0x00000030190219220220+/*221221+ * The card status registers shows what the card/firmware actually222222+ * accepts:223223+ *224224+ * IF_CS_BIT_TX you may send a data packet225225+ * IF_CS_BIT_RX you may retrieve a data packet226226+ * IF_CS_BIT_COMMAND you may send a command227227+ * IF_CS_BIT_RESP you may retrieve a command response228228+ * IF_CS_BIT_EVENT the card has a event for use (link lost, snr low etc)229229+ *230230+ * When reading this register several times, you will get back the same231231+ * results --- with one exception: the IF_CS_BIT_EVENT clear itself232232+ * automatically.233233+ *234234+ * Not that we don't rely on BIT_RX,_BIT_RESP or BIT_EVENT because235235+ * we handle this via the card int cause register.236236+ */191237#define IF_CS_CARD_STATUS 0x00000020192238#define IF_CS_CARD_STATUS_MASK 0x7f00193239240240+/*241241+ * The card int cause register is used by the card/firmware to notify us242242+ * about the following events:243243+ *244244+ * IF_CS_BIT_TX a data packet has successfully been sentx245245+ * IF_CS_BIT_RX a data packet has been received and can be retrieved246246+ * IF_CS_BIT_COMMAND not used247247+ * IF_CS_BIT_RESP the firmware has a command response for us248248+ * IF_CS_BIT_EVENT the card has a event for use (link lost, snr low etc)249249+ */194250#define IF_CS_CARD_INT_CAUSE 0x00000022195251196196-#define IF_CS_CARD_SQ_READ_LOW 0x00000028197197-#define IF_CS_CARD_SQ_HELPER_OK 0x10252252+/*253253+ * This is used to for handshaking with the card's bootloader/helper image254254+ * to synchronize downloading of firmware blocks.255255+ */256256+#define IF_CS_SQ_READ_LOW 0x00000028257257+#define IF_CS_SQ_HELPER_OK 0x10198258259259+/*260260+ * The scratch register tells us ...261261+ *262262+ * IF_CS_SCRATCH_BOOT_OK the bootloader runs263263+ * IF_CS_SCRATCH_HELPER_OK the helper firmware already runs264264+ */199265#define IF_CS_SCRATCH 0x0000003F266266+#define IF_CS_SCRATCH_BOOT_OK 0x00267267+#define IF_CS_SCRATCH_HELPER_OK 0x5a200268269269+/*270270+ * Used to detect ancient chips:271271+ */272272+#define IF_CS_PRODUCT_ID 0x0000001C273273+#define IF_CS_CF8385_B1_REV 0x12201274202275203276/********************************************************************/···305228306229 /* Is hardware ready? */307230 while (1) {308308- u16 val = if_cs_read16(card, IF_CS_CARD_STATUS);309309- if (val & IF_CS_BIT_COMMAND)231231+ u16 status = if_cs_read16(card, IF_CS_CARD_STATUS);232232+ if (status & IF_CS_BIT_COMMAND)310233 break;311234 if (++loops > 100) {312235 lbs_pr_err("card not ready for commands\n");···315238 mdelay(1);316239 }317240318318- if_cs_write16(card, IF_CS_HOST_CMD_LEN, nb);241241+ if_cs_write16(card, IF_CS_CMD_LEN, nb);319242320320- if_cs_write16_rep(card, IF_CS_HOST_CMD, buf, nb / 2);243243+ if_cs_write16_rep(card, IF_CS_CMD, buf, nb / 2);321244 /* Are we supposed to transfer an odd amount of bytes? */322245 if (nb & 1)323323- if_cs_write8(card, IF_CS_HOST_CMD, buf[nb-1]);246246+ if_cs_write8(card, IF_CS_CMD, buf[nb-1]);324247325248 /* "Assert the download over interrupt command in the Host326249 * status register" */···351274 status = if_cs_read16(card, IF_CS_CARD_STATUS);352275 BUG_ON((status & IF_CS_BIT_TX) == 0);353276354354- if_cs_write16(card, IF_CS_HOST_WRITE_LEN, nb);277277+ if_cs_write16(card, IF_CS_WRITE_LEN, nb);355278356279 /* write even number of bytes, then odd byte if necessary */357357- if_cs_write16_rep(card, IF_CS_HOST_WRITE, buf, nb / 2);280280+ if_cs_write16_rep(card, IF_CS_WRITE, buf, nb / 2);358281 if (nb & 1)359359- if_cs_write8(card, IF_CS_HOST_WRITE, buf[nb-1]);282282+ if_cs_write8(card, IF_CS_WRITE, buf[nb-1]);360283361284 if_cs_write16(card, IF_CS_HOST_STATUS, IF_CS_BIT_TX);362285 if_cs_write16(card, IF_CS_HOST_INT_CAUSE, IF_CS_BIT_TX);···384307 goto out;385308 }386309387387- *len = if_cs_read16(priv->card, IF_CS_CARD_CMD_LEN);310310+ *len = if_cs_read16(priv->card, IF_CS_RESP_LEN);388311 if ((*len == 0) || (*len > LBS_CMD_BUFFER_SIZE)) {389312 lbs_pr_err("card cmd buffer has invalid # of bytes (%d)\n", *len);390313 goto out;391314 }392315393316 /* read even number of bytes, then odd byte if necessary */394394- if_cs_read16_rep(priv->card, IF_CS_CARD_CMD, data, *len/sizeof(u16));317317+ if_cs_read16_rep(priv->card, IF_CS_RESP, data, *len/sizeof(u16));395318 if (*len & 1)396396- data[*len-1] = if_cs_read8(priv->card, IF_CS_CARD_CMD);319319+ data[*len-1] = if_cs_read8(priv->card, IF_CS_RESP);397320398321 /* This is a workaround for a firmware that reports too much399322 * bytes */···456379457380 /* Ask card interrupt cause register if there is something for us */458381 cause = if_cs_read16(card, IF_CS_CARD_INT_CAUSE);382382+ lbs_deb_cs("cause 0x%04x\n", cause);383383+459384 if (cause == 0) {460385 /* Not for us */461386 return IRQ_NONE;···468389 card->priv->surpriseremoved = 1;469390 return IRQ_HANDLED;470391 }471471-472472- /* Clear interrupt cause */473473- if_cs_write16(card, IF_CS_CARD_INT_CAUSE, cause & IF_CS_BIT_MASK);474474- lbs_deb_cs("cause 0x%04x\n", cause);475392476393 if (cause & IF_CS_BIT_RX) {477394 struct sk_buff *skb;···501426 }502427503428 if (cause & IF_CS_BIT_EVENT) {504504- u16 event = if_cs_read16(priv->card, IF_CS_CARD_STATUS)505505- & IF_CS_CARD_STATUS_MASK;429429+ u16 status = if_cs_read16(priv->card, IF_CS_CARD_STATUS);506430 if_cs_write16(priv->card, IF_CS_HOST_INT_CAUSE,507431 IF_CS_BIT_EVENT);508508- lbs_deb_cs("host event 0x%04x\n", event);509509- lbs_queue_event(priv, event >> 8 & 0xff);432432+ lbs_queue_event(priv, (status & IF_CS_CARD_STATUS_MASK) >> 8);510433 }434434+435435+ /* Clear interrupt cause */436436+ if_cs_write16(card, IF_CS_CARD_INT_CAUSE, cause & IF_CS_BIT_MASK);511437512438 lbs_deb_leave(LBS_DEB_CS);513439 return IRQ_HANDLED;···540464 /* "If the value is 0x5a, the firmware is already541465 * downloaded successfully"542466 */543543- if (scratch == 0x5a)467467+ if (scratch == IF_CS_SCRATCH_HELPER_OK)544468 goto done;545469546470 /* "If the value is != 00, it is invalid value of register */547547- if (scratch != 0x00) {471471+ if (scratch != IF_CS_SCRATCH_BOOT_OK) {548472 ret = -ENODEV;549473 goto done;550474 }···572496573497 /* "write the number of bytes to be sent to the I/O Command574498 * write length register" */575575- if_cs_write16(card, IF_CS_HOST_CMD_LEN, count);499499+ if_cs_write16(card, IF_CS_CMD_LEN, count);576500577501 /* "write this to I/O Command port register as 16 bit writes */578502 if (count)579579- if_cs_write16_rep(card, IF_CS_HOST_CMD,503503+ if_cs_write16_rep(card, IF_CS_CMD,580504 &fw->data[sent],581505 count >> 1);582506···633557 }634558 lbs_deb_cs("fw size %td\n", fw->size);635559636636- ret = if_cs_poll_while_fw_download(card, IF_CS_CARD_SQ_READ_LOW,637637- IF_CS_CARD_SQ_HELPER_OK);560560+ ret = if_cs_poll_while_fw_download(card, IF_CS_SQ_READ_LOW,561561+ IF_CS_SQ_HELPER_OK);638562 if (ret < 0) {639563 lbs_pr_err("helper firmware doesn't answer\n");640564 goto err_release;641565 }642566643567 for (sent = 0; sent < fw->size; sent += len) {644644- len = if_cs_read16(card, IF_CS_CARD_SQ_READ_LOW);568568+ len = if_cs_read16(card, IF_CS_SQ_READ_LOW);645569 if (len & 1) {646570 retry++;647571 lbs_pr_info("odd, need to retry this firmware block\n");···659583 }660584661585662662- if_cs_write16(card, IF_CS_HOST_CMD_LEN, len);586586+ if_cs_write16(card, IF_CS_CMD_LEN, len);663587664664- if_cs_write16_rep(card, IF_CS_HOST_CMD,588588+ if_cs_write16_rep(card, IF_CS_CMD,665589 &fw->data[sent],666590 (len+1) >> 1);667591 if_cs_write8(card, IF_CS_HOST_STATUS, IF_CS_BIT_COMMAND);···865789 p_dev->irq.AssignedIRQ, p_dev->io.BasePort1,866790 p_dev->io.BasePort1 + p_dev->io.NumPorts1 - 1);867791792792+ /* Check if we have a current silicon */793793+ if (if_cs_read8(card, IF_CS_PRODUCT_ID) < IF_CS_CF8385_B1_REV) {794794+ lbs_pr_err("old chips like 8385 rev B1 aren't supported\n");795795+ ret = -ENODEV;796796+ goto out2;797797+ }868798869799 /* Load the firmware early, before calling into libertas.ko */870800 ret = if_cs_prog_helper(card);
···3434 struct sk_buff *frag_skb)3535{3636 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(frag_skb);3737- struct skb_frame_desc *skbdesc;3837 struct ieee80211_tx_info *rts_info;3938 struct sk_buff *skb;4039 int size;···6465 memcpy(skb->cb, frag_skb->cb, sizeof(skb->cb));6566 rts_info = IEEE80211_SKB_CB(skb);6667 rts_info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT;6868+ rts_info->flags &= ~IEEE80211_TX_CTL_USE_RTS_CTS;6769 rts_info->flags &= ~IEEE80211_TX_CTL_USE_CTS_PROTECT;6870 rts_info->flags &= ~IEEE80211_TX_CTL_REQ_TX_STATUS;6971···8282 frag_skb->data, size, tx_info,8383 (struct ieee80211_rts *)(skb->data));84848585- /*8686- * Initialize skb descriptor8787- */8888- skbdesc = get_skb_frame_desc(skb);8989- memset(skbdesc, 0, sizeof(*skbdesc));9090- skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED;9191-9292- if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb)) {8585+ if (rt2x00queue_write_tx_frame(queue, skb)) {9386 WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n");9487 return NETDEV_TX_BUSY;9588 }···128135 }129136130137 /*131131- * If CTS/RTS is required. and this frame is not CTS or RTS,132132- * create and queue that frame first. But make sure we have133133- * at least enough entries available to send this CTS/RTS134134- * frame as well as the data frame.138138+ * If CTS/RTS is required. create and queue that frame first.139139+ * Make sure we have at least enough entries available to send140140+ * this CTS/RTS frame as well as the data frame.135141 * Note that when the driver has set the set_rts_threshold()136142 * callback function it doesn't need software generation of137137- * neither RTS or CTS-to-self frames and handles everything143143+ * either RTS or CTS-to-self frame and handles everything138144 * inside the hardware.139145 */140146 frame_control = le16_to_cpu(ieee80211hdr->frame_control);141141- if (!is_rts_frame(frame_control) && !is_cts_frame(frame_control) &&142142- (tx_info->flags & (IEEE80211_TX_CTL_USE_RTS_CTS |147147+ if ((tx_info->flags & (IEEE80211_TX_CTL_USE_RTS_CTS |143148 IEEE80211_TX_CTL_USE_CTS_PROTECT)) &&144149 !rt2x00dev->ops->hw->set_rts_threshold) {145150 if (rt2x00queue_available(queue) <= 1) {···151160 }152161 }153162154154- if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb)) {163163+ if (rt2x00queue_write_tx_frame(queue, skb)) {155164 ieee80211_stop_queue(rt2x00dev->hw, qid);156165 return NETDEV_TX_BUSY;157166 }158167159159- if (rt2x00queue_full(queue))168168+ if (rt2x00queue_threshold(queue))160169 ieee80211_stop_queue(rt2x00dev->hw, qid);161161-162162- if (rt2x00dev->ops->lib->kick_tx_queue)163163- rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, qid);164170165171 return NETDEV_TX_OK;166172}
+21-51
drivers/net/wireless/rt2x00/rt2x00pci.c
···3434/*3535 * TX data handlers.3636 */3737-int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev,3838- struct data_queue *queue, struct sk_buff *skb)3737+int rt2x00pci_write_tx_data(struct queue_entry *entry)3938{4040- struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);4139 struct queue_entry_priv_pci *entry_priv = entry->priv_data;4240 struct skb_frame_desc *skbdesc;4343- struct txentry_desc txdesc;4441 u32 word;4545-4646- if (rt2x00queue_full(queue))4747- return -EINVAL;48424943 rt2x00_desc_read(entry_priv->desc, 0, &word);50445151- if (rt2x00_get_field32(word, TXD_ENTRY_OWNER_NIC) ||5252- rt2x00_get_field32(word, TXD_ENTRY_VALID)) {5353- ERROR(rt2x00dev,5454- "Arrived at non-free entry in the non-full queue %d.\n"4545+ /*4646+ * This should not happen, we already checked the entry4747+ * was ours. When the hardware disagrees there has been4848+ * a queue corruption!4949+ */5050+ if (unlikely(rt2x00_get_field32(word, TXD_ENTRY_OWNER_NIC) ||5151+ rt2x00_get_field32(word, TXD_ENTRY_VALID))) {5252+ ERROR(entry->queue->rt2x00dev,5353+ "Corrupt queue %d, accessing entry which is not ours.\n"5554 "Please file bug report to %s.\n",5655 entry->queue->qid, DRV_PROJECT);5756 return -EINVAL;5857 }59586059 /*6161- * Copy all TX descriptor information into txdesc,6262- * after that we are free to use the skb->cb array6363- * for our information.6464- */6565- entry->skb = skb;6666- rt2x00queue_create_tx_descriptor(entry, &txdesc);6767-6868- /*6960 * Fill in skb descriptor7061 */7171- skbdesc = get_skb_frame_desc(skb);6262+ skbdesc = get_skb_frame_desc(entry->skb);7263 memset(skbdesc, 0, sizeof(*skbdesc));7373- skbdesc->data = skb->data;7474- skbdesc->data_len = skb->len;7564 skbdesc->desc = entry_priv->desc;7676- skbdesc->desc_len = queue->desc_size;6565+ skbdesc->desc_len = entry->queue->desc_size;7766 skbdesc->entry = entry;78677979- memcpy(entry_priv->data, skb->data, skb->len);8080-8181- rt2x00queue_write_tx_descriptor(entry, &txdesc);8282- rt2x00queue_index_inc(queue, Q_INDEX);6868+ memcpy(entry_priv->data, entry->skb->data, entry->skb->len);83698470 return 0;8571}···7993 struct data_queue *queue = rt2x00dev->rx;8094 struct queue_entry *entry;8195 struct queue_entry_priv_pci *entry_priv;8282- struct ieee80211_hdr *hdr;8396 struct skb_frame_desc *skbdesc;8497 struct rxdone_entry_desc rxdesc;8585- int header_size;8686- int align;8798 u32 word;889989100 while (1) {···94111 memset(&rxdesc, 0, sizeof(rxdesc));95112 rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc);961139797- hdr = (struct ieee80211_hdr *)entry_priv->data;9898- header_size =9999- ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control));100100-101114 /*102102- * The data behind the ieee80211 header must be103103- * aligned on a 4 byte boundary.115115+ * Allocate the sk_buffer and copy all data into it.104116 */105105- align = header_size % 4;106106-107107- /*108108- * Allocate the sk_buffer, initialize it and copy109109- * all data into it.110110- */111111- entry->skb = dev_alloc_skb(rxdesc.size + align);117117+ entry->skb = rt2x00queue_alloc_rxskb(queue);112118 if (!entry->skb)113119 return;114120115115- skb_reserve(entry->skb, align);116116- memcpy(skb_put(entry->skb, rxdesc.size),117117- entry_priv->data, rxdesc.size);121121+ memcpy(entry->skb->data, entry_priv->data, rxdesc.size);122122+ skb_trim(entry->skb, rxdesc.size);118123119124 /*120125 * Fill in skb descriptor121126 */122127 skbdesc = get_skb_frame_desc(entry->skb);123128 memset(skbdesc, 0, sizeof(*skbdesc));124124- skbdesc->data = entry->skb->data;125125- skbdesc->data_len = entry->skb->len;126129 skbdesc->desc = entry_priv->desc;127130 skbdesc->desc_len = queue->desc_size;128131 skbdesc->entry = entry;···147178 rt2x00_set_field32(&word, TXD_ENTRY_VALID, 0);148179 rt2x00_desc_write(entry_priv->desc, 0, word);149180181181+ __clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);150182 rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);151183152184 /*153153- * If the data queue was full before the txdone handler154154- * we must make sure the packet queue in the mac80211 stack185185+ * If the data queue was below the threshold before the txdone186186+ * handler we must make sure the packet queue in the mac80211 stack155187 * is reenabled when the txdone handler has finished.156188 */157157- if (!rt2x00queue_full(entry->queue))189189+ if (!rt2x00queue_threshold(entry->queue))158190 ieee80211_wake_queue(rt2x00dev->hw, qid);159191160192}
+7-4
drivers/net/wireless/rt2x00/rt2x00pci.h
···8787 memcpy_toio(rt2x00dev->csr.base + offset, value, length);8888}89899090-/*9191- * TX data handlers.9090+/**9191+ * rt2x00pci_write_tx_data - Initialize data for TX operation9292+ * @entry: The entry where the frame is located9393+ *9494+ * This function will initialize the DMA and skb descriptor9595+ * to prepare the entry for the actual TX operation.9296 */9393-int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev,9494- struct data_queue *queue, struct sk_buff *skb);9797+int rt2x00pci_write_tx_data(struct queue_entry *entry);95989699/**97100 * struct queue_entry_priv_pci: Per entry PCI specific information
+98-15
drivers/net/wireless/rt2x00/rt2x00queue.c
···2929#include "rt2x00.h"3030#include "rt2x00lib.h"31313232+struct sk_buff *rt2x00queue_alloc_rxskb(struct data_queue *queue)3333+{3434+ struct sk_buff *skb;3535+ unsigned int frame_size;3636+ unsigned int reserved_size;3737+3838+ /*3939+ * The frame size includes descriptor size, because the4040+ * hardware directly receive the frame into the skbuffer.4141+ */4242+ frame_size = queue->data_size + queue->desc_size;4343+4444+ /*4545+ * For the allocation we should keep a few things in mind:4646+ * 1) 4byte alignment of 802.11 payload4747+ *4848+ * For (1) we need at most 4 bytes to guarentee the correct4949+ * alignment. We are going to optimize the fact that the chance5050+ * that the 802.11 header_size % 4 == 2 is much bigger then5151+ * anything else. However since we need to move the frame up5252+ * to 3 bytes to the front, which means we need to preallocate5353+ * 6 bytes.5454+ */5555+ reserved_size = 6;5656+5757+ /*5858+ * Allocate skbuffer.5959+ */6060+ skb = dev_alloc_skb(frame_size + reserved_size);6161+ if (!skb)6262+ return NULL;6363+6464+ skb_reserve(skb, reserved_size);6565+ skb_put(skb, frame_size);6666+6767+ return skb;6868+}6969+EXPORT_SYMBOL_GPL(rt2x00queue_alloc_rxskb);7070+3271void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,3372 struct txentry_desc *txdesc)3473{···13091 /*13192 * Check if more fragments are pending13293 */133133- if (ieee80211_get_morefrag(hdr)) {9494+ if (ieee80211_has_morefrags(hdr->frame_control)) {13495 __set_bit(ENTRY_TXD_BURST, &txdesc->flags);13596 __set_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags);13697 }···202163void rt2x00queue_write_tx_descriptor(struct queue_entry *entry,203164 struct txentry_desc *txdesc)204165{205205- struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;206206- struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);166166+ struct data_queue *queue = entry->queue;167167+ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;207168208169 rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, entry->skb, txdesc);209170···214175 rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TX, entry->skb);215176216177 /*217217- * We are done writing the frame to the queue entry,218218- * also kick the queue in case the correct flags are set,219219- * note that this will automatically filter beacons and220220- * RTS/CTS frames since those frames don't have this flag221221- * set.178178+ * Check if we need to kick the queue, there are however a few rules179179+ * 1) Don't kick beacon queue180180+ * 2) Don't kick unless this is the last in frame in a burst.181181+ * When the burst flag is set, this frame is always followed182182+ * by another frame which in some way are related to eachother.183183+ * This is true for fragments, RTS or CTS-to-self frames.184184+ * 3) Rule 2 can be broken when the available entries185185+ * in the queue are less then a certain threshold.222186 */223223- if (rt2x00dev->ops->lib->kick_tx_queue &&224224- !(skbdesc->flags & FRAME_DESC_DRIVER_GENERATED))225225- rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev,226226- entry->queue->qid);187187+ if (entry->queue->qid == QID_BEACON)188188+ return;189189+190190+ if (rt2x00queue_threshold(queue) ||191191+ !test_bit(ENTRY_TXD_BURST, &txdesc->flags))192192+ rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, queue->qid);227193}228194EXPORT_SYMBOL_GPL(rt2x00queue_write_tx_descriptor);195195+196196+int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)197197+{198198+ struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);199199+ struct txentry_desc txdesc;200200+201201+ if (unlikely(rt2x00queue_full(queue)))202202+ return -EINVAL;203203+204204+ if (__test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) {205205+ ERROR(queue->rt2x00dev,206206+ "Arrived at non-free entry in the non-full queue %d.\n"207207+ "Please file bug report to %s.\n",208208+ queue->qid, DRV_PROJECT);209209+ return -EINVAL;210210+ }211211+212212+ /*213213+ * Copy all TX descriptor information into txdesc,214214+ * after that we are free to use the skb->cb array215215+ * for our information.216216+ */217217+ entry->skb = skb;218218+ rt2x00queue_create_tx_descriptor(entry, &txdesc);219219+220220+ if (unlikely(queue->rt2x00dev->ops->lib->write_tx_data(entry))) {221221+ __clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);222222+ return -EIO;223223+ }224224+225225+ __set_bit(ENTRY_DATA_PENDING, &entry->flags);226226+227227+ rt2x00queue_index_inc(queue, Q_INDEX);228228+ rt2x00queue_write_tx_descriptor(entry, &txdesc);229229+230230+ return 0;231231+}229232230233struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev,231234 const enum data_queue_qid queue)···393312 rt2x00queue_reset(queue);394313395314 queue->limit = qdesc->entry_num;315315+ queue->threshold = DIV_ROUND_UP(qdesc->entry_num, 10);396316 queue->data_size = qdesc->data_size;397317 queue->desc_size = qdesc->desc_size;398318···521439 * TX: qid = QID_AC_BE + index522440 * TX: cw_min: 2^5 = 32.523441 * TX: cw_max: 2^10 = 1024.524524- * BCN & Atim: qid = QID_MGMT442442+ * BCN: qid = QID_BEACON443443+ * ATIM: qid = QID_ATIM525444 */526445 rt2x00queue_init(rt2x00dev, rt2x00dev->rx, QID_RX);527446···530447 tx_queue_for_each(rt2x00dev, queue)531448 rt2x00queue_init(rt2x00dev, queue, qid++);532449533533- rt2x00queue_init(rt2x00dev, &rt2x00dev->bcn[0], QID_MGMT);450450+ rt2x00queue_init(rt2x00dev, &rt2x00dev->bcn[0], QID_BEACON);534451 if (req_atim)535535- rt2x00queue_init(rt2x00dev, &rt2x00dev->bcn[1], QID_MGMT);452452+ rt2x00queue_init(rt2x00dev, &rt2x00dev->bcn[1], QID_ATIM);536453537454 return 0;538455}
+18-9
drivers/net/wireless/rt2x00/rt2x00queue.h
···8282/**8383 * enum skb_frame_desc_flags: Flags for &struct skb_frame_desc8484 *8585- * @FRAME_DESC_DRIVER_GENERATED: Frame was generated inside driver8686- * and should not be reported back to mac80211 during txdone.8785 */8888-enum skb_frame_desc_flags {8989- FRAME_DESC_DRIVER_GENERATED = 1 << 0,9090-};8686+//enum skb_frame_desc_flags {8787+// TEMPORARILY EMPTY8888+//};91899290/**9391 * struct skb_frame_desc: Descriptor information for the skb buffer···105107struct skb_frame_desc {106108 unsigned int flags;107109108108- unsigned short data_len;109109- unsigned short desc_len;110110-111111- void *data;112110 void *desc;111111+ unsigned int desc_len;113112114113 struct queue_entry *entry;115114};···255260 * @ENTRY_OWNER_DEVICE_CRYPTO: This entry is owned by the device for data256261 * encryption or decryption. The entry should only be touched after257262 * the device has signaled it is done with it.263263+ * @ENTRY_DATA_PENDING: This entry contains a valid frame and is waiting264264+ * for the signal to start sending.258265 */259266enum queue_entry_flags {260267 ENTRY_BCN_ASSIGNED,261268 ENTRY_OWNER_DEVICE_DATA,262269 ENTRY_OWNER_DEVICE_CRYPTO,270270+ ENTRY_DATA_PENDING,263271};264272265273/**···320322 * index corruption due to concurrency.321323 * @count: Number of frames handled in the queue.322324 * @limit: Maximum number of entries in the queue.325325+ * @threshold: Minimum number of free entries before queue is kicked by force.323326 * @length: Number of frames in queue.324327 * @index: Index pointers to entry positions in the queue,325328 * use &enum queue_index to get a specific index field.···339340 spinlock_t lock;340341 unsigned int count;341342 unsigned short limit;343343+ unsigned short threshold;342344 unsigned short length;343345 unsigned short index[Q_INDEX_MAX];344346···461461static inline int rt2x00queue_available(struct data_queue *queue)462462{463463 return queue->limit - queue->length;464464+}465465+466466+/**467467+ * rt2x00queue_threshold - Check if the queue is below threshold468468+ * @queue: Queue to check.469469+ */470470+static inline int rt2x00queue_threshold(struct data_queue *queue)471471+{472472+ return rt2x00queue_available(queue) < queue->threshold;464473}465474466475/**
+75-51
drivers/net/wireless/rt2x00/rt2x00reg.h
···130130131131/*132132 * Power of two check, this will check133133- * if the mask that has been given contains134134- * and contiguous set of bits.133133+ * if the mask that has been given contains and contiguous set of bits.134134+ * Note that we cannot use the is_power_of_2() function since this135135+ * check must be done at compile-time.135136 */136137#define is_power_of_two(x) ( !((x) & ((x)-1)) )137138#define low_bit_mask(x) ( ((x)-1) & ~(x) )138139#define is_valid_mask(x) is_power_of_two(1 + (x) + low_bit_mask(x))139140141141+/*142142+ * Macro's to find first set bit in a variable.143143+ * These macro's behaves the same as the __ffs() function with144144+ * the most important difference that this is done during145145+ * compile-time rather then run-time.146146+ */147147+#define compile_ffs2(__x) \148148+ __builtin_choose_expr(((__x) & 0x1), 0, 1)149149+150150+#define compile_ffs4(__x) \151151+ __builtin_choose_expr(((__x) & 0x3), \152152+ (compile_ffs2((__x))), \153153+ (compile_ffs2((__x) >> 2) + 2))154154+155155+#define compile_ffs8(__x) \156156+ __builtin_choose_expr(((__x) & 0xf), \157157+ (compile_ffs4((__x))), \158158+ (compile_ffs4((__x) >> 4) + 4))159159+160160+#define compile_ffs16(__x) \161161+ __builtin_choose_expr(((__x) & 0xff), \162162+ (compile_ffs8((__x))), \163163+ (compile_ffs8((__x) >> 8) + 8))164164+165165+#define compile_ffs32(__x) \166166+ __builtin_choose_expr(((__x) & 0xffff), \167167+ (compile_ffs16((__x))), \168168+ (compile_ffs16((__x) >> 16) + 16))169169+170170+/*171171+ * This macro will check the requirements for the FIELD{8,16,32} macros172172+ * The mask should be a constant non-zero contiguous set of bits which173173+ * does not exceed the given typelimit.174174+ */175175+#define FIELD_CHECK(__mask, __type) \176176+ BUILD_BUG_ON(!__builtin_constant_p(__mask) || \177177+ !(__mask) || \178178+ !is_valid_mask(__mask) || \179179+ (__mask) != (__type)(__mask)) \180180+140181#define FIELD8(__mask) \141182({ \142142- BUILD_BUG_ON(!(__mask) || \143143- !is_valid_mask(__mask) || \144144- (__mask) != (u8)(__mask)); \183183+ FIELD_CHECK(__mask, u8); \145184 (struct rt2x00_field8) { \146146- __ffs(__mask), (__mask) \185185+ compile_ffs8(__mask), (__mask) \147186 }; \148187})149188150189#define FIELD16(__mask) \151190({ \152152- BUILD_BUG_ON(!(__mask) || \153153- !is_valid_mask(__mask) || \154154- (__mask) != (u16)(__mask));\191191+ FIELD_CHECK(__mask, u16); \155192 (struct rt2x00_field16) { \156156- __ffs(__mask), (__mask) \193193+ compile_ffs16(__mask), (__mask) \157194 }; \158195})159196160197#define FIELD32(__mask) \161198({ \162162- BUILD_BUG_ON(!(__mask) || \163163- !is_valid_mask(__mask) || \164164- (__mask) != (u32)(__mask));\199199+ FIELD_CHECK(__mask, u32); \165200 (struct rt2x00_field32) { \166166- __ffs(__mask), (__mask) \201201+ compile_ffs32(__mask), (__mask) \167202 }; \168203})169204170170-static inline void rt2x00_set_field32(u32 *reg,171171- const struct rt2x00_field32 field,172172- const u32 value)173173-{174174- *reg &= ~(field.bit_mask);175175- *reg |= (value << field.bit_offset) & field.bit_mask;176176-}205205+#define SET_FIELD(__reg, __type, __field, __value)\206206+({ \207207+ typecheck(__type, __field); \208208+ *(__reg) &= ~((__field).bit_mask); \209209+ *(__reg) |= ((__value) << \210210+ ((__field).bit_offset)) & \211211+ ((__field).bit_mask); \212212+})177213178178-static inline u32 rt2x00_get_field32(const u32 reg,179179- const struct rt2x00_field32 field)180180-{181181- return (reg & field.bit_mask) >> field.bit_offset;182182-}214214+#define GET_FIELD(__reg, __type, __field) \215215+({ \216216+ typecheck(__type, __field); \217217+ ((__reg) & ((__field).bit_mask)) >> \218218+ ((__field).bit_offset); \219219+})183220184184-static inline void rt2x00_set_field16(u16 *reg,185185- const struct rt2x00_field16 field,186186- const u16 value)187187-{188188- *reg &= ~(field.bit_mask);189189- *reg |= (value << field.bit_offset) & field.bit_mask;190190-}221221+#define rt2x00_set_field32(__reg, __field, __value) \222222+ SET_FIELD(__reg, struct rt2x00_field32, __field, __value)223223+#define rt2x00_get_field32(__reg, __field) \224224+ GET_FIELD(__reg, struct rt2x00_field32, __field)191225192192-static inline u16 rt2x00_get_field16(const u16 reg,193193- const struct rt2x00_field16 field)194194-{195195- return (reg & field.bit_mask) >> field.bit_offset;196196-}226226+#define rt2x00_set_field16(__reg, __field, __value) \227227+ SET_FIELD(__reg, struct rt2x00_field16, __field, __value)228228+#define rt2x00_get_field16(__reg, __field) \229229+ GET_FIELD(__reg, struct rt2x00_field16, __field)197230198198-static inline void rt2x00_set_field8(u8 *reg,199199- const struct rt2x00_field8 field,200200- const u8 value)201201-{202202- *reg &= ~(field.bit_mask);203203- *reg |= (value << field.bit_offset) & field.bit_mask;204204-}205205-206206-static inline u8 rt2x00_get_field8(const u8 reg,207207- const struct rt2x00_field8 field)208208-{209209- return (reg & field.bit_mask) >> field.bit_offset;210210-}231231+#define rt2x00_set_field8(__reg, __field, __value) \232232+ SET_FIELD(__reg, struct rt2x00_field8, __field, __value)233233+#define rt2x00_get_field8(__reg, __field) \234234+ GET_FIELD(__reg, struct rt2x00_field8, __field)211235212236#endif /* RT2X00REG_H */
+65-114
drivers/net/wireless/rt2x00/rt2x00usb.c
···130130 struct queue_entry *entry = (struct queue_entry *)urb->context;131131 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;132132 struct txdone_entry_desc txdesc;133133- __le32 *txd = (__le32 *)entry->skb->data;134133 enum data_queue_qid qid = skb_get_queue_mapping(entry->skb);135135- u32 word;136134137135 if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) ||138136 !__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))139137 return;140140-141141- rt2x00_desc_read(txd, 0, &word);142138143139 /*144140 * Remove the descriptor data from the buffer.···165169 rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);166170167171 /*168168- * If the data queue was full before the txdone handler169169- * we must make sure the packet queue in the mac80211 stack172172+ * If the data queue was below the threshold before the txdone173173+ * handler we must make sure the packet queue in the mac80211 stack170174 * is reenabled when the txdone handler has finished.171175 */172172- if (!rt2x00queue_full(entry->queue))176176+ if (!rt2x00queue_threshold(entry->queue))173177 ieee80211_wake_queue(rt2x00dev->hw, qid);174178}175179176176-int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev,177177- struct data_queue *queue, struct sk_buff *skb)180180+int rt2x00usb_write_tx_data(struct queue_entry *entry)178181{182182+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;179183 struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev);180180- struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);181184 struct queue_entry_priv_usb *entry_priv = entry->priv_data;182185 struct skb_frame_desc *skbdesc;183183- struct txentry_desc txdesc;184186 u32 length;185185-186186- if (rt2x00queue_full(queue))187187- return -EINVAL;188188-189189- if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) {190190- ERROR(rt2x00dev,191191- "Arrived at non-free entry in the non-full queue %d.\n"192192- "Please file bug report to %s.\n",193193- entry->queue->qid, DRV_PROJECT);194194- return -EINVAL;195195- }196196-197197- /*198198- * Copy all TX descriptor information into txdesc,199199- * after that we are free to use the skb->cb array200200- * for our information.201201- */202202- entry->skb = skb;203203- rt2x00queue_create_tx_descriptor(entry, &txdesc);204187205188 /*206189 * Add the descriptor in front of the skb.207190 */208208- skb_push(skb, queue->desc_size);209209- memset(skb->data, 0, queue->desc_size);191191+ skb_push(entry->skb, entry->queue->desc_size);192192+ memset(entry->skb->data, 0, entry->queue->desc_size);210193211194 /*212195 * Fill in skb descriptor213196 */214214- skbdesc = get_skb_frame_desc(skb);197197+ skbdesc = get_skb_frame_desc(entry->skb);215198 memset(skbdesc, 0, sizeof(*skbdesc));216216- skbdesc->data = skb->data + queue->desc_size;217217- skbdesc->data_len = skb->len - queue->desc_size;218218- skbdesc->desc = skb->data;219219- skbdesc->desc_len = queue->desc_size;199199+ skbdesc->desc = entry->skb->data;200200+ skbdesc->desc_len = entry->queue->desc_size;220201 skbdesc->entry = entry;221221-222222- rt2x00queue_write_tx_descriptor(entry, &txdesc);223202224203 /*225204 * USB devices cannot blindly pass the skb->len as the226205 * length of the data to usb_fill_bulk_urb. Pass the skb227206 * to the driver to determine what the length should be.228207 */229229- length = rt2x00dev->ops->lib->get_tx_data_len(rt2x00dev, skb);208208+ length = rt2x00dev->ops->lib->get_tx_data_len(rt2x00dev, entry->skb);230209231231- /*232232- * Initialize URB and send the frame to the device.233233- */234234- __set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);235235- usb_fill_bulk_urb(entry_priv->urb, usb_dev, usb_sndbulkpipe(usb_dev, 1),236236- skb->data, length, rt2x00usb_interrupt_txdone, entry);237237- usb_submit_urb(entry_priv->urb, GFP_ATOMIC);238238-239239- rt2x00queue_index_inc(queue, Q_INDEX);210210+ usb_fill_bulk_urb(entry_priv->urb, usb_dev,211211+ usb_sndbulkpipe(usb_dev, 1),212212+ entry->skb->data, length,213213+ rt2x00usb_interrupt_txdone, entry);240214241215 return 0;242216}243217EXPORT_SYMBOL_GPL(rt2x00usb_write_tx_data);244218219219+static inline void rt2x00usb_kick_tx_entry(struct queue_entry *entry)220220+{221221+ struct queue_entry_priv_usb *entry_priv = entry->priv_data;222222+223223+ if (__test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags))224224+ usb_submit_urb(entry_priv->urb, GFP_ATOMIC);225225+}226226+227227+void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,228228+ const enum data_queue_qid qid)229229+{230230+ struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, qid);231231+ unsigned long irqflags;232232+ unsigned int index;233233+ unsigned int index_done;234234+ unsigned int i;235235+236236+ /*237237+ * Only protect the range we are going to loop over,238238+ * if during our loop a extra entry is set to pending239239+ * it should not be kicked during this run, since it240240+ * is part of another TX operation.241241+ */242242+ spin_lock_irqsave(&queue->lock, irqflags);243243+ index = queue->index[Q_INDEX];244244+ index_done = queue->index[Q_INDEX_DONE];245245+ spin_unlock_irqrestore(&queue->lock, irqflags);246246+247247+ /*248248+ * Start from the TX done pointer, this guarentees that we will249249+ * send out all frames in the correct order.250250+ */251251+ if (index_done < index) {252252+ for (i = index_done; i < index; i++)253253+ rt2x00usb_kick_tx_entry(&queue->entries[i]);254254+ } else {255255+ for (i = index_done; i < queue->limit; i++)256256+ rt2x00usb_kick_tx_entry(&queue->entries[i]);257257+258258+ for (i = 0; i < index; i++)259259+ rt2x00usb_kick_tx_entry(&queue->entries[i]);260260+ }261261+}262262+EXPORT_SYMBOL_GPL(rt2x00usb_kick_tx_queue);263263+245264/*246265 * RX data handlers.247266 */248248-static struct sk_buff* rt2x00usb_alloc_rxskb(struct data_queue *queue)249249-{250250- struct sk_buff *skb;251251- unsigned int frame_size;252252- unsigned int reserved_size;253253-254254- /*255255- * The frame size includes descriptor size, because the256256- * hardware directly receive the frame into the skbuffer.257257- */258258- frame_size = queue->data_size + queue->desc_size;259259-260260- /*261261- * For the allocation we should keep a few things in mind:262262- * 1) 4byte alignment of 802.11 payload263263- *264264- * For (1) we need at most 4 bytes to guarentee the correct265265- * alignment. We are going to optimize the fact that the chance266266- * that the 802.11 header_size % 4 == 2 is much bigger then267267- * anything else. However since we need to move the frame up268268- * to 3 bytes to the front, which means we need to preallocate269269- * 6 bytes.270270- */271271- reserved_size = 6;272272-273273- /*274274- * Allocate skbuffer.275275- */276276- skb = dev_alloc_skb(frame_size + reserved_size);277277- if (!skb)278278- return NULL;279279-280280- skb_reserve(skb, reserved_size);281281- skb_put(skb, frame_size);282282-283283- return skb;284284-}285285-286267static void rt2x00usb_interrupt_rxdone(struct urb *urb)287268{288269 struct queue_entry *entry = (struct queue_entry *)urb->context;···267294 struct sk_buff *skb;268295 struct skb_frame_desc *skbdesc;269296 struct rxdone_entry_desc rxdesc;270270- unsigned int header_size;271271- unsigned int align;297297+ u8 rxd[32];272298273299 if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) ||274300 !test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))···287315 skbdesc = get_skb_frame_desc(entry->skb);288316 memset(skbdesc, 0, sizeof(*skbdesc));289317 skbdesc->entry = entry;318318+ skbdesc->desc = rxd;319319+ skbdesc->desc_len = entry->queue->desc_size;290320291321 memset(&rxdesc, 0, sizeof(rxdesc));292322 rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc);293293-294294- header_size = ieee80211_get_hdrlen_from_skb(entry->skb);295295-296296- /*297297- * The data behind the ieee80211 header must be298298- * aligned on a 4 byte boundary. We already reserved299299- * 2 bytes for header_size % 4 == 2 optimization.300300- * To determine the number of bytes which the data301301- * should be moved to the left, we must add these302302- * 2 bytes to the header_size.303303- */304304- align = (header_size + 2) % 4;305305-306306- if (align) {307307- skb_push(entry->skb, align);308308- /* Move entire frame in 1 command */309309- memmove(entry->skb->data, entry->skb->data + align,310310- rxdesc.size);311311- }312312-313313- /* Update data pointers, trim buffer to correct size */314314- skbdesc->data = entry->skb->data;315315- skb_trim(entry->skb, rxdesc.size);316323317324 /*318325 * Allocate a new sk buffer to replace the current one.319326 * If allocation fails, we should drop the current frame320327 * so we can recycle the existing sk buffer for the new frame.321328 */322322- skb = rt2x00usb_alloc_rxskb(entry->queue);329329+ skb = rt2x00queue_alloc_rxskb(entry->queue);323330 if (!skb)324331 goto skip_entry;325332···470519 */471520 entry_size = rt2x00dev->rx->data_size + rt2x00dev->rx->desc_size;472521 for (i = 0; i < rt2x00dev->rx->limit; i++) {473473- skb = rt2x00usb_alloc_rxskb(rt2x00dev->rx);522522+ skb = rt2x00queue_alloc_rxskb(rt2x00dev->rx);474523 if (!skb)475524 goto exit;476525
+18-4
drivers/net/wireless/rt2x00/rt2x00usb.h
···212212 */213213void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev);214214215215-/*216216- * TX data handlers.215215+/**216216+ * rt2x00usb_write_tx_data - Initialize URB for TX operation217217+ * @entry: The entry where the frame is located218218+ *219219+ * This function will initialize the URB and skb descriptor220220+ * to prepare the entry for the actual TX operation.217221 */218218-int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev,219219- struct data_queue *queue, struct sk_buff *skb);222222+int rt2x00usb_write_tx_data(struct queue_entry *entry);220223221224/**222225 * struct queue_entry_priv_usb: Per entry USB specific information···247244 unsigned int guardian_data;248245 struct urb *guardian_urb;249246};247247+248248+/**249249+ * rt2x00usb_kick_tx_queue - Kick data queue250250+ * @rt2x00dev: Pointer to &struct rt2x00_dev251251+ * @qid: Data queue to kick252252+ *253253+ * This will walk through all entries of the queue and push all pending254254+ * frames to the hardware as a single burst.255255+ */256256+void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,257257+ const enum data_queue_qid qid);250258251259/*252260 * Device initialization handlers.
···3939 * Signal information.4040 * Defaul offset is required for RSSI <-> dBm conversion.4141 */4242-#define MAX_SIGNAL 1004343-#define MAX_RX_SSI -14442#define DEFAULT_RSSI_OFFSET 12045434644/*
+57-65
drivers/net/wireless/rt2x00/rt73usb.c
···335335336336 return 0;337337}338338+339339+static void rt73usb_init_led(struct rt2x00_dev *rt2x00dev,340340+ struct rt2x00_led *led,341341+ enum led_type type)342342+{343343+ led->rt2x00dev = rt2x00dev;344344+ led->type = type;345345+ led->led_dev.brightness_set = rt73usb_brightness_set;346346+ led->led_dev.blink_set = rt73usb_blink_set;347347+ led->flags = LED_INITIALIZED;348348+}338349#endif /* CONFIG_RT73USB_LEDS */339350340351/*···10951084 return 0;10961085}1097108610871087+static int rt73usb_wait_bbp_ready(struct rt2x00_dev *rt2x00dev)10881088+{10891089+ unsigned int i;10901090+ u8 value;10911091+10921092+ for (i = 0; i < REGISTER_BUSY_COUNT; i++) {10931093+ rt73usb_bbp_read(rt2x00dev, 0, &value);10941094+ if ((value != 0xff) && (value != 0x00))10951095+ return 0;10961096+ udelay(REGISTER_BUSY_DELAY);10971097+ }10981098+10991099+ ERROR(rt2x00dev, "BBP register access failed, aborting.\n");11001100+ return -EACCES;11011101+}11021102+10981103static int rt73usb_init_bbp(struct rt2x00_dev *rt2x00dev)10991104{11001105 unsigned int i;···11181091 u8 reg_id;11191092 u8 value;1120109311211121- for (i = 0; i < REGISTER_BUSY_COUNT; i++) {11221122- rt73usb_bbp_read(rt2x00dev, 0, &value);11231123- if ((value != 0xff) && (value != 0x00))11241124- goto continue_csr_init;11251125- NOTICE(rt2x00dev, "Waiting for BBP register.\n");11261126- udelay(REGISTER_BUSY_DELAY);11271127- }10941094+ if (unlikely(rt73usb_wait_bbp_ready(rt2x00dev)))10951095+ return -EACCES;1128109611291129- ERROR(rt2x00dev, "BBP register access failed, aborting.\n");11301130- return -EACCES;11311131-11321132-continue_csr_init:11331097 rt73usb_bbp_write(rt2x00dev, 3, 0x80);11341098 rt73usb_bbp_write(rt2x00dev, 15, 0x30);11351099 rt73usb_bbp_write(rt2x00dev, 21, 0xc8);···1170115211711153 rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®);11721154 rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX,11731173- state == STATE_RADIO_RX_OFF);11551155+ (state == STATE_RADIO_RX_OFF) ||11561156+ (state == STATE_RADIO_RX_OFF_LINK));11741157 rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg);11751158}11761159···11801161 /*11811162 * Initialize all registers.11821163 */11831183- if (rt73usb_init_registers(rt2x00dev) ||11841184- rt73usb_init_bbp(rt2x00dev)) {11851185- ERROR(rt2x00dev, "Register initialization failed.\n");11641164+ if (unlikely(rt73usb_init_registers(rt2x00dev) ||11651165+ rt73usb_init_bbp(rt2x00dev)))11861166 return -EIO;11871187- }1188116711891168 return 0;11901169}···12041187 u32 reg;12051188 unsigned int i;12061189 char put_to_sleep;12071207- char current_state;1208119012091191 put_to_sleep = (state != STATE_AWAKE);12101192···12191203 */12201204 for (i = 0; i < REGISTER_BUSY_COUNT; i++) {12211205 rt73usb_register_read(rt2x00dev, MAC_CSR12, ®);12221222- current_state =12231223- rt2x00_get_field32(reg, MAC_CSR12_BBP_CURRENT_STATE);12241224- if (current_state == !put_to_sleep)12061206+ state = rt2x00_get_field32(reg, MAC_CSR12_BBP_CURRENT_STATE);12071207+ if (state == !put_to_sleep)12251208 return 0;12261209 msleep(10);12271210 }12281228-12291229- NOTICE(rt2x00dev, "Device failed to enter state %d, "12301230- "current device state %d.\n", !put_to_sleep, current_state);1231121112321212 return -EBUSY;12331213}···12421230 break;12431231 case STATE_RADIO_RX_ON:12441232 case STATE_RADIO_RX_ON_LINK:12451245- rt73usb_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);12461246- break;12471233 case STATE_RADIO_RX_OFF:12481234 case STATE_RADIO_RX_OFF_LINK:12491249- rt73usb_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);12351235+ rt73usb_toggle_rx(rt2x00dev, state);12361236+ break;12371237+ case STATE_RADIO_IRQ_ON:12381238+ case STATE_RADIO_IRQ_OFF:12391239+ /* No support, but no error either */12501240 break;12511241 case STATE_DEEP_SLEEP:12521242 case STATE_SLEEP:···12601246 retval = -ENOTSUPP;12611247 break;12621248 }12491249+12501250+ if (unlikely(retval))12511251+ ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n",12521252+ state, retval);1263125312641254 return retval;12651255}···13201302 rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,13211303 test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags));13221304 rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0);13231323- rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len);13051305+ rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT,13061306+ skb->len - skbdesc->desc_len);13241307 rt2x00_set_field32(&word, TXD_W0_BURST2,13251308 test_bit(ENTRY_TXD_BURST, &txdesc->flags));13261309 rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE);···13511332{13521333 u32 reg;1353133413541354- if (queue != QID_BEACON)13351335+ if (queue != QID_BEACON) {13361336+ rt2x00usb_kick_tx_queue(rt2x00dev, queue);13551337 return;13381338+ }1356133913571340 /*13581341 * For Wi-Fi faily generated beacons between participating stations.···14281407 u32 word1;1429140814301409 /*14311431- * Copy descriptor to the skb->cb array, this has 2 benefits:14321432- * 1) Each descriptor word is 4 byte aligned.14331433- * 2) Descriptor is safe from moving of frame data in rt2x00usb.14101410+ * Copy descriptor to the skbdesc->desc buffer, making it safe from moving of14111411+ * frame data in rt2x00usb.14341412 */14351435- skbdesc->desc_len =14361436- min_t(u16, entry->queue->desc_size, sizeof(entry->skb->cb));14371437- memcpy(entry->skb->cb, rxd, skbdesc->desc_len);14381438- skbdesc->desc = entry->skb->cb;14131413+ memcpy(skbdesc->desc, rxd, skbdesc->desc_len);14391414 rxd = (__le32 *)skbdesc->desc;1440141514411416 /*···14631446 */14641447 skb_pull(entry->skb, entry->queue->desc_size);14651448 skb_trim(entry->skb, rxdesc->size);14661466- skbdesc->data = entry->skb->data;14671467- skbdesc->data_len = rxdesc->size;14681449}1469145014701451/*···16351620#ifdef CONFIG_RT73USB_LEDS16361621 rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom);1637162216381638- rt2x00dev->led_radio.rt2x00dev = rt2x00dev;16391639- rt2x00dev->led_radio.type = LED_TYPE_RADIO;16401640- rt2x00dev->led_radio.led_dev.brightness_set =16411641- rt73usb_brightness_set;16421642- rt2x00dev->led_radio.led_dev.blink_set =16431643- rt73usb_blink_set;16441644- rt2x00dev->led_radio.flags = LED_INITIALIZED;16451645-16461646- rt2x00dev->led_assoc.rt2x00dev = rt2x00dev;16471647- rt2x00dev->led_assoc.type = LED_TYPE_ASSOC;16481648- rt2x00dev->led_assoc.led_dev.brightness_set =16491649- rt73usb_brightness_set;16501650- rt2x00dev->led_assoc.led_dev.blink_set =16511651- rt73usb_blink_set;16521652- rt2x00dev->led_assoc.flags = LED_INITIALIZED;16531653-16541654- if (value == LED_MODE_SIGNAL_STRENGTH) {16551655- rt2x00dev->led_qual.rt2x00dev = rt2x00dev;16561656- rt2x00dev->led_qual.type = LED_TYPE_QUALITY;16571657- rt2x00dev->led_qual.led_dev.brightness_set =16581658- rt73usb_brightness_set;16591659- rt2x00dev->led_qual.led_dev.blink_set =16601660- rt73usb_blink_set;16611661- rt2x00dev->led_qual.flags = LED_INITIALIZED;16621662- }16231623+ rt73usb_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO);16241624+ rt73usb_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC);16251625+ if (value == LED_MODE_SIGNAL_STRENGTH)16261626+ rt73usb_init_led(rt2x00dev, &rt2x00dev->led_qual,16271627+ LED_TYPE_QUALITY);1663162816641629 rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_LED_MODE, value);16651630 rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_0,···19751980 */19761981 skbdesc = get_skb_frame_desc(skb);19771982 memset(skbdesc, 0, sizeof(*skbdesc));19781978- skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED;19791979- skbdesc->data = skb->data + intf->beacon->queue->desc_size;19801980- skbdesc->data_len = skb->len - intf->beacon->queue->desc_size;19811983 skbdesc->desc = skb->data;19821984 skbdesc->desc_len = intf->beacon->queue->desc_size;19831985 skbdesc->entry = intf->beacon;
-2
drivers/net/wireless/rt2x00/rt73usb.h
···3939 * Signal information.4040 * Defaul offset is required for RSSI <-> dBm conversion.4141 */4242-#define MAX_SIGNAL 1004343-#define MAX_RX_SSI -14442#define DEFAULT_RSSI_OFFSET 12045434644/*
+1-1
drivers/net/wireless/rtl8187_dev.c
···181181 flags |= RTL8187_TX_FLAG_NO_ENCRYPT;182182183183 flags |= ieee80211_get_tx_rate(dev, info)->hw_value << 24;184184- if (ieee80211_get_morefrag((struct ieee80211_hdr *)skb->data))184184+ if (ieee80211_has_morefrags(((struct ieee80211_hdr *)skb->data)->frame_control))185185 flags |= RTL8187_TX_FLAG_MORE_FRAG;186186 if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) {187187 flags |= RTL8187_TX_FLAG_RTS;
+375-32
include/linux/ieee80211.h
···98989999#define IEEE80211_MAX_SSID_LEN 32100100#define IEEE80211_MAX_MESH_ID_LEN 32101101+#define IEEE80211_QOS_CTL_LEN 2101102102103struct ieee80211_hdr {103104 __le16 frame_control;···110109 u8 addr4[6];111110} __attribute__ ((packed));112111112112+/**113113+ * ieee80211_has_tods - check if IEEE80211_FCTL_TODS is set114114+ * @fc: frame control bytes in little-endian byteorder115115+ */116116+static inline int ieee80211_has_tods(__le16 fc)117117+{118118+ return (fc & cpu_to_le16(IEEE80211_FCTL_TODS)) != 0;119119+}120120+121121+/**122122+ * ieee80211_has_fromds - check if IEEE80211_FCTL_FROMDS is set123123+ * @fc: frame control bytes in little-endian byteorder124124+ */125125+static inline int ieee80211_has_fromds(__le16 fc)126126+{127127+ return (fc & cpu_to_le16(IEEE80211_FCTL_FROMDS)) != 0;128128+}129129+130130+/**131131+ * ieee80211_has_a4 - check if IEEE80211_FCTL_TODS and IEEE80211_FCTL_FROMDS are set132132+ * @fc: frame control bytes in little-endian byteorder133133+ */134134+static inline int ieee80211_has_a4(__le16 fc)135135+{136136+ __le16 tmp = cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS);137137+ return (fc & tmp) == tmp;138138+}139139+140140+/**141141+ * ieee80211_has_morefrags - check if IEEE80211_FCTL_MOREFRAGS is set142142+ * @fc: frame control bytes in little-endian byteorder143143+ */144144+static inline int ieee80211_has_morefrags(__le16 fc)145145+{146146+ return (fc & cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) != 0;147147+}148148+149149+/**150150+ * ieee80211_has_retry - check if IEEE80211_FCTL_RETRY is set151151+ * @fc: frame control bytes in little-endian byteorder152152+ */153153+static inline int ieee80211_has_retry(__le16 fc)154154+{155155+ return (fc & cpu_to_le16(IEEE80211_FCTL_RETRY)) != 0;156156+}157157+158158+/**159159+ * ieee80211_has_pm - check if IEEE80211_FCTL_PM is set160160+ * @fc: frame control bytes in little-endian byteorder161161+ */162162+static inline int ieee80211_has_pm(__le16 fc)163163+{164164+ return (fc & cpu_to_le16(IEEE80211_FCTL_PM)) != 0;165165+}166166+167167+/**168168+ * ieee80211_has_moredata - check if IEEE80211_FCTL_MOREDATA is set169169+ * @fc: frame control bytes in little-endian byteorder170170+ */171171+static inline int ieee80211_has_moredata(__le16 fc)172172+{173173+ return (fc & cpu_to_le16(IEEE80211_FCTL_MOREDATA)) != 0;174174+}175175+176176+/**177177+ * ieee80211_has_protected - check if IEEE80211_FCTL_PROTECTED is set178178+ * @fc: frame control bytes in little-endian byteorder179179+ */180180+static inline int ieee80211_has_protected(__le16 fc)181181+{182182+ return (fc & cpu_to_le16(IEEE80211_FCTL_PROTECTED)) != 0;183183+}184184+185185+/**186186+ * ieee80211_has_order - check if IEEE80211_FCTL_ORDER is set187187+ * @fc: frame control bytes in little-endian byteorder188188+ */189189+static inline int ieee80211_has_order(__le16 fc)190190+{191191+ return (fc & cpu_to_le16(IEEE80211_FCTL_ORDER)) != 0;192192+}193193+194194+/**195195+ * ieee80211_is_mgmt - check if type is IEEE80211_FTYPE_MGMT196196+ * @fc: frame control bytes in little-endian byteorder197197+ */198198+static inline int ieee80211_is_mgmt(__le16 fc)199199+{200200+ return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE)) ==201201+ cpu_to_le16(IEEE80211_FTYPE_MGMT);202202+}203203+204204+/**205205+ * ieee80211_is_ctl - check if type is IEEE80211_FTYPE_CTL206206+ * @fc: frame control bytes in little-endian byteorder207207+ */208208+static inline int ieee80211_is_ctl(__le16 fc)209209+{210210+ return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE)) ==211211+ cpu_to_le16(IEEE80211_FTYPE_CTL);212212+}213213+214214+/**215215+ * ieee80211_is_data - check if type is IEEE80211_FTYPE_DATA216216+ * @fc: frame control bytes in little-endian byteorder217217+ */218218+static inline int ieee80211_is_data(__le16 fc)219219+{220220+ return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE)) ==221221+ cpu_to_le16(IEEE80211_FTYPE_DATA);222222+}223223+224224+/**225225+ * ieee80211_is_data_qos - check if type is IEEE80211_FTYPE_DATA and IEEE80211_STYPE_QOS_DATA is set226226+ * @fc: frame control bytes in little-endian byteorder227227+ */228228+static inline int ieee80211_is_data_qos(__le16 fc)229229+{230230+ /*231231+ * mask with QOS_DATA rather than IEEE80211_FCTL_STYPE as we just need232232+ * to check the one bit233233+ */234234+ return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_STYPE_QOS_DATA)) ==235235+ cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA);236236+}237237+238238+/**239239+ * ieee80211_is_data_present - check if type is IEEE80211_FTYPE_DATA and has data240240+ * @fc: frame control bytes in little-endian byteorder241241+ */242242+static inline int ieee80211_is_data_present(__le16 fc)243243+{244244+ /*245245+ * mask with 0x40 and test that that bit is clear to only return true246246+ * for the data-containing substypes.247247+ */248248+ return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | 0x40)) ==249249+ cpu_to_le16(IEEE80211_FTYPE_DATA);250250+}251251+252252+/**253253+ * ieee80211_is_assoc_req - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_ASSOC_REQ254254+ * @fc: frame control bytes in little-endian byteorder255255+ */256256+static inline int ieee80211_is_assoc_req(__le16 fc)257257+{258258+ return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==259259+ cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ASSOC_REQ);260260+}261261+262262+/**263263+ * ieee80211_is_assoc_resp - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_ASSOC_RESP264264+ * @fc: frame control bytes in little-endian byteorder265265+ */266266+static inline int ieee80211_is_assoc_resp(__le16 fc)267267+{268268+ return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==269269+ cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ASSOC_RESP);270270+}271271+272272+/**273273+ * ieee80211_is_reassoc_req - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_REASSOC_REQ274274+ * @fc: frame control bytes in little-endian byteorder275275+ */276276+static inline int ieee80211_is_reassoc_req(__le16 fc)277277+{278278+ return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==279279+ cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_REASSOC_REQ);280280+}281281+282282+/**283283+ * ieee80211_is_reassoc_resp - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_REASSOC_RESP284284+ * @fc: frame control bytes in little-endian byteorder285285+ */286286+static inline int ieee80211_is_reassoc_resp(__le16 fc)287287+{288288+ return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==289289+ cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_REASSOC_RESP);290290+}291291+292292+/**293293+ * ieee80211_is_probe_req - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_PROBE_REQ294294+ * @fc: frame control bytes in little-endian byteorder295295+ */296296+static inline int ieee80211_is_probe_req(__le16 fc)297297+{298298+ return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==299299+ cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ);300300+}301301+302302+/**303303+ * ieee80211_is_probe_resp - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_PROBE_RESP304304+ * @fc: frame control bytes in little-endian byteorder305305+ */306306+static inline int ieee80211_is_probe_resp(__le16 fc)307307+{308308+ return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==309309+ cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);310310+}311311+312312+/**313313+ * ieee80211_is_beacon - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_BEACON314314+ * @fc: frame control bytes in little-endian byteorder315315+ */316316+static inline int ieee80211_is_beacon(__le16 fc)317317+{318318+ return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==319319+ cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);320320+}321321+322322+/**323323+ * ieee80211_is_atim - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_ATIM324324+ * @fc: frame control bytes in little-endian byteorder325325+ */326326+static inline int ieee80211_is_atim(__le16 fc)327327+{328328+ return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==329329+ cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ATIM);330330+}331331+332332+/**333333+ * ieee80211_is_disassoc - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_DISASSOC334334+ * @fc: frame control bytes in little-endian byteorder335335+ */336336+static inline int ieee80211_is_disassoc(__le16 fc)337337+{338338+ return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==339339+ cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_DISASSOC);340340+}341341+342342+/**343343+ * ieee80211_is_auth - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_AUTH344344+ * @fc: frame control bytes in little-endian byteorder345345+ */346346+static inline int ieee80211_is_auth(__le16 fc)347347+{348348+ return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==349349+ cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH);350350+}351351+352352+/**353353+ * ieee80211_is_deauth - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_DEAUTH354354+ * @fc: frame control bytes in little-endian byteorder355355+ */356356+static inline int ieee80211_is_deauth(__le16 fc)357357+{358358+ return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==359359+ cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_DEAUTH);360360+}361361+362362+/**363363+ * ieee80211_is_action - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_ACTION364364+ * @fc: frame control bytes in little-endian byteorder365365+ */366366+static inline int ieee80211_is_action(__le16 fc)367367+{368368+ return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==369369+ cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION);370370+}371371+372372+/**373373+ * ieee80211_is_back_req - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_BACK_REQ374374+ * @fc: frame control bytes in little-endian byteorder375375+ */376376+static inline int ieee80211_is_back_req(__le16 fc)377377+{378378+ return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==379379+ cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_BACK_REQ);380380+}381381+382382+/**383383+ * ieee80211_is_back - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_BACK384384+ * @fc: frame control bytes in little-endian byteorder385385+ */386386+static inline int ieee80211_is_back(__le16 fc)387387+{388388+ return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==389389+ cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_BACK);390390+}391391+392392+/**393393+ * ieee80211_is_pspoll - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_PSPOLL394394+ * @fc: frame control bytes in little-endian byteorder395395+ */396396+static inline int ieee80211_is_pspoll(__le16 fc)397397+{398398+ return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==399399+ cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL);400400+}401401+402402+/**403403+ * ieee80211_is_rts - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_RTS404404+ * @fc: frame control bytes in little-endian byteorder405405+ */406406+static inline int ieee80211_is_rts(__le16 fc)407407+{408408+ return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==409409+ cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);410410+}411411+412412+/**413413+ * ieee80211_is_cts - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_CTS414414+ * @fc: frame control bytes in little-endian byteorder415415+ */416416+static inline int ieee80211_is_cts(__le16 fc)417417+{418418+ return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==419419+ cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS);420420+}421421+422422+/**423423+ * ieee80211_is_ack - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_ACK424424+ * @fc: frame control bytes in little-endian byteorder425425+ */426426+static inline int ieee80211_is_ack(__le16 fc)427427+{428428+ return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==429429+ cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_ACK);430430+}431431+432432+/**433433+ * ieee80211_is_cfend - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_CFEND434434+ * @fc: frame control bytes in little-endian byteorder435435+ */436436+static inline int ieee80211_is_cfend(__le16 fc)437437+{438438+ return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==439439+ cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CFEND);440440+}441441+442442+/**443443+ * ieee80211_is_cfendack - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_CFENDACK444444+ * @fc: frame control bytes in little-endian byteorder445445+ */446446+static inline int ieee80211_is_cfendack(__le16 fc)447447+{448448+ return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==449449+ cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CFENDACK);450450+}451451+452452+/**453453+ * ieee80211_is_nullfunc - check if FTYPE=IEEE80211_FTYPE_DATA and STYPE=IEEE80211_STYPE_NULLFUNC454454+ * @fc: frame control bytes in little-endian byteorder455455+ */456456+static inline int ieee80211_is_nullfunc(__le16 fc)457457+{458458+ return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) ==459459+ cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC);460460+}113461114462struct ieee80211s_hdr {115463 u8 flags;···670320#define IEEE80211_HT_CAP_MCS_TX_UEQM 0x10671321/* 802.11n HT IE masks */672322#define IEEE80211_HT_IE_CHA_SEC_OFFSET 0x03323323+#define IEEE80211_HT_IE_CHA_SEC_NONE 0x00673324#define IEEE80211_HT_IE_CHA_SEC_ABOVE 0x01674325#define IEEE80211_HT_IE_CHA_SEC_BELOW 0x03675326#define IEEE80211_HT_IE_CHA_WIDTH 0x04···903552#define WLAN_MAX_KEY_LEN 32904553905554/**555555+ * ieee80211_get_qos_ctl - get pointer to qos control bytes556556+ * @hdr: the frame557557+ *558558+ * The qos ctrl bytes come after the frame_control, duration, seq_num559559+ * and 3 or 4 addresses of length ETH_ALEN.560560+ * 3 addr: 2 + 2 + 2 + 3*6 = 24561561+ * 4 addr: 2 + 2 + 2 + 4*6 = 30562562+ */563563+static inline u8 *ieee80211_get_qos_ctl(struct ieee80211_hdr *hdr)564564+{565565+ if (ieee80211_has_a4(hdr->frame_control))566566+ return (u8 *)hdr + 30;567567+ else568568+ return (u8 *)hdr + 24;569569+}570570+571571+/**906572 * ieee80211_get_SA - get pointer to SA573573+ * @hdr: the frame907574 *908575 * Given an 802.11 frame, this function returns the offset909576 * to the source address (SA). It does not verify that the910577 * header is long enough to contain the address, and the911578 * header must be long enough to contain the frame control912579 * field.913913- *914914- * @hdr: the frame915580 */916581static inline u8 *ieee80211_get_SA(struct ieee80211_hdr *hdr)917582{918918- __le16 fc = hdr->frame_control;919919- fc &= cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS);920920-921921- switch (fc) {922922- case __constant_cpu_to_le16(IEEE80211_FCTL_FROMDS):923923- return hdr->addr3;924924- case __constant_cpu_to_le16(IEEE80211_FCTL_TODS|IEEE80211_FCTL_FROMDS):583583+ if (ieee80211_has_a4(hdr->frame_control))925584 return hdr->addr4;926926- default:927927- return hdr->addr2;928928- }585585+ if (ieee80211_has_fromds(hdr->frame_control))586586+ return hdr->addr3;587587+ return hdr->addr2;929588}930589931590/**932591 * ieee80211_get_DA - get pointer to DA592592+ * @hdr: the frame933593 *934594 * Given an 802.11 frame, this function returns the offset935595 * to the destination address (DA). It does not verify that936596 * the header is long enough to contain the address, and the937597 * header must be long enough to contain the frame control938598 * field.939939- *940940- * @hdr: the frame941599 */942600static inline u8 *ieee80211_get_DA(struct ieee80211_hdr *hdr)943601{944944- __le16 fc = hdr->frame_control;945945- fc &= cpu_to_le16(IEEE80211_FCTL_TODS);946946-947947- if (fc)602602+ if (ieee80211_has_tods(hdr->frame_control))948603 return hdr->addr3;949604 else950605 return hdr->addr1;951951-}952952-953953-/**954954- * ieee80211_get_morefrag - determine whether the MOREFRAGS bit is set955955- *956956- * This function determines whether the "more fragments" bit is set957957- * in the frame.958958- *959959- * @hdr: the frame960960- */961961-static inline int ieee80211_get_morefrag(struct ieee80211_hdr *hdr)962962-{963963- __le16 fc = hdr->frame_control;964964- return !!(fc & cpu_to_le16(IEEE80211_FCTL_MOREFRAGS));965606}966607967608#endif /* IEEE80211_H */
+4-4
include/linux/nl80211.h
···122122 NL80211_CMD_NEW_STATION,123123 NL80211_CMD_DEL_STATION,124124125125- /* add commands here */126126-127125 NL80211_CMD_GET_MPATH,128126 NL80211_CMD_SET_MPATH,129127 NL80211_CMD_NEW_MPATH,130128 NL80211_CMD_DEL_MPATH,129129+130130+ /* add commands here */131131132132 /* used to define NL80211_CMD_MAX below */133133 __NL80211_CMD_AFTER_LAST,···230230231231 NL80211_ATTR_MNTR_FLAGS,232232233233- /* add attributes here, update the policy in nl80211.c */234234-235233 NL80211_ATTR_MESH_ID,236234 NL80211_ATTR_STA_PLINK_ACTION,237235 NL80211_ATTR_MPATH_NEXT_HOP,238236 NL80211_ATTR_MPATH_INFO,237237+238238+ /* add attributes here, update the policy in nl80211.c */239239240240 __NL80211_ATTR_AFTER_LAST,241241 NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1
+7-1
include/net/mac80211.h
···15351535 *15361536 * @skb: the frame15371537 */15381538-int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb);15381538+unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb);1539153915401540/**15411541 * ieee80211_get_hdrlen - get header length from frame control···15461546 * @fc: the frame control field (in CPU endianness)15471547 */15481548int ieee80211_get_hdrlen(u16 fc);15491549+15501550+/**15511551+ * ieee80211_hdrlen - get header length in bytes from frame control15521552+ * @fc: frame control field in little-endian format15531553+ */15541554+unsigned int ieee80211_hdrlen(__le16 fc);1549155515501556/**15511557 * ieee80211_get_tkip_key - get a TKIP rc4 for skb
···660660661661 /*662662 * Warn when submitting a fragmented A-MPDU frame and drop it.663663- * This is an error and needs to be fixed elsewhere, but when664664- * done needs to take care of monitor interfaces (injection)665665- * etc.663663+ * This scenario is handled in __ieee80211_tx_prepare but extra664664+ * caution taken here as fragmented ampdu may cause Tx stop.666665 */667666 if (WARN_ON(tx->flags & IEEE80211_TX_CTL_AMPDU ||668667 skb_get_queue_mapping(tx->skb) >=···980981 if (tx->flags & IEEE80211_TX_FRAGMENTED) {981982 if ((tx->flags & IEEE80211_TX_UNICAST) &&982983 skb->len + FCS_LEN > local->fragmentation_threshold &&983983- !local->ops->set_frag_threshold)984984+ !local->ops->set_frag_threshold &&985985+ !(info->flags & IEEE80211_TX_CTL_AMPDU))984986 tx->flags |= IEEE80211_TX_FRAGMENTED;985987 else986988 tx->flags &= ~IEEE80211_TX_FRAGMENTED;
+55-26
net/mac80211/util.c
···4545u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len,4646 enum ieee80211_if_types type)4747{4848- u16 fc;4848+ __le16 fc = hdr->frame_control;49495050 /* drop ACK/CTS frames and incorrect hdr len (ctrl) */5151 if (len < 16)5252 return NULL;53535454- fc = le16_to_cpu(hdr->frame_control);5555-5656- switch (fc & IEEE80211_FCTL_FTYPE) {5757- case IEEE80211_FTYPE_DATA:5454+ if (ieee80211_is_data(fc)) {5855 if (len < 24) /* drop incorrect hdr len (data) */5956 return NULL;6060- switch (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) {6161- case IEEE80211_FCTL_TODS:6262- return hdr->addr1;6363- case (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS):5757+5858+ if (ieee80211_has_a4(fc))6459 return NULL;6565- case IEEE80211_FCTL_FROMDS:6060+ if (ieee80211_has_tods(fc))6161+ return hdr->addr1;6262+ if (ieee80211_has_fromds(fc))6663 return hdr->addr2;6767- case 0:6868- return hdr->addr3;6969- }7070- break;7171- case IEEE80211_FTYPE_MGMT:6464+6565+ return hdr->addr3;6666+ }6767+6868+ if (ieee80211_is_mgmt(fc)) {7269 if (len < 24) /* drop incorrect hdr len (mgmt) */7370 return NULL;7471 return hdr->addr3;7575- case IEEE80211_FTYPE_CTL:7676- if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)7272+ }7373+7474+ if (ieee80211_is_ctl(fc)) {7575+ if(ieee80211_is_pspoll(fc))7776 return hdr->addr1;7878- else if ((fc & IEEE80211_FCTL_STYPE) ==7979- IEEE80211_STYPE_BACK_REQ) {7777+7878+ if (ieee80211_is_back_req(fc)) {8079 switch (type) {8180 case IEEE80211_IF_TYPE_STA:8281 return hdr->addr2;···8384 case IEEE80211_IF_TYPE_VLAN:8485 return hdr->addr1;8586 default:8686- return NULL;8787+ break; /* fall through to the return */8788 }8889 }8989- else9090- return NULL;9190 }92919392 return NULL;···130133}131134EXPORT_SYMBOL(ieee80211_get_hdrlen);132135133133-int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb)136136+unsigned int ieee80211_hdrlen(__le16 fc)134137{135135- const struct ieee80211_hdr *hdr = (const struct ieee80211_hdr *) skb->data;136136- int hdrlen;138138+ unsigned int hdrlen = 24;139139+140140+ if (ieee80211_is_data(fc)) {141141+ if (ieee80211_has_a4(fc))142142+ hdrlen = 30;143143+ if (ieee80211_is_data_qos(fc))144144+ hdrlen += IEEE80211_QOS_CTL_LEN;145145+ goto out;146146+ }147147+148148+ if (ieee80211_is_ctl(fc)) {149149+ /*150150+ * ACK and CTS are 10 bytes, all others 16. To see how151151+ * to get this condition consider152152+ * subtype mask: 0b0000000011110000 (0x00F0)153153+ * ACK subtype: 0b0000000011010000 (0x00D0)154154+ * CTS subtype: 0b0000000011000000 (0x00C0)155155+ * bits that matter: ^^^ (0x00E0)156156+ * value of those: 0b0000000011000000 (0x00C0)157157+ */158158+ if ((fc & cpu_to_le16(0x00E0)) == cpu_to_le16(0x00C0))159159+ hdrlen = 10;160160+ else161161+ hdrlen = 16;162162+ }163163+out:164164+ return hdrlen;165165+}166166+EXPORT_SYMBOL(ieee80211_hdrlen);167167+168168+unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb)169169+{170170+ const struct ieee80211_hdr *hdr = (const struct ieee80211_hdr *)skb->data;171171+ unsigned int hdrlen;137172138173 if (unlikely(skb->len < 10))139174 return 0;140140- hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control));175175+ hdrlen = ieee80211_hdrlen(hdr->frame_control);141176 if (unlikely(hdrlen > skb->len))142177 return 0;143178 return hdrlen;
+5-13
net/mac80211/wme.c
···105105{106106 struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);107107 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;108108- unsigned short fc = le16_to_cpu(hdr->frame_control);109109- int qos;110108111111- /* see if frame is data or non data frame */112112- if (unlikely((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)) {109109+ if (!ieee80211_is_data(hdr->frame_control)) {113110 /* management frames go on AC_VO queue, but are sent114111 * without QoS control fields */115112 return 0;···116119 /* use AC from radiotap */117120 }118121119119- /* is this a QoS frame? */120120- qos = fc & IEEE80211_STYPE_QOS_DATA;121121-122122- if (!qos) {122122+ if (!ieee80211_is_data_qos(hdr->frame_control)) {123123 skb->priority = 0; /* required for correct WPA/11i MIC */124124 return ieee802_1d_to_ac[skb->priority];125125 }···145151 struct ieee80211_sched_data *q = qdisc_priv(qd);146152 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);147153 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;148148- unsigned short fc = le16_to_cpu(hdr->frame_control);149154 struct Qdisc *qdisc;150155 struct sta_info *sta;151156 int err, queue;···178185179186 /* now we know the 1d priority, fill in the QoS header if there is one180187 */181181- if (WLAN_FC_IS_QOS_DATA(fc)) {182182- u8 *p = skb->data + ieee80211_get_hdrlen(fc) - 2;188188+ if (ieee80211_is_data_qos(hdr->frame_control)) {189189+ u8 *p = ieee80211_get_qos_ctl(hdr);183190 u8 ack_policy = 0;184191 tid = skb->priority & QOS_CONTROL_TAG1D_MASK;185192 if (local->wifi_wme_noack_test)186193 ack_policy |= QOS_CONTROL_ACK_POLICY_NOACK <<187194 QOS_CONTROL_ACK_POLICY_SHIFT;188195 /* qos header is 2 bytes, second reserved */189189- *p = ack_policy | tid;190190- p++;196196+ *p++ = ack_policy | tid;191197 *p = 0;192198193199 rcu_read_lock();