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
This commit is contained in:
Chandrasekaran, Manishekar 2015-10-20 19:54:55 +05:30 committed by Prakash Dhavali
parent 123d863c0c
commit ef70c0dd64
12 changed files with 489 additions and 63 deletions

View File

@ -600,6 +600,9 @@ static inline bool cds_handle_conc_rule2(hdd_context_t *hdd_ctx,
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 @@ CDF_STATUS cds_update_connection_info(hdd_context_t *hdd_ctx,
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 @@ enum cds_con_mode cds_convert_device_mode_to_hdd_type(
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,

View File

@ -2377,12 +2377,14 @@ static void cds_hw_mode_transition_cb(uint32_t old_hw_mode_index,
/**
* 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 @@ static void cds_hw_mode_transition_cb(uint32_t old_hw_mode_index,
* 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 @@ CDF_STATUS cds_soc_set_hw_mode(hdd_context_t *hdd_ctx,
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 @@ void cds_dbs_opportunistic_timer_handler(void *data)
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 @@ CDF_STATUS cds_mode_switch_mcc_to_dbs(hdd_context_t *hdd_ctx)
* 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 @@ CDF_STATUS cds_mode_switch_mcc_to_dbs(hdd_context_t *hdd_ctx)
*
* 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 @@ CDF_STATUS cds_current_connections_update(
}
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 @@ void cds_nss_update_cb(void *context, uint8_t tx_status, uint8_t vdev_id,
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 @@ void cds_nss_update_cb(void *context, uint8_t tx_status, uint8_t vdev_id,
* @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 @@ void cds_nss_update_cb(void *context, uint8_t tx_status, uint8_t vdev_id,
* 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 @@ CDF_STATUS cds_complete_action(hdd_context_t *hdd_ctx,
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 @@ CDF_STATUS cds_complete_action(hdd_context_t *hdd_ctx,
* 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 @@ CDF_STATUS cds_complete_action(hdd_context_t *hdd_ctx,
* 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 @@ CDF_STATUS cds_next_actions(hdd_context_t *hdd_ctx,
* 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 @@ CDF_STATUS cds_next_actions(hdd_context_t *hdd_ctx,
* 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 @@ CDF_STATUS cds_get_channel_from_scan_result(hdd_adapter_t *adapter,
}
/**
* 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 @@ bool cds_handle_conc_multiport(uint8_t session_id,
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 @@ bool cds_handle_conc_multiport(uint8_t session_id,
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 @@ bool cds_handle_conc_multiport(uint8_t session_id,
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;

View File

@ -4107,7 +4107,8 @@ static int __wlan_hdd_cfg80211_set_probable_oper_channel(struct wiphy *wiphy,
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 @@ static int __wlan_hdd_cfg80211_set_probable_oper_channel(struct wiphy *wiphy,
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 @@ static int __wlan_hdd_cfg80211_join_ibss(struct wiphy *wiphy,
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;

View File

@ -8241,7 +8241,9 @@ static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
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;

View File

@ -7692,19 +7692,25 @@ static int __iw_set_var_ints_getnone(struct net_device *dev,
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 @@ static int __iw_set_var_ints_getnone(struct net_device *dev,
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;

View File

@ -95,6 +95,28 @@ typedef uint8_t tSirVersionString[SIR_VERSION_STRING_LEN];
/* 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 @@ typedef struct sSirSmeReadyReq {
* 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;
};
/**

View File

@ -156,6 +156,7 @@ static CDF_STATUS lim_process_set_hw_mode(tpAniSirGlobal mac, uint32_t *msg)
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;

View File

@ -218,6 +218,7 @@ typedef struct tagSmeStruct {
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 ) */

View File

@ -156,7 +156,10 @@ static CDF_STATUS sme_process_set_hw_mode_resp(tpAniSirGlobal mac, uint8_t *msg)
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 @@ static CDF_STATUS sme_process_set_hw_mode_resp(tpAniSirGlobal mac, uint8_t *msg)
}
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 @@ static CDF_STATUS sme_process_set_hw_mode_resp(tpAniSirGlobal mac, uint8_t *msg)
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 @@ CDF_STATUS sme_soc_set_hw_mode(tHalHandle hal,
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);

View File

@ -453,6 +453,10 @@ CDF_STATUS csr_close(tpAniSirGlobal pMac)
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 @@ void csr_process_set_hw_mode(tpAniSirGlobal mac, tSmeCmd *command)
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.

View File

@ -2022,8 +2022,11 @@ csr_parse_scan_results(tpAniSirGlobal pMac,
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 @@ csr_parse_scan_results(tpAniSirGlobal pMac,
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 @@ CDF_STATUS csr_scan_get_result(tpAniSirGlobal pMac,
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 @@ void csr_reinit_scan_cmd(tpAniSirGlobal pMac, tSmeCmd *pCommand)
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 @@ eCsrScanCompleteNextCommand csr_scan_get_next_command_state(tpAniSirGlobal pMac,
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 @@ csr_diag_scan_complete(tpAniSirGlobal pMac,
}
#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 @@ csr_handle_nxt_cmd(tpAniSirGlobal mac_ctx, tSmeCmd *pCommand,
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 csr_scan_complete(tpAniSirGlobal pMac, tSirSmeScanRsp *pScanRsp)
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 @@ bool csr_scan_complete(tpAniSirGlobal pMac, tSirSmeScanRsp *pScanRsp)
#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;
}

View File

@ -123,6 +123,7 @@ typedef enum {
eCsrNext11dScan2Success,
eCsrNext11dScanComplete,
eCsrNexteScanForSsidFailure,
eCsrNextCheckAllowConc,
} eCsrScanCompleteNextCommand;
@ -1060,6 +1061,10 @@ void csr_clear_votes_for_country_info(tpAniSirGlobal pMac);
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);