···25252626config ATH9K_PCI2727 bool "Atheros ath9k PCI/PCIe bus support"2828+ default y2829 depends on ATH9K && PCI2930 ---help---3031 This option enables the PCI bus support in ath9k.
···109109#define BPHY_PLCP_TIME 192110110#define RIFS_11N_TIME 2111111112112-#define AC_BE 0113113-#define AC_BK 1114114-#define AC_VI 2115115-#define AC_VO 3116116-117112/* length of the BCN template area */118113#define BCN_TMPL_LEN 512119114···300305#endif /* BCMDBG */301306302307/* TX FIFO number to WME/802.1E Access Category */303303-static const u8 wme_fifo2ac[] = { AC_BK, AC_BE, AC_VI, AC_VO, AC_BE, AC_BE };308308+static const u8 wme_fifo2ac[] = {309309+ IEEE80211_AC_BK,310310+ IEEE80211_AC_BE,311311+ IEEE80211_AC_VI,312312+ IEEE80211_AC_VO,313313+ IEEE80211_AC_BE,314314+ IEEE80211_AC_BE315315+};304316305305-/* WME/802.1E Access Category to TX FIFO number */306306-static const u8 wme_ac2fifo[] = { 1, 0, 2, 3 };317317+/* ieee80211 Access Category to TX FIFO number */318318+static const u8 wme_ac2fifo[] = {319319+ TX_AC_VO_FIFO,320320+ TX_AC_VI_FIFO,321321+ TX_AC_BE_FIFO,322322+ TX_AC_BK_FIFO323323+};307324308325/* 802.1D Priority to precedence queue mapping */309326const u8 wlc_prio2prec_map[] = {···900893 lfbl, /* Long Frame Rate Fallback Limit */901894 fbl;902895903903- if (queue < AC_COUNT) {896896+ if (queue < IEEE80211_NUM_ACS) {904897 sfbl = GFIELD(wlc->wme_retries[wme_fifo2ac[queue]],905898 EDCF_SFB);906899 lfbl = GFIELD(wlc->wme_retries[wme_fifo2ac[queue]],···949942 tx_info->flags |= IEEE80211_TX_STAT_ACK;950943 }951944952952- totlen = brcmu_pkttotlen(p);945945+ totlen = p->len;953946 free_pdu = true;954947955948 brcms_c_txfifo_complete(wlc, queue, 1);···35833576 brcms_c_set_phy_chanspec(wlc, chanspec);35843577}3585357835863586-static void brcms_c_mac_bcn_promisc(struct brcms_c_info *wlc)35793579+/*35803580+ * Set or clear maccontrol bits MCTL_PROMISC, MCTL_BCNS_PROMISC and35813581+ * MCTL_KEEPCONTROL35823582+ */35833583+static void brcms_c_mac_promisc(struct brcms_c_info *wlc)35873584{35853585+ u32 promisc_bits = 0;35863586+35883587 if (wlc->bcnmisc_monitor)35893589- brcms_b_mctrl(wlc->hw, MCTL_BCNS_PROMISC, MCTL_BCNS_PROMISC);35903590- else35913591- brcms_b_mctrl(wlc->hw, MCTL_BCNS_PROMISC, 0);35883588+ promisc_bits |= MCTL_BCNS_PROMISC;35893589+35903590+ if (wlc->monitor)35913591+ promisc_bits |=35923592+ MCTL_PROMISC | MCTL_BCNS_PROMISC | MCTL_KEEPCONTROL;35933593+35943594+ brcms_b_mctrl(wlc->hw,35953595+ MCTL_PROMISC | MCTL_BCNS_PROMISC | MCTL_KEEPCONTROL,35963596+ promisc_bits);35923597}3593359835943599void brcms_c_mac_bcn_promisc_change(struct brcms_c_info *wlc, bool promisc)35953600{35963601 wlc->bcnmisc_monitor = promisc;35973597- brcms_c_mac_bcn_promisc(wlc);35983598-}35993599-36003600-/* set or clear maccontrol bits MCTL_PROMISC and MCTL_KEEPCONTROL */36013601-static void brcms_c_mac_promisc(struct brcms_c_info *wlc)36023602-{36033603- u32 promisc_bits = 0;36043604-36053605- /*36063606- * promiscuous mode just sets MCTL_PROMISC36073607- * Note: APs get all BSS traffic without the need to set36083608- * the MCTL_PROMISC bit since all BSS data traffic is36093609- * directed at the AP36103610- */36113611- if (wlc->pub->promisc)36123612- promisc_bits |= MCTL_PROMISC;36133613-36143614- /* monitor mode needs both MCTL_PROMISC and MCTL_KEEPCONTROL36153615- * Note: monitor mode also needs MCTL_BCNS_PROMISC, but that is36163616- * handled in brcms_c_mac_bcn_promisc()36173617- */36183618- if (wlc->monitor)36193619- promisc_bits |= MCTL_PROMISC | MCTL_KEEPCONTROL;36203620-36213621- brcms_b_mctrl(wlc->hw, MCTL_PROMISC | MCTL_KEEPCONTROL, promisc_bits);36023602+ brcms_c_mac_promisc(wlc);36223603}3623360436243605/*···36383643 }3639364436403645 /* update the various promisc bits */36413641- brcms_c_mac_bcn_promisc(wlc);36423646 brcms_c_mac_promisc(wlc);36433647}36443648···41194125 EDCF_TXOP2USEC(acp_shm.txop);41204126 acp_shm.aifs = (params->aifs & EDCF_AIFSN_MASK);4121412741224122- if (aci == AC_VI && acp_shm.txop == 041284128+ if (aci == IEEE80211_AC_VI && acp_shm.txop == 041234129 && acp_shm.aifs < EDCF_AIFSN_MAX)41244130 acp_shm.aifs++;41254131···41694175 }; /* ucode needs these parameters during its initialization */41704176 const struct edcf_acparam *edcf_acp = &default_edcf_acparams[0];4171417741724172- for (i_ac = 0; i_ac < AC_COUNT; i_ac++, edcf_acp++) {41784178+ for (i_ac = 0; i_ac < IEEE80211_NUM_ACS; i_ac++, edcf_acp++) {41734179 /* find out which ac this set of params applies to */41744180 aci = (edcf_acp->ACI & EDCF_ACI_MASK) >> EDCF_ACI_SHIFT;41754181···51665172 if (!wlc->clk)51675173 return;5168517451695169- for (ac = 0; ac < AC_COUNT; ac++)51755175+ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)51705176 brcms_b_write_shm(wlc->hw, M_AC_TXLMT_ADDR(ac),51715177 wlc->wme_retries[ac]);51725178}···5641564756425648 brcms_b_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL);5643564956445644- for (ac = 0; ac < AC_COUNT; ac++) {56505650+ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {56455651 wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac],56465652 EDCF_SHORT, wlc->SRL);56475653 wlc->wme_retries[ac] = SFIELD(wlc->wme_retries[ac],···67036709 qos = ieee80211_is_data_qos(h->frame_control);6704671067056711 /* compute length of frame in bytes for use in PLCP computations */67066706- len = brcmu_pkttotlen(p);67126712+ len = p->len;67076713 phylen = len + FCS_LEN;6708671467096715 /* Get tx_info */···83528358 /* Uninitialized; read from HW */83538359 int ac;8354836083558355- for (ac = 0; ac < AC_COUNT; ac++)83618361+ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)83568362 wlc->wme_retries[ac] =83578363 brcms_b_read_shm(wlc->hw, M_AC_TXLMT_ADDR(ac));83588364 }
+3-5
drivers/net/wireless/brcm80211/brcmsmac/main.h
···4444/* transmit buffer max headroom for protocol headers */4545#define TXOFF (D11_TXH_LEN + D11_PHY_HDR_LEN)46464747-#define AC_COUNT 44848-4947/* Macros for doing definition and get/set of bitfields5048 * Usage example, e.g. a three-bit field (bits 4-6):5149 * #define <NAME>_M BITFIELD_MASK(3)···434436 * bcn_li_dtim: beacon listen interval in # dtims.435437 * WDarmed: watchdog timer is armed.436438 * WDlast: last time wlc_watchdog() was called.437437- * edcf_txop[AC_COUNT]: current txop for each ac.439439+ * edcf_txop[IEEE80211_NUM_ACS]: current txop for each ac.438440 * wme_retries: per-AC retry limits.439441 * tx_prec_map: Precedence map based on HW FIFO space.440442 * fifo2prec_map[NFIFO]: pointer to fifo2_prec map based on WME.···533535 u32 WDlast;534536535537 /* WME */536536- u16 edcf_txop[AC_COUNT];538538+ u16 edcf_txop[IEEE80211_NUM_ACS];537539538538- u16 wme_retries[AC_COUNT];540540+ u16 wme_retries[IEEE80211_NUM_ACS];539541 u16 tx_prec_map;540542 u16 fifo2prec_map[NFIFO];541543
···827827 case IEEE80211_SMPS_STATIC:828828 case IEEE80211_SMPS_DYNAMIC:829829 return IWL_NUM_IDLE_CHAINS_SINGLE;830830+ case IEEE80211_SMPS_AUTOMATIC:830831 case IEEE80211_SMPS_OFF:831832 return active_cnt;832833 default:···984983 list_del(&wait_entry->list);985984 spin_unlock_bh(&priv->notif_wait_lock);986985}986986+987987+#ifdef CONFIG_PM_SLEEP988988+static void iwlagn_convert_p1k(u16 *p1k, __le16 *out)989989+{990990+ int i;991991+992992+ for (i = 0; i < IWLAGN_P1K_SIZE; i++)993993+ out[i] = cpu_to_le16(p1k[i]);994994+}995995+996996+struct wowlan_key_data {997997+ struct iwl_rxon_context *ctx;998998+ struct iwlagn_wowlan_rsc_tsc_params_cmd *rsc_tsc;999999+ struct iwlagn_wowlan_tkip_params_cmd *tkip;10001000+ const u8 *bssid;10011001+ bool error, use_rsc_tsc, use_tkip;10021002+};10031003+10041004+10051005+static void iwlagn_wowlan_program_keys(struct ieee80211_hw *hw,10061006+ struct ieee80211_vif *vif,10071007+ struct ieee80211_sta *sta,10081008+ struct ieee80211_key_conf *key,10091009+ void *_data)10101010+{10111011+ struct iwl_priv *priv = hw->priv;10121012+ struct wowlan_key_data *data = _data;10131013+ struct iwl_rxon_context *ctx = data->ctx;10141014+ struct aes_sc *aes_sc, *aes_tx_sc = NULL;10151015+ struct tkip_sc *tkip_sc, *tkip_tx_sc = NULL;10161016+ struct iwlagn_p1k_cache *rx_p1ks;10171017+ u8 *rx_mic_key;10181018+ struct ieee80211_key_seq seq;10191019+ u32 cur_rx_iv32 = 0;10201020+ u16 p1k[IWLAGN_P1K_SIZE];10211021+ int ret, i;10221022+10231023+ mutex_lock(&priv->shrd->mutex);10241024+10251025+ if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 ||10261026+ key->cipher == WLAN_CIPHER_SUITE_WEP104) &&10271027+ !sta && !ctx->key_mapping_keys)10281028+ ret = iwl_set_default_wep_key(priv, ctx, key);10291029+ else10301030+ ret = iwl_set_dynamic_key(priv, ctx, key, sta);10311031+10321032+ if (ret) {10331033+ IWL_ERR(priv, "Error setting key during suspend!\n");10341034+ data->error = true;10351035+ }10361036+10371037+ switch (key->cipher) {10381038+ case WLAN_CIPHER_SUITE_TKIP:10391039+ if (sta) {10401040+ tkip_sc = data->rsc_tsc->all_tsc_rsc.tkip.unicast_rsc;10411041+ tkip_tx_sc = &data->rsc_tsc->all_tsc_rsc.tkip.tsc;10421042+10431043+ rx_p1ks = data->tkip->rx_uni;10441044+10451045+ ieee80211_get_key_tx_seq(key, &seq);10461046+ tkip_tx_sc->iv16 = cpu_to_le16(seq.tkip.iv16);10471047+ tkip_tx_sc->iv32 = cpu_to_le32(seq.tkip.iv32);10481048+10491049+ ieee80211_get_tkip_p1k_iv(key, seq.tkip.iv32, p1k);10501050+ iwlagn_convert_p1k(p1k, data->tkip->tx.p1k);10511051+10521052+ memcpy(data->tkip->mic_keys.tx,10531053+ &key->key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY],10541054+ IWLAGN_MIC_KEY_SIZE);10551055+10561056+ rx_mic_key = data->tkip->mic_keys.rx_unicast;10571057+ } else {10581058+ tkip_sc =10591059+ data->rsc_tsc->all_tsc_rsc.tkip.multicast_rsc;10601060+ rx_p1ks = data->tkip->rx_multi;10611061+ rx_mic_key = data->tkip->mic_keys.rx_mcast;10621062+ }10631063+10641064+ /*10651065+ * For non-QoS this relies on the fact that both the uCode and10661066+ * mac80211 use TID 0 (as they need to to avoid replay attacks)10671067+ * for checking the IV in the frames.10681068+ */10691069+ for (i = 0; i < IWLAGN_NUM_RSC; i++) {10701070+ ieee80211_get_key_rx_seq(key, i, &seq);10711071+ tkip_sc[i].iv16 = cpu_to_le16(seq.tkip.iv16);10721072+ tkip_sc[i].iv32 = cpu_to_le32(seq.tkip.iv32);10731073+ /* wrapping isn't allowed, AP must rekey */10741074+ if (seq.tkip.iv32 > cur_rx_iv32)10751075+ cur_rx_iv32 = seq.tkip.iv32;10761076+ }10771077+10781078+ ieee80211_get_tkip_rx_p1k(key, data->bssid, cur_rx_iv32, p1k);10791079+ iwlagn_convert_p1k(p1k, rx_p1ks[0].p1k);10801080+ ieee80211_get_tkip_rx_p1k(key, data->bssid,10811081+ cur_rx_iv32 + 1, p1k);10821082+ iwlagn_convert_p1k(p1k, rx_p1ks[1].p1k);10831083+10841084+ memcpy(rx_mic_key,10851085+ &key->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY],10861086+ IWLAGN_MIC_KEY_SIZE);10871087+10881088+ data->use_tkip = true;10891089+ data->use_rsc_tsc = true;10901090+ break;10911091+ case WLAN_CIPHER_SUITE_CCMP:10921092+ if (sta) {10931093+ u8 *pn = seq.ccmp.pn;10941094+10951095+ aes_sc = data->rsc_tsc->all_tsc_rsc.aes.unicast_rsc;10961096+ aes_tx_sc = &data->rsc_tsc->all_tsc_rsc.aes.tsc;10971097+10981098+ ieee80211_get_key_tx_seq(key, &seq);10991099+ aes_tx_sc->pn = cpu_to_le64(11001100+ (u64)pn[5] |11011101+ ((u64)pn[4] << 8) |11021102+ ((u64)pn[3] << 16) |11031103+ ((u64)pn[2] << 24) |11041104+ ((u64)pn[1] << 32) |11051105+ ((u64)pn[0] << 40));11061106+ } else11071107+ aes_sc = data->rsc_tsc->all_tsc_rsc.aes.multicast_rsc;11081108+11091109+ /*11101110+ * For non-QoS this relies on the fact that both the uCode and11111111+ * mac80211 use TID 0 for checking the IV in the frames.11121112+ */11131113+ for (i = 0; i < IWLAGN_NUM_RSC; i++) {11141114+ u8 *pn = seq.ccmp.pn;11151115+11161116+ ieee80211_get_key_rx_seq(key, i, &seq);11171117+ aes_sc->pn = cpu_to_le64(11181118+ (u64)pn[5] |11191119+ ((u64)pn[4] << 8) |11201120+ ((u64)pn[3] << 16) |11211121+ ((u64)pn[2] << 24) |11221122+ ((u64)pn[1] << 32) |11231123+ ((u64)pn[0] << 40));11241124+ }11251125+ data->use_rsc_tsc = true;11261126+ break;11271127+ }11281128+11291129+ mutex_unlock(&priv->shrd->mutex);11301130+}11311131+11321132+int iwlagn_send_patterns(struct iwl_priv *priv,11331133+ struct cfg80211_wowlan *wowlan)11341134+{11351135+ struct iwlagn_wowlan_patterns_cmd *pattern_cmd;11361136+ struct iwl_host_cmd cmd = {11371137+ .id = REPLY_WOWLAN_PATTERNS,11381138+ .dataflags[0] = IWL_HCMD_DFL_NOCOPY,11391139+ .flags = CMD_SYNC,11401140+ };11411141+ int i, err;11421142+11431143+ if (!wowlan->n_patterns)11441144+ return 0;11451145+11461146+ cmd.len[0] = sizeof(*pattern_cmd) +11471147+ wowlan->n_patterns * sizeof(struct iwlagn_wowlan_pattern);11481148+11491149+ pattern_cmd = kmalloc(cmd.len[0], GFP_KERNEL);11501150+ if (!pattern_cmd)11511151+ return -ENOMEM;11521152+11531153+ pattern_cmd->n_patterns = cpu_to_le32(wowlan->n_patterns);11541154+11551155+ for (i = 0; i < wowlan->n_patterns; i++) {11561156+ int mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8);11571157+11581158+ memcpy(&pattern_cmd->patterns[i].mask,11591159+ wowlan->patterns[i].mask, mask_len);11601160+ memcpy(&pattern_cmd->patterns[i].pattern,11611161+ wowlan->patterns[i].pattern,11621162+ wowlan->patterns[i].pattern_len);11631163+ pattern_cmd->patterns[i].mask_size = mask_len;11641164+ pattern_cmd->patterns[i].pattern_size =11651165+ wowlan->patterns[i].pattern_len;11661166+ }11671167+11681168+ cmd.data[0] = pattern_cmd;11691169+ err = iwl_trans_send_cmd(trans(priv), &cmd);11701170+ kfree(pattern_cmd);11711171+ return err;11721172+}11731173+11741174+int iwlagn_suspend(struct iwl_priv *priv,11751175+ struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)11761176+{11771177+ struct iwlagn_wowlan_wakeup_filter_cmd wakeup_filter_cmd;11781178+ struct iwl_rxon_cmd rxon;11791179+ struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];11801180+ struct iwlagn_wowlan_kek_kck_material_cmd kek_kck_cmd;11811181+ struct iwlagn_wowlan_tkip_params_cmd tkip_cmd = {};11821182+ struct iwlagn_d3_config_cmd d3_cfg_cmd = {};11831183+ struct wowlan_key_data key_data = {11841184+ .ctx = ctx,11851185+ .bssid = ctx->active.bssid_addr,11861186+ .use_rsc_tsc = false,11871187+ .tkip = &tkip_cmd,11881188+ .use_tkip = false,11891189+ };11901190+ int ret, i;11911191+ u16 seq;11921192+11931193+ key_data.rsc_tsc = kzalloc(sizeof(*key_data.rsc_tsc), GFP_KERNEL);11941194+ if (!key_data.rsc_tsc)11951195+ return -ENOMEM;11961196+11971197+ memset(&wakeup_filter_cmd, 0, sizeof(wakeup_filter_cmd));11981198+11991199+ /*12001200+ * We know the last used seqno, and the uCode expects to know that12011201+ * one, it will increment before TX.12021202+ */12031203+ seq = le16_to_cpu(priv->last_seq_ctl) & IEEE80211_SCTL_SEQ;12041204+ wakeup_filter_cmd.non_qos_seq = cpu_to_le16(seq);12051205+12061206+ /*12071207+ * For QoS counters, we store the one to use next, so subtract 0x1012081208+ * since the uCode will add 0x10 before using the value.12091209+ */12101210+ for (i = 0; i < 8; i++) {12111211+ seq = priv->shrd->tid_data[IWL_AP_ID][i].seq_number;12121212+ seq -= 0x10;12131213+ wakeup_filter_cmd.qos_seq[i] = cpu_to_le16(seq);12141214+ }12151215+12161216+ if (wowlan->disconnect)12171217+ wakeup_filter_cmd.enabled |=12181218+ cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_BEACON_MISS |12191219+ IWLAGN_WOWLAN_WAKEUP_LINK_CHANGE);12201220+ if (wowlan->magic_pkt)12211221+ wakeup_filter_cmd.enabled |=12221222+ cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_MAGIC_PACKET);12231223+ if (wowlan->gtk_rekey_failure)12241224+ wakeup_filter_cmd.enabled |=12251225+ cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_GTK_REKEY_FAIL);12261226+ if (wowlan->eap_identity_req)12271227+ wakeup_filter_cmd.enabled |=12281228+ cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_EAP_IDENT_REQ);12291229+ if (wowlan->four_way_handshake)12301230+ wakeup_filter_cmd.enabled |=12311231+ cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_4WAY_HANDSHAKE);12321232+ if (wowlan->n_patterns)12331233+ wakeup_filter_cmd.enabled |=12341234+ cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_PATTERN_MATCH);12351235+12361236+ if (wowlan->rfkill_release)12371237+ d3_cfg_cmd.wakeup_flags |=12381238+ cpu_to_le32(IWLAGN_D3_WAKEUP_RFKILL);12391239+12401240+ iwl_scan_cancel_timeout(priv, 200);12411241+12421242+ memcpy(&rxon, &ctx->active, sizeof(rxon));12431243+12441244+ iwl_trans_stop_device(trans(priv));12451245+12461246+ priv->shrd->wowlan = true;12471247+12481248+ ret = iwlagn_load_ucode_wait_alive(priv, IWL_UCODE_WOWLAN);12491249+ if (ret)12501250+ goto out;12511251+12521252+ /* now configure WoWLAN ucode */12531253+ ret = iwl_alive_start(priv);12541254+ if (ret)12551255+ goto out;12561256+12571257+ memcpy(&ctx->staging, &rxon, sizeof(rxon));12581258+ ret = iwlagn_commit_rxon(priv, ctx);12591259+ if (ret)12601260+ goto out;12611261+12621262+ ret = iwl_power_update_mode(priv, true);12631263+ if (ret)12641264+ goto out;12651265+12661266+ if (!iwlagn_mod_params.sw_crypto) {12671267+ /* mark all keys clear */12681268+ priv->ucode_key_table = 0;12691269+ ctx->key_mapping_keys = 0;12701270+12711271+ /*12721272+ * This needs to be unlocked due to lock ordering12731273+ * constraints. Since we're in the suspend path12741274+ * that isn't really a problem though.12751275+ */12761276+ mutex_unlock(&priv->shrd->mutex);12771277+ ieee80211_iter_keys(priv->hw, ctx->vif,12781278+ iwlagn_wowlan_program_keys,12791279+ &key_data);12801280+ mutex_lock(&priv->shrd->mutex);12811281+ if (key_data.error) {12821282+ ret = -EIO;12831283+ goto out;12841284+ }12851285+12861286+ if (key_data.use_rsc_tsc) {12871287+ struct iwl_host_cmd rsc_tsc_cmd = {12881288+ .id = REPLY_WOWLAN_TSC_RSC_PARAMS,12891289+ .flags = CMD_SYNC,12901290+ .data[0] = key_data.rsc_tsc,12911291+ .dataflags[0] = IWL_HCMD_DFL_NOCOPY,12921292+ .len[0] = sizeof(key_data.rsc_tsc),12931293+ };12941294+12951295+ ret = iwl_trans_send_cmd(trans(priv), &rsc_tsc_cmd);12961296+ if (ret)12971297+ goto out;12981298+ }12991299+13001300+ if (key_data.use_tkip) {13011301+ ret = iwl_trans_send_cmd_pdu(trans(priv),13021302+ REPLY_WOWLAN_TKIP_PARAMS,13031303+ CMD_SYNC, sizeof(tkip_cmd),13041304+ &tkip_cmd);13051305+ if (ret)13061306+ goto out;13071307+ }13081308+13091309+ if (priv->have_rekey_data) {13101310+ memset(&kek_kck_cmd, 0, sizeof(kek_kck_cmd));13111311+ memcpy(kek_kck_cmd.kck, priv->kck, NL80211_KCK_LEN);13121312+ kek_kck_cmd.kck_len = cpu_to_le16(NL80211_KCK_LEN);13131313+ memcpy(kek_kck_cmd.kek, priv->kek, NL80211_KEK_LEN);13141314+ kek_kck_cmd.kek_len = cpu_to_le16(NL80211_KEK_LEN);13151315+ kek_kck_cmd.replay_ctr = priv->replay_ctr;13161316+13171317+ ret = iwl_trans_send_cmd_pdu(trans(priv),13181318+ REPLY_WOWLAN_KEK_KCK_MATERIAL,13191319+ CMD_SYNC, sizeof(kek_kck_cmd),13201320+ &kek_kck_cmd);13211321+ if (ret)13221322+ goto out;13231323+ }13241324+ }13251325+13261326+ ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_D3_CONFIG, CMD_SYNC,13271327+ sizeof(d3_cfg_cmd), &d3_cfg_cmd);13281328+ if (ret)13291329+ goto out;13301330+13311331+ ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_WOWLAN_WAKEUP_FILTER,13321332+ CMD_SYNC, sizeof(wakeup_filter_cmd),13331333+ &wakeup_filter_cmd);13341334+ if (ret)13351335+ goto out;13361336+13371337+ ret = iwlagn_send_patterns(priv, wowlan);13381338+ out:13391339+ kfree(key_data.rsc_tsc);13401340+ return ret;13411341+}13421342+#endif
+2-6
drivers/net/wireless/iwlwifi/iwl-agn-rs.c
···14581458 break;14591459 case IWL_BT_COEX_TRAFFIC_LOAD_LOW:14601460 /* avoid antenna B unless MIMO */14611461- valid_tx_ant =14621462- first_antenna(hw_params(priv).valid_tx_ant);14631461 if (tbl->action == IWL_LEGACY_SWITCH_ANTENNA2)14641464- tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;14621462+ tbl->action = IWL_LEGACY_SWITCH_SISO;14651463 break;14661464 case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:14671465 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:···16341636 break;16351637 case IWL_BT_COEX_TRAFFIC_LOAD_LOW:16361638 /* avoid antenna B unless MIMO */16371637- valid_tx_ant =16381638- first_antenna(hw_params(priv).valid_tx_ant);16391639 if (tbl->action == IWL_SISO_SWITCH_ANTENNA2)16401640- tbl->action = IWL_SISO_SWITCH_ANTENNA1;16401640+ tbl->action = IWL_SISO_SWITCH_MIMO2_AB;16411641 break;16421642 case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:16431643 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
+48-1
drivers/net/wireless/iwlwifi/iwl-agn-rx.c
···800800 ctx->active.bssid_addr))801801 continue;802802 ctx->last_tx_rejected = false;803803- iwl_trans_wake_any_queue(trans(priv), ctx->ctxid);803803+ iwl_trans_wake_any_queue(trans(priv), ctx->ctxid,804804+ "channel got active");804805 }805806 }806807···10331032 return 0;10341033}1035103410351035+static int iwlagn_rx_noa_notification(struct iwl_priv *priv,10361036+ struct iwl_rx_mem_buffer *rxb,10371037+ struct iwl_device_cmd *cmd)10381038+{10391039+ struct iwl_wipan_noa_data *new_data, *old_data;10401040+ struct iwl_rx_packet *pkt = rxb_addr(rxb);10411041+ struct iwl_wipan_noa_notification *noa_notif = (void *)pkt->u.raw;10421042+10431043+ /* no condition -- we're in softirq */10441044+ old_data = rcu_dereference_protected(priv->noa_data, true);10451045+10461046+ if (noa_notif->noa_active) {10471047+ u32 len = le16_to_cpu(noa_notif->noa_attribute.length);10481048+ u32 copylen = len;10491049+10501050+ /* EID, len, OUI, subtype */10511051+ len += 1 + 1 + 3 + 1;10521052+ /* P2P id, P2P length */10531053+ len += 1 + 2;10541054+ copylen += 1 + 2;10551055+10561056+ new_data = kmalloc(sizeof(*new_data) + len, GFP_ATOMIC);10571057+ if (new_data) {10581058+ new_data->length = len;10591059+ new_data->data[0] = WLAN_EID_VENDOR_SPECIFIC;10601060+ new_data->data[1] = len - 2; /* not counting EID, len */10611061+ new_data->data[2] = (WLAN_OUI_WFA >> 16) & 0xff;10621062+ new_data->data[3] = (WLAN_OUI_WFA >> 8) & 0xff;10631063+ new_data->data[4] = (WLAN_OUI_WFA >> 0) & 0xff;10641064+ new_data->data[5] = WLAN_OUI_TYPE_WFA_P2P;10651065+ memcpy(&new_data->data[6], &noa_notif->noa_attribute,10661066+ copylen);10671067+ }10681068+ } else10691069+ new_data = NULL;10701070+10711071+ rcu_assign_pointer(priv->noa_data, new_data);10721072+10731073+ if (old_data)10741074+ kfree_rcu(old_data, rcu_head);10751075+10761076+ return 0;10771077+}10781078+10361079/**10371080 * iwl_setup_rx_handlers - Initialize Rx handler callbacks10381081 *···10991054 iwlagn_rx_pm_debug_statistics_notif;11001055 handlers[BEACON_NOTIFICATION] = iwlagn_rx_beacon_notif;11011056 handlers[REPLY_ADD_STA] = iwl_add_sta_callback;10571057+10581058+ handlers[REPLY_WIPAN_NOA_NOTIFICATION] = iwlagn_rx_noa_notification;1102105911031060 /*11041061 * The same handler is used for both the REPLY to a discrete
+9-4
drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
···4545 send->filter_flags = old_filter;46464747 if (ret)4848- IWL_ERR(priv, "Error clearing ASSOC_MSK on BSS (%d)\n", ret);4848+ IWL_DEBUG_QUIET_RFKILL(priv,4949+ "Error clearing ASSOC_MSK on BSS (%d)\n", ret);49505051 return ret;5152}···117116 if (ctx->ht.enabled)118117 ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;119118120120- IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",119119+ IWL_DEBUG_INFO(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",121120 ctx->qos_data.qos_active,122121 ctx->qos_data.def_qos_parm.qos_flags);123122···125124 sizeof(struct iwl_qosparam_cmd),126125 &ctx->qos_data.def_qos_parm);127126 if (ret)128128- IWL_ERR(priv, "Failed to update QoS\n");127127+ IWL_DEBUG_QUIET_RFKILL(priv, "Failed to update QoS\n");129128}130129131130static int iwlagn_update_beacon(struct iwl_priv *priv,···542541543542 mutex_lock(&priv->shrd->mutex);544543544544+ if (test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))545545+ goto out;546546+545547 if (unlikely(test_bit(STATUS_SCANNING, &priv->shrd->status))) {546548 IWL_DEBUG_MAC80211(priv, "leave - scanning\n");547549 goto out;···844840 if (ctx->last_tx_rejected) {845841 ctx->last_tx_rejected = false;846842 iwl_trans_wake_any_queue(trans(priv),847847- ctx->ctxid);843843+ ctx->ctxid,844844+ "Disassoc: flush queue");848845 }849846 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;850847
···416416417417 if (!iwl_is_associated_ctx(ctx))418418 continue;419419+ if (ctx->staging.dev_type == RXON_DEV_TYPE_P2P)420420+ continue;419421 value = ctx->beacon_int;420422 if (!value)421423 value = IWL_PASSIVE_DWELL_BASE;···941939 return 0;942940}943941944944-int iwlagn_mac_hw_scan(struct ieee80211_hw *hw,945945- struct ieee80211_vif *vif,946946- struct cfg80211_scan_request *req)947947-{948948- struct iwl_priv *priv = hw->priv;949949- int ret;950950-951951- IWL_DEBUG_MAC80211(priv, "enter\n");952952-953953- if (req->n_channels == 0)954954- return -EINVAL;955955-956956- mutex_lock(&priv->shrd->mutex);957957-958958- /*959959- * If an internal scan is in progress, just set960960- * up the scan_request as per above.961961- */962962- if (priv->scan_type != IWL_SCAN_NORMAL) {963963- IWL_DEBUG_SCAN(priv,964964- "SCAN request during internal scan - defer\n");965965- priv->scan_request = req;966966- priv->scan_vif = vif;967967- ret = 0;968968- } else {969969- priv->scan_request = req;970970- priv->scan_vif = vif;971971- /*972972- * mac80211 will only ask for one band at a time973973- * so using channels[0] here is ok974974- */975975- ret = iwl_scan_initiate(priv, vif, IWL_SCAN_NORMAL,976976- req->channels[0]->band);977977- if (ret) {978978- priv->scan_request = NULL;979979- priv->scan_vif = NULL;980980- }981981- }982982-983983- IWL_DEBUG_MAC80211(priv, "leave\n");984984-985985- mutex_unlock(&priv->shrd->mutex);986986-987987- return ret;988988-}989942990943/*991944 * internal short scan, this function should only been called while associated.
+2-5
drivers/net/wireless/iwlwifi/iwl-sv-open.c
···396396 break;397397398398 case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW:399399- status = iwlagn_load_ucode_wait_alive(priv, &priv->ucode_init,400400- IWL_UCODE_INIT);399399+ status = iwlagn_load_ucode_wait_alive(priv, IWL_UCODE_INIT);401400 if (status)402401 IWL_DEBUG_INFO(priv,403402 "Error loading init ucode: %d\n", status);···408409 break;409410410411 case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW:411411- status = iwlagn_load_ucode_wait_alive(priv,412412- &priv->ucode_rt,413413- IWL_UCODE_REGULAR);412412+ status = iwlagn_load_ucode_wait_alive(priv, IWL_UCODE_REGULAR);414413 if (status) {415414 IWL_DEBUG_INFO(priv,416415 "Error loading runtime ucode: %d\n", status);
+29-6
drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h
···355355}356356357357static inline void iwl_wake_queue(struct iwl_trans *trans,358358- struct iwl_tx_queue *txq)358358+ struct iwl_tx_queue *txq, const char *msg)359359{360360 u8 queue = txq->swq_id;361361 u8 ac = queue & 3;···363363 struct iwl_trans_pcie *trans_pcie =364364 IWL_TRANS_GET_PCIE_TRANS(trans);365365366366- if (test_and_clear_bit(hwq, trans_pcie->queue_stopped))367367- if (atomic_dec_return(&trans_pcie->queue_stop_count[ac]) <= 0)366366+ if (test_and_clear_bit(hwq, trans_pcie->queue_stopped)) {367367+ if (atomic_dec_return(&trans_pcie->queue_stop_count[ac]) <= 0) {368368 iwl_wake_sw_queue(priv(trans), ac);369369+ IWL_DEBUG_TX_QUEUES(trans, "Wake hwq %d ac %d. %s",370370+ hwq, ac, msg);371371+ } else {372372+ IWL_DEBUG_TX_QUEUES(trans, "Don't wake hwq %d ac %d"373373+ " stop count %d. %s",374374+ hwq, ac, atomic_read(&trans_pcie->375375+ queue_stop_count[ac]), msg);376376+ }377377+ }369378}370379371380static inline void iwl_stop_queue(struct iwl_trans *trans,372372- struct iwl_tx_queue *txq)381381+ struct iwl_tx_queue *txq, const char *msg)373382{374383 u8 queue = txq->swq_id;375384 u8 ac = queue & 3;···386377 struct iwl_trans_pcie *trans_pcie =387378 IWL_TRANS_GET_PCIE_TRANS(trans);388379389389- if (!test_and_set_bit(hwq, trans_pcie->queue_stopped))390390- if (atomic_inc_return(&trans_pcie->queue_stop_count[ac]) > 0)380380+ if (!test_and_set_bit(hwq, trans_pcie->queue_stopped)) {381381+ if (atomic_inc_return(&trans_pcie->queue_stop_count[ac]) > 0) {391382 iwl_stop_sw_queue(priv(trans), ac);383383+ IWL_DEBUG_TX_QUEUES(trans, "Stop hwq %d ac %d"384384+ " stop count %d. %s",385385+ hwq, ac, atomic_read(&trans_pcie->386386+ queue_stop_count[ac]), msg);387387+ } else {388388+ IWL_DEBUG_TX_QUEUES(trans, "Don't stop hwq %d ac %d"389389+ " stop count %d. %s",390390+ hwq, ac, atomic_read(&trans_pcie->391391+ queue_stop_count[ac]), msg);392392+ }393393+ } else {394394+ IWL_DEBUG_TX_QUEUES(trans, "stop hwq %d, but it is stopped/ %s",395395+ hwq, msg);396396+ }392397}393398394399#ifdef ieee80211_stop_queue
+1-1
drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
···11081108 isr_stats->tx++;11091109 handled |= CSR_INT_BIT_FH_TX;11101110 /* Wake up uCode load routine, now that load is complete */11111111- priv(trans)->ucode_write_complete = 1;11111111+ trans->ucode_write_complete = 1;11121112 wake_up(&trans->shrd->wait_command_queue);11131113 }11141114
+29-23
drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
···430430431431 txq->sched_retry = scd_retry;432432433433- IWL_DEBUG_INFO(trans, "%s %s Queue %d on FIFO %d\n",433433+ IWL_DEBUG_TX_QUEUES(trans, "%s %s Queue %d on FIFO %d\n",434434 active ? "Activate" : "Deactivate",435435 scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id);436436}···561561562562 tid_data = &trans->shrd->tid_data[sta_id][tid];563563 if (tid_data->tfds_in_queue == 0) {564564- IWL_DEBUG_HT(trans, "HW queue is empty\n");564564+ IWL_DEBUG_TX_QUEUES(trans, "HW queue is empty\n");565565 tid_data->agg.state = IWL_AGG_ON;566566 iwl_start_tx_ba_trans_ready(priv(trans), ctx, sta_id, tid);567567 } else {568568- IWL_DEBUG_HT(trans, "HW queue is NOT empty: %d packets in HW"569569- "queue\n", tid_data->tfds_in_queue);568568+ IWL_DEBUG_TX_QUEUES(trans,569569+ "HW queue is NOT empty: %d packets in HW"570570+ " queue\n", tid_data->tfds_in_queue);570571 tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA;571572 }572573 spin_unlock_irqrestore(&trans->shrd->sta_lock, flags);···644643645644 /* The queue is not empty */646645 if (write_ptr != read_ptr) {647647- IWL_DEBUG_HT(trans, "Stopping a non empty AGG HW QUEUE\n");646646+ IWL_DEBUG_TX_QUEUES(trans,647647+ "Stopping a non empty AGG HW QUEUE\n");648648 trans->shrd->tid_data[sta_id][tid].agg.state =649649 IWL_EMPTYING_HW_QUEUE_DELBA;650650 spin_unlock_irqrestore(&trans->shrd->sta_lock, flags);651651 return 0;652652 }653653654654- IWL_DEBUG_HT(trans, "HW queue is empty\n");654654+ IWL_DEBUG_TX_QUEUES(trans, "HW queue is empty\n");655655turn_off:656656 trans->shrd->tid_data[sta_id][tid].agg.state = IWL_AGG_OFF;657657···984982985983 ret = iwl_enqueue_hcmd(trans, cmd);986984 if (ret < 0) {987987- IWL_ERR(trans, "Error sending %s: enqueue_hcmd failed: %d\n",985985+ IWL_DEBUG_QUIET_RFKILL(trans,986986+ "Error sending %s: enqueue_hcmd failed: %d\n",988987 get_cmd_string(cmd->id), ret);989988 return ret;990989 }···10031000 IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n",10041001 get_cmd_string(cmd->id));1005100210031003+ if (test_bit(STATUS_EXIT_PENDING, &trans->shrd->status))10041004+ return -EBUSY;10051005+10061006+10071007+ if (test_bit(STATUS_RF_KILL_HW, &trans->shrd->status)) {10081008+ IWL_ERR(trans, "Command %s aborted: RF KILL Switch\n",10091009+ get_cmd_string(cmd->id));10101010+ return -ECANCELED;10111011+ }10121012+ if (test_bit(STATUS_FW_ERROR, &trans->shrd->status)) {10131013+ IWL_ERR(trans, "Command %s failed: FW Error\n",10141014+ get_cmd_string(cmd->id));10151015+ return -EIO;10161016+ }10061017 set_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status);10071018 IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n",10081019 get_cmd_string(cmd->id));···10251008 if (cmd_idx < 0) {10261009 ret = cmd_idx;10271010 clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status);10281028- IWL_ERR(trans, "Error sending %s: enqueue_hcmd failed: %d\n",10111011+ IWL_DEBUG_QUIET_RFKILL(trans,10121012+ "Error sending %s: enqueue_hcmd failed: %d\n",10291013 get_cmd_string(cmd->id), ret);10301014 return ret;10311015 }···10401022 &trans_pcie->txq[trans->shrd->cmd_queue];10411023 struct iwl_queue *q = &txq->q;1042102410431043- IWL_ERR(trans,10251025+ IWL_DEBUG_QUIET_RFKILL(trans,10441026 "Error sending %s: time out after %dms.\n",10451027 get_cmd_string(cmd->id),10461028 jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));1047102910481048- IWL_ERR(trans,10301030+ IWL_DEBUG_QUIET_RFKILL(trans,10491031 "Current CMD queue read_ptr %d write_ptr %d\n",10501032 q->read_ptr, q->write_ptr);10511033···10571039 }10581040 }1059104110601060- if (test_bit(STATUS_RF_KILL_HW, &trans->shrd->status)) {10611061- IWL_ERR(trans, "Command %s aborted: RF KILL Switch\n",10621062- get_cmd_string(cmd->id));10631063- ret = -ECANCELED;10641064- goto fail;10651065- }10661066- if (test_bit(STATUS_FW_ERROR, &trans->shrd->status)) {10671067- IWL_ERR(trans, "Command %s failed: FW Error\n",10681068- get_cmd_string(cmd->id));10691069- ret = -EIO;10701070- goto fail;10711071- }10721042 if ((cmd->flags & CMD_WANT_SKB) && !cmd->reply_page) {10731043 IWL_ERR(trans, "Error: Response NULL in '%s'\n",10741044 get_cmd_string(cmd->id));···10771071 trans_pcie->txq[trans->shrd->cmd_queue].meta[cmd_idx].flags &=10781072 ~CMD_WANT_SKB;10791073 }10801080-fail:10741074+10811075 if (cmd->reply_page) {10821076 iwl_free_pages(trans->shrd, cmd->reply_page);10831077 cmd->reply_page = 0;
···3333 * Since the buffer is linear, the function uses rotation to simulate3434 * circular buffer.3535 */3636-static int3636+static void3737mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv,3838 struct mwifiex_rx_reorder_tbl3939 *rx_reor_tbl_ptr, int start_win)···71717272 rx_reor_tbl_ptr->start_win = start_win;7373 spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);7474-7575- return 0;7674}77757876/*···8183 * Since the buffer is linear, the function uses rotation to simulate8284 * circular buffer.8385 */8484-static int8686+static void8587mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv,8688 struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr)8789{···117119 rx_reor_tbl_ptr->start_win = (rx_reor_tbl_ptr->start_win + i)118120 &(MAX_TID_VALUE - 1);119121 spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);120120- return 0;121122}122123123124/*···402405 u8 *ta, u8 pkt_type, void *payload)403406{404407 struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr;405405- int start_win, end_win, win_size, ret;408408+ int start_win, end_win, win_size;406409 u16 pkt_index;407410408411 rx_reor_tbl_ptr =···449452 start_win = (end_win - win_size) + 1;450453 else451454 start_win = (MAX_TID_VALUE - (win_size - seq_num)) + 1;452452- ret = mwifiex_11n_dispatch_pkt_until_start_win(priv,455455+ mwifiex_11n_dispatch_pkt_until_start_win(priv,453456 rx_reor_tbl_ptr, start_win);454454-455455- if (ret)456456- return ret;457457 }458458459459 if (pkt_type != PKT_TYPE_BAR) {···469475 * Dispatch all packets sequentially from start_win until a470476 * hole is found and adjust the start_win appropriately471477 */472472- ret = mwifiex_11n_scan_and_dispatch(priv, rx_reor_tbl_ptr);478478+ mwifiex_11n_scan_and_dispatch(priv, rx_reor_tbl_ptr);473479474474- return ret;480480+ return 0;475481}476482477483/*
+2-2
drivers/net/wireless/mwifiex/Kconfig
···1010 mwifiex.11111212config MWIFIEX_SDIO1313- tristate "Marvell WiFi-Ex Driver for SD8787"1313+ tristate "Marvell WiFi-Ex Driver for SD8787/SD8797"1414 depends on MWIFIEX && MMC1515 select FW_LOADER1616 ---help---1717 This adds support for wireless adapters based on Marvell1818- 8787 chipset with SDIO interface.1818+ 8787/8797 chipsets with SDIO interface.19192020 If you choose to build it as a module, it will be called2121 mwifiex_sdio.
···11601160 *11611161 * @NL80211_ATTR_FEATURE_FLAGS: This u32 attribute contains flags from11621162 * &enum nl80211_feature_flags and is advertised in wiphy information.11631163+ * @NL80211_ATTR_PROBE_RESP_OFFLOAD: Indicates that the HW responds to probe11641164+ *11651165+ * requests while operating in AP-mode.11661166+ * This attribute holds a bitmap of the supported protocols for11671167+ * offloading (see &enum nl80211_probe_resp_offload_support_attr).11681168+ *11691169+ * @NL80211_ATTR_PROBE_RESP: Probe Response template data. Contains the entire11701170+ * probe-response frame. The DA field in the 802.11 header is zero-ed out,11711171+ * to be filled by the FW.11631172 *11641173 * @NL80211_ATTR_MAX: highest attribute number currently defined11651174 * @__NL80211_ATTR_AFTER_LAST: internal use···14031394 NL80211_ATTR_DONT_WAIT_FOR_ACK,1404139514051396 NL80211_ATTR_FEATURE_FLAGS,13971397+13981398+ NL80211_ATTR_PROBE_RESP_OFFLOAD,13991399+14001400+ NL80211_ATTR_PROBE_RESP,1406140114071402 /* add attributes here, update the policy in nl80211.c */14081403···27382725 */27392726enum nl80211_feature_flags {27402727 NL80211_FEATURE_SK_TX_STATUS = 1 << 0,27282728+};27292729+27302730+/**27312731+ * enum nl80211_probe_resp_offload_support_attr - optional supported27322732+ * protocols for probe-response offloading by the driver/FW.27332733+ * To be used with the %NL80211_ATTR_PROBE_RESP_OFFLOAD attribute.27342734+ * Each enum value represents a bit in the bitmap of supported27352735+ * protocols. Typically a subset of probe-requests belonging to a27362736+ * supported protocol will be excluded from offload and uploaded27372737+ * to the host.27382738+ *27392739+ * @NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS: Support for WPS ver. 127402740+ * @NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2: Support for WPS ver. 227412741+ * @NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P: Support for P2P27422742+ * @NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U: Support for 802.11u27432743+ */27442744+enum nl80211_probe_resp_offload_support_attr {27452745+ NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS = 1<<0,27462746+ NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 = 1<<1,27472747+ NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P = 1<<2,27482748+ NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U = 1<<3,27412749};2742275027432751#endif /* __LINUX_NL80211_H */
+19
include/net/cfg80211.h
···391391 * @assocresp_ies: extra information element(s) to add into (Re)Association392392 * Response frames or %NULL393393 * @assocresp_ies_len: length of assocresp_ies in octets394394+ * @probe_resp_len: length of probe response template (@probe_resp)395395+ * @probe_resp: probe response template (AP mode only)394396 */395397struct beacon_parameters {396398 u8 *head, *tail;···410408 size_t proberesp_ies_len;411409 const u8 *assocresp_ies;412410 size_t assocresp_ies_len;411411+ int probe_resp_len;412412+ u8 *probe_resp;413413};414414415415/**···13461342 * doesn't verify much. Note, however, that the passed netdev may be13471343 * %NULL as well if the user requested changing the channel for the13481344 * device itself, or for a monitor interface.13451345+ * @get_channel: Get the current operating channel, should return %NULL if13461346+ * there's no single defined operating channel if for example the13471347+ * device implements channel hopping for multi-channel virtual interfaces.13491348 *13501349 * @scan: Request to do a scan. If returning zero, the scan request is given13511350 * the driver, and will be valid until passed to cfg80211_scan_done().···1634162716351628 int (*probe_client)(struct wiphy *wiphy, struct net_device *dev,16361629 const u8 *peer, u64 *cookie);16301630+16311631+ struct ieee80211_channel *(*get_channel)(struct wiphy *wiphy);16371632};1638163316391634/*···16981689 * @WIPHY_FLAG_REPORTS_OBSS: the device will report beacons from other BSSes16991690 * when there are virtual interfaces in AP mode by calling17001691 * cfg80211_report_obss_beacon().16921692+ * @WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD: When operating as an AP, the device16931693+ * responds to probe-requests in hardware.17011694 */17021695enum wiphy_flags {17031696 WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0),···17201709 WIPHY_FLAG_TDLS_EXTERNAL_SETUP = BIT(16),17211710 WIPHY_FLAG_HAVE_AP_SME = BIT(17),17221711 WIPHY_FLAG_REPORTS_OBSS = BIT(18),17121712+ WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD = BIT(19),17231713};1724171417251715/**···1988197619891977 u32 available_antennas_tx;19901978 u32 available_antennas_rx;19791979+19801980+ /*19811981+ * Bitmap of supported protocols for probe response offloading19821982+ * see &enum nl80211_probe_resp_offload_support_attr. Only valid19831983+ * when the wiphy flag @WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD is set.19841984+ */19851985+ u32 probe_resp_offload;1991198619921987 /* If multiple wiphys are registered and you're handed e.g.19931988 * a regular netdev with assigned ieee80211_ptr, you won't
-8
include/net/ieee80211_radiotap.h
···271271#define IEEE80211_RADIOTAP_MCS_FEC_LDPC 0x10272272273273274274-/* Ugly macro to convert literal channel numbers into their mhz equivalents275275- * There are certianly some conditions that will break this (like feeding it '30')276276- * but they shouldn't arise since nothing talks on channel 30. */277277-#define ieee80211chan2mhz(x) \278278- (((x) <= 14) ? \279279- (((x) == 14) ? 2484 : ((x) * 5) + 2407) : \280280- ((x) + 1000) * 5)281281-282274/* helpers */283275static inline int ieee80211_get_radiotap_len(unsigned char *data)284276{
+15
include/net/mac80211.h
···166166 * that it is only ever disabled for station mode.167167 * @BSS_CHANGED_IDLE: Idle changed for this BSS/interface.168168 * @BSS_CHANGED_SSID: SSID changed for this BSS (AP mode)169169+ * @BSS_CHANGED_AP_PROBE_RESP: Probe Response changed for this BSS (AP mode)169170 */170171enum ieee80211_bss_change {171172 BSS_CHANGED_ASSOC = 1<<0,···185184 BSS_CHANGED_QOS = 1<<13,186185 BSS_CHANGED_IDLE = 1<<14,187186 BSS_CHANGED_SSID = 1<<15,187187+ BSS_CHANGED_AP_PROBE_RESP = 1<<16,188188189189 /* when adding here, make sure to change ieee80211_reconfig */190190};···26752673{26762674 return ieee80211_beacon_get_tim(hw, vif, NULL, NULL);26772675}26762676+26772677+/**26782678+ * ieee80211_proberesp_get - retrieve a Probe Response template26792679+ * @hw: pointer obtained from ieee80211_alloc_hw().26802680+ * @vif: &struct ieee80211_vif pointer from the add_interface callback.26812681+ *26822682+ * Creates a Probe Response template which can, for example, be uploaded to26832683+ * hardware. The destination address should be set by the caller.26842684+ *26852685+ * Can only be called in AP mode.26862686+ */26872687+struct sk_buff *ieee80211_proberesp_get(struct ieee80211_hw *hw,26882688+ struct ieee80211_vif *vif);2678268926792690/**26802691 * ieee80211_pspoll_get - retrieve a PS Poll template
···491491 (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE);492492}493493494494+static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata,495495+ u8 *resp, size_t resp_len)496496+{497497+ struct sk_buff *new, *old;498498+499499+ if (!resp || !resp_len)500500+ return -EINVAL;501501+502502+ old = sdata->u.ap.probe_resp;503503+504504+ new = dev_alloc_skb(resp_len);505505+ if (!new)506506+ return -ENOMEM;507507+508508+ memcpy(skb_put(new, resp_len), resp, resp_len);509509+510510+ rcu_assign_pointer(sdata->u.ap.probe_resp, new);511511+ synchronize_rcu();512512+513513+ if (old)514514+ dev_kfree_skb(old);515515+516516+ return 0;517517+}518518+494519/*495520 * This handles both adding a beacon and setting new beacon info496521 */···526501 int new_head_len, new_tail_len;527502 int size;528503 int err = -EINVAL;504504+ u32 changed = 0;529505530506 old = rtnl_dereference(sdata->u.ap.beacon);531507···610584611585 kfree(old);612586613613- ieee80211_config_ap_ssid(sdata, params);587587+ err = ieee80211_set_probe_resp(sdata, params->probe_resp,588588+ params->probe_resp_len);589589+ if (!err)590590+ changed |= BSS_CHANGED_AP_PROBE_RESP;614591615615- ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED |616616- BSS_CHANGED_BEACON |617617- BSS_CHANGED_SSID);592592+ ieee80211_config_ap_ssid(sdata, params);593593+ changed |= BSS_CHANGED_BEACON_ENABLED |594594+ BSS_CHANGED_BEACON |595595+ BSS_CHANGED_SSID;596596+597597+ ieee80211_bss_info_change_notify(sdata, changed);618598 return 0;619599}620600···901869902870 sta_apply_parameters(local, sta, params);903871904904- rate_control_rate_init(sta);872872+ /*873873+ * for TDLS, rate control should be initialized only when supported874874+ * rates are known.875875+ */876876+ if (!test_sta_flag(sta, WLAN_STA_TDLS_PEER))877877+ rate_control_rate_init(sta);905878906879 layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||907880 sdata->vif.type == NL80211_IFTYPE_AP;···989952 }990953991954 sta_apply_parameters(local, sta, params);955955+956956+ if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) && params->supported_rates)957957+ rate_control_rate_init(sta);992958993959 rcu_read_unlock();994960···2570253025712531 rcu_read_lock();25722532 sta = sta_info_get(sdata, peer);25732573- if (sta)25332533+ if (sta) {25742534 qos = test_sta_flag(sta, WLAN_STA_WME);25752575- rcu_read_unlock();25762576-25772577- if (!sta)25352535+ rcu_read_unlock();25362536+ } else {25372537+ rcu_read_unlock();25782538 return -ENOLINK;25392539+ }2579254025802541 if (qos) {25812542 fc = cpu_to_le16(IEEE80211_FTYPE_DATA |···2621258026222581 *cookie = (unsigned long) skb;26232582 return 0;25832583+}25842584+25852585+static struct ieee80211_channel *25862586+ieee80211_wiphy_get_channel(struct wiphy *wiphy)25872587+{25882588+ struct ieee80211_local *local = wiphy_priv(wiphy);25892589+25902590+ return local->oper_channel;26242591}2625259226262593struct cfg80211_ops mac80211_config_ops = {···26972648 .tdls_oper = ieee80211_tdls_oper,26982649 .tdls_mgmt = ieee80211_tdls_mgmt,26992650 .probe_client = ieee80211_probe_client,26512651+ .get_channel = ieee80211_wiphy_get_channel,27002652};
+3
net/mac80211/ibss.c
···9797 /* if merging, indicate to driver that we leave the old IBSS */9898 if (sdata->vif.bss_conf.ibss_joined) {9999 sdata->vif.bss_conf.ibss_joined = false;100100+ netif_carrier_off(sdata->dev);100101 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IBSS);101102 }102103···208207 bss = cfg80211_inform_bss_frame(local->hw.wiphy, local->hw.conf.channel,209208 mgmt, skb->len, 0, GFP_KERNEL);210209 cfg80211_put_bss(bss);210210+ netif_carrier_on(sdata->dev);211211 cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL);212212}213213···992990 }993991994992 sta_info_flush(sdata->local, sdata);993993+ netif_carrier_off(sdata->dev);995994996995 /* remove beacon */997996 kfree(sdata->u.ibss.ie);
+6-6
net/mac80211/ieee80211_i.h
···232232233233struct ieee80211_if_ap {234234 struct beacon_data __rcu *beacon;235235+ struct sk_buff __rcu *probe_resp;235236236237 struct list_head vlans;237238···729728 * operating channel730729 * @SCAN_SET_CHANNEL: Set the next channel to be scanned731730 * @SCAN_SEND_PROBE: Send probe requests and wait for probe responses732732- * @SCAN_LEAVE_OPER_CHANNEL: Leave the operating channel, notify the AP733733- * about us leaving the channel and stop all associated STA interfaces734734- * @SCAN_ENTER_OPER_CHANNEL: Enter the operating channel again, notify the735735- * AP about us being back and restart all associated STA interfaces731731+ * @SCAN_SUSPEND: Suspend the scan and go back to operating channel to732732+ * send out data733733+ * @SCAN_RESUME: Resume the scan and scan the next channel736734 */737735enum mac80211_scan_state {738736 SCAN_DECISION,739737 SCAN_SET_CHANNEL,740738 SCAN_SEND_PROBE,741741- SCAN_LEAVE_OPER_CHANNEL,742742- SCAN_ENTER_OPER_CHANNEL,739739+ SCAN_SUSPEND,740740+ SCAN_RESUME,743741};744742745743struct ieee80211_local {
+7-2
net/mac80211/iface.c
···293293 changed |= ieee80211_reset_erp_info(sdata);294294 ieee80211_bss_info_change_notify(sdata, changed);295295296296- if (sdata->vif.type == NL80211_IFTYPE_STATION)296296+ if (sdata->vif.type == NL80211_IFTYPE_STATION ||297297+ sdata->vif.type == NL80211_IFTYPE_ADHOC)297298 netif_carrier_off(dev);298299 else299300 netif_carrier_on(dev);···462461 struct ieee80211_sub_if_data *vlan, *tmpsdata;463462 struct beacon_data *old_beacon =464463 rtnl_dereference(sdata->u.ap.beacon);464464+ struct sk_buff *old_probe_resp =465465+ rtnl_dereference(sdata->u.ap.probe_resp);465466466467 /* sdata_running will return false, so this will disable */467468 ieee80211_bss_info_change_notify(sdata,468469 BSS_CHANGED_BEACON_ENABLED);469470470470- /* remove beacon */471471+ /* remove beacon and probe response */471472 RCU_INIT_POINTER(sdata->u.ap.beacon, NULL);473473+ RCU_INIT_POINTER(sdata->u.ap.probe_resp, NULL);472474 synchronize_rcu();473475 kfree(old_beacon);476476+ kfree_skb(old_probe_resp);474477475478 /* down all dependent devices, that is VLANs */476479 list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans,
···13571357 ieee80211_set_disassoc(sdata, true, true);13581358 mutex_unlock(&ifmgd->mtx);1359135913601360- mutex_lock(&local->mtx);13611361- ieee80211_recalc_idle(local);13621362- mutex_unlock(&local->mtx);13631360 /*13641361 * must be outside lock due to cfg80211,13651362 * but that's not a problem.···13651368 IEEE80211_STYPE_DEAUTH,13661369 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,13671370 NULL, true);13711371+13721372+ mutex_lock(&local->mtx);13731373+ ieee80211_recalc_idle(local);13741374+ mutex_unlock(&local->mtx);13681375}1369137613701377void ieee80211_beacon_connection_loss_work(struct work_struct *work)···2135213421362135 ieee80211_set_disassoc(sdata, true, true);21372136 mutex_unlock(&ifmgd->mtx);21382138- mutex_lock(&local->mtx);21392139- ieee80211_recalc_idle(local);21402140- mutex_unlock(&local->mtx);21412137 /*21422138 * must be outside lock due to cfg80211,21432139 * but that's not a problem.···21422144 ieee80211_send_deauth_disassoc(sdata, bssid,21432145 IEEE80211_STYPE_DEAUTH, reason,21442146 NULL, true);21472147+21482148+ mutex_lock(&local->mtx);21492149+ ieee80211_recalc_idle(local);21502150+ mutex_unlock(&local->mtx);21512151+21452152 mutex_lock(&ifmgd->mtx);21462153}21472154
···334334335335336336static void337337-calc_rate_durations(struct minstrel_sta_info *mi, struct ieee80211_local *local,338338- struct minstrel_rate *d, struct ieee80211_rate *rate)337337+calc_rate_durations(struct ieee80211_local *local, struct minstrel_rate *d,338338+ struct ieee80211_rate *rate)339339{340340 int erp = !!(rate->flags & IEEE80211_RATE_ERP_G);341341···402402403403 mr->rix = i;404404 mr->bitrate = sband->bitrates[i].bitrate / 5;405405- calc_rate_durations(mi, local, mr,406406- &sband->bitrates[i]);405405+ calc_rate_durations(local, mr, &sband->bitrates[i]);407406408407 /* calculate maximum number of retransmissions before409408 * fallback (based on maximum segment size) */
+30-32
net/mac80211/rc80211_minstrel_ht.c
···3636/* Transmit duration for the raw data part of an average sized packet */3737#define MCS_DURATION(streams, sgi, bps) MCS_SYMBOL_TIME(sgi, MCS_NSYMS((streams) * (bps)))38383939+/*4040+ * Define group sort order: HT40 -> SGI -> #streams4141+ */4242+#define GROUP_IDX(_streams, _sgi, _ht40) \4343+ MINSTREL_MAX_STREAMS * 2 * _ht40 + \4444+ MINSTREL_MAX_STREAMS * _sgi + \4545+ _streams - 14646+3947/* MCS rate information for an MCS group */4040-#define MCS_GROUP(_streams, _sgi, _ht40) { \4848+#define MCS_GROUP(_streams, _sgi, _ht40) \4949+ [GROUP_IDX(_streams, _sgi, _ht40)] = { \4150 .streams = _streams, \4251 .flags = \4352 (_sgi ? IEEE80211_TX_RC_SHORT_GI : 0) | \···6758 * To enable sufficiently targeted rate sampling, MCS rates are divided into6859 * groups, based on the number of streams and flags (HT40, SGI) that they6960 * use.6161+ *6262+ * Sortorder has to be fixed for GROUP_IDX macro to be applicable:6363+ * HT40 -> SGI -> #streams7064 */7165const struct mcs_group minstrel_mcs_groups[] = {7266 MCS_GROUP(1, 0, 0),···114102static int115103minstrel_ht_get_group_idx(struct ieee80211_tx_rate *rate)116104{117117- int streams = (rate->idx / MCS_GROUP_RATES) + 1;118118- u32 flags = IEEE80211_TX_RC_SHORT_GI | IEEE80211_TX_RC_40_MHZ_WIDTH;119119- int i;120120-121121- for (i = 0; i < ARRAY_SIZE(minstrel_mcs_groups); i++) {122122- if (minstrel_mcs_groups[i].streams != streams)123123- continue;124124- if (minstrel_mcs_groups[i].flags != (rate->flags & flags))125125- continue;126126-127127- return i;128128- }129129-130130- WARN_ON(1);131131- return 0;105105+ return GROUP_IDX((rate->idx / MCS_GROUP_RATES) + 1,106106+ !!(rate->flags & IEEE80211_TX_RC_SHORT_GI),107107+ !!(rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH));132108}133109134110static inline struct minstrel_rate_stats *···130130 * Recalculate success probabilities and counters for a rate using EWMA131131 */132132static void133133-minstrel_calc_rate_ewma(struct minstrel_priv *mp, struct minstrel_rate_stats *mr)133133+minstrel_calc_rate_ewma(struct minstrel_rate_stats *mr)134134{135135 if (unlikely(mr->attempts > 0)) {136136 mr->sample_skipped = 0;···156156 * the expected number of retransmissions and their expected length157157 */158158static void159159-minstrel_ht_calc_tp(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,160160- int group, int rate)159159+minstrel_ht_calc_tp(struct minstrel_ht_sta *mi, int group, int rate)161160{162161 struct minstrel_rate_stats *mr;163162 unsigned int usecs;···225226 mr = &mg->rates[i];226227 mr->retry_updated = false;227228 index = MCS_GROUP_RATES * group + i;228228- minstrel_calc_rate_ewma(mp, mr);229229- minstrel_ht_calc_tp(mp, mi, group, i);229229+ minstrel_calc_rate_ewma(mr);230230+ minstrel_ht_calc_tp(mi, group, i);230231231232 if (!mr->cur_tp)232233 continue;···299300static bool300301minstrel_ht_txstat_valid(struct ieee80211_tx_rate *rate)301302{302302- if (!rate->count)303303+ if (rate->idx < 0)303304 return false;304305305305- if (rate->idx < 0)306306+ if (!rate->count)306307 return false;307308308309 return !!(rate->flags & IEEE80211_TX_RC_MCS);···356357}357358358359static void359359-minstrel_aggr_check(struct minstrel_priv *mp, struct ieee80211_sta *pubsta, struct sk_buff *skb)360360+minstrel_aggr_check(struct ieee80211_sta *pubsta, struct sk_buff *skb)360361{361362 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;362363 struct sta_info *sta = container_of(pubsta, struct sta_info, sta);···454455 if (time_after(jiffies, mi->stats_update + (mp->update_interval / 2 * HZ) / 1000)) {455456 minstrel_ht_update_stats(mp, mi);456457 if (!(info->flags & IEEE80211_TX_CTL_AMPDU))457457- minstrel_aggr_check(mp, sta, skb);458458+ minstrel_aggr_check(sta, skb);458459 }459460}460461···514515static void515516minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,516517 struct ieee80211_tx_rate *rate, int index,517517- struct ieee80211_tx_rate_control *txrc,518518 bool sample, bool rtscts)519519{520520 const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES];···626628 if (sample_idx >= 0) {627629 sample = true;628630 minstrel_ht_set_rate(mp, mi, &ar[0], sample_idx,629629- txrc, true, false);631631+ true, false);630632 info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;631633 } else {632634 minstrel_ht_set_rate(mp, mi, &ar[0], mi->max_tp_rate,633633- txrc, false, false);635635+ false, false);634636 }635637636638 if (mp->hw->max_rates >= 3) {···641643 */642644 if (sample_idx >= 0)643645 minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_tp_rate,644644- txrc, false, false);646646+ false, false);645647 else646648 minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_tp_rate2,647647- txrc, false, true);649649+ false, true);648650649651 minstrel_ht_set_rate(mp, mi, &ar[2], mi->max_prob_rate,650650- txrc, false, !sample);652652+ false, !sample);651653652654 ar[3].count = 0;653655 ar[3].idx = -1;···658660 * max_tp_rate -> max_prob_rate by default.659661 */660662 minstrel_ht_set_rate(mp, mi, &ar[1], mi->max_prob_rate,661661- txrc, false, !sample);663663+ false, !sample);662664663665 ar[2].count = 0;664666 ar[2].idx = -1;
+78-123
net/mac80211/scan.c
···212212 if (bss)213213 ieee80211_rx_bss_put(sdata->local, bss);214214215215- /* If we are on-operating-channel, and this packet is for the216216- * current channel, pass the pkt on up the stack so that217217- * the rest of the stack can make use of it.218218- */219219- if (ieee80211_cfg_on_oper_channel(sdata->local)220220- && (channel == sdata->local->oper_channel))215215+ if (channel == sdata->local->oper_channel)221216 return RX_CONTINUE;222217223218 dev_kfree_skb(skb);···258263 bool was_hw_scan)259264{260265 struct ieee80211_local *local = hw_to_local(hw);261261- bool on_oper_chan;262262- bool enable_beacons = false;263266264267 lockdep_assert_held(&local->mtx);265268···290297 local->scanning = 0;291298 local->scan_channel = NULL;292299293293- on_oper_chan = ieee80211_cfg_on_oper_channel(local);294294-295295- if (was_hw_scan || !on_oper_chan)296296- ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);297297- else298298- /* Set power back to normal operating levels. */299299- ieee80211_hw_config(local, 0);300300+ /* Set power back to normal operating levels. */301301+ ieee80211_hw_config(local, 0);300302301303 if (!was_hw_scan) {302302- bool on_oper_chan2;303304 ieee80211_configure_filter(local);304305 drv_sw_scan_complete(local);305305- on_oper_chan2 = ieee80211_cfg_on_oper_channel(local);306306- /* We should always be on-channel at this point. */307307- WARN_ON(!on_oper_chan2);308308- if (on_oper_chan2 && (on_oper_chan != on_oper_chan2))309309- enable_beacons = true;310310-311311- ieee80211_offchannel_return(local, enable_beacons, true);306306+ ieee80211_offchannel_return(local, true, true);312307 }313308314309 ieee80211_recalc_idle(local);···341360 local->next_scan_state = SCAN_DECISION;342361 local->scan_channel_idx = 0;343362344344- /* We always want to use off-channel PS, even if we345345- * are not really leaving oper-channel. Don't346346- * tell the AP though, as long as we are on-channel.347347- */348348- ieee80211_offchannel_enable_all_ps(local, false);363363+ ieee80211_offchannel_stop_vifs(local, true);349364350365 ieee80211_configure_filter(local);351366···349372 ieee80211_hw_config(local, 0);350373351374 ieee80211_queue_delayed_work(&local->hw,352352- &local->scan_work,353353- IEEE80211_CHANNEL_TIME);375375+ &local->scan_work, 0);354376355377 return 0;356378}···485509486510 next_chan = local->scan_req->channels[local->scan_channel_idx];487511488488- if (ieee80211_cfg_on_oper_channel(local)) {489489- /* We're currently on operating channel. */490490- if (next_chan == local->oper_channel)491491- /* We don't need to move off of operating channel. */492492- local->next_scan_state = SCAN_SET_CHANNEL;493493- else494494- /*495495- * We do need to leave operating channel, as next496496- * scan is somewhere else.497497- */498498- local->next_scan_state = SCAN_LEAVE_OPER_CHANNEL;499499- } else {500500- /*501501- * we're currently scanning a different channel, let's502502- * see if we can scan another channel without interfering503503- * with the current traffic situation.504504- *505505- * Since we don't know if the AP has pending frames for us506506- * we can only check for our tx queues and use the current507507- * pm_qos requirements for rx. Hence, if no tx traffic occurs508508- * at all we will scan as many channels in a row as the pm_qos509509- * latency allows us to. Additionally we also check for the510510- * currently negotiated listen interval to prevent losing511511- * frames unnecessarily.512512- *513513- * Otherwise switch back to the operating channel.514514- */512512+ /*513513+ * we're currently scanning a different channel, let's514514+ * see if we can scan another channel without interfering515515+ * with the current traffic situation.516516+ *517517+ * Since we don't know if the AP has pending frames for us518518+ * we can only check for our tx queues and use the current519519+ * pm_qos requirements for rx. Hence, if no tx traffic occurs520520+ * at all we will scan as many channels in a row as the pm_qos521521+ * latency allows us to. Additionally we also check for the522522+ * currently negotiated listen interval to prevent losing523523+ * frames unnecessarily.524524+ *525525+ * Otherwise switch back to the operating channel.526526+ */515527516516- bad_latency = time_after(jiffies +517517- ieee80211_scan_get_channel_time(next_chan),518518- local->leave_oper_channel_time +519519- usecs_to_jiffies(pm_qos_request(PM_QOS_NETWORK_LATENCY)));528528+ bad_latency = time_after(jiffies +529529+ ieee80211_scan_get_channel_time(next_chan),530530+ local->leave_oper_channel_time +531531+ usecs_to_jiffies(pm_qos_request(PM_QOS_NETWORK_LATENCY)));520532521521- listen_int_exceeded = time_after(jiffies +522522- ieee80211_scan_get_channel_time(next_chan),523523- local->leave_oper_channel_time +524524- usecs_to_jiffies(min_beacon_int * 1024) *525525- local->hw.conf.listen_interval);533533+ listen_int_exceeded = time_after(jiffies +534534+ ieee80211_scan_get_channel_time(next_chan),535535+ local->leave_oper_channel_time +536536+ usecs_to_jiffies(min_beacon_int * 1024) *537537+ local->hw.conf.listen_interval);526538527527- if (associated && ( !tx_empty || bad_latency ||528528- listen_int_exceeded))529529- local->next_scan_state = SCAN_ENTER_OPER_CHANNEL;530530- else531531- local->next_scan_state = SCAN_SET_CHANNEL;532532- }539539+ if (associated && (!tx_empty || bad_latency || listen_int_exceeded))540540+ local->next_scan_state = SCAN_SUSPEND;541541+ else542542+ local->next_scan_state = SCAN_SET_CHANNEL;533543534544 *next_delay = 0;535535-}536536-537537-static void ieee80211_scan_state_leave_oper_channel(struct ieee80211_local *local,538538- unsigned long *next_delay)539539-{540540- /* PS will already be in off-channel mode,541541- * we do that once at the beginning of scanning.542542- */543543- ieee80211_offchannel_stop_vifs(local, false);544544-545545- /*546546- * What if the nullfunc frames didn't arrive?547547- */548548- drv_flush(local, false);549549- if (local->ops->flush)550550- *next_delay = 0;551551- else552552- *next_delay = HZ / 10;553553-554554- /* remember when we left the operating channel */555555- local->leave_oper_channel_time = jiffies;556556-557557- /* advance to the next channel to be scanned */558558- local->next_scan_state = SCAN_SET_CHANNEL;559559-}560560-561561-static void ieee80211_scan_state_enter_oper_channel(struct ieee80211_local *local,562562- unsigned long *next_delay)563563-{564564- /* switch back to the operating channel */565565- local->scan_channel = NULL;566566- if (!ieee80211_cfg_on_oper_channel(local))567567- ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);568568-569569- /*570570- * Re-enable vifs and beaconing. Leave PS571571- * in off-channel state..will put that back572572- * on-channel at the end of scanning.573573- */574574- ieee80211_offchannel_return(local, true, false);575575-576576- *next_delay = HZ / 5;577577- local->next_scan_state = SCAN_DECISION;578545}579546580547static void ieee80211_scan_state_set_channel(struct ieee80211_local *local,···531612532613 local->scan_channel = chan;533614534534- /* Only call hw-config if we really need to change channels. */535535- if (chan != local->hw.conf.channel)536536- if (ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL))537537- skip = 1;615615+ if (ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL))616616+ skip = 1;538617539618 /* advance state machine to next channel/band */540619 local->scan_channel_idx++;···586669 * on the channel.587670 */588671 *next_delay = IEEE80211_CHANNEL_TIME;672672+ local->next_scan_state = SCAN_DECISION;673673+}674674+675675+static void ieee80211_scan_state_suspend(struct ieee80211_local *local,676676+ unsigned long *next_delay)677677+{678678+ /* switch back to the operating channel */679679+ local->scan_channel = NULL;680680+ ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);681681+682682+ /*683683+ * Re-enable vifs and beaconing. Leave PS684684+ * in off-channel state..will put that back685685+ * on-channel at the end of scanning.686686+ */687687+ ieee80211_offchannel_return(local, true, false);688688+689689+ *next_delay = HZ / 5;690690+ /* afterwards, resume scan & go to next channel */691691+ local->next_scan_state = SCAN_RESUME;692692+}693693+694694+static void ieee80211_scan_state_resume(struct ieee80211_local *local,695695+ unsigned long *next_delay)696696+{697697+ /* PS already is in off-channel mode */698698+ ieee80211_offchannel_stop_vifs(local, false);699699+700700+ if (local->ops->flush) {701701+ drv_flush(local, false);702702+ *next_delay = 0;703703+ } else704704+ *next_delay = HZ / 10;705705+706706+ /* remember when we left the operating channel */707707+ local->leave_oper_channel_time = jiffies;708708+709709+ /* advance to the next channel to be scanned */589710 local->next_scan_state = SCAN_DECISION;590711}591712···697742 case SCAN_SEND_PROBE:698743 ieee80211_scan_state_send_probe(local, &next_delay);699744 break;700700- case SCAN_LEAVE_OPER_CHANNEL:701701- ieee80211_scan_state_leave_oper_channel(local, &next_delay);745745+ case SCAN_SUSPEND:746746+ ieee80211_scan_state_suspend(local, &next_delay);702747 break;703703- case SCAN_ENTER_OPER_CHANNEL:704704- ieee80211_scan_state_enter_oper_channel(local, &next_delay);748748+ case SCAN_RESUME:749749+ ieee80211_scan_state_resume(local, &next_delay);705750 break;706751 }707752 } while (next_delay == 0);
···10711071 changed |= BSS_CHANGED_IBSS;10721072 /* fall through */10731073 case NL80211_IFTYPE_AP:10741074- changed |= BSS_CHANGED_SSID;10741074+ changed |= BSS_CHANGED_SSID |10751075+ BSS_CHANGED_AP_PROBE_RESP;10751076 /* fall through */10761077 case NL80211_IFTYPE_MESH_POINT:10771078 changed |= BSS_CHANGED_BEACON |···10931092 break;10941093 }10951094 }10951095+10961096+ ieee80211_recalc_ps(local, -1);1096109710971098 /*10981099 * Clear the WLAN_STA_BLOCK_BA flag so new aggregation
+2-1
net/mac80211/wpa.c
···415415 memmove(pos, pos + CCMP_HDR_LEN, hdrlen);416416417417 /* the HW only needs room for the IV, but not the actual IV */418418- if (info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)418418+ if (info->control.hw_key &&419419+ (info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE))419420 return 0;420421421422 hdr = (struct ieee80211_hdr *) pos;
+9-9
net/nfc/nci/core.c
···125125126126static void nci_reset_req(struct nci_dev *ndev, unsigned long opt)127127{128128- nci_send_cmd(ndev, NCI_OP_CORE_RESET_CMD, 0, NULL);128128+ struct nci_core_reset_cmd cmd;129129+130130+ cmd.reset_type = NCI_RESET_TYPE_RESET_CONFIG;131131+ nci_send_cmd(ndev, NCI_OP_CORE_RESET_CMD, 1, &cmd);129132}130133131134static void nci_init_req(struct nci_dev *ndev, unsigned long opt)···138135139136static void nci_init_complete_req(struct nci_dev *ndev, unsigned long opt)140137{141141- struct nci_core_conn_create_cmd conn_cmd;142138 struct nci_rf_disc_map_cmd cmd;143139 struct disc_map_config *cfg = cmd.mapping_configs;144140 __u8 *num = &cmd.num_mapping_configs;145141 int i;146146-147147- /* create static rf connection */148148- conn_cmd.target_handle = 0;149149- conn_cmd.num_target_specific_params = 0;150150- nci_send_cmd(ndev, NCI_OP_CORE_CONN_CREATE_CMD, 2, &conn_cmd);151142152143 /* set rf mapping configurations */153144 *num = 0;···466469 ndev->data_exchange_cb = cb;467470 ndev->data_exchange_cb_context = cb_context;468471469469- rc = nci_send_data(ndev, ndev->conn_id, skb);472472+ rc = nci_send_data(ndev, NCI_STATIC_RF_CONN_ID, skb);470473 if (rc)471474 clear_bit(NCI_DATA_EXCHANGE, &ndev->flags);472475···722725 if (!skb)723726 return;724727725725- atomic_dec(&ndev->credits_cnt);728728+ /* Check if data flow control is used */729729+ if (atomic_read(&ndev->credits_cnt) !=730730+ NCI_DATA_FLOW_CONTROL_NOT_USED)731731+ atomic_dec(&ndev->credits_cnt);726732727733 nfc_dbg("NCI TX: MT=data, PBF=%d, conn_id=%d, plen=%d",728734 nci_pbf(skb->data),
+3-2
net/nfc/nci/data.c
···9595 __skb_queue_head_init(&frags_q);96969797 while (total_len) {9898- frag_len = min_t(int, total_len, ndev->max_pkt_payload_size);9898+ frag_len =9999+ min_t(int, total_len, ndev->max_data_pkt_payload_size);99100100101 skb_frag = nci_skb_alloc(ndev,101102 (NCI_DATA_HDR_SIZE + frag_len),···152151 nfc_dbg("entry, conn_id 0x%x, plen %d", conn_id, skb->len);153152154153 /* check if the packet need to be fragmented */155155- if (skb->len <= ndev->max_pkt_payload_size) {154154+ if (skb->len <= ndev->max_data_pkt_payload_size) {156155 /* no need to fragment packet */157156 nci_push_data_hdr(ndev, conn_id, skb, NCI_PBF_LAST);158157
+1-7
net/nfc/nci/lib.c
···4242 case NCI_STATUS_REJECTED:4343 return -EBUSY;44444545- case NCI_STATUS_MESSAGE_CORRUPTED:4545+ case NCI_STATUS_RF_FRAME_CORRUPTED:4646 return -EBADMSG;4747-4848- case NCI_STATUS_BUFFER_FULL:4949- return -ENOBUFS;50475148 case NCI_STATUS_NOT_INITIALIZED:5249 return -EHOSTDOWN;···7679 case NCI_STATUS_RF_TIMEOUT_ERROR:7780 case NCI_STATUS_NFCEE_TIMEOUT_ERROR:7881 return -ETIMEDOUT;7979-8080- case NCI_STATUS_RF_LINK_LOSS_ERROR:8181- return -ENOLINK;82828383 case NCI_STATUS_MAX_ACTIVE_NFCEE_INTERFACES_REACHED:8484 return -EDQUOT;
···355355 sizeof(struct ieee80211_meshconf_ie) - 2) == 0;356356}357357358358-static int cmp_bss(struct cfg80211_bss *a,359359- struct cfg80211_bss *b)358358+static int cmp_bss_core(struct cfg80211_bss *a,359359+ struct cfg80211_bss *b)360360{361361 int r;362362···378378 b->len_information_elements);379379 }380380381381- r = memcmp(a->bssid, b->bssid, ETH_ALEN);381381+ return memcmp(a->bssid, b->bssid, ETH_ALEN);382382+}383383+384384+static int cmp_bss(struct cfg80211_bss *a,385385+ struct cfg80211_bss *b)386386+{387387+ int r;388388+389389+ r = cmp_bss_core(a, b);382390 if (r)383391 return r;384392···395387 a->len_information_elements,396388 b->information_elements,397389 b->len_information_elements);390390+}391391+392392+static int cmp_hidden_bss(struct cfg80211_bss *a,393393+ struct cfg80211_bss *b)394394+{395395+ const u8 *ie1;396396+ const u8 *ie2;397397+ int i;398398+ int r;399399+400400+ r = cmp_bss_core(a, b);401401+ if (r)402402+ return r;403403+404404+ ie1 = cfg80211_find_ie(WLAN_EID_SSID,405405+ a->information_elements,406406+ a->len_information_elements);407407+ ie2 = cfg80211_find_ie(WLAN_EID_SSID,408408+ b->information_elements,409409+ b->len_information_elements);410410+411411+ /* Key comparator must use same algorithm in any rb-tree412412+ * search function (order is important), otherwise ordering413413+ * of items in the tree is broken and search gives incorrect414414+ * results. This code uses same order as cmp_ies() does. */415415+416416+ /* sort missing IE before (left of) present IE */417417+ if (!ie1)418418+ return -1;419419+ if (!ie2)420420+ return 1;421421+422422+ /* zero-size SSID is used as an indication of the hidden bss */423423+ if (!ie2[1])424424+ return 0;425425+426426+ /* sort by length first, then by contents */427427+ if (ie1[1] != ie2[1])428428+ return ie2[1] - ie1[1];429429+430430+ /* zeroed SSID ie is another indication of a hidden bss */431431+ for (i = 0; i < ie2[1]; i++)432432+ if (ie2[i + 2])433433+ return -1;434434+435435+ return 0;398436}399437400438struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy,···559505}560506561507static struct cfg80211_internal_bss *508508+rb_find_hidden_bss(struct cfg80211_registered_device *dev,509509+ struct cfg80211_internal_bss *res)510510+{511511+ struct rb_node *n = dev->bss_tree.rb_node;512512+ struct cfg80211_internal_bss *bss;513513+ int r;514514+515515+ while (n) {516516+ bss = rb_entry(n, struct cfg80211_internal_bss, rbn);517517+ r = cmp_hidden_bss(&res->pub, &bss->pub);518518+519519+ if (r == 0)520520+ return bss;521521+ else if (r < 0)522522+ n = n->rb_left;523523+ else524524+ n = n->rb_right;525525+ }526526+527527+ return NULL;528528+}529529+530530+static void531531+copy_hidden_ies(struct cfg80211_internal_bss *res,532532+ struct cfg80211_internal_bss *hidden)533533+{534534+ if (unlikely(res->pub.beacon_ies))535535+ return;536536+ if (WARN_ON(!hidden->pub.beacon_ies))537537+ return;538538+539539+ res->pub.beacon_ies = kmalloc(hidden->pub.len_beacon_ies, GFP_ATOMIC);540540+ if (unlikely(!res->pub.beacon_ies))541541+ return;542542+543543+ res->beacon_ies_allocated = true;544544+ res->pub.len_beacon_ies = hidden->pub.len_beacon_ies;545545+ memcpy(res->pub.beacon_ies, hidden->pub.beacon_ies,546546+ res->pub.len_beacon_ies);547547+}548548+549549+static struct cfg80211_internal_bss *562550cfg80211_bss_update(struct cfg80211_registered_device *dev,563551 struct cfg80211_internal_bss *res)564552{···703607704608 kref_put(&res->ref, bss_release);705609 } else {610610+ struct cfg80211_internal_bss *hidden;611611+612612+ /* First check if the beacon is a probe response from613613+ * a hidden bss. If so, copy beacon ies (with nullified614614+ * ssid) into the probe response bss entry (with real ssid).615615+ * It is required basically for PSM implementation616616+ * (probe responses do not contain tim ie) */617617+618618+ /* TODO: The code is not trying to update existing probe619619+ * response bss entries when beacon ies are620620+ * getting changed. */621621+ hidden = rb_find_hidden_bss(dev, res);622622+ if (hidden)623623+ copy_hidden_ies(res, hidden);624624+706625 /* this "consumes" the reference */707626 list_add_tail(&res->list, &dev->bss_list);708627 rb_insert_bss(dev, res);