···4141#include "iwl-power.h"42424343/*4444- * Setting power level allow the card to go to sleep when not busy4545- * there are three factor that decide the power level to go to, they4646- * are list here with its priority4747- * 1- critical_power_setting this will be set according to card temperature.4848- * 2- system_power_setting this will be set by system PM manager.4949- * 3- user_power_setting this will be set by user either by writing to sys or5050- * mac802114444+ * Setting power level allow the card to go to sleep when not busy.5145 *5252- * if system_power_setting and user_power_setting is set to auto5353- * the power level will be decided according to association status and battery5454- * status.4646+ * The power level is set to INDEX_1 (the least deep state) by4747+ * default, and will, in the future, be the deepest state unless4848+ * otherwise required by pm_qos network latency requirements.5549 *5050+ * Using INDEX_1 without pm_qos is ok because mac80211 will disable5151+ * PS when even checking every beacon for the TIM bit would exceed5252+ * the required latency.5653 */57545858-#define MSEC_TO_USEC 10245955#define IWL_POWER_RANGE_0_MAX (2)6056#define IWL_POWER_RANGE_1_MAX (10)615762586363-6464-#define IWL_POWER_ON_BATTERY IWL_POWER_INDEX_56565-#define IWL_POWER_ON_AC_DISASSOC IWL_POWER_MODE_CAM6666-#define IWL_POWER_ON_AC_ASSOC IWL_POWER_MODE_CAM6767-6868-6969-#define IWL_CT_KILL_TEMPERATURE 1107070-#define IWL_MIN_POWER_TEMPERATURE 1007171-#define IWL_REDUCED_POWER_TEMPERATURE 957272-5959+#define NOSLP cpu_to_le16(0), 0, 06060+#define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 06161+#define TU_TO_USEC 10246262+#define SLP_TOUT(T) cpu_to_le32((T) * TU_TO_USEC)6363+#define SLP_VEC(X0, X1, X2, X3, X4) {cpu_to_le32(X0), \6464+ cpu_to_le32(X1), \6565+ cpu_to_le32(X2), \6666+ cpu_to_le32(X3), \6767+ cpu_to_le32(X4)}7368/* default power management (not Tx power) table values */7474-/* for TIM 0-10 */7575-static struct iwl_power_vec_entry range_0[IWL_POWER_MAX] = {6969+/* for DTIM period 0 through IWL_POWER_RANGE_0_MAX */7070+static const struct iwl_power_vec_entry range_0[IWL_POWER_NUM] = {7671 {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},7772 {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0},7873 {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0},···7782};788379848080-/* for TIM = 3-10 */8181-static struct iwl_power_vec_entry range_1[IWL_POWER_MAX] = {8585+/* for DTIM period IWL_POWER_RANGE_0_MAX + 1 through IWL_POWER_RANGE_1_MAX */8686+static const struct iwl_power_vec_entry range_1[IWL_POWER_NUM] = {8287 {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},8388 {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0},8489 {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 3, 4, 7)}, 0},···8792 {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(2, 4, 7, 10, 10)}, 2}8893};89949090-/* for TIM > 11 */9191-static struct iwl_power_vec_entry range_2[IWL_POWER_MAX] = {9595+/* for DTIM period > IWL_POWER_RANGE_1_MAX */9696+static const struct iwl_power_vec_entry range_2[IWL_POWER_NUM] = {9297 {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},9398 {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 0xFF)}, 0},9499 {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(2, 4, 6, 7, 0xFF)}, 0},···101106/* set card power command */102107static int iwl_set_power(struct iwl_priv *priv, void *cmd)103108{104104- return iwl_send_cmd_pdu_async(priv, POWER_TABLE_CMD,105105- sizeof(struct iwl_powertable_cmd),106106- cmd, NULL);107107-}108108-/* decide the right power level according to association status109109- * and battery status110110- */111111-static u16 iwl_get_auto_power_mode(struct iwl_priv *priv)112112-{113113- u16 mode;114114-115115- switch (priv->power_data.user_power_setting) {116116- case IWL_POWER_AUTO:117117- /* if running on battery */118118- if (priv->power_data.is_battery_active)119119- mode = IWL_POWER_ON_BATTERY;120120- else if (iwl_is_associated(priv))121121- mode = IWL_POWER_ON_AC_ASSOC;122122- else123123- mode = IWL_POWER_ON_AC_DISASSOC;124124- break;125125- default:126126- mode = priv->power_data.user_power_setting;127127- break;128128- }129129- return mode;109109+ return iwl_send_cmd_pdu(priv, POWER_TABLE_CMD,110110+ sizeof(struct iwl_powertable_cmd), cmd);130111}131112132113/* initialize to default */133114static void iwl_power_init_handle(struct iwl_priv *priv)134115{135116 struct iwl_power_mgr *pow_data;136136- int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_MAX;117117+ int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_NUM;137118 struct iwl_powertable_cmd *cmd;138119 int i;139120 u16 lctl;···128157129158 IWL_DEBUG_POWER(priv, "adjust power command flags\n");130159131131- for (i = 0; i < IWL_POWER_MAX; i++) {160160+ for (i = 0; i < IWL_POWER_NUM; i++) {132161 cmd = &pow_data->pwr_range_0[i].cmd;133162134163 if (lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN)···218247 update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE ||219248 priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE;220249221221- /* If on battery, set to 3,222222- * if plugged into AC power, set to CAM ("continuously aware mode"),223223- * else user level */250250+ final_mode = priv->power_data.user_power_setting;224251225225- switch (setting->system_power_setting) {226226- case IWL_POWER_SYS_AUTO:227227- final_mode = iwl_get_auto_power_mode(priv);228228- break;229229- case IWL_POWER_SYS_BATTERY:230230- final_mode = IWL_POWER_INDEX_3;231231- break;232232- case IWL_POWER_SYS_AC:233233- final_mode = IWL_POWER_MODE_CAM;234234- break;235235- default:236236- final_mode = IWL_POWER_INDEX_3;237237- WARN_ON(1);238238- }239239-240240- if (setting->critical_power_setting > final_mode)241241- final_mode = setting->critical_power_setting;242242-243243- /* driver only support CAM for non STA network */244244- if (priv->iw_mode != NL80211_IFTYPE_STATION)252252+ if (setting->power_disabled)245253 final_mode = IWL_POWER_MODE_CAM;246254247247- if (iwl_is_ready_rf(priv) && !setting->power_disabled &&255255+ if (iwl_is_ready_rf(priv) &&248256 ((setting->power_mode != final_mode) || force)) {249257 struct iwl_powertable_cmd cmd;250258···240290241291 if (final_mode == IWL_POWER_MODE_CAM)242292 clear_bit(STATUS_POWER_PMI, &priv->status);243243- else244244- set_bit(STATUS_POWER_PMI, &priv->status);245293246294 if (priv->cfg->ops->lib->update_chain_flags && update_chains)247295 priv->cfg->ops->lib->update_chain_flags(priv);···255307}256308EXPORT_SYMBOL(iwl_power_update_mode);257309258258-/* Allow other iwl code to disable/enable power management active259259- * this will be useful for rate scale to disable PM during heavy260260- * Tx/Rx activities261261- */262262-int iwl_power_disable_management(struct iwl_priv *priv, u32 ms)263263-{264264- u16 prev_mode;265265- int ret = 0;266266-267267- if (priv->power_data.power_disabled)268268- return -EBUSY;269269-270270- prev_mode = priv->power_data.user_power_setting;271271- priv->power_data.user_power_setting = IWL_POWER_MODE_CAM;272272- ret = iwl_power_update_mode(priv, 0);273273- priv->power_data.power_disabled = 1;274274- priv->power_data.user_power_setting = prev_mode;275275- cancel_delayed_work(&priv->set_power_save);276276- if (ms)277277- queue_delayed_work(priv->workqueue, &priv->set_power_save,278278- msecs_to_jiffies(ms));279279-280280-281281- return ret;282282-}283283-EXPORT_SYMBOL(iwl_power_disable_management);284284-285285-/* Allow other iwl code to disable/enable power management active286286- * this will be useful for rate scale to disable PM during high287287- * volume activities288288- */289289-int iwl_power_enable_management(struct iwl_priv *priv)290290-{291291- int ret = 0;292292-293293- priv->power_data.power_disabled = 0;294294- ret = iwl_power_update_mode(priv, 0);295295- return ret;296296-}297297-EXPORT_SYMBOL(iwl_power_enable_management);298298-299310/* set user_power_setting */300311int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode)301312{302302- if (mode > IWL_POWER_MAX)313313+ if (mode >= IWL_POWER_NUM)303314 return -EINVAL;304315305316 priv->power_data.user_power_setting = mode;···267360}268361EXPORT_SYMBOL(iwl_power_set_user_mode);269362270270-/* set system_power_setting. This should be set by over all271271- * PM application.272272- */273273-int iwl_power_set_system_mode(struct iwl_priv *priv, u16 mode)274274-{275275- if (mode < IWL_POWER_SYS_MAX)276276- priv->power_data.system_power_setting = mode;277277- else278278- return -EINVAL;279279- return iwl_power_update_mode(priv, 0);280280-}281281-EXPORT_SYMBOL(iwl_power_set_system_mode);282282-283363/* initialize to default */284364void iwl_power_initialize(struct iwl_priv *priv)285365{286366 iwl_power_init_handle(priv);287287- priv->power_data.user_power_setting = IWL_POWER_AUTO;288288- priv->power_data.system_power_setting = IWL_POWER_SYS_AUTO;289289- priv->power_data.power_disabled = 0;290290- priv->power_data.is_battery_active = 0;291291- priv->power_data.critical_power_setting = 0;367367+ priv->power_data.user_power_setting = IWL_POWER_INDEX_1;368368+ /* default to disabled until mac80211 says otherwise */369369+ priv->power_data.power_disabled = 1;292370}293371EXPORT_SYMBOL(iwl_power_initialize);294294-295295-/* set critical_power_setting according to temperature value */296296-int iwl_power_temperature_change(struct iwl_priv *priv)297297-{298298- int ret = 0;299299- s32 temperature = KELVIN_TO_CELSIUS(priv->last_temperature);300300- u16 new_critical = priv->power_data.critical_power_setting;301301-302302- if (temperature > IWL_CT_KILL_TEMPERATURE)303303- return 0;304304- else if (temperature > IWL_MIN_POWER_TEMPERATURE)305305- new_critical = IWL_POWER_INDEX_5;306306- else if (temperature > IWL_REDUCED_POWER_TEMPERATURE)307307- new_critical = IWL_POWER_INDEX_3;308308- else309309- new_critical = IWL_POWER_MODE_CAM;310310-311311- if (new_critical != priv->power_data.critical_power_setting)312312- priv->power_data.critical_power_setting = new_critical;313313-314314- if (priv->power_data.critical_power_setting >315315- priv->power_data.power_mode)316316- ret = iwl_power_update_mode(priv, 0);317317-318318- return ret;319319-}320320-EXPORT_SYMBOL(iwl_power_temperature_change);321321-322322-static void iwl_bg_set_power_save(struct work_struct *work)323323-{324324- struct iwl_priv *priv = container_of(work,325325- struct iwl_priv, set_power_save.work);326326- IWL_DEBUG_POWER(priv, "update power\n");327327-328328- if (test_bit(STATUS_EXIT_PENDING, &priv->status))329329- return;330330-331331- mutex_lock(&priv->mutex);332332-333333- /* on starting association we disable power management334334- * until association, if association failed then this335335- * timer will expire and enable PM again.336336- */337337- if (!iwl_is_associated(priv))338338- iwl_power_enable_management(priv);339339-340340- mutex_unlock(&priv->mutex);341341-}342342-void iwl_setup_power_deferred_work(struct iwl_priv *priv)343343-{344344- INIT_DELAYED_WORK(&priv->set_power_save, iwl_bg_set_power_save);345345-}346346-EXPORT_SYMBOL(iwl_setup_power_deferred_work);347347-348348-void iwl_power_cancel_timeout(struct iwl_priv *priv)349349-{350350- cancel_delayed_work(&priv->set_power_save);351351-}352352-EXPORT_SYMBOL(iwl_power_cancel_timeout);
+6-33
drivers/net/wireless/iwlwifi/iwl-power.h
···4040 IWL_POWER_INDEX_3,4141 IWL_POWER_INDEX_4,4242 IWL_POWER_INDEX_5,4343- IWL_POWER_AUTO,4444- IWL_POWER_MAX = IWL_POWER_AUTO,4343+ IWL_POWER_NUM4544};4646-4747-enum {4848- IWL_POWER_SYS_AUTO,4949- IWL_POWER_SYS_AC,5050- IWL_POWER_SYS_BATTERY,5151- IWL_POWER_SYS_MAX,5252-};5353-54455546/* Power management (not Tx power) structures */56475757-#define NOSLP cpu_to_le16(0), 0, 05858-#define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 05959-#define SLP_TOUT(T) cpu_to_le32((T) * MSEC_TO_USEC)6060-#define SLP_VEC(X0, X1, X2, X3, X4) {cpu_to_le32(X0), \6161- cpu_to_le32(X1), \6262- cpu_to_le32(X2), \6363- cpu_to_le32(X3), \6464- cpu_to_le32(X4)}6548struct iwl_power_vec_entry {6649 struct iwl_powertable_cmd cmd;6750 u8 no_dtim;6851};69527053struct iwl_power_mgr {7171- spinlock_t lock;7272- struct iwl_power_vec_entry pwr_range_0[IWL_POWER_MAX];7373- struct iwl_power_vec_entry pwr_range_1[IWL_POWER_MAX];7474- struct iwl_power_vec_entry pwr_range_2[IWL_POWER_MAX];5454+ struct iwl_power_vec_entry pwr_range_0[IWL_POWER_NUM];5555+ struct iwl_power_vec_entry pwr_range_1[IWL_POWER_NUM];5656+ struct iwl_power_vec_entry pwr_range_2[IWL_POWER_NUM];7557 u32 dtim_period;7658 /* final power level that used to calculate final power command */7759 u8 power_mode;7878- u8 user_power_setting; /* set by user through mac80211 or sysfs */7979- u8 system_power_setting; /* set by kernel system tools */8080- u8 critical_power_setting; /* set if driver over heated */8181- u8 is_battery_active; /* DC/AC power */8282- u8 power_disabled; /* flag to disable using power saving level */6060+ u8 user_power_setting; /* set by user through sysfs */6161+ u8 power_disabled; /* set by mac80211's CONF_PS */8362};84638585-void iwl_setup_power_deferred_work(struct iwl_priv *priv);8686-void iwl_power_cancel_timeout(struct iwl_priv *priv);8764int iwl_power_update_mode(struct iwl_priv *priv, bool force);8888-int iwl_power_disable_management(struct iwl_priv *priv, u32 ms);8989-int iwl_power_enable_management(struct iwl_priv *priv);9065int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode);9191-int iwl_power_set_system_mode(struct iwl_priv *priv, u16 mode);9266void iwl_power_initialize(struct iwl_priv *priv);9393-int iwl_power_temperature_change(struct iwl_priv *priv);94679568#endif /* __iwl_power_setting_h__ */
+8-6
drivers/net/wireless/iwlwifi/iwl-scan.c
···580580 int ret = 0;581581 u32 rate_flags = 0;582582 u16 cmd_len;583583+ u16 rx_chain = 0;583584 enum ieee80211_band band;584585 u8 n_probes = 0;585585- u8 rx_chain = priv->hw_params.valid_rx_ant;586586+ u8 rx_ant = priv->hw_params.valid_rx_ant;586587 u8 rate;587588 bool is_active = false;588589···724723 * Avoid A (0x1) because of its off-channel reception on A-band.725724 */726725 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965)727727- rx_chain = 0x6;726726+ rx_ant = ANT_BC;728727 } else {729728 IWL_WARN(priv, "Invalid scan band count\n");730729 goto done;···736735 scan->tx_cmd.rate_n_flags = iwl_hw_set_rate_n_flags(rate, rate_flags);737736738737 /* MIMO is not used here, but value is required */739739- scan->rx_chain = RXON_RX_CHAIN_DRIVER_FORCE_MSK |740740- cpu_to_le16((0x7 << RXON_RX_CHAIN_VALID_POS) |741741- (rx_chain << RXON_RX_CHAIN_FORCE_SEL_POS) |742742- (0x7 << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS));738738+ rx_chain |= ANT_ABC << RXON_RX_CHAIN_VALID_POS;739739+ rx_chain |= ANT_ABC << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;740740+ rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS;741741+ rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS;742742+ scan->rx_chain = cpu_to_le16(rx_chain);743743 cmd_len = iwl_fill_probe_req(priv,744744 (struct ieee80211_mgmt *)scan->data,745745 priv->scan_request->ie,
+13-43
drivers/net/wireless/iwlwifi/iwl3945-base.c
···18371837 iwl_release_nic_access(priv);18381838}1839183918401840-static void iwl3945_error_recovery(struct iwl_priv *priv)18411841-{18421842- unsigned long flags;18431843-18441844- memcpy(&priv->staging_rxon, &priv->recovery_rxon,18451845- sizeof(priv->staging_rxon));18461846- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;18471847- iwlcore_commit_rxon(priv);18481848-18491849- priv->cfg->ops->smgmt->add_station(priv, priv->bssid, 1, 0, NULL);18501850-18511851- spin_lock_irqsave(&priv->lock, flags);18521852- priv->assoc_id = le16_to_cpu(priv->staging_rxon.assoc_id);18531853- priv->error_recovering = 0;18541854- spin_unlock_irqrestore(&priv->lock, flags);18551855-}18561856-18571840static void iwl3945_irq_tasklet(struct iwl_priv *priv)18581841{18591842 u32 inta, handled = 0;···26662683 /* After the ALIVE response, we can send commands to 3945 uCode */26672684 set_bit(STATUS_ALIVE, &priv->status);2668268526692669- /* Clear out the uCode error bit if it is set */26702670- clear_bit(STATUS_FW_ERROR, &priv->status);26712671-26722686 if (iwl_is_rfkill(priv))26732687 return;26742688···27012721 IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n");27022722 set_bit(STATUS_READY, &priv->status);27032723 wake_up_interruptible(&priv->wait_command_queue);27042704-27052705- if (priv->error_recovering)27062706- iwl3945_error_recovery(priv);2707272427082725 /* reassociate for ADHOC mode */27092726 if (priv->vif && (priv->iw_mode == NL80211_IFTYPE_ADHOC)) {···32083231 if (test_bit(STATUS_EXIT_PENDING, &priv->status))32093232 return;3210323332113211- iwl3945_down(priv);32123212- queue_work(priv->workqueue, &priv->up);32343234+ if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) {32353235+ mutex_lock(&priv->mutex);32363236+ priv->vif = NULL;32373237+ priv->is_open = 0;32383238+ mutex_unlock(&priv->mutex);32393239+ iwl3945_down(priv);32403240+ ieee80211_restart_hw(priv->hw);32413241+ } else {32423242+ iwl3945_down(priv);32433243+ queue_work(priv->workqueue, &priv->up);32443244+ }32133245}3214324632153247static void iwl3945_bg_rx_replenish(struct work_struct *data)···38453859{38463860 struct iwl_priv *priv = dev_get_drvdata(d);38473861 int mode = priv->power_data.user_power_setting;38483848- int system = priv->power_data.system_power_setting;38493862 int level = priv->power_data.power_mode;38503863 char *p = buf;3851386438523852- switch (system) {38533853- case IWL_POWER_SYS_AUTO:38543854- p += sprintf(p, "SYSTEM:auto");38553855- break;38563856- case IWL_POWER_SYS_AC:38573857- p += sprintf(p, "SYSTEM:ac");38583858- break;38593859- case IWL_POWER_SYS_BATTERY:38603860- p += sprintf(p, "SYSTEM:battery");38613861- break;38623862- }38633863-38643864- p += sprintf(p, "\tMODE:%s", (mode < IWL_POWER_AUTO) ?38653865- "fixed" : "auto");38663866- p += sprintf(p, "\tINDEX:%d", level);38673867- p += sprintf(p, "\n");38653865+ p += sprintf(p, "INDEX:%d\t", level);38663866+ p += sprintf(p, "USER:%d\n", mode);38683867 return p - buf + 1;38693868}38703869···40934122 priv->ibss_beacon = NULL;4094412340954124 spin_lock_init(&priv->lock);40964096- spin_lock_init(&priv->power_data.lock);40974125 spin_lock_init(&priv->sta_lock);40984126 spin_lock_init(&priv->hcmd_lock);40994127
+1-1
drivers/net/wireless/mac80211_hwsim.c
···642642 if (changed & BSS_CHANGED_HT) {643643 printk(KERN_DEBUG " %s: HT: op_mode=0x%x\n",644644 wiphy_name(hw->wiphy),645645- info->ht.operation_mode);645645+ info->ht_operation_mode);646646 }647647648648 if (changed & BSS_CHANGED_BASIC_RATES) {
···2525 *2626 */27272828+#include <linux/types.h>2929+2830/**2931 * DOC: Station handling3032 *···7977 * @NL80211_CMD_SET_KEY: Set key attributes %NL80211_ATTR_KEY_DEFAULT,8078 * %NL80211_ATTR_KEY_DEFAULT_MGMT, or %NL80211_ATTR_KEY_THRESHOLD.8179 * @NL80211_CMD_NEW_KEY: add a key with given %NL80211_ATTR_KEY_DATA,8282- * %NL80211_ATTR_KEY_IDX, %NL80211_ATTR_MAC and %NL80211_ATTR_KEY_CIPHER8383- * attributes.8080+ * %NL80211_ATTR_KEY_IDX, %NL80211_ATTR_MAC, %NL80211_ATTR_KEY_CIPHER,8181+ * and %NL80211_ATTR_KEY_SEQ attributes.8482 * @NL80211_CMD_DEL_KEY: delete a key identified by %NL80211_ATTR_KEY_IDX8583 * or %NL80211_ATTR_MAC.8684 *···382380 *383381 * @NL80211_ATTR_STA_AID: Association ID for the station (u16)384382 * @NL80211_ATTR_STA_FLAGS: flags, nested element with NLA_FLAG attributes of385385- * &enum nl80211_sta_flags.383383+ * &enum nl80211_sta_flags (deprecated, use %NL80211_ATTR_STA_FLAGS2)386384 * @NL80211_ATTR_STA_LISTEN_INTERVAL: listen interval as defined by387385 * IEEE 802.11 7.3.1.6 (u16).388386 * @NL80211_ATTR_STA_SUPPORTED_RATES: supported rates, array of supported···496494 * @NL80211_ATTR_TIMED_OUT: a flag indicating than an operation timed out; this497495 * is used, e.g., with %NL80211_CMD_AUTHENTICATE event498496 *497497+ * @NL80211_ATTR_USE_MFP: Whether management frame protection (IEEE 802.11w) is498498+ * used for the association (&enum nl80211_mfp, represented as a u32);499499+ * this attribute can be used500500+ * with %NL80211_CMD_ASSOCIATE request501501+ *502502+ * @NL80211_ATTR_STA_FLAGS2: Attribute containing a503503+ * &struct nl80211_sta_flag_update.504504+ *505505+ * @NL80211_ATTR_CONTROL_PORT: A flag indicating whether user space controls506506+ * IEEE 802.1X port, i.e., sets/clears %NL80211_STA_FLAG_AUTHORIZED, in507507+ * station mode. If the flag is included in %NL80211_CMD_ASSOCIATE508508+ * request, the driver will assume that the port is unauthorized until509509+ * authorized by user space. Otherwise, port is marked authorized by510510+ * default in station mode.511511+ *499512 * @NL80211_ATTR_MAX: highest attribute number currently defined500513 * @__NL80211_ATTR_AFTER_LAST: internal use501514 */···613596614597 NL80211_ATTR_TIMED_OUT,615598599599+ NL80211_ATTR_USE_MFP,600600+601601+ NL80211_ATTR_STA_FLAGS2,602602+603603+ NL80211_ATTR_CONTROL_PORT,604604+616605 /* add attributes here, update the policy in nl80211.c */617606618607 __NL80211_ATTR_AFTER_LAST,···706683 __NL80211_STA_FLAG_AFTER_LAST,707684 NL80211_STA_FLAG_MAX = __NL80211_STA_FLAG_AFTER_LAST - 1708685};686686+687687+/**688688+ * struct nl80211_sta_flag_update - station flags mask/set689689+ * @mask: mask of station flags to set690690+ * @set: which values to set them to691691+ *692692+ * Both mask and set contain bits as per &enum nl80211_sta_flags.693693+ */694694+struct nl80211_sta_flag_update {695695+ __u32 mask;696696+ __u32 set;697697+} __attribute__((packed));709698710699/**711700 * enum nl80211_rate_info - bitrate information···12121177 NL80211_KEYTYPE_GROUP,12131178 NL80211_KEYTYPE_PAIRWISE,12141179 NL80211_KEYTYPE_PEERKEY,11801180+};11811181+11821182+/**11831183+ * enum nl80211_mfp - Management frame protection state11841184+ * @NL80211_MFP_NO: Management frame protection not used11851185+ * @NL80211_MFP_REQUIRED: Management frame protection required11861186+ */11871187+enum nl80211_mfp {11881188+ NL80211_MFP_NO,11891189+ NL80211_MFP_REQUIRED,12151190};1216119112171192#endif /* __LINUX_NL80211_H */
+29-28
include/net/cfg80211.h
···252252};253253254254/**255255- * enum station_flags - station flags256256- *257257- * Station capability flags. Note that these must be the bits258258- * according to the nl80211 flags.259259- *260260- * @STATION_FLAG_CHANGED: station flags were changed261261- * @STATION_FLAG_AUTHORIZED: station is authorized to send frames (802.1X)262262- * @STATION_FLAG_SHORT_PREAMBLE: station is capable of receiving frames263263- * with short preambles264264- * @STATION_FLAG_WME: station is WME/QoS capable265265- * @STATION_FLAG_MFP: station uses management frame protection266266- */267267-enum station_flags {268268- STATION_FLAG_CHANGED = 1<<0,269269- STATION_FLAG_AUTHORIZED = 1<<NL80211_STA_FLAG_AUTHORIZED,270270- STATION_FLAG_SHORT_PREAMBLE = 1<<NL80211_STA_FLAG_SHORT_PREAMBLE,271271- STATION_FLAG_WME = 1<<NL80211_STA_FLAG_WME,272272- STATION_FLAG_MFP = 1<<NL80211_STA_FLAG_MFP,273273-};274274-275275-/**276255 * enum plink_action - actions to perform in mesh peers277256 *278257 * @PLINK_ACTION_INVALID: action 0 is reserved···273294 * @supported_rates: supported rates in IEEE 802.11 format274295 * (or NULL for no change)275296 * @supported_rates_len: number of supported rates276276- * @station_flags: station flags (see &enum station_flags)297297+ * @sta_flags_mask: station flags that changed298298+ * (bitmask of BIT(NL80211_STA_FLAG_...))299299+ * @sta_flags_set: station flags values300300+ * (bitmask of BIT(NL80211_STA_FLAG_...))277301 * @listen_interval: listen interval or -1 for no change278302 * @aid: AID or zero for no change279303 */280304struct station_parameters {281305 u8 *supported_rates;282306 struct net_device *vlan;283283- u32 station_flags;307307+ u32 sta_flags_mask, sta_flags_set;284308 int listen_interval;285309 u16 aid;286310 u8 supported_rates_len;···654672 * @ssid_len: Length of ssid in octets655673 * @ie: Extra IEs to add to (Re)Association Request frame or %NULL656674 * @ie_len: Length of ie buffer in octets675675+ * @use_mfp: Use management frame protection (IEEE 802.11w) in this association676676+ * @control_port: Whether user space controls IEEE 802.1X port, i.e.,677677+ * sets/clears %NL80211_STA_FLAG_AUTHORIZED. If true, the driver is678678+ * required to assume that the port is unauthorized until authorized by679679+ * user space. Otherwise, port is marked authorized by default.657680 */658681struct cfg80211_assoc_request {659682 struct ieee80211_channel *chan;···667680 size_t ssid_len;668681 const u8 *ie;669682 size_t ie_len;683683+ bool use_mfp;684684+ bool control_port;670685};671686672687/**···847858 struct vif_params *params);848859849860 int (*add_key)(struct wiphy *wiphy, struct net_device *netdev,850850- u8 key_index, u8 *mac_addr,861861+ u8 key_index, const u8 *mac_addr,851862 struct key_params *params);852863 int (*get_key)(struct wiphy *wiphy, struct net_device *netdev,853853- u8 key_index, u8 *mac_addr, void *cookie,864864+ u8 key_index, const u8 *mac_addr, void *cookie,854865 void (*callback)(void *cookie, struct key_params*));855866 int (*del_key)(struct wiphy *wiphy, struct net_device *netdev,856856- u8 key_index, u8 *mac_addr);867867+ u8 key_index, const u8 *mac_addr);857868 int (*set_default_key)(struct wiphy *wiphy,858869 struct net_device *netdev,859870 u8 key_index);···1134114511351146#ifdef CONFIG_WIRELESS_EXT11361147 /* wext data */11371137- struct cfg80211_ibss_params wext;11381138- u8 wext_bssid[ETH_ALEN];11481148+ struct {11491149+ struct cfg80211_ibss_params ibss;11501150+ u8 bssid[ETH_ALEN];11511151+ s8 default_key, default_mgmt_key;11521152+ } wext;11391153#endif11401154};11411155···13881396int cfg80211_wext_giwretry(struct net_device *dev,13891397 struct iw_request_info *info,13901398 struct iw_param *retry, char *extra);13991399+int cfg80211_wext_siwencodeext(struct net_device *dev,14001400+ struct iw_request_info *info,14011401+ struct iw_point *erq, char *extra);14021402+int cfg80211_wext_siwencode(struct net_device *dev,14031403+ struct iw_request_info *info,14041404+ struct iw_point *erq, char *keybuf);14051405+int cfg80211_wext_giwencode(struct net_device *dev,14061406+ struct iw_request_info *info,14071407+ struct iw_point *erq, char *keybuf);1391140813921409/*13931410 * callbacks for asynchronous cfg80211 methods, notification
+3-25
include/net/mac80211.h
···7373 */74747575/**7676- * struct ieee80211_ht_bss_info - describing BSS's HT characteristics7777- *7878- * This structure describes most essential parameters needed7979- * to describe 802.11n HT characteristics in a BSS.8080- *8181- * @primary_channel: channel number of primery channel8282- * @bss_cap: 802.11n's general BSS capabilities (e.g. channel width)8383- * @bss_op_mode: 802.11n's BSS operation modes (e.g. HT protection)8484- */8585-struct ieee80211_ht_bss_info {8686- u8 primary_channel;8787- u8 bss_cap; /* use IEEE80211_HT_IE_CHA_ */8888- u8 bss_op_mode; /* use IEEE80211_HT_IE_ */8989-};9090-9191-/**9276 * enum ieee80211_max_queues - maximum number of queues9377 *9478 * @IEEE80211_MAX_QUEUES: Maximum number of regular device queues.···155171};156172157173/**158158- * struct ieee80211_bss_ht_conf - BSS's changing HT configuration159159- * @operation_mode: HT operation mode (like in &struct ieee80211_ht_info)160160- */161161-struct ieee80211_bss_ht_conf {162162- u16 operation_mode;163163-};164164-165165-/**166174 * struct ieee80211_bss_conf - holds the BSS's changing parameters167175 *168176 * This structure keeps information about a BSS (and an association···179203 * the current band.180204 * @bssid: The BSSID for this BSS181205 * @enable_beacon: whether beaconing should be enabled or not206206+ * @ht_operation_mode: HT operation mode (like in &struct ieee80211_ht_info).207207+ * This field is only valid when the channel type is one of the HT types.182208 */183209struct ieee80211_bss_conf {184210 const u8 *bssid;···197219 u16 assoc_capability;198220 u64 timestamp;199221 u32 basic_rates;200200- struct ieee80211_bss_ht_conf ht;222222+ u16 ht_operation_mode;201223};202224203225/**
+43-25
net/mac80211/cfg.c
···112112}113113114114static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,115115- u8 key_idx, u8 *mac_addr,115115+ u8 key_idx, const u8 *mac_addr,116116 struct key_params *params)117117{118118 struct ieee80211_sub_if_data *sdata;···141141 return -EINVAL;142142 }143143144144- key = ieee80211_key_alloc(alg, key_idx, params->key_len, params->key);144144+ key = ieee80211_key_alloc(alg, key_idx, params->key_len, params->key,145145+ params->seq_len, params->seq);145146 if (!key)146147 return -ENOMEM;147148···167166}168167169168static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,170170- u8 key_idx, u8 *mac_addr)169169+ u8 key_idx, const u8 *mac_addr)171170{172171 struct ieee80211_sub_if_data *sdata;173172 struct sta_info *sta;···209208}210209211210static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,212212- u8 key_idx, u8 *mac_addr, void *cookie,211211+ u8 key_idx, const u8 *mac_addr, void *cookie,213212 void (*callback)(void *cookie,214213 struct key_params *params))215214{···630629 int i, j;631630 struct ieee80211_supported_band *sband;632631 struct ieee80211_sub_if_data *sdata = sta->sdata;632632+ u32 mask, set;633633634634 sband = local->hw.wiphy->bands[local->oper_channel->band];635635636636- /*637637- * FIXME: updating the flags is racy when this function is638638- * called from ieee80211_change_station(), this will639639- * be resolved in a future patch.640640- */636636+ spin_lock_bh(&sta->lock);637637+ mask = params->sta_flags_mask;638638+ set = params->sta_flags_set;641639642642- if (params->station_flags & STATION_FLAG_CHANGED) {643643- spin_lock_bh(&sta->lock);640640+ if (mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) {644641 sta->flags &= ~WLAN_STA_AUTHORIZED;645645- if (params->station_flags & STATION_FLAG_AUTHORIZED)642642+ if (set & BIT(NL80211_STA_FLAG_AUTHORIZED))646643 sta->flags |= WLAN_STA_AUTHORIZED;647647-648648- sta->flags &= ~WLAN_STA_SHORT_PREAMBLE;649649- if (params->station_flags & STATION_FLAG_SHORT_PREAMBLE)650650- sta->flags |= WLAN_STA_SHORT_PREAMBLE;651651-652652- sta->flags &= ~WLAN_STA_WME;653653- if (params->station_flags & STATION_FLAG_WME)654654- sta->flags |= WLAN_STA_WME;655655-656656- sta->flags &= ~WLAN_STA_MFP;657657- if (params->station_flags & STATION_FLAG_MFP)658658- sta->flags |= WLAN_STA_MFP;659659- spin_unlock_bh(&sta->lock);660644 }645645+646646+ if (mask & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE)) {647647+ sta->flags &= ~WLAN_STA_SHORT_PREAMBLE;648648+ if (set & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE))649649+ sta->flags |= WLAN_STA_SHORT_PREAMBLE;650650+ }651651+652652+ if (mask & BIT(NL80211_STA_FLAG_WME)) {653653+ sta->flags &= ~WLAN_STA_WME;654654+ if (set & BIT(NL80211_STA_FLAG_WME))655655+ sta->flags |= WLAN_STA_WME;656656+ }657657+658658+ if (mask & BIT(NL80211_STA_FLAG_MFP)) {659659+ sta->flags &= ~WLAN_STA_MFP;660660+ if (set & BIT(NL80211_STA_FLAG_MFP))661661+ sta->flags |= WLAN_STA_MFP;662662+ }663663+ spin_unlock_bh(&sta->lock);661664662665 /*663666 * FIXME: updating the following information is racy when this···12571252 ret = ieee80211_sta_set_extra_ie(sdata, req->ie, req->ie_len);12581253 if (ret)12591254 return ret;12551255+12561256+ if (req->use_mfp) {12571257+ sdata->u.mgd.mfp = IEEE80211_MFP_REQUIRED;12581258+ sdata->u.mgd.flags |= IEEE80211_STA_MFP_ENABLED;12591259+ } else {12601260+ sdata->u.mgd.mfp = IEEE80211_MFP_DISABLED;12611261+ sdata->u.mgd.flags &= ~IEEE80211_STA_MFP_ENABLED;12621262+ }12631263+12641264+ if (req->control_port)12651265+ sdata->u.mgd.flags |= IEEE80211_STA_CONTROL_PORT;12661266+ else12671267+ sdata->u.mgd.flags &= ~IEEE80211_STA_CONTROL_PORT;1260126812611269 sdata->u.mgd.flags |= IEEE80211_STA_EXT_SME;12621270 sdata->u.mgd.state = IEEE80211_STA_MLME_ASSOCIATE;
···290290struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg,291291 int idx,292292 size_t key_len,293293- const u8 *key_data)293293+ const u8 *key_data,294294+ size_t seq_len, const u8 *seq)294295{295296 struct ieee80211_key *key;297297+ int i, j;296298297299 BUG_ON(idx < 0 || idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS);298300···320318 case ALG_TKIP:321319 key->conf.iv_len = TKIP_IV_LEN;322320 key->conf.icv_len = TKIP_ICV_LEN;321321+ if (seq && seq_len == 6) {322322+ for (i = 0; i < NUM_RX_DATA_QUEUES; i++) {323323+ key->u.tkip.rx[i].iv32 =324324+ get_unaligned_le32(&seq[2]);325325+ key->u.tkip.rx[i].iv16 =326326+ get_unaligned_le16(seq);327327+ }328328+ }323329 break;324330 case ALG_CCMP:325331 key->conf.iv_len = CCMP_HDR_LEN;326332 key->conf.icv_len = CCMP_MIC_LEN;333333+ if (seq && seq_len == CCMP_PN_LEN) {334334+ for (i = 0; i < NUM_RX_DATA_QUEUES; i++)335335+ for (j = 0; j < CCMP_PN_LEN; j++)336336+ key->u.ccmp.rx_pn[i][j] =337337+ seq[CCMP_PN_LEN - j - 1];338338+ }327339 break;328340 case ALG_AES_CMAC:329341 key->conf.iv_len = 0;330342 key->conf.icv_len = sizeof(struct ieee80211_mmie);343343+ if (seq && seq_len == 6)344344+ for (j = 0; j < 6; j++)345345+ key->u.aes_cmac.rx_pn[j] = seq[6 - j - 1];331346 break;332347 }333348 memcpy(key->conf.key, key_data, key_len);
+2-1
net/mac80211/key.h
···144144struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg,145145 int idx,146146 size_t key_len,147147- const u8 *key_data);147147+ const u8 *key_data,148148+ size_t seq_len, const u8 *seq);148149/*149150 * Insert a key into data structures (sdata, sta if necessary)150151 * to make it used, free old key.
+8-6
net/mac80211/main.c
···154154155155int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)156156{157157- struct ieee80211_channel *chan;157157+ struct ieee80211_channel *chan, *scan_chan;158158 int ret = 0;159159 int power;160160 enum nl80211_channel_type channel_type;161161162162 might_sleep();163163164164- if (local->sw_scanning) {165165- chan = local->scan_channel;164164+ scan_chan = local->scan_channel;165165+166166+ if (scan_chan) {167167+ chan = scan_chan;166168 channel_type = NL80211_CHAN_NO_HT;167169 } else {168170 chan = local->oper_channel;···178176 changed |= IEEE80211_CONF_CHANGE_CHANNEL;179177 }180178181181- if (local->sw_scanning)179179+ if (scan_chan)182180 power = chan->max_power;183181 else184182 power = local->power_constr_level ?···861859 if (!local->oper_channel) {862860 /* init channel we're on */863861 local->hw.conf.channel =864864- local->oper_channel =865865- local->scan_channel = &sband->channels[0];862862+ local->oper_channel = &sband->channels[0];863863+ local->hw.conf.channel_type = NL80211_CHAN_NO_HT;866864 }867865 channels += sband->n_channels;868866
+30-11
net/mac80211/mlme.c
···3333#define IEEE80211_ASSOC_TIMEOUT (HZ / 5)3434#define IEEE80211_ASSOC_MAX_TRIES 33535#define IEEE80211_MONITORING_INTERVAL (2 * HZ)3636+#define IEEE80211_PROBE_WAIT (HZ / 20)3637#define IEEE80211_PROBE_IDLE_TIME (60 * HZ)3738#define IEEE80211_RETRY_AUTH_INTERVAL (1 * HZ)3839···9695 struct ieee80211_local *local = sdata->local;9796 struct ieee80211_supported_band *sband;9897 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;9999- struct ieee80211_bss_ht_conf ht;10098 struct sta_info *sta;10199 u32 changed = 0;100100+ u16 ht_opmode;102101 bool enable_ht = true, ht_changed;103102 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;104103105104 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];106106-107107- memset(&ht, 0, sizeof(ht));108105109106 /* HT is not supported */110107 if (!sband->ht_cap.ht_supported)···147148 IEEE80211_RC_HT_CHANGED);148149149150 rcu_read_unlock();150150-151151 }152152153153 /* disable HT */154154 if (!enable_ht)155155 return 0;156156157157- ht.operation_mode = le16_to_cpu(hti->operation_mode);157157+ ht_opmode = le16_to_cpu(hti->operation_mode);158158159159 /* if bss configuration changed store the new one */160160- if (memcmp(&sdata->vif.bss_conf.ht, &ht, sizeof(ht))) {160160+ if (!sdata->ht_opmode_valid ||161161+ sdata->vif.bss_conf.ht_operation_mode != ht_opmode) {161162 changed |= BSS_CHANGED_HT;162162- sdata->vif.bss_conf.ht = ht;163163+ sdata->vif.bss_conf.ht_operation_mode = ht_opmode;164164+ sdata->ht_opmode_valid = true;163165 }164166165167 return changed;···1043104310441044 rcu_read_unlock();1045104510461046+ ieee80211_set_wmm_default(sdata);10471047+10461048 ieee80211_recalc_idle(local);1047104910481050 /* channel(_type) changes are handled by ieee80211_hw_config */10491051 local->oper_channel_type = NL80211_CHAN_NO_HT;10521052+10531053+ /* on the next assoc, re-program HT parameters */10541054+ sdata->ht_opmode_valid = false;1050105510511056 local->power_constr_level = 0;10521057···11831178 u.mgd.beacon_loss_work);11841179 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;1185118011811181+ /*11821182+ * The driver has already reported this event and we have11831183+ * already sent a probe request. Maybe the AP died and the11841184+ * driver keeps reporting until we disassociate... We have11851185+ * to ignore that because otherwise we would continually11861186+ * reset the timer and never check whether we received a11871187+ * probe response!11881188+ */11891189+ if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL)11901190+ return;11911191+11861192#ifdef CONFIG_MAC80211_VERBOSE_DEBUG11871193 if (net_ratelimit()) {11881194 printk(KERN_DEBUG "%s: driver reports beacon loss from AP %pM "···12061190 ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid,12071191 ifmgd->ssid_len, NULL, 0);1208119212091209- mod_timer(&ifmgd->timer, jiffies + IEEE80211_MONITORING_INTERVAL);11931193+ mod_timer(&ifmgd->timer, jiffies + IEEE80211_PROBE_WAIT);12101194}1211119512121196void ieee80211_beacon_loss(struct ieee80211_vif *vif)···12431227 }1244122812451229 if ((ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) &&12461246- time_after(jiffies, sta->last_rx + IEEE80211_MONITORING_INTERVAL)) {12301230+ time_after(jiffies, sta->last_rx + IEEE80211_PROBE_WAIT)) {12471231 printk(KERN_DEBUG "%s: no probe response from AP %pM "12481232 "- disassociating\n",12491233 sdata->dev->name, ifmgd->bssid);···15931577 * to between the sta_info_alloc() and sta_info_insert() above.15941578 */1595157915961596- set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP |15971597- WLAN_STA_AUTHORIZED);15801580+ set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP);15811581+ if (!(ifmgd->flags & IEEE80211_STA_CONTROL_PORT))15821582+ set_sta_flags(sta, WLAN_STA_AUTHORIZED);1598158315991584 rates = 0;16001585 basic_rates = 0;···16751658 if (elems.wmm_param)16761659 ieee80211_sta_wmm_params(local, ifmgd, elems.wmm_param,16771660 elems.wmm_param_len);16611661+ else16621662+ ieee80211_set_wmm_default(sdata);1678166316791664 if (elems.ht_info_elem && elems.wmm_param &&16801665 (ifmgd->flags & IEEE80211_STA_WMM_ENABLED) &&
+40-18
net/mac80211/rx.c
···630630 * possible.631631 */632632633633- if (!ieee80211_has_protected(hdr->frame_control)) {634634- if (!ieee80211_is_mgmt(hdr->frame_control) ||635635- rx->sta == NULL || !test_sta_flags(rx->sta, WLAN_STA_MFP))636636- return RX_CONTINUE;637637- mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb);638638- if (mmie_keyidx < 0)639639- return RX_CONTINUE;640640- }641641-642633 /*643634 * No point in finding a key and decrypting if the frame is neither644635 * addressed to us nor a multicast frame.···640649 if (rx->sta)641650 stakey = rcu_dereference(rx->sta->key);642651652652+ if (!ieee80211_has_protected(hdr->frame_control))653653+ mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb);654654+643655 if (!is_multicast_ether_addr(hdr->addr1) && stakey) {644656 rx->key = stakey;657657+ /* Skip decryption if the frame is not protected. */658658+ if (!ieee80211_has_protected(hdr->frame_control))659659+ return RX_CONTINUE;645660 } else if (mmie_keyidx >= 0) {646661 /* Broadcast/multicast robust management frame / BIP */647662 if ((rx->status->flag & RX_FLAG_DECRYPTED) &&···658661 mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS)659662 return RX_DROP_MONITOR; /* unexpected BIP keyidx */660663 rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]);664664+ } else if (!ieee80211_has_protected(hdr->frame_control)) {665665+ /*666666+ * The frame was not protected, so skip decryption. However, we667667+ * need to set rx->key if there is a key that could have been668668+ * used so that the frame may be dropped if encryption would669669+ * have been expected.670670+ */671671+ struct ieee80211_key *key = NULL;672672+ if (ieee80211_is_mgmt(hdr->frame_control) &&673673+ is_multicast_ether_addr(hdr->addr1) &&674674+ (key = rcu_dereference(rx->sdata->default_mgmt_key)))675675+ rx->key = key;676676+ else if ((key = rcu_dereference(rx->sdata->default_key)))677677+ rx->key = key;678678+ return RX_CONTINUE;661679 } else {662680 /*663681 * The device doesn't give us the IV so we won't be···12211209 /* Drop unencrypted frames if key is set. */12221210 if (unlikely(!ieee80211_has_protected(fc) &&12231211 !ieee80211_is_nullfunc(fc) &&12241224- (!ieee80211_is_mgmt(fc) ||12251225- (ieee80211_is_unicast_robust_mgmt_frame(rx->skb) &&12261226- rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP))) &&12121212+ ieee80211_is_data(fc) &&12271213 (rx->key || rx->sdata->drop_unencrypted)))12281214 return -EACCES;12291229- /* BIP does not use Protected field, so need to check MMIE */12301230- if (unlikely(rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP) &&12311231- ieee80211_is_multicast_robust_mgmt_frame(rx->skb) &&12321232- ieee80211_get_mmie_keyidx(rx->skb) < 0 &&12331233- (rx->key || rx->sdata->drop_unencrypted)))12341234- return -EACCES;12151215+ if (rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP)) {12161216+ if (unlikely(ieee80211_is_unicast_robust_mgmt_frame(rx->skb) &&12171217+ rx->key))12181218+ return -EACCES;12191219+ /* BIP does not use Protected field, so need to check MMIE */12201220+ if (unlikely(ieee80211_is_multicast_robust_mgmt_frame(rx->skb)12211221+ && ieee80211_get_mmie_keyidx(rx->skb) < 0 &&12221222+ rx->key))12231223+ return -EACCES;12241224+ /*12251225+ * When using MFP, Action frames are not allowed prior to12261226+ * having configured keys.12271227+ */12281228+ if (unlikely(ieee80211_is_action(fc) && !rx->key &&12291229+ ieee80211_is_robust_mgmt_frame(12301230+ (struct ieee80211_hdr *) rx->skb->data)))12311231+ return -EACCES;12321232+ }1235123312361234 return 0;12371235}
+24-8
net/mac80211/scan.c
···298298 was_hw_scan = local->hw_scanning;299299 local->hw_scanning = false;300300 local->sw_scanning = false;301301+ local->scan_channel = NULL;301302302303 /* we only have to protect scan_req and hw/sw scan */303304 mutex_unlock(&local->scan_mtx);···559558 if (skip)560559 break;561560562562- next_delay = IEEE80211_PROBE_DELAY +563563- usecs_to_jiffies(local->hw.channel_change_time);561561+ /*562562+ * Probe delay is used to update the NAV, cf. 11.1.3.2.2563563+ * (which unfortunately doesn't say _why_ step a) is done,564564+ * but it waits for the probe delay or until a frame is565565+ * received - and the received frame would update the NAV).566566+ * For now, we do not support waiting until a frame is567567+ * received.568568+ *569569+ * In any case, it is not necessary for a passive scan.570570+ */571571+ if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN ||572572+ !local->scan_req->n_ssids) {573573+ next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;574574+ break;575575+ }576576+577577+ next_delay = IEEE80211_PROBE_DELAY;564578 local->scan_state = SCAN_SEND_PROBE;565579 break;566580 case SCAN_SEND_PROBE:567567- next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;568568- local->scan_state = SCAN_SET_CHANNEL;569569-570570- if (local->scan_channel->flags & IEEE80211_CHAN_PASSIVE_SCAN ||571571- !local->scan_req->n_ssids)572572- break;573581 for (i = 0; i < local->scan_req->n_ssids; i++)574582 ieee80211_send_probe_req(575583 sdata, NULL,576584 local->scan_req->ssids[i].ssid,577585 local->scan_req->ssids[i].ssid_len,578586 local->scan_req->ie, local->scan_req->ie_len);587587+588588+ /*589589+ * After sending probe requests, wait for probe responses590590+ * on the channel.591591+ */579592 next_delay = IEEE80211_CHANNEL_TIME;593593+ local->scan_state = SCAN_SET_CHANNEL;580594 break;581595 }582596