diff options
Diffstat (limited to 'drivers/net/wireless/marvell/mwifiex/scan.c')
| -rw-r--r-- | drivers/net/wireless/marvell/mwifiex/scan.c | 228 |
1 files changed, 116 insertions, 112 deletions
diff --git a/drivers/net/wireless/marvell/mwifiex/scan.c b/drivers/net/wireless/marvell/mwifiex/scan.c index ae9630b49342..cab889af4c4a 100644 --- a/drivers/net/wireless/marvell/mwifiex/scan.c +++ b/drivers/net/wireless/marvell/mwifiex/scan.c @@ -1,20 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* - * Marvell Wireless LAN device driver: scan ioctl and command handling + * NXP Wireless LAN device driver: scan ioctl and command handling * - * Copyright (C) 2011-2014, Marvell International Ltd. - * - * This software file (the "File") is distributed by Marvell International - * Ltd. under the terms of the GNU General Public License Version 2, June 1991 - * (the "License"). You may use, redistribute and/or modify this File in - * accordance with the terms and conditions of the License, a copy of which - * is available by writing to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the - * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. - * - * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE - * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE - * ARE EXPRESSLY DISCLAIMED. The License provides additional details about - * this warranty disclaimer. + * Copyright 2011-2020 NXP */ #include "decl.h" @@ -181,7 +169,8 @@ mwifiex_is_wpa_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher) u8 ret = MWIFIEX_OUI_NOT_PRESENT; if (has_vendor_hdr(bss_desc->bcn_wpa_ie, WLAN_EID_VENDOR_SPECIFIC)) { - iebody = (struct ie_body *) bss_desc->bcn_wpa_ie->data; + iebody = (struct ie_body *)((u8 *)bss_desc->bcn_wpa_ie->data + + WPA_GTK_OUI_OFFSET); oui = &mwifiex_wpa_oui[cipher][0]; ret = mwifiex_search_oui_in_ie(iebody, oui); if (ret) @@ -191,17 +180,6 @@ mwifiex_is_wpa_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher) } /* - * This function compares two SSIDs and checks if they match. - */ -s32 -mwifiex_ssid_cmp(struct cfg80211_ssid *ssid1, struct cfg80211_ssid *ssid2) -{ - if (!ssid1 || !ssid2 || (ssid1->ssid_len != ssid2->ssid_len)) - return -1; - return memcmp(ssid1->ssid, ssid2->ssid, ssid1->ssid_len); -} - -/* * This function checks if wapi is enabled in driver and scanned network is * compatible with it. */ @@ -482,7 +460,8 @@ mwifiex_scan_create_channel_list(struct mwifiex_private *priv, scan_chan_list[chan_idx].max_scan_time = cpu_to_le16((u16) user_scan_in-> chan_list[0].scan_time); - else if (ch->flags & IEEE80211_CHAN_NO_IR) + else if ((ch->flags & IEEE80211_CHAN_NO_IR) || + (ch->flags & IEEE80211_CHAN_RADAR)) scan_chan_list[chan_idx].max_scan_time = cpu_to_le16(adapter->passive_scan_time); else @@ -502,10 +481,12 @@ mwifiex_scan_create_channel_list(struct mwifiex_private *priv, scan_chan_list[chan_idx].chan_scan_mode_bitmap |= MWIFIEX_DISABLE_CHAN_FILT; - if (filtered_scan) { + if (filtered_scan && + !((ch->flags & IEEE80211_CHAN_NO_IR) || + (ch->flags & IEEE80211_CHAN_RADAR))) scan_chan_list[chan_idx].max_scan_time = cpu_to_le16(adapter->specific_scan_time); - } + chan_idx++; } @@ -620,7 +601,6 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv, struct mwifiex_adapter *adapter = priv->adapter; int ret = 0; struct mwifiex_chan_scan_param_set *tmp_chan_list; - struct mwifiex_chan_scan_param_set *start_chan; u32 tlv_idx, rates_size, cmd_no; u32 total_scan_time; u32 done_early; @@ -651,7 +631,6 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv, total_scan_time = 0; radio_type = 0; chan_tlv_out->header.len = 0; - start_chan = tmp_chan_list; done_early = false; /* @@ -685,15 +664,14 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv, /* Copy the current channel TLV to the command being prepared */ - memcpy(chan_tlv_out->chan_scan_param + tlv_idx, + memcpy(&chan_tlv_out->chan_scan_param[tlv_idx], tmp_chan_list, - sizeof(chan_tlv_out->chan_scan_param)); + sizeof(*chan_tlv_out->chan_scan_param)); /* Increment the TLV header length by the size appended */ le16_unaligned_add_cpu(&chan_tlv_out->header.len, - sizeof( - chan_tlv_out->chan_scan_param)); + sizeof(*chan_tlv_out->chan_scan_param)); /* * The tlv buffer length is set to the number of bytes @@ -758,8 +736,6 @@ mwifiex_scan_channel_list(struct mwifiex_private *priv, rates_size = mwifiex_append_rate_tlv(priv, scan_cfg_out, radio_type); - priv->adapter->scan_channels = start_chan; - /* Send the scan command to the firmware with the specified cfg */ if (priv->adapter->ext_scan) @@ -836,7 +812,6 @@ mwifiex_config_scan(struct mwifiex_private *priv, u8 ssid_filter; struct mwifiex_ie_types_htcap *ht_cap; struct mwifiex_ie_types_bss_mode *bss_mode; - const u8 zero_mac[6] = {0, 0, 0, 0, 0, 0}; /* The tlv_buf_len is calculated for each scan command. The TLVs added in this routine will be preserved since the routine that sends the @@ -974,7 +949,7 @@ mwifiex_config_scan(struct mwifiex_private *priv, sizeof(struct mwifiex_ie_types_scan_chan_gap); } - if (!ether_addr_equal(user_scan_in->random_mac, zero_mac)) { + if (!is_zero_ether_addr(user_scan_in->random_mac)) { random_mac_tlv = (void *)tlv_pos; random_mac_tlv->header.type = cpu_to_le16(TLV_TYPE_RANDOM_MAC); @@ -1207,7 +1182,6 @@ mwifiex_ret_802_11_scan_get_tlv_ptrs(struct mwifiex_adapter *adapter, int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, struct mwifiex_bssdescriptor *bss_entry) { - int ret = 0; u8 element_id; struct ieee_types_fh_param_set *fh_param_set; struct ieee_types_ds_param_set *ds_param_set; @@ -1240,10 +1214,12 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, mwifiex_dbg(adapter, ERROR, "err: InterpretIE: in processing\t" "IE, bytes left < IE length\n"); - return -1; + return -EINVAL; } switch (element_id) { case WLAN_EID_SSID: + if (element_len > IEEE80211_MAX_SSID_LEN) + return -EINVAL; bss_entry->ssid.ssid_len = element_len; memcpy(bss_entry->ssid.ssid, (current_ptr + 2), element_len); @@ -1253,6 +1229,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, break; case WLAN_EID_SUPP_RATES: + if (element_len > MWIFIEX_SUPPORTED_RATES) + return -EINVAL; memcpy(bss_entry->data_rates, current_ptr + 2, element_len); memcpy(bss_entry->supported_rates, current_ptr + 2, @@ -1262,6 +1240,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, break; case WLAN_EID_FH_PARAMS: + if (total_ie_len < sizeof(*fh_param_set)) + return -EINVAL; fh_param_set = (struct ieee_types_fh_param_set *) current_ptr; memcpy(&bss_entry->phy_param_set.fh_param_set, @@ -1270,6 +1250,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, break; case WLAN_EID_DS_PARAMS: + if (total_ie_len < sizeof(*ds_param_set)) + return -EINVAL; ds_param_set = (struct ieee_types_ds_param_set *) current_ptr; @@ -1281,6 +1263,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, break; case WLAN_EID_CF_PARAMS: + if (total_ie_len < sizeof(*cf_param_set)) + return -EINVAL; cf_param_set = (struct ieee_types_cf_param_set *) current_ptr; memcpy(&bss_entry->ss_param_set.cf_param_set, @@ -1289,6 +1273,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, break; case WLAN_EID_IBSS_PARAMS: + if (total_ie_len < sizeof(*ibss_param_set)) + return -EINVAL; ibss_param_set = (struct ieee_types_ibss_param_set *) current_ptr; @@ -1298,16 +1284,21 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, break; case WLAN_EID_ERP_INFO: + if (!element_len) + return -EINVAL; bss_entry->erp_flags = *(current_ptr + 2); break; case WLAN_EID_PWR_CONSTRAINT: + if (!element_len) + return -EINVAL; bss_entry->local_constraint = *(current_ptr + 2); bss_entry->sensed_11h = true; break; case WLAN_EID_CHANNEL_SWITCH: bss_entry->chan_sw_ie_present = true; + fallthrough; case WLAN_EID_PWR_CAPABILITY: case WLAN_EID_TPC_REPORT: case WLAN_EID_QUIET: @@ -1344,15 +1335,22 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, vendor_ie = (struct ieee_types_vendor_specific *) current_ptr; - if (!memcmp - (vendor_ie->vend_hdr.oui, wpa_oui, - sizeof(wpa_oui))) { + /* 802.11 requires at least 3-byte OUI. */ + if (element_len < sizeof(vendor_ie->vend_hdr.oui.oui)) + return -EINVAL; + + /* Not long enough for a match? Skip it. */ + if (element_len < sizeof(wpa_oui)) + break; + + if (!memcmp(&vendor_ie->vend_hdr.oui, wpa_oui, + sizeof(wpa_oui))) { bss_entry->bcn_wpa_ie = (struct ieee_types_vendor_specific *) current_ptr; bss_entry->wpa_offset = (u16) (current_ptr - bss_entry->beacon_buf); - } else if (!memcmp(vendor_ie->vend_hdr.oui, wmm_oui, + } else if (!memcmp(&vendor_ie->vend_hdr.oui, wmm_oui, sizeof(wmm_oui))) { if (total_ie_len == sizeof(struct ieee_types_wmm_parameter) || @@ -1373,6 +1371,12 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, bss_entry->rsn_offset = (u16) (current_ptr - bss_entry->beacon_buf); break; + case WLAN_EID_RSNX: + bss_entry->bcn_rsnx_ie = + (struct ieee_types_generic *)current_ptr; + bss_entry->rsnx_offset = + (u16)(current_ptr - bss_entry->beacon_buf); + break; case WLAN_EID_BSS_AC_ACCESS_DELAY: bss_entry->bcn_wapi_ie = (struct ieee_types_generic *) current_ptr; @@ -1432,13 +1436,11 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, break; } - current_ptr += element_len + 2; - - /* Need to account for IE ID and IE Len */ - bytes_left -= (element_len + 2); + current_ptr += total_ie_len; + bytes_left -= total_ie_len; } /* while (bytes_left > 2) */ - return ret; + return 0; } /* @@ -1477,7 +1479,6 @@ int mwifiex_scan_networks(struct mwifiex_private *priv, u8 filtered_scan; u8 scan_current_chan_only; u8 max_chan_per_scan; - unsigned long flags; if (adapter->scan_processing) { mwifiex_dbg(adapter, WARN, @@ -1491,15 +1492,16 @@ int mwifiex_scan_networks(struct mwifiex_private *priv, return -EBUSY; } - if (adapter->surprise_removed || adapter->is_cmd_timedout) { + if (test_bit(MWIFIEX_SURPRISE_REMOVED, &adapter->work_flags) || + test_bit(MWIFIEX_IS_CMD_TIMEDOUT, &adapter->work_flags)) { mwifiex_dbg(adapter, ERROR, "Ignore scan. Card removed or firmware in bad state\n"); return -EFAULT; } - spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); + spin_lock_bh(&adapter->mwifiex_cmd_lock); adapter->scan_processing = true; - spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); + spin_unlock_bh(&adapter->mwifiex_cmd_lock); scan_cfg_out = kzalloc(sizeof(union mwifiex_scan_cmd_config_tlv), GFP_KERNEL); @@ -1527,15 +1529,13 @@ int mwifiex_scan_networks(struct mwifiex_private *priv, /* Get scan command from scan_pending_q and put to cmd_pending_q */ if (!ret) { - spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); + spin_lock_bh(&adapter->scan_pending_q_lock); if (!list_empty(&adapter->scan_pending_q)) { cmd_node = list_first_entry(&adapter->scan_pending_q, struct cmd_ctrl_node, list); list_del(&cmd_node->list); - spin_unlock_irqrestore(&adapter->scan_pending_q_lock, - flags); - mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, - true); + spin_unlock_bh(&adapter->scan_pending_q_lock); + mwifiex_insert_cmd_to_pending_q(adapter, cmd_node); queue_work(adapter->workqueue, &adapter->main_work); /* Perform internal scan synchronously */ @@ -1545,8 +1545,7 @@ int mwifiex_scan_networks(struct mwifiex_private *priv, mwifiex_wait_queue_complete(adapter, cmd_node); } } else { - spin_unlock_irqrestore(&adapter->scan_pending_q_lock, - flags); + spin_unlock_bh(&adapter->scan_pending_q_lock); } } @@ -1554,9 +1553,9 @@ int mwifiex_scan_networks(struct mwifiex_private *priv, kfree(scan_chan_list); done: if (ret) { - spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); + spin_lock_bh(&adapter->mwifiex_cmd_lock); adapter->scan_processing = false; - spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); + spin_unlock_bh(&adapter->mwifiex_cmd_lock); } return ret; } @@ -1692,7 +1691,6 @@ static int mwifiex_update_curr_bss_params(struct mwifiex_private *priv, { struct mwifiex_bssdescriptor *bss_desc; int ret; - unsigned long flags; /* Allocate and fill new bss descriptor */ bss_desc = kzalloc(sizeof(struct mwifiex_bssdescriptor), GFP_KERNEL); @@ -1707,7 +1705,7 @@ static int mwifiex_update_curr_bss_params(struct mwifiex_private *priv, if (ret) goto done; - spin_lock_irqsave(&priv->curr_bcn_buf_lock, flags); + spin_lock_bh(&priv->curr_bcn_buf_lock); /* Make a copy of current BSSID descriptor */ memcpy(&priv->curr_bss_params.bss_descriptor, bss_desc, sizeof(priv->curr_bss_params.bss_descriptor)); @@ -1716,7 +1714,7 @@ static int mwifiex_update_curr_bss_params(struct mwifiex_private *priv, * in mwifiex_save_curr_bcn() */ mwifiex_save_curr_bcn(priv); - spin_unlock_irqrestore(&priv->curr_bcn_buf_lock, flags); + spin_unlock_bh(&priv->curr_bcn_buf_lock); done: /* beacon_ie buffer was allocated in function @@ -1867,7 +1865,7 @@ mwifiex_parse_single_response_buf(struct mwifiex_private *priv, u8 **bss_info, chan, CFG80211_BSS_FTYPE_UNKNOWN, bssid, timestamp, cap_info_bitmap, beacon_period, - ie_buf, ie_len, rssi, GFP_KERNEL); + ie_buf, ie_len, rssi, GFP_ATOMIC); if (bss) { bss_priv = (struct mwifiex_bss_priv *)bss->priv; bss_priv->band = band; @@ -1878,15 +1876,17 @@ mwifiex_parse_single_response_buf(struct mwifiex_private *priv, u8 **bss_info, ETH_ALEN)) mwifiex_update_curr_bss_params(priv, bss); - cfg80211_put_bss(priv->wdev.wiphy, bss); - } - if ((chan->flags & IEEE80211_CHAN_RADAR) || - (chan->flags & IEEE80211_CHAN_NO_IR)) { - mwifiex_dbg(adapter, INFO, - "radar or passive channel %d\n", - channel); - mwifiex_save_hidden_ssid_channels(priv, bss); + if ((chan->flags & IEEE80211_CHAN_RADAR) || + (chan->flags & IEEE80211_CHAN_NO_IR)) { + mwifiex_dbg(adapter, INFO, + "radar or passive channel %d\n", + channel); + mwifiex_save_hidden_ssid_channels(priv, + bss); + } + + cfg80211_put_bss(priv->wdev.wiphy, bss); } } } else { @@ -1937,8 +1937,6 @@ mwifiex_active_scan_req_for_passive_chan(struct mwifiex_private *priv) if (!user_scan_cfg) return -ENOMEM; - memset(user_scan_cfg, 0, sizeof(*user_scan_cfg)); - for (id = 0; id < MWIFIEX_USER_SCAN_CHAN_MAX; id++) { if (!priv->hidden_chan[id].chan_number) break; @@ -1948,7 +1946,9 @@ mwifiex_active_scan_req_for_passive_chan(struct mwifiex_private *priv) } adapter->active_scan_triggered = true; - ether_addr_copy(user_scan_cfg->random_mac, priv->random_mac); + if (priv->scan_request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) + ether_addr_copy(user_scan_cfg->random_mac, + priv->scan_request->mac_addr); user_scan_cfg->num_ssids = priv->scan_request->n_ssids; user_scan_cfg->ssid_list = priv->scan_request->ssids; @@ -1968,15 +1968,14 @@ static void mwifiex_check_next_scan_command(struct mwifiex_private *priv) { struct mwifiex_adapter *adapter = priv->adapter; struct cmd_ctrl_node *cmd_node; - unsigned long flags; - spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); + spin_lock_bh(&adapter->scan_pending_q_lock); if (list_empty(&adapter->scan_pending_q)) { - spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); + spin_unlock_bh(&adapter->scan_pending_q_lock); - spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); + spin_lock_bh(&adapter->mwifiex_cmd_lock); adapter->scan_processing = false; - spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); + spin_unlock_bh(&adapter->mwifiex_cmd_lock); mwifiex_active_scan_req_for_passive_chan(priv); @@ -2000,13 +1999,13 @@ static void mwifiex_check_next_scan_command(struct mwifiex_private *priv) } } else if ((priv->scan_aborting && !priv->scan_request) || priv->scan_block) { - spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); + spin_unlock_bh(&adapter->scan_pending_q_lock); mwifiex_cancel_pending_scan_cmd(adapter); - spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); + spin_lock_bh(&adapter->mwifiex_cmd_lock); adapter->scan_processing = false; - spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); + spin_unlock_bh(&adapter->mwifiex_cmd_lock); if (!adapter->active_scan_triggered) { if (priv->scan_request) { @@ -2032,8 +2031,8 @@ static void mwifiex_check_next_scan_command(struct mwifiex_private *priv) cmd_node = list_first_entry(&adapter->scan_pending_q, struct cmd_ctrl_node, list); list_del(&cmd_node->list); - spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); - mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true); + spin_unlock_bh(&adapter->scan_pending_q_lock); + mwifiex_insert_cmd_to_pending_q(adapter, cmd_node); } return; @@ -2042,19 +2041,16 @@ static void mwifiex_check_next_scan_command(struct mwifiex_private *priv) void mwifiex_cancel_scan(struct mwifiex_adapter *adapter) { struct mwifiex_private *priv; - unsigned long cmd_flags; int i; mwifiex_cancel_pending_scan_cmd(adapter); if (adapter->scan_processing) { - spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags); + spin_lock_bh(&adapter->mwifiex_cmd_lock); adapter->scan_processing = false; - spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags); + spin_unlock_bh(&adapter->mwifiex_cmd_lock); for (i = 0; i < adapter->priv_num; i++) { priv = adapter->priv[i]; - if (!priv) - continue; if (priv->scan_request) { struct cfg80211_scan_info info = { .aborted = true, @@ -2178,9 +2174,9 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, if (nd_config) { adapter->nd_info = - kzalloc(sizeof(struct cfg80211_wowlan_nd_match) + - sizeof(struct cfg80211_wowlan_nd_match *) * - scan_rsp->number_of_sets, GFP_ATOMIC); + kzalloc(struct_size(adapter->nd_info, matches, + scan_rsp->number_of_sets), + GFP_ATOMIC); if (adapter->nd_info) adapter->nd_info->n_matches = scan_rsp->number_of_sets; @@ -2376,12 +2372,11 @@ int mwifiex_cmd_802_11_bg_scan_config(struct mwifiex_private *priv, chan_idx < MWIFIEX_BG_SCAN_CHAN_MAX && bgscan_cfg_in->chan_list[chan_idx].chan_number; chan_idx++) { - temp_chan = chan_list_tlv->chan_scan_param + chan_idx; + temp_chan = &chan_list_tlv->chan_scan_param[chan_idx]; /* Increment the TLV header length by size appended */ le16_unaligned_add_cpu(&chan_list_tlv->header.len, - sizeof( - chan_list_tlv->chan_scan_param)); + sizeof(*chan_list_tlv->chan_scan_param)); temp_chan->chan_number = bgscan_cfg_in->chan_list[chan_idx].chan_number; @@ -2420,7 +2415,7 @@ int mwifiex_cmd_802_11_bg_scan_config(struct mwifiex_private *priv, chan_scan_param); le16_unaligned_add_cpu(&chan_list_tlv->header.len, chan_num * - sizeof(chan_list_tlv->chan_scan_param[0])); + sizeof(*chan_list_tlv->chan_scan_param)); } tlv_pos += (sizeof(chan_list_tlv->header) @@ -2492,6 +2487,12 @@ mwifiex_update_chan_statistics(struct mwifiex_private *priv, sizeof(struct mwifiex_chan_stats); for (i = 0 ; i < num_chan; i++) { + if (adapter->survey_idx >= adapter->num_in_chan_stats) { + mwifiex_dbg(adapter, WARN, + "FW reported too many channel results (max %d)\n", + adapter->num_in_chan_stats); + return; + } chan_stats.chan_num = fw_chan_stats->chan_num; chan_stats.bandcfg = fw_chan_stats->bandcfg; chan_stats.flags = fw_chan_stats->flags; @@ -2526,7 +2527,6 @@ int mwifiex_ret_802_11_scan_ext(struct mwifiex_private *priv, struct host_cmd_ds_command *cmd_ptr; struct cmd_ctrl_node *cmd_node; - unsigned long cmd_flags, scan_flags; bool complete_scan = false; mwifiex_dbg(adapter, INFO, "info: EXT scan returns successfully\n"); @@ -2534,8 +2534,7 @@ int mwifiex_ret_802_11_scan_ext(struct mwifiex_private *priv, ext_scan_resp = &resp->params.ext_scan; tlv = (void *)ext_scan_resp->tlv_buffer; - buf_left = le16_to_cpu(resp->size) - (sizeof(*ext_scan_resp) + S_DS_GEN - - 1); + buf_left = le16_to_cpu(resp->size) - (sizeof(*ext_scan_resp) + S_DS_GEN); while (buf_left >= sizeof(struct mwifiex_ie_types_header)) { type = le16_to_cpu(tlv->type); @@ -2561,8 +2560,8 @@ int mwifiex_ret_802_11_scan_ext(struct mwifiex_private *priv, sizeof(struct mwifiex_ie_types_header)); } - spin_lock_irqsave(&adapter->cmd_pending_q_lock, cmd_flags); - spin_lock_irqsave(&adapter->scan_pending_q_lock, scan_flags); + spin_lock_bh(&adapter->cmd_pending_q_lock); + spin_lock_bh(&adapter->scan_pending_q_lock); if (list_empty(&adapter->scan_pending_q)) { complete_scan = true; list_for_each_entry(cmd_node, &adapter->cmd_pending_q, list) { @@ -2576,8 +2575,8 @@ int mwifiex_ret_802_11_scan_ext(struct mwifiex_private *priv, } } } - spin_unlock_irqrestore(&adapter->scan_pending_q_lock, scan_flags); - spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, cmd_flags); + spin_unlock_bh(&adapter->scan_pending_q_lock); + spin_unlock_bh(&adapter->cmd_pending_q_lock); if (complete_scan) mwifiex_complete_scan(priv); @@ -2749,13 +2748,12 @@ mwifiex_queue_scan_cmd(struct mwifiex_private *priv, struct cmd_ctrl_node *cmd_node) { struct mwifiex_adapter *adapter = priv->adapter; - unsigned long flags; cmd_node->wait_q_enabled = true; cmd_node->condition = &adapter->scan_wait_q_woken; - spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); + spin_lock_bh(&adapter->scan_pending_q_lock); list_add_tail(&cmd_node->list, &adapter->scan_pending_q); - spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); + spin_unlock_bh(&adapter->scan_pending_q_lock); } /* @@ -2785,7 +2783,6 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, if (!scan_cfg) return -ENOMEM; - ether_addr_copy(scan_cfg->random_mac, priv->random_mac); scan_cfg->ssid_list = req_ssid; scan_cfg->num_ssids = 1; @@ -2859,6 +2856,13 @@ mwifiex_cmd_append_vsie_tlv(struct mwifiex_private *priv, vs_param_set->header.len = cpu_to_le16((((u16) priv->vs_ie[id].ie[1]) & 0x00FF) + 2); + if (le16_to_cpu(vs_param_set->header.len) > + MWIFIEX_MAX_VSIE_LEN) { + mwifiex_dbg(priv->adapter, ERROR, + "Invalid param length!\n"); + break; + } + memcpy(vs_param_set->ie, priv->vs_ie[id].ie, le16_to_cpu(vs_param_set->header.len)); *buffer += le16_to_cpu(vs_param_set->header.len) + |
