qcacld-3.0: Set HW mode before issuing connect for Hidden SSID
Set the HW mode if needed before connecting to an SSID that
is hidden.
CRs-Fixed: 928208
Change-Id: Ibefd207327da1b85ae26a91afd27fc6baf98cf14
diff --git a/core/cds/inc/cds_concurrency.h b/core/cds/inc/cds_concurrency.h
index 9cf3ec0..ff9f30b 100644
--- a/core/cds/inc/cds_concurrency.h
+++ b/core/cds/inc/cds_concurrency.h
@@ -600,6 +600,9 @@
return true;
}
#endif /* FEATURE_WLAN_CH_AVOID */
+uint8_t cds_search_and_check_for_session_conc(uint8_t session_id,
+ tCsrRoamProfile * roam_profile);
+bool cds_check_for_session_conc(uint8_t session_id, uint8_t channel);
bool cds_handle_conc_multiport(uint8_t session_id, uint8_t channel);
#ifdef FEATURE_WLAN_FORCE_SAP_SCC
@@ -681,8 +684,9 @@
uint32_t vdev_id);
CDF_STATUS cds_decr_connection_count(hdd_context_t *hdd_ctx,
uint32_t vdev_id);
-CDF_STATUS cds_current_connections_update(
- hdd_context_t *hdd_ctx, uint8_t channel);
+CDF_STATUS cds_current_connections_update(uint32_t session_id,
+ uint8_t channel,
+ enum cds_conn_update_reason);
#ifdef MPC_UT_FRAMEWORK
CDF_STATUS cds_incr_connection_count_utfw(hdd_context_t *hdd_ctx,
uint32_t vdev_id, uint32_t tx_streams, uint32_t rx_streams,
@@ -738,16 +742,20 @@
device_mode_t device_mode);
uint32_t cds_get_connection_count(hdd_context_t *hdd_ctx);
CDF_STATUS cds_soc_set_hw_mode(hdd_context_t *hdd_ctx,
+ uint32_t session_id,
enum hw_mode_ss_config mac0_ss,
enum hw_mode_bandwidth mac0_bw,
enum hw_mode_ss_config mac1_ss,
enum hw_mode_bandwidth mac1_bw,
enum hw_mode_dbs_capab dbs,
- enum hw_mode_agile_dfs_capab dfs);
+ enum hw_mode_agile_dfs_capab dfs,
+ enum cds_conn_update_reason reason);
enum cds_conc_next_action cds_need_opportunistic_upgrade(
hdd_context_t *hdd_ctx);
CDF_STATUS cds_next_actions(
- hdd_context_t *hdd_ctx, enum cds_conc_next_action action);
+ hdd_context_t *hdd_ctx, uint32_t session_id,
+ enum cds_conc_next_action action,
+ enum cds_conn_update_reason reason);
void cds_set_dual_mac_scan_config(hdd_context_t *hdd_ctx,
uint8_t dbs_val,
uint8_t dbs_plus_agile_scan_val,
diff --git a/core/cds/src/cds_concurrency.c b/core/cds/src/cds_concurrency.c
index 28c0d3b..6792d11 100644
--- a/core/cds/src/cds_concurrency.c
+++ b/core/cds/src/cds_concurrency.c
@@ -2377,12 +2377,14 @@
/**
* cds_soc_set_hw_mode() - Set HW mode command to SME
* @hdd_ctx: HDD context
+ * @session_id: Session ID
* @mac0_ss: MAC0 spatial stream configuration
* @mac0_bw: MAC0 bandwidth configuration
* @mac1_ss: MAC1 spatial stream configuration
* @mac1_bw: MAC1 bandwidth configuration
* @dbs: HW DBS capability
* @dfs: HW Agile DFS capability
+ * @reason: Reason for connection update
*
* Sends the set hw mode to the SME module which will pass on
* this message to WMA layer
@@ -2403,12 +2405,14 @@
* Return: Success if the message made it down to the next layer
*/
CDF_STATUS cds_soc_set_hw_mode(hdd_context_t *hdd_ctx,
+ uint32_t session_id,
enum hw_mode_ss_config mac0_ss,
enum hw_mode_bandwidth mac0_bw,
enum hw_mode_ss_config mac1_ss,
enum hw_mode_bandwidth mac1_bw,
enum hw_mode_dbs_capab dbs,
- enum hw_mode_agile_dfs_capab dfs)
+ enum hw_mode_agile_dfs_capab dfs,
+ enum cds_conn_update_reason reason)
{
int8_t hw_mode_index;
struct sir_hw_mode msg;
@@ -2428,6 +2432,8 @@
msg.hw_mode_index = hw_mode_index;
msg.set_hw_mode_cb = (void *)cds_soc_set_hw_mode_cb;
+ msg.reason = reason;
+ msg.session_id = session_id;
cds_info("set hw mode to sme: hw_mode_index: %d",
msg.hw_mode_index);
@@ -3625,7 +3631,12 @@
action = cds_need_opportunistic_upgrade(hdd_ctx);
if (action) {
/* lets call for action */
- cds_next_actions(hdd_ctx, action);
+ /* session id is being used only
+ * in hidden ssid case for now.
+ * So, session id 0 is ok here.
+ */
+ cds_next_actions(hdd_ctx, 0, action,
+ CDS_UPDATE_REASON_OPPORTUNISTIC);
}
cdf_mutex_release(&hdd_ctx->hdd_conc_list_lock);
@@ -5240,8 +5251,9 @@
* cds_current_connections_update() - initiates actions
* needed on current connections once channel has been decided
* for the new connection
- * @hdd_ctx: HDD Context
+ * @session_id: Session id
* @channel: Channel on which new connection will be
+ * @reason: Reason for which connection update is required
*
* This function initiates initiates actions
* needed on current connections once channel has been decided
@@ -5249,17 +5261,24 @@
*
* Return: CDF_STATUS enum
*/
-CDF_STATUS cds_current_connections_update(
- hdd_context_t *hdd_ctx,
- uint8_t channel)
+CDF_STATUS cds_current_connections_update(uint32_t session_id,
+ uint8_t channel,
+ enum cds_conn_update_reason reason)
{
enum cds_conc_next_action next_action = CDS_NOP;
uint32_t num_connections = 0;
enum cds_one_connection_mode second_index = 0;
enum cds_two_connection_mode third_index = 0;
enum cds_band band;
+ hdd_context_t *hdd_ctx;
CDF_STATUS status = CDF_STATUS_E_FAILURE;
+ hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
+ if (!hdd_ctx) {
+ cds_err("Invalid HDD context");
+ return CDF_STATUS_E_FAILURE;
+ }
+
if (wma_is_hw_dbs_capable() == false) {
cds_err("driver isn't dbs capable, no further action needed");
return CDF_STATUS_E_NOSUPPORT;
@@ -5315,12 +5334,14 @@
}
if (CDS_NOP != next_action)
- status = cds_next_actions(hdd_ctx, next_action);
+ status = cds_next_actions(hdd_ctx, session_id,
+ next_action, reason);
else
status = CDF_STATUS_E_NOSUPPORT;
- cds_debug("index2=%d index3=%d next_action=%d, band=%d status=%d",
- second_index, third_index, next_action, band, status);
+ cds_debug("index2=%d index3=%d next_action=%d, band=%d status=%d reason=%d session_id=%d",
+ second_index, third_index, next_action, band, status,
+ reason, session_id);
done:
cdf_mutex_release(&hdd_ctx->hdd_conc_list_lock);
@@ -5437,7 +5458,9 @@
break;
}
if (!wait)
- cds_next_actions(hdd_ctx, next_action);
+ cds_next_actions(hdd_ctx, vdev_id,
+ next_action,
+ CDS_UPDATE_REASON_NSS_UPDATE);
cdf_mutex_release(&hdd_ctx->hdd_conc_list_lock);
return;
}
@@ -5450,6 +5473,8 @@
* @new_nss: the new nss value
* @next_action: next action to happen at policy mgr after
* beacon update
+ * @reason: Reason for connection update
+ * @session_id: Session id
*
* This function initiates initiates actions
* needed on current connections once channel has been decided
@@ -5458,7 +5483,9 @@
* Return: CDF_STATUS enum
*/
CDF_STATUS cds_complete_action(hdd_context_t *hdd_ctx,
- uint8_t new_nss, uint8_t next_action)
+ uint8_t new_nss, uint8_t next_action,
+ enum cds_conn_update_reason reason,
+ uint32_t session_id)
{
CDF_STATUS status = CDF_STATUS_E_FAILURE;
uint32_t index = 0, count = 0;
@@ -5518,7 +5545,8 @@
index++;
}
if (!CDF_IS_STATUS_SUCCESS(status))
- status = cds_next_actions(hdd_ctx, next_action);
+ status = cds_next_actions(hdd_ctx, session_id,
+ next_action, reason);
return status;
}
@@ -5528,7 +5556,9 @@
* connections once channel has been decided for the new
* connection
* @hdd_ctx: HDD Context
+ * @session_id: Session id
* @action: action to be executed
+ * @reason: Reason for connection update
*
* This function initiates initiates actions
* needed on current connections once channel has been decided
@@ -5537,7 +5567,9 @@
* Return: CDF_STATUS enum
*/
CDF_STATUS cds_next_actions(hdd_context_t *hdd_ctx,
- enum cds_conc_next_action action)
+ uint32_t session_id,
+ enum cds_conc_next_action action,
+ enum cds_conn_update_reason reason)
{
CDF_STATUS status = CDF_STATUS_E_FAILURE;
struct sir_hw_mode_params hw_mode;
@@ -5574,14 +5606,17 @@
* update the beacon template & notify FW. Once FW confirms
* beacon updated, send down the HW mode change req
*/
- status = cds_complete_action(hdd_ctx, 1, CDS_DBS);
+ status = cds_complete_action(hdd_ctx, 1, CDS_DBS, reason,
+ session_id);
break;
case CDS_DBS:
- status = cds_soc_set_hw_mode(hdd_ctx, HW_MODE_SS_1x1,
+ status = cds_soc_set_hw_mode(hdd_ctx, session_id,
+ HW_MODE_SS_1x1,
HW_MODE_80_MHZ,
HW_MODE_SS_1x1, HW_MODE_40_MHZ,
HW_MODE_DBS,
- HW_MODE_AGILE_DFS_NONE);
+ HW_MODE_AGILE_DFS_NONE,
+ reason);
break;
case CDS_MCC_UPGRADE:
/*
@@ -5589,14 +5624,17 @@
* intially. If yes, update the beacon template & notify FW.
* Once FW confirms beacon updated, send the HW mode change req
*/
- status = cds_complete_action(hdd_ctx, 0, CDS_MCC);
+ status = cds_complete_action(hdd_ctx, 0, CDS_MCC, reason,
+ session_id);
break;
case CDS_MCC:
- status = cds_soc_set_hw_mode(hdd_ctx, HW_MODE_SS_2x2,
+ status = cds_soc_set_hw_mode(hdd_ctx, session_id,
+ HW_MODE_SS_2x2,
HW_MODE_80_MHZ,
HW_MODE_SS_0x0, HW_MODE_BW_NONE,
HW_MODE_DBS_NONE,
- HW_MODE_AGILE_DFS_NONE);
+ HW_MODE_AGILE_DFS_NONE,
+ reason);
break;
default:
/* err msg */
@@ -6118,29 +6156,72 @@
}
/**
- * cds_handle_conc_multiport() - to handle multiport concurrency
+ * cds_search_and_check_for_session_conc() - Checks if concurrecy is allowed
+ * @session_id: Session id
+ * @roam_profile: Pointer to the roam profile
+ *
+ * Searches and gets the channel number from the scan results and checks if
+ * concurrency is allowed for the given session ID
+ *
+ * Non zero channel number if concurrency is allowed, zero otherwise
+ */
+uint8_t cds_search_and_check_for_session_conc(uint8_t session_id,
+ tCsrRoamProfile *roam_profile)
+{
+ uint8_t channel = 0;
+ CDF_STATUS status;
+ hdd_context_t *hdd_ctx;
+ hdd_adapter_t *adapter;
+ bool ret;
+
+ hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
+ if (!hdd_ctx) {
+ cds_err("Invalid HDD context");
+ return channel;
+ }
+
+ adapter = hdd_get_adapter_by_vdev(hdd_ctx, session_id);
+ if (!adapter) {
+ cds_err("Invalid HDD adapter");
+ return channel;
+ }
+
+ status = cds_get_channel_from_scan_result(adapter,
+ roam_profile, &channel);
+ if ((CDF_STATUS_SUCCESS != status) || (channel == 0)) {
+ cds_err("%s error %d %d",
+ __func__, status, channel);
+ return 0;
+ }
+
+ /* Take care of 160MHz and 80+80Mhz later */
+ ret = cds_allow_concurrency(hdd_ctx,
+ cds_convert_device_mode_to_hdd_type(
+ adapter->device_mode),
+ channel, HW_MODE_20_MHZ);
+ if (false == ret) {
+ cds_err("Connection failed due to conc check fail");
+ return 0;
+ }
+
+ return channel;
+}
+
+/**
+ * cds_check_for_session_conc() - Check if concurrency is allowed for a session
* @session_id: Session ID
* @channel: Channel number
*
- * This routine will handle STA side concurrency when policy manager
- * is enabled.
+ * Checks if connection is allowed for a given session_id
*
- * Return: true or false
+ * True if the concurrency is allowed, false otherwise
*/
-bool cds_handle_conc_multiport(uint8_t session_id,
+bool cds_check_for_session_conc(uint8_t session_id,
uint8_t channel)
{
- bool ret = true;
- CDF_STATUS status;
- p_cds_contextType cds_context;
- hdd_adapter_t *adapter;
hdd_context_t *hdd_ctx;
-
- cds_context = cds_get_global_context();
- if (!cds_context) {
- cds_err("Invalid CDS context");
- return false;
- }
+ hdd_adapter_t *adapter;
+ bool ret;
hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
if (!hdd_ctx) {
@@ -6158,6 +6239,7 @@
cds_err("Invalid channel number 0");
return false;
}
+
/* Take care of 160MHz and 80+80Mhz later */
ret = cds_allow_concurrency(hdd_ctx,
cds_convert_device_mode_to_hdd_type(
@@ -6165,6 +6247,36 @@
channel, HW_MODE_20_MHZ);
if (false == ret) {
cds_err("Connection failed due to conc check fail");
+ return 0;
+ }
+
+ return true;
+}
+
+/**
+ * cds_handle_conc_multiport() - to handle multiport concurrency
+ * @session_id: Session ID
+ * @channel: Channel number
+ *
+ * This routine will handle STA side concurrency when policy manager
+ * is enabled.
+ *
+ * Return: true or false
+ */
+bool cds_handle_conc_multiport(uint8_t session_id,
+ uint8_t channel)
+{
+ CDF_STATUS status;
+ p_cds_contextType cds_context;
+
+ cds_context = cds_get_global_context();
+ if (!cds_context) {
+ cds_err("Invalid CDS context");
+ return false;
+ }
+
+ if (!cds_check_for_session_conc(session_id, channel)) {
+ cds_err("Conc not allowed for the session %d", session_id);
return false;
}
@@ -6172,7 +6284,9 @@
if (!CDF_IS_STATUS_SUCCESS(status))
cds_err("clearing event failed");
- status = cds_current_connections_update(hdd_ctx, channel);
+ status = cds_current_connections_update(session_id,
+ channel,
+ CDS_UPDATE_REASON_NORMAL_STA);
if (CDF_STATUS_E_FAILURE == status) {
cds_err("connections update failed");
return false;
diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c
index 9012628..c78b8bf 100644
--- a/core/hdd/src/wlan_hdd_cfg80211.c
+++ b/core/hdd/src/wlan_hdd_cfg80211.c
@@ -4107,7 +4107,8 @@
const void *data,
int data_len)
{
-
+ struct net_device *ndev = wdev->netdev;
+ hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(ndev);
hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
int ret = 0;
enum cds_con_mode intf_mode;
@@ -4165,8 +4166,9 @@
if (!CDF_IS_STATUS_SUCCESS(ret))
hdd_err("clearing event failed");
- ret = cds_current_connections_update(hdd_ctx,
- channel_hint);
+ ret = cds_current_connections_update(adapter->sessionId,
+ channel_hint,
+ CDS_UPDATE_REASON_SET_OPER_CHAN);
if (CDF_STATUS_E_FAILURE == ret) {
/* return in the failure case */
hdd_err("ERROR: connections update failed!!");
@@ -8807,8 +8809,9 @@
if (!CDF_IS_STATUS_SUCCESS(status))
hdd_err("ERR: clear event failed");
- status = cds_current_connections_update(pHddCtx,
- channelNum);
+ status = cds_current_connections_update(pAdapter->sessionId,
+ channelNum,
+ CDS_UPDATE_REASON_JOIN_IBSS);
if (CDF_STATUS_E_FAILURE == status) {
hdd_err("ERROR: connections update failed!!");
return -EINVAL;
diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c
index 2727e12..437a541 100644
--- a/core/hdd/src/wlan_hdd_hostapd.c
+++ b/core/hdd/src/wlan_hdd_hostapd.c
@@ -8241,7 +8241,9 @@
if (!CDF_IS_STATUS_SUCCESS(status))
hdd_err("ERR: clear event failed");
- status = cds_current_connections_update(pHddCtx, channel);
+ status = cds_current_connections_update(pAdapter->sessionId,
+ channel,
+ CDS_UPDATE_REASON_START_AP);
if (CDF_STATUS_E_FAILURE == status) {
hdd_err("ERROR: connections update failed!!");
return -EINVAL;
diff --git a/core/hdd/src/wlan_hdd_wext.c b/core/hdd/src/wlan_hdd_wext.c
index 9110a2b..1f7cc49 100644
--- a/core/hdd/src/wlan_hdd_wext.c
+++ b/core/hdd/src/wlan_hdd_wext.c
@@ -7692,19 +7692,25 @@
if (apps_args[0] == 0) {
hddLog(LOGE,
FL("set hw mode for single mac\n"));
- cds_soc_set_hw_mode(hdd_ctx, HW_MODE_SS_2x2,
+ cds_soc_set_hw_mode(hdd_ctx,
+ pAdapter->sessionId,
+ HW_MODE_SS_2x2,
HW_MODE_80_MHZ,
HW_MODE_SS_0x0, HW_MODE_BW_NONE,
HW_MODE_DBS_NONE,
- HW_MODE_AGILE_DFS_NONE);
+ HW_MODE_AGILE_DFS_NONE,
+ CDS_UPDATE_REASON_UT);
} else if (apps_args[0] == 1) {
hddLog(LOGE,
FL("set hw mode for dual mac\n"));
- cds_soc_set_hw_mode(hdd_ctx, HW_MODE_SS_1x1,
+ cds_soc_set_hw_mode(hdd_ctx,
+ pAdapter->sessionId,
+ HW_MODE_SS_1x1,
HW_MODE_80_MHZ,
HW_MODE_SS_1x1, HW_MODE_40_MHZ,
HW_MODE_DBS,
- HW_MODE_AGILE_DFS_NONE);
+ HW_MODE_AGILE_DFS_NONE,
+ CDS_UPDATE_REASON_UT);
}
}
break;
@@ -7714,8 +7720,9 @@
enum cds_conc_next_action action;
hddLog(LOGE,
FL("<iwpriv wlan0 pm_query_action> is called\n"));
- action = cds_current_connections_update(hdd_ctx,
- apps_args[0]);
+ action = cds_current_connections_update(pAdapter->sessionId,
+ apps_args[0],
+ CDS_UPDATE_REASON_UT);
pr_info("next action is %d {HDD_NOP = 0, HDD_DBS, HDD_DBS_DOWNGRADE, HDD_MCC, HDD_MCC_UPGRADE}", action);
}
break;
diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h
index 887901b..ba16dd9 100644
--- a/core/mac/inc/sir_api.h
+++ b/core/mac/inc/sir_api.h
@@ -95,6 +95,28 @@
/* This should not be greater than MAX_NUMBER_OF_CONC_CONNECTIONS */
#define MAX_VDEV_SUPPORTED 4
+/**
+ * enum cds_conn_update_reason: Reason for conc connection update
+ * @CDS_UPDATE_REASON_SET_OPER_CHAN: Set probable operating channel
+ * @CDS_UPDATE_REASON_JOIN_IBSS: Join IBSS
+ * @CDS_UPDATE_REASON_UT: Unit test related
+ * @CDS_UPDATE_REASON_START_AP: Start AP
+ * @CDS_UPDATE_REASON_NORMAL_STA: Connection to Normal STA
+ * @CDS_UPDATE_REASON_HIDDEN_STA: Connection to Hidden STA
+ * @CDS_UPDATE_REASON_OPPORTUNISTIC: Opportunistic HW mode update
+ * @CDS_UPDATE_REASON_NSS_UPDATE: NSS update
+ */
+enum cds_conn_update_reason {
+ CDS_UPDATE_REASON_SET_OPER_CHAN,
+ CDS_UPDATE_REASON_JOIN_IBSS,
+ CDS_UPDATE_REASON_UT,
+ CDS_UPDATE_REASON_START_AP,
+ CDS_UPDATE_REASON_NORMAL_STA,
+ CDS_UPDATE_REASON_HIDDEN_STA,
+ CDS_UPDATE_REASON_OPPORTUNISTIC,
+ CDS_UPDATE_REASON_NSS_UPDATE,
+};
+
typedef enum {
eSIR_EXTSCAN_INVALID,
eSIR_EXTSCAN_START_RSP,
@@ -397,10 +419,14 @@
* struct sir_hw_mode - Format of set HW mode
* @hw_mode_index: Index of HW mode to be set
* @set_hw_mode_cb: HDD set HW mode callback
+ * @reason: Reason for HW mode change
+ * @session_id: Session id
*/
struct sir_hw_mode {
uint32_t hw_mode_index;
void *set_hw_mode_cb;
+ enum cds_conn_update_reason reason;
+ uint32_t session_id;
};
/**
diff --git a/core/mac/src/pe/lim/lim_process_sme_req_messages.c b/core/mac/src/pe/lim/lim_process_sme_req_messages.c
index 0db6d07..b06e32d 100644
--- a/core/mac/src/pe/lim/lim_process_sme_req_messages.c
+++ b/core/mac/src/pe/lim/lim_process_sme_req_messages.c
@@ -156,6 +156,7 @@
cdf_mem_zero(req_msg, len);
req_msg->hw_mode_index = buf->set_hw.hw_mode_index;
+ req_msg->reason = buf->set_hw.reason;
/* Other parameters are not needed for WMA */
cds_message.bodyptr = req_msg;
diff --git a/core/sme/inc/sme_internal.h b/core/sme/inc/sme_internal.h
index 4ff54c7..adc01cb 100644
--- a/core/sme/inc/sme_internal.h
+++ b/core/sme/inc/sme_internal.h
@@ -218,6 +218,7 @@
void *dcc_stats_event_context;
ocb_callback dcc_stats_event_callback;
sme_set_thermal_level_callback set_thermal_level_cb;
+ void *saved_scan_cmd;
} tSmeStruct, *tpSmeStruct;
#endif /* #if !defined( __SMEINTERNAL_H ) */
diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c
index c436ce5..60c8729 100644
--- a/core/sme/src/common/sme_api.c
+++ b/core/sme/src/common/sme_api.c
@@ -156,7 +156,10 @@
bool found;
hw_mode_cb callback = NULL;
struct sir_set_hw_mode_resp *param;
+ enum cds_conn_update_reason reason;
+ tSmeCmd *saved_cmd;
+ sms_log(mac, LOG1, FL("%s"), __func__);
param = (struct sir_set_hw_mode_resp *)msg;
if (!param) {
sms_log(mac, LOGE, FL("HW mode resp param is NULL"));
@@ -184,10 +187,48 @@
}
callback = command->u.set_hw_mode_cmd.set_hw_mode_cb;
+ reason = command->u.set_hw_mode_cmd.reason;
if (callback) {
if (!param) {
sms_log(mac, LOGE,
FL("Callback failed since HW mode params is NULL"));
+ } else if (reason == CDS_UPDATE_REASON_HIDDEN_STA) {
+ /* In the case of hidden SSID, connection update
+ * (set hw mode) is done after the scan with reason
+ * code eCsrScanForSsid completes. The connect/failure
+ * needs to be handled after the response of set hw
+ * mode
+ */
+ saved_cmd = (tSmeCmd *)mac->sme.saved_scan_cmd;
+ if (!saved_cmd) {
+ sms_log(mac, LOGP,
+ FL("saved cmd is NULL, Check this"));
+ goto end;
+ }
+ if (param->status == SET_HW_MODE_STATUS_OK) {
+ sms_log(mac, LOG1,
+ FL("search for ssid success"));
+ csr_scan_handle_search_for_ssid(mac,
+ saved_cmd);
+ } else {
+ sms_log(mac, LOG1,
+ FL("search for ssid failure"));
+ csr_scan_handle_search_for_ssid_failure(mac,
+ saved_cmd);
+ }
+ if (saved_cmd->u.roamCmd.pRoamBssEntry)
+ cdf_mem_free(
+ saved_cmd->u.roamCmd.pRoamBssEntry);
+ if (saved_cmd->u.scanCmd.u.scanRequest.SSIDs.SSIDList)
+ cdf_mem_free(saved_cmd->u.scanCmd.u.
+ scanRequest.SSIDs.SSIDList);
+ if (saved_cmd->u.scanCmd.pToRoamProfile)
+ cdf_mem_free(saved_cmd->u.scanCmd.
+ pToRoamProfile);
+ if (saved_cmd) {
+ cdf_mem_free(saved_cmd);
+ saved_cmd = NULL;
+ }
} else {
sms_log(mac, LOGE,
FL("Calling HDD callback for HW mode response"));
@@ -200,6 +241,7 @@
sms_log(mac, LOGE, FL("Callback does not exist"));
}
+end:
found = csr_ll_remove_entry(&mac->sme.smeCmdActiveList, entry,
LL_ACCESS_LOCK);
if (found) {
@@ -14391,6 +14433,8 @@
cmd->command = e_sme_command_set_hw_mode;
cmd->u.set_hw_mode_cmd.hw_mode_index = msg.hw_mode_index;
cmd->u.set_hw_mode_cmd.set_hw_mode_cb = msg.set_hw_mode_cb;
+ cmd->u.set_hw_mode_cmd.reason = msg.reason;
+ cmd->u.set_hw_mode_cmd.session_id = msg.session_id;
sms_log(mac, LOG1, FL("Queuing e_sme_command_set_hw_mode to CSR"));
csr_queue_sme_command(mac, cmd, false);
diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c
index f4dfbbe..b6125f0 100644
--- a/core/sme/src/csr/csr_api_roam.c
+++ b/core/sme/src/csr/csr_api_roam.c
@@ -453,6 +453,10 @@
csr_ll_close(&pMac->roam.statsClientReqList);
csr_ll_close(&pMac->roam.peStatsReqList);
csr_ll_close(&pMac->roam.roamCmdPendingList);
+ if (pMac->sme.saved_scan_cmd) {
+ cdf_mem_free(pMac->sme.saved_scan_cmd);
+ pMac->sme.saved_scan_cmd = NULL;
+ }
/* DeInit Globals */
csr_roam_de_init_globals(pMac);
return status;
@@ -18818,11 +18822,25 @@
goto fail;
}
+ /* For hidden SSID case, if there is any scan command pending
+ * it needs to be cleared before issuing set HW mode
+ */
+ if (command->u.set_hw_mode_cmd.reason == CDS_UPDATE_REASON_HIDDEN_STA) {
+ sms_log(mac, LOGE, FL("clear any pending scan command"));
+ status = csr_scan_abort_mac_scan_not_for_connect(mac,
+ command->u.set_hw_mode_cmd.session_id);
+ if (!CDF_IS_STATUS_SUCCESS(status)) {
+ sms_log(mac, LOGE, FL("Failed to clear scan cmd"));
+ goto fail;
+ }
+ }
+
cdf_mem_set(cmd, len, 0);
cmd->messageType = eWNI_SME_SET_HW_MODE_REQ;
cmd->length = len;
cmd->set_hw.hw_mode_index = command->u.set_hw_mode_cmd.hw_mode_index;
+ cmd->set_hw.reason = command->u.set_hw_mode_cmd.reason;
/*
* Below callback and context info are not needed for PE as of now.
* Storing the passed value in the same s_sir_set_hw_mode format.
diff --git a/core/sme/src/csr/csr_api_scan.c b/core/sme/src/csr/csr_api_scan.c
index 68f0aee..e66a541 100644
--- a/core/sme/src/csr/csr_api_scan.c
+++ b/core/sme/src/csr/csr_api_scan.c
@@ -2022,8 +2022,11 @@
pNewIes = NULL;
status = csr_save_ies(pMac, pFilter, pBssDesc, &pNewIes,
&fMatch, &uc, &mc, &auth);
- if (!CDF_IS_STATUS_SUCCESS(status))
+ if (!CDF_IS_STATUS_SUCCESS(status)) {
+ sms_log(pMac, LOG1, FL("save ies fail %d"),
+ status);
break;
+ }
/*
* Modify the prefer value to honor PCL list
*/
@@ -2032,8 +2035,11 @@
status = csr_save_scan_entry(pMac, pFilter, fMatch, pBssDesc,
pNewIes, pRetList, count, uc, mc,
&auth);
- if (!CDF_IS_STATUS_SUCCESS(status))
+ if (!CDF_IS_STATUS_SUCCESS(status)) {
+ sms_log(pMac, LOG1, FL("save entry fail %d"),
+ status);
break;
+ }
pEntry = csr_ll_next(&pMac->scan.scanResultList, pEntry,
LL_ACCESS_NOLOCK);
} /* while */
@@ -2055,14 +2061,17 @@
csr_prefer_5ghz(pMac, pFilter);
pRetList = cdf_mem_malloc(sizeof(tScanResultList));
- if (NULL == pRetList)
+ if (NULL == pRetList) {
+ sms_log(pMac, LOGE, FL("pRetList is NULL"));
return CDF_STATUS_E_NOMEM;
+ }
cdf_mem_set(pRetList, sizeof(tScanResultList), 0);
csr_ll_open(pMac->hHdd, &pRetList->List);
pRetList->pCurEntry = NULL;
status = csr_parse_scan_results(pMac, pFilter, pRetList, &count);
- sms_log(pMac, LOG2, FL("return %d BSS"), csr_ll_count(&pRetList->List));
+ sms_log(pMac, LOG1, FL("return %d BSS %d"),
+ csr_ll_count(&pRetList->List), status);
if (!CDF_IS_STATUS_SUCCESS(status) || (phResult == NULL)) {
/* Fail or No one wants the result. */
csr_scan_result_purge(pMac, (tScanResultHandle) pRetList);
@@ -3654,9 +3663,11 @@
eCsrScanCompleteNextCommand csr_scan_get_next_command_state(tpAniSirGlobal pMac,
tSmeCmd *pCommand,
- bool fSuccess)
+ bool fSuccess,
+ uint8_t *chan)
{
eCsrScanCompleteNextCommand NextCommand = eCsrNextScanNothing;
+ int8_t channel;
switch (pCommand->u.scanCmd.reason) {
case eCsrScan11d1:
@@ -3688,9 +3699,35 @@
eCsrNextLostLinkScan3Failed;
break;
case eCsrScanForSsid:
- NextCommand =
- (fSuccess) ? eCsrNexteScanForSsidSuccess :
- eCsrNexteScanForSsidFailure;
+ /* When policy manager is disabled:
+ * success: csr_scan_handle_search_for_ssid
+ * failure: csr_scan_handle_search_for_ssid_failure
+ *
+ * When policy manager is enabled:
+ * success:
+ * set hw_mode success -> csr_scan_handle_search_for_ssid
+ * set hw_mode fail -> csr_scan_handle_search_for_ssid_failure
+ * failure: csr_scan_handle_search_for_ssid_failure
+ */
+ if (pMac->policy_manager_enabled) {
+ sms_log(pMac, LOG1, FL("Resp for eCsrScanForSsid"));
+ channel = cds_search_and_check_for_session_conc(
+ pCommand->sessionId,
+ pCommand->u.scanCmd.pToRoamProfile);
+ if ((!channel) || !fSuccess) {
+ NextCommand = eCsrNexteScanForSsidFailure;
+ sms_log(pMac, LOG1,
+ FL("next ScanForSsidFailure %d %d"),
+ channel, fSuccess);
+ } else {
+ NextCommand = eCsrNextCheckAllowConc;
+ *chan = channel;
+ sms_log(pMac, LOG1, FL("next CheckAllowConc"));
+ }
+ } else {
+ NextCommand = (fSuccess) ? eCsrNexteScanForSsidSuccess :
+ eCsrNexteScanForSsidFailure;
+ }
break;
default:
NextCommand = eCsrNextScanNothing;
@@ -3789,12 +3826,122 @@
}
#endif /* #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR */
+/**
+ * csr_save_profile() - Save the profile info from sme command
+ * @mac_ctx: Global MAC context
+ * @save_cmd: Pointer where the command will be saved
+ * @command: Command from which the profile will be saved
+ *
+ * Saves the profile information from the SME's scan command
+ *
+ * Return: CDF_STATUS
+ */
+CDF_STATUS csr_save_profile(tpAniSirGlobal mac_ctx,
+ tSmeCmd *save_cmd, tSmeCmd *command)
+{
+ tCsrScanResult *scan_result;
+ tCsrScanResult *temp;
+ uint32_t bss_len;
+ CDF_STATUS status;
+
+ save_cmd->u.scanCmd.pToRoamProfile =
+ cdf_mem_malloc(sizeof(tCsrRoamProfile));
+ if (!save_cmd->u.scanCmd.pToRoamProfile) {
+ sms_log(mac_ctx, LOGE, FL("pToRoamProfile mem fail"));
+ goto error;
+ }
+
+ status = csr_roam_copy_profile(mac_ctx,
+ save_cmd->u.scanCmd.pToRoamProfile,
+ command->u.scanCmd.pToRoamProfile);
+ if (!CDF_IS_STATUS_SUCCESS(status)) {
+ sms_log(mac_ctx, LOGE, FL("csr_roam_copy_profile fail"));
+ goto error;
+ }
+
+ save_cmd->sessionId = command->sessionId;
+ save_cmd->u.scanCmd.roamId = command->u.scanCmd.roamId;
+ save_cmd->u.scanCmd.u.scanRequest.SSIDs.numOfSSIDs =
+ command->u.scanCmd.u.scanRequest.SSIDs.numOfSSIDs;
+ save_cmd->u.scanCmd.u.scanRequest.SSIDs.SSIDList =
+ cdf_mem_malloc(
+ save_cmd->u.scanCmd.u.scanRequest.SSIDs.numOfSSIDs *
+ sizeof(tCsrSSIDInfo));
+ if (!save_cmd->u.scanCmd.u.scanRequest.SSIDs.SSIDList) {
+ sms_log(mac_ctx, LOGE, FL("SSIDList mem fail"));
+ goto error;
+ }
+
+ cdf_mem_copy(save_cmd->u.scanCmd.u.scanRequest.SSIDs.SSIDList,
+ command->u.scanCmd.u.scanRequest.SSIDs.SSIDList,
+ save_cmd->u.scanCmd.u.scanRequest.SSIDs.numOfSSIDs *
+ sizeof(tCsrSSIDInfo));
+
+ if (!command->u.roamCmd.pRoamBssEntry)
+ return CDF_STATUS_SUCCESS;
+
+ scan_result = GET_BASE_ADDR(command->u.roamCmd.pRoamBssEntry,
+ tCsrScanResult, Link);
+
+ bss_len = scan_result->Result.BssDescriptor.length +
+ sizeof(scan_result->Result.BssDescriptor.length);
+
+ temp = cdf_mem_malloc(sizeof(tCsrScanResult) + bss_len);
+ if (!temp) {
+ sms_log(mac_ctx, LOGE, FL("bss mem fail"));
+ goto error;
+ }
+
+ temp->AgingCount = scan_result->AgingCount;
+ temp->preferValue = scan_result->preferValue;
+ temp->capValue = scan_result->capValue;
+ temp->ucEncryptionType = scan_result->ucEncryptionType;
+ temp->mcEncryptionType = scan_result->mcEncryptionType;
+ temp->authType = scan_result->authType;
+ /* pvIes is unsued in success/failure */
+ temp->Result.pvIes = NULL;
+
+ cdf_mem_copy(temp->Result.pvIes,
+ scan_result->Result.pvIes,
+ sizeof(*scan_result->Result.pvIes));
+ temp->Result.ssId.length = scan_result->Result.ssId.length;
+ cdf_mem_copy(temp->Result.ssId.ssId,
+ scan_result->Result.ssId.ssId,
+ sizeof(scan_result->Result.ssId.ssId));
+ temp->Result.timer = scan_result->Result.timer;
+ cdf_mem_copy(&temp->Result.BssDescriptor,
+ &scan_result->Result.BssDescriptor,
+ sizeof(temp->Result.BssDescriptor));
+ temp->Link.last = temp->Link.next = NULL;
+ save_cmd->u.roamCmd.pRoamBssEntry = (tListElem *)temp;
+
+ return CDF_STATUS_SUCCESS;
+error:
+ csr_scan_handle_search_for_ssid_failure(mac_ctx,
+ command);
+ if (save_cmd->u.roamCmd.pRoamBssEntry)
+ cdf_mem_free(save_cmd->u.roamCmd.pRoamBssEntry);
+ if (save_cmd->u.scanCmd.u.scanRequest.SSIDs.SSIDList)
+ cdf_mem_free(save_cmd->u.scanCmd.u.scanRequest.SSIDs.SSIDList);
+ if (save_cmd->u.scanCmd.pToRoamProfile)
+ cdf_mem_free(save_cmd->u.scanCmd.pToRoamProfile);
+ if (save_cmd) {
+ cdf_mem_free(save_cmd);
+ save_cmd = NULL;
+ }
+
+ return CDF_STATUS_E_FAILURE;
+}
+
static void
csr_handle_nxt_cmd(tpAniSirGlobal mac_ctx, tSmeCmd *pCommand,
eCsrScanCompleteNextCommand *nxt_cmd,
- bool *remove_cmd, uint32_t session_id)
+ bool *remove_cmd, uint32_t session_id,
+ uint8_t chan)
{
- CDF_STATUS status;
+ CDF_STATUS status, ret;
+ tSmeCmd *save_cmd = NULL;
+
switch (*nxt_cmd) {
case eCsrNext11dScan1Success:
case eCsrNext11dScan2Success:
@@ -3852,6 +3999,54 @@
case eCsrNexteScanForSsidFailure:
csr_scan_handle_search_for_ssid_failure(mac_ctx, pCommand);
break;
+ case eCsrNextCheckAllowConc:
+ ret = cds_current_connections_update(pCommand->sessionId,
+ chan,
+ CDS_UPDATE_REASON_HIDDEN_STA);
+ sms_log(mac_ctx, LOG1, FL("chan: %d session: %d status: %d"),
+ chan, pCommand->sessionId, ret);
+ if (mac_ctx->sme.saved_scan_cmd) {
+ cdf_mem_free(mac_ctx->sme.saved_scan_cmd);
+ mac_ctx->sme.saved_scan_cmd = NULL;
+ sms_log(mac_ctx, LOGE,
+ FL("memory should have been free. Check!"));
+ }
+
+ save_cmd = (tSmeCmd *) cdf_mem_malloc(sizeof(*pCommand));
+ if (!save_cmd) {
+ sms_log(mac_ctx, LOGE, FL("save_cmd mem fail"));
+ goto error;
+ }
+
+ status = csr_save_profile(mac_ctx, save_cmd, pCommand);
+ if (!CDF_IS_STATUS_SUCCESS(status) ||
+ !save_cmd) {
+ /* csr_save_profile should report error */
+ sms_log(mac_ctx, LOGE, FL("profile save failed %d"),
+ status);
+ return;
+ }
+
+ mac_ctx->sme.saved_scan_cmd = (void *)save_cmd;
+
+ if (CDF_STATUS_E_FAILURE == ret) {
+error:
+ sms_log(mac_ctx, LOGE, FL("conn update fail %d"), chan);
+ csr_scan_handle_search_for_ssid_failure(mac_ctx,
+ pCommand);
+ if (mac_ctx->sme.saved_scan_cmd) {
+ cdf_mem_free(mac_ctx->sme.saved_scan_cmd);
+ mac_ctx->sme.saved_scan_cmd = NULL;
+ }
+ } else if (CDF_STATUS_E_NOSUPPORT == ret) {
+ sms_log(mac_ctx, LOGE, FL("conn update not supported"));
+ csr_scan_handle_search_for_ssid(mac_ctx, pCommand);
+ if (mac_ctx->sme.saved_scan_cmd) {
+ cdf_mem_free(mac_ctx->sme.saved_scan_cmd);
+ mac_ctx->sme.saved_scan_cmd = NULL;
+ }
+ }
+ break;
default:
break;
}
@@ -3916,6 +4111,7 @@
bool fRemoveCommand = true;
bool fSuccess;
uint32_t sessionId = 0;
+ uint8_t chan;
csr_get_active_scan_entry(pMac, pScanRsp->scan_id, &pEntry);
if (!pEntry) {
@@ -3966,10 +4162,11 @@
#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
csr_diag_scan_complete(pMac, pCommand, pScanRsp);
#endif /* #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR */
- NextCommand = csr_scan_get_next_command_state(pMac, pCommand, fSuccess);
+ NextCommand = csr_scan_get_next_command_state(pMac, pCommand, fSuccess,
+ &chan);
/* We reuse the command here instead reissue a new command */
csr_handle_nxt_cmd(pMac, pCommand, &NextCommand,
- &fRemoveCommand, sessionId);
+ &fRemoveCommand, sessionId, chan);
return fRemoveCommand;
}
diff --git a/core/sme/src/csr/csr_inside_api.h b/core/sme/src/csr/csr_inside_api.h
index 1679784..0c7fef8 100644
--- a/core/sme/src/csr/csr_inside_api.h
+++ b/core/sme/src/csr/csr_inside_api.h
@@ -123,6 +123,7 @@
eCsrNext11dScan2Success,
eCsrNext11dScanComplete,
eCsrNexteScanForSsidFailure,
+ eCsrNextCheckAllowConc,
} eCsrScanCompleteNextCommand;
@@ -1060,6 +1061,10 @@
CDF_STATUS csr_set_ht2040_mode(tpAniSirGlobal pMac, uint32_t sessionId,
ePhyChanBondState cbMode, bool obssEnabled);
#endif
+CDF_STATUS csr_scan_handle_search_for_ssid(tpAniSirGlobal mac,
+ tSmeCmd *command);
+CDF_STATUS csr_scan_handle_search_for_ssid_failure(tpAniSirGlobal mac,
+ tSmeCmd *command);
tSirBssDescription*
csr_get_bssdescr_from_scan_handle(tScanResultHandle result_handle,
tSirBssDescription *bss_descr);