diff options
Diffstat (limited to 'drivers/net/wireless/mwifiex/scan.c')
-rw-r--r-- | drivers/net/wireless/mwifiex/scan.c | 108 |
1 files changed, 57 insertions, 51 deletions
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 74f04571572..04dc7ca4ac2 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -28,7 +28,10 @@ /* The maximum number of channels the firmware can scan per command */ #define MWIFIEX_MAX_CHANNELS_PER_SPECIFIC_SCAN 14 -#define MWIFIEX_CHANNELS_PER_SCAN_CMD 4 +#define MWIFIEX_DEF_CHANNELS_PER_SCAN_CMD 4 +#define MWIFIEX_LIMIT_1_CHANNEL_PER_SCAN_CMD 15 +#define MWIFIEX_LIMIT_2_CHANNELS_PER_SCAN_CMD 27 +#define MWIFIEX_LIMIT_3_CHANNELS_PER_SCAN_CMD 35 /* Memory needed to store a max sized Channel List TLV for a firmware scan */ #define CHAN_TLV_MAX_SIZE (sizeof(struct mwifiex_ie_types_header) \ @@ -471,7 +474,7 @@ mwifiex_is_network_compatible(struct mwifiex_private *priv, * This routine is used for any scan that is not provided with a * specific channel list to scan. */ -static void +static int mwifiex_scan_create_channel_list(struct mwifiex_private *priv, const struct mwifiex_user_scan_cfg *user_scan_in, @@ -528,6 +531,7 @@ mwifiex_scan_create_channel_list(struct mwifiex_private *priv, } } + return chan_idx; } /* @@ -727,6 +731,7 @@ mwifiex_config_scan(struct mwifiex_private *priv, u32 num_probes; u32 ssid_len; u32 chan_idx; + u32 chan_num; u32 scan_type; u16 scan_dur; u8 channel; @@ -850,7 +855,7 @@ mwifiex_config_scan(struct mwifiex_private *priv, if (*filtered_scan) *max_chan_per_scan = MWIFIEX_MAX_CHANNELS_PER_SPECIFIC_SCAN; else - *max_chan_per_scan = MWIFIEX_CHANNELS_PER_SCAN_CMD; + *max_chan_per_scan = MWIFIEX_DEF_CHANNELS_PER_SCAN_CMD; /* If the input config or adapter has the number of Probes set, add tlv */ @@ -962,13 +967,28 @@ mwifiex_config_scan(struct mwifiex_private *priv, dev_dbg(adapter->dev, "info: Scan: Scanning current channel only\n"); } - + chan_num = chan_idx; } else { dev_dbg(adapter->dev, "info: Scan: Creating full region channel list\n"); - mwifiex_scan_create_channel_list(priv, user_scan_in, - scan_chan_list, - *filtered_scan); + chan_num = mwifiex_scan_create_channel_list(priv, user_scan_in, + scan_chan_list, + *filtered_scan); + } + + /* + * In associated state we will reduce the number of channels scanned per + * scan command to avoid any traffic delay/loss. This number is decided + * based on total number of channels to be scanned due to constraints + * of command buffers. + */ + if (priv->media_connected) { + if (chan_num < MWIFIEX_LIMIT_1_CHANNEL_PER_SCAN_CMD) + *max_chan_per_scan = 1; + else if (chan_num < MWIFIEX_LIMIT_2_CHANNELS_PER_SCAN_CMD) + *max_chan_per_scan = 2; + else if (chan_num < MWIFIEX_LIMIT_3_CHANNELS_PER_SCAN_CMD) + *max_chan_per_scan = 3; } } @@ -1014,14 +1034,12 @@ mwifiex_ret_802_11_scan_get_tlv_ptrs(struct mwifiex_adapter *adapter, case TLV_TYPE_TSFTIMESTAMP: dev_dbg(adapter->dev, "info: SCAN_RESP: TSF " "timestamp TLV, len = %d\n", tlv_len); - *tlv_data = (struct mwifiex_ie_types_data *) - current_tlv; + *tlv_data = current_tlv; break; case TLV_TYPE_CHANNELBANDLIST: dev_dbg(adapter->dev, "info: SCAN_RESP: channel" " band list TLV, len = %d\n", tlv_len); - *tlv_data = (struct mwifiex_ie_types_data *) - current_tlv; + *tlv_data = current_tlv; break; default: dev_err(adapter->dev, @@ -1226,15 +1244,15 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, bss_entry->beacon_buf); break; case WLAN_EID_BSS_COEX_2040: - bss_entry->bcn_bss_co_2040 = (u8 *) (current_ptr + - sizeof(struct ieee_types_header)); + bss_entry->bcn_bss_co_2040 = current_ptr + + sizeof(struct ieee_types_header); bss_entry->bss_co_2040_offset = (u16) (current_ptr + sizeof(struct ieee_types_header) - bss_entry->beacon_buf); break; case WLAN_EID_EXT_CAPABILITY: - bss_entry->bcn_ext_cap = (u8 *) (current_ptr + - sizeof(struct ieee_types_header)); + bss_entry->bcn_ext_cap = current_ptr + + sizeof(struct ieee_types_header); bss_entry->ext_cap_offset = (u16) (current_ptr + sizeof(struct ieee_types_header) - bss_entry->beacon_buf); @@ -1276,8 +1294,8 @@ mwifiex_radio_type_to_band(u8 radio_type) * order to send the appropriate scan commands to firmware to populate or * update the internal driver scan table. */ -static int mwifiex_scan_networks(struct mwifiex_private *priv, - const struct mwifiex_user_scan_cfg *user_scan_in) +int mwifiex_scan_networks(struct mwifiex_private *priv, + const struct mwifiex_user_scan_cfg *user_scan_in) { int ret = 0; struct mwifiex_adapter *adapter = priv->adapter; @@ -1342,6 +1360,7 @@ static int mwifiex_scan_networks(struct mwifiex_private *priv, adapter->cmd_queued = cmd_node; mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true); + queue_work(adapter->workqueue, &adapter->main_work); } else { spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); @@ -1358,26 +1377,6 @@ static int mwifiex_scan_networks(struct mwifiex_private *priv, } /* - * Sends IOCTL request to start a scan with user configurations. - * - * This function allocates the IOCTL request buffer, fills it - * with requisite parameters and calls the IOCTL handler. - * - * Upon completion, it also generates a wireless event to notify - * applications. - */ -int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv, - struct mwifiex_user_scan_cfg *scan_req) -{ - int status; - - status = mwifiex_scan_networks(priv, scan_req); - queue_work(priv->adapter->workqueue, &priv->adapter->main_work); - - return status; -} - -/* * This function prepares a scan command to be sent to the firmware. * * This uses the scan command configuration sent to the command processing @@ -1683,8 +1682,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, goto done; } if (element_id == WLAN_EID_DS_PARAMS) { - channel = *(u8 *) (current_ptr + - sizeof(struct ieee_types_header)); + channel = *(current_ptr + sizeof(struct ieee_types_header)); break; } @@ -1772,14 +1770,23 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, priv->user_scan_cfg = NULL; } } else { - /* Get scan command from scan_pending_q and put to - cmd_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); + if (!mwifiex_wmm_lists_empty(adapter)) { + spin_unlock_irqrestore(&adapter->scan_pending_q_lock, + flags); + adapter->scan_delay_cnt = 1; + mod_timer(&priv->scan_delay_timer, jiffies + + msecs_to_jiffies(MWIFIEX_SCAN_DELAY_MSEC)); + } else { + /* Get scan command from scan_pending_q and put to + cmd_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); + } } done: @@ -2010,12 +2017,11 @@ mwifiex_save_curr_bcn(struct mwifiex_private *priv) if (curr_bss->bcn_bss_co_2040) curr_bss->bcn_bss_co_2040 = - (u8 *) (curr_bss->beacon_buf + - curr_bss->bss_co_2040_offset); + (curr_bss->beacon_buf + curr_bss->bss_co_2040_offset); if (curr_bss->bcn_ext_cap) - curr_bss->bcn_ext_cap = (u8 *) (curr_bss->beacon_buf + - curr_bss->ext_cap_offset); + curr_bss->bcn_ext_cap = curr_bss->beacon_buf + + curr_bss->ext_cap_offset; } /* |