diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 9542d87c17..c522927cb6 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -1234,7 +1234,7 @@ struct hdd_adapter { struct hdd_ap_ctx ap; } session; - qdf_atomic_t dfs_radar_found; + qdf_atomic_t ch_switch_in_progress; #ifdef WLAN_FEATURE_TSF /* tsf value received from firmware */ @@ -3662,4 +3662,14 @@ void wlan_hdd_send_tcp_param_update_event(struct hdd_context *hdd_ctx, QDF_STATUS hdd_md_host_evt_cb(void *ctx, struct sir_md_evt *event); #endif /* WLAN_FEATURE_MOTION_DETECTION */ +/** + * hdd_hidden_ssid_enable_roaming() - enable roaming after hidden ssid rsp + * @hdd_handle: Hdd handler + * @vdev_id: Vdev Id + * + * This is a wrapper function to enable roaming after getting hidden + * ssid rsp + */ +void hdd_hidden_ssid_enable_roaming(hdd_handle_t hdd_handle, uint8_t vdev_id); + #endif /* end #if !defined(WLAN_HDD_MAIN_H) */ diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index 290e142ab5..1715d12951 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -1729,7 +1729,7 @@ QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent, hostapd_state->qdf_status = pSapEvent->sapevt.sapStartBssCompleteEvent.status; - qdf_atomic_set(&adapter->dfs_radar_found, 0); + qdf_atomic_set(&adapter->ch_switch_in_progress, 0); status = policy_mgr_set_chan_switch_complete_evt( hdd_ctx->psoc); @@ -1939,7 +1939,7 @@ QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent, hdd_debug("Sent CAC start to user space"); } - qdf_atomic_set(&adapter->dfs_radar_found, 0); + qdf_atomic_set(&adapter->ch_switch_in_progress, 0); break; case eSAP_DFS_CAC_INTERRUPTED: /* @@ -2529,7 +2529,7 @@ QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent, return QDF_STATUS_SUCCESS; case eSAP_ECSA_CHANGE_CHAN_IND: hdd_debug("Channel change indication from peer for channel %d", - pSapEvent->sapevt.sap_chan_cng_ind.new_chan); + pSapEvent->sapevt.sap_chan_cng_ind.new_chan); if (hdd_softap_set_channel_change(dev, pSapEvent->sapevt.sap_chan_cng_ind.new_chan, CH_WIDTH_MAX, false)) @@ -2551,6 +2551,18 @@ QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent, schedule_work(&adapter->sap_stop_bss_work); return QDF_STATUS_SUCCESS; + case eSAP_CHANNEL_CHANGE_RESP: + hdd_debug("Channel change rsp status = %d", + pSapEvent->sapevt.ch_change_rsp_status); + /* + * Set the ch_switch_in_progress flag to zero and also enable + * roaming once channel change process (success/failure) + * is completed + */ + qdf_atomic_set(&adapter->ch_switch_in_progress, 0); + wlan_hdd_enable_roaming(adapter); + return QDF_STATUS_SUCCESS; + default: hdd_debug("SAP message is not handled"); goto stopbss; @@ -2832,7 +2844,7 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_channel, } /* - * Set the dfs_radar_found flag to mimic channel change + * Set the ch_switch_in_progress flag to mimic channel change * when a radar is found. This will enable synchronizing * SAP and HDD states similar to that of radar indication. * Suspend the netif queues to stop queuing Tx frames @@ -2840,7 +2852,7 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_channel, * once the channel change is completed and SAP will * post eSAP_START_BSS_EVENT success event to HDD. */ - if (qdf_atomic_inc_return(&adapter->dfs_radar_found) > 1) { + if (qdf_atomic_inc_return(&adapter->ch_switch_in_progress) > 1) { hdd_err("Channel switch in progress!!"); return -EBUSY; } @@ -2864,14 +2876,14 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_channel, target_channel, adapter->session_id)) { hdd_err("Channel switch failed due to concurrency check failure"); - qdf_atomic_set(&adapter->dfs_radar_found, 0); + qdf_atomic_set(&adapter->ch_switch_in_progress, 0); return -EINVAL; } status = policy_mgr_reset_chan_switch_complete_evt(hdd_ctx->psoc); if (!QDF_IS_STATUS_SUCCESS(status)) { hdd_err("clear event failed"); - qdf_atomic_set(&adapter->dfs_radar_found, 0); + qdf_atomic_set(&adapter->ch_switch_in_progress, 0); return -EINVAL; } @@ -2880,9 +2892,24 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_channel, &scc_on_lte_coex); if (!QDF_IS_STATUS_SUCCESS(status)) { hdd_err("can't get STA-SAP SCC on lte coex channel setting"); - qdf_atomic_set(&adapter->dfs_radar_found, 0); + qdf_atomic_set(&adapter->ch_switch_in_progress, 0); return -EINVAL; } + + /* + * Reject channel change req if reassoc in progress on any adapter. + * sme_is_any_session_in_middle_of_roaming is for LFR2 and + * hdd_is_roaming_in_progress is for LFR3 + */ + if (sme_is_any_session_in_middle_of_roaming(hdd_ctx->mac_handle) || + hdd_is_roaming_in_progress(hdd_ctx)) { + hdd_info("Channel switch not allowed as reassoc in progress"); + qdf_atomic_set(&adapter->ch_switch_in_progress, 0); + return -EINVAL; + } + /* Disable Roaming on all adapters before doing channel change */ + wlan_hdd_disable_roaming(adapter); + /* * Post the Channel Change request to SAP. */ @@ -2900,7 +2927,13 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_channel, * radar found flag and also restart the netif * queues. */ - qdf_atomic_set(&adapter->dfs_radar_found, 0); + qdf_atomic_set(&adapter->ch_switch_in_progress, 0); + + /* + * If Posting of the Channel Change request fails + * enable roaming on all adapters + */ + wlan_hdd_enable_roaming(adapter); ret = -EINVAL; } @@ -3351,7 +3384,7 @@ struct hdd_adapter *hdd_wlan_create_ap_dev(struct hdd_context *hdd_ctx, spin_lock_init(&adapter->pause_map_lock); adapter->start_time = adapter->last_time = qdf_system_ticks(); - qdf_atomic_init(&adapter->dfs_radar_found); + qdf_atomic_init(&adapter->ch_switch_in_progress); return adapter; } diff --git a/core/hdd/src/wlan_hdd_hostapd_wext.c b/core/hdd/src/wlan_hdd_hostapd_wext.c index 4a9d66b8b0..0bb4802307 100644 --- a/core/hdd/src/wlan_hdd_hostapd_wext.c +++ b/core/hdd/src/wlan_hdd_hostapd_wext.c @@ -549,11 +549,29 @@ static __iw_softap_setparam(struct net_device *dev, { QDF_STATUS status; + /* + * Reject hidden ssid param update if reassoc in progress on + * any adapter. sme_is_any_session_in_middle_of_roaming is for + * LFR2 and hdd_is_roaming_in_progress is for LFR3 + */ + if (hdd_is_roaming_in_progress(hdd_ctx) || + sme_is_any_session_in_middle_of_roaming(mac_handle)) { + hdd_info("Reassociation in progress"); + return -EINVAL; + } + + /* + * Disable Roaming on all adapters before start of + * start of Hidden ssid connection + */ + wlan_hdd_disable_roaming(adapter); + status = sme_update_session_param(mac_handle, adapter->session_id, SIR_PARAM_SSID_HIDDEN, set_value); if (QDF_STATUS_SUCCESS != status) { hdd_err("QCSAP_PARAM_HIDE_SSID failed"); + wlan_hdd_enable_roaming(adapter); return -EIO; } break; diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 62128ead07..5bdb825f9b 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -12198,6 +12198,8 @@ int hdd_register_cb(struct hdd_context *hdd_ctx) sme_set_link_layer_ext_cb(mac_handle, wlan_hdd_cfg80211_link_layer_stats_ext_callback); + sme_update_hidden_ssid_status_cb(mac_handle, + hdd_hidden_ssid_enable_roaming); status = sme_set_lost_link_info_cb(mac_handle, hdd_lost_link_info_cb); @@ -15175,6 +15177,21 @@ void hdd_set_rx_mode_rps(bool enable) } } +void hdd_hidden_ssid_enable_roaming(hdd_handle_t hdd_handle, uint8_t vdev_id) +{ + struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle); + struct hdd_adapter *adapter; + + adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id); + + if (!adapter) { + hdd_err("Adapter is null"); + return; + } + /* enable roaming on all adapters once hdd get hidden ssid rsp */ + wlan_hdd_enable_roaming(adapter); +} + /* Register the module init/exit functions */ module_init(hdd_module_init); module_exit(hdd_module_exit); diff --git a/core/mac/inc/wni_api.h b/core/mac/inc/wni_api.h index e4e3a97205..26bfffb6d4 100644 --- a/core/mac/inc/wni_api.h +++ b/core/mac/inc/wni_api.h @@ -234,7 +234,9 @@ enum eWniMsgTypes { eWNI_SME_CSA_RESTART_REQ = SIR_SME_MSG_TYPES_BEGIN + 148, eWNI_SME_CSA_RESTART_RSP = SIR_SME_MSG_TYPES_BEGIN + 149, WNI_SME_CFG_ACTION_FRM_HE_TB_PPDU = SIR_SME_MSG_TYPES_BEGIN + 150, - eWNI_SME_MSG_TYPES_END = SIR_SME_MSG_TYPES_BEGIN + 151 + /* To indicate Hidden ssid start complition to upper layer */ + eWNI_SME_HIDDEN_SSID_RESTART_RSP = SIR_SME_MSG_TYPES_BEGIN + 151, + eWNI_SME_MSG_TYPES_END = SIR_SME_MSG_TYPES_BEGIN + 152 }; typedef struct sAniCfgTxRateCtrs { diff --git a/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c b/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c index 8a76beaa96..40523d14e3 100644 --- a/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c +++ b/core/mac/src/pe/lim/lim_process_mlm_rsp_messages.c @@ -2741,6 +2741,8 @@ void lim_process_mlm_update_hidden_ssid_rsp(struct mac_context *mac_ctx, { struct pe_session *session_entry; tpHalHiddenSsidVdevRestart hidden_ssid_vdev_restart; + struct scheduler_msg message = {0}; + QDF_STATUS status; hidden_ssid_vdev_restart = (tpHalHiddenSsidVdevRestart)(msg->bodyptr); @@ -2761,6 +2763,15 @@ void lim_process_mlm_update_hidden_ssid_rsp(struct mac_context *mac_ctx, sch_set_fixed_beacon_fields(mac_ctx, session_entry); lim_send_beacon(mac_ctx, session_entry); + message.type = eWNI_SME_HIDDEN_SSID_RESTART_RSP; + message.bodyval = hidden_ssid_vdev_restart->sessionId; + status = scheduler_post_message(QDF_MODULE_ID_PE, + QDF_MODULE_ID_SME, + QDF_MODULE_ID_SME, &message); + + if (status != QDF_STATUS_SUCCESS) + pe_err("Failed to post message %u", status); + free_req: if (NULL != hidden_ssid_vdev_restart) { qdf_mem_free(hidden_ssid_vdev_restart); diff --git a/core/mac/src/pe/lim/lim_types.h b/core/mac/src/pe/lim/lim_types.h index 342dd5b564..5902b07c7a 100644 --- a/core/mac/src/pe/lim/lim_types.h +++ b/core/mac/src/pe/lim/lim_types.h @@ -546,7 +546,7 @@ void lim_send_deauth_mgmt_frame(struct mac_context *, uint16_t, tSirMacAddr, str bool waitForAck); void lim_process_mlm_update_hidden_ssid_rsp(struct mac_context *mac_ctx, - struct scheduler_msg *msg); + struct scheduler_msg *msg); tSirResultCodes lim_mlm_add_bss(struct mac_context *, tLimMlmStartReq *, struct pe_session *pe_session); diff --git a/core/mac/src/sys/legacy/src/utils/src/mac_trace.c b/core/mac/src/sys/legacy/src/utils/src/mac_trace.c index d3db6877b3..d9c4e86784 100644 --- a/core/mac/src/sys/legacy/src/utils/src/mac_trace.c +++ b/core/mac/src/sys/legacy/src/utils/src/mac_trace.c @@ -374,6 +374,7 @@ uint8_t *mac_trace_get_sme_msg_string(uint16_t sme_msg) CASE_RETURN_STRING(eWNI_SME_CSA_RESTART_REQ); CASE_RETURN_STRING(eWNI_SME_CSA_RESTART_RSP); CASE_RETURN_STRING(eWNI_SME_MSG_TYPES_END); + CASE_RETURN_STRING(eWNI_SME_HIDDEN_SSID_RESTART_RSP); default: return (uint8_t *) "UNKNOWN"; break; diff --git a/core/sap/inc/sap_api.h b/core/sap/inc/sap_api.h index 241d520925..f6b16a303c 100644 --- a/core/sap/inc/sap_api.h +++ b/core/sap/inc/sap_api.h @@ -169,6 +169,8 @@ typedef enum { eSAP_ACS_CHANNEL_SELECTED, eSAP_ECSA_CHANGE_CHAN_IND, eSAP_DFS_NEXT_CHANNEL_REQ, + /* Event sent channel switch status to upper layer */ + eSAP_CHANNEL_CHANGE_RESP, } eSapHddEvent; typedef enum { @@ -427,6 +429,7 @@ typedef struct sap_Event_s { struct sap_ch_selected_s sap_ch_selected; struct sap_ch_change_ind sap_chan_cng_ind; struct sap_acs_scan_complete_event sap_acs_scan_comp; + QDF_STATUS ch_change_rsp_status; } sapevt; } tSap_Event, *tpSap_Event; diff --git a/core/sap/src/sap_api_link_cntl.c b/core/sap/src/sap_api_link_cntl.c index a1de3d59aa..e91bfb163c 100644 --- a/core/sap/src/sap_api_link_cntl.c +++ b/core/sap/src/sap_api_link_cntl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -1206,6 +1206,11 @@ wlansap_roam_callback(void *ctx, struct csr_roam_info *csr_roam_info, case eCSR_ROAM_RESULT_CHANNEL_CHANGE_SUCCESS: wlansap_roam_process_ch_change_success(mac_ctx, sap_ctx, csr_roam_info, &qdf_ret_status); + + qdf_ret_status = + sap_signal_hdd_event(sap_ctx, csr_roam_info, + eSAP_CHANNEL_CHANGE_RESP, + (void *)QDF_STATUS_SUCCESS); break; case eCSR_ROAM_RESULT_CHANNEL_CHANGE_FAILURE: /* This is much more serious issue, we have to vacate the @@ -1213,6 +1218,11 @@ wlansap_roam_callback(void *ctx, struct csr_roam_info *csr_roam_info, * failed, stop the BSS operation completely and inform hostapd */ qdf_ret_status = wlansap_stop_bss(sap_ctx); + + qdf_ret_status = + sap_signal_hdd_event(sap_ctx, csr_roam_info, + eSAP_CHANNEL_CHANGE_RESP, + (void *)QDF_STATUS_E_FAILURE); break; case eCSR_ROAM_EXT_CHG_CHNL_UPDATE_IND: qdf_status = sap_signal_hdd_event(sap_ctx, csr_roam_info, diff --git a/core/sap/src/sap_fsm.c b/core/sap/src/sap_fsm.c index cfba3c7599..37d2362a69 100644 --- a/core/sap/src/sap_fsm.c +++ b/core/sap/src/sap_fsm.c @@ -1736,6 +1736,15 @@ QDF_STATUS sap_signal_hdd_event(struct sap_context *sap_ctx, sap_ctx->sessionId, sap_ctx->self_mac_addr, sap_ctx->channel); break; + + case eSAP_CHANNEL_CHANGE_RESP: + sap_ap_event.sapHddEventCode = eSAP_CHANNEL_CHANGE_RESP; + sap_ap_event.sapevt.ch_change_rsp_status = (QDF_STATUS)context; + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, + "In %s, SAP event callback event = %s", + __func__, "eSAP_CHANNEL_CHANGE_RESP"); + break; + default: QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, FL("SAP Unknown callback event = %d"), diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index f098807840..5e92c9db15 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -3197,4 +3197,13 @@ QDF_STATUS sme_set_thermal_mgmt(mac_handle_t mac_handle, uint16_t lower_thresh_deg, uint16_t higher_thresh_deg); #endif /* FW_THERMAL_THROTTLE_SUPPORT */ + +/** + * sme_update_hidden_ssid_status_cb() - cb fun to update hidden ssid stats + * @mac_handle: mac handler + * @cb: cb of type hidden_ssid_cb + */ +QDF_STATUS sme_update_hidden_ssid_status_cb(mac_handle_t mac_handle, + hidden_ssid_cb cb); + #endif /* #if !defined( __SME_API_H ) */ diff --git a/core/sme/inc/sme_internal.h b/core/sme/inc/sme_internal.h index 9e6b196236..77b3d1464d 100644 --- a/core/sme/inc/sme_internal.h +++ b/core/sme/inc/sme_internal.h @@ -227,6 +227,13 @@ typedef void (*rso_cmd_status_cb)(hdd_handle_t hdd_handle, */ typedef void (*lost_link_info_cb)(hdd_handle_t hdd_handle, struct sir_lost_link_info *lost_link_info); +/** + * typedef hidden_ssid_cb - hidden ssid rsp callback fun + * @hdd_handle: HDD handle registered with SME + * @vdev_id: Vdev Id + */ +typedef void (*hidden_ssid_cb)(hdd_handle_t hdd_handle, + uint8_t vdev_id); #ifdef WLAN_FEATURE_MOTION_DETECTION typedef QDF_STATUS (*md_host_evt_cb)(void *hdd_ctx, sir_md_evt *event); @@ -323,6 +330,9 @@ typedef struct tagSmeStruct { md_host_evt_cb md_host_evt_cb; void *md_ctx; #endif /* WLAN_FEATURE_MOTION_DETECTION */ + /* hidden ssid rsp callback */ + hidden_ssid_cb hidden_ssid_cb; + } 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 ff5cfbbf52..5d0365389b 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -2247,6 +2247,12 @@ QDF_STATUS sme_process_msg(struct mac_context *mac, struct scheduler_msg *pMsg) mac->sme.bt_activity_info_cb(mac->hdd_handle, pMsg->bodyval); break; + case eWNI_SME_HIDDEN_SSID_RESTART_RSP: + if (mac->sme.hidden_ssid_cb) + mac->sme.hidden_ssid_cb(mac->hdd_handle, pMsg->bodyval); + else + sme_err("callback is NULL"); + break; default: if ((pMsg->type >= eWNI_SME_MSG_TYPES_BEGIN) @@ -15020,3 +15026,18 @@ QDF_STATUS sme_set_thermal_mgmt(mac_handle_t mac_handle, return qdf_status; } #endif /* FW_THERMAL_THROTTLE_SUPPORT */ + +QDF_STATUS sme_update_hidden_ssid_status_cb(mac_handle_t mac_handle, + hidden_ssid_cb cb) +{ + QDF_STATUS status; + struct mac_context *mac = MAC_CONTEXT(mac_handle); + + status = sme_acquire_global_lock(&mac->sme); + if (QDF_IS_STATUS_SUCCESS(status)) { + mac->sme.hidden_ssid_cb = cb; + sme_release_global_lock(&mac->sme); + } + + return status; +}