diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 39b2bbc50f9e..fd1335eaec3f 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -1439,6 +1439,8 @@ struct hdd_adapter { ol_txrx_rx_fp rx_stack; qdf_work_t netdev_features_update_work; + /* Flag to indicate whether it is a pre cac adapter or not */ + bool is_pre_cac_adapter; }; #define WLAN_HDD_GET_STATION_CTX_PTR(adapter) (&(adapter)->session.station) diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index b2aa28748236..8ae00d461806 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -1081,9 +1081,7 @@ static void __wlan_hdd_sap_pre_cac_failure(struct hdd_adapter *adapter) if (wlan_hdd_validate_context(hdd_ctx)) return; - wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes); hdd_stop_adapter(hdd_ctx, adapter); - hdd_close_adapter(hdd_ctx, adapter, false); hdd_exit(); } @@ -1106,13 +1104,10 @@ void wlan_hdd_sap_pre_cac_failure(void *data) if (errno) return; - osif_vdev_sync_unregister(adapter->dev); - osif_vdev_sync_wait_for_ops(vdev_sync); __wlan_hdd_sap_pre_cac_failure(data); osif_vdev_sync_trans_stop(vdev_sync); - osif_vdev_sync_destroy(vdev_sync); } /** @@ -1140,7 +1135,6 @@ static void __wlan_hdd_sap_pre_cac_success(struct hdd_adapter *adapter) wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes); hdd_stop_adapter(hdd_ctx, adapter); - hdd_close_adapter(hdd_ctx, adapter, false); /* Prepare to switch AP from 2.4GHz channel to the pre CAC channel */ ap_adapter = hdd_get_adapter(hdd_ctx, QDF_SAP_MODE); diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 1802b654dc4f..c0d881a3723e 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -6787,6 +6787,8 @@ struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t sessio hdd_periodic_sta_stats_init(adapter); + adapter->is_pre_cac_adapter = false; + return adapter; err_destroy_adapter_features_update_work: @@ -6979,6 +6981,32 @@ static inline void hdd_dump_func_call_map(void) } #endif +static void hdd_close_pre_cac_adapter(struct hdd_context *hdd_ctx) +{ + struct hdd_adapter *pre_cac_adapter; + struct osif_vdev_sync *vdev_sync; + int errno; + + pre_cac_adapter = hdd_get_adapter_by_iface_name(hdd_ctx, + SAP_PRE_CAC_IFNAME); + if (!pre_cac_adapter) + return; + + errno = osif_vdev_sync_trans_start_wait(pre_cac_adapter->dev, + &vdev_sync); + if (errno) + return; + + osif_vdev_sync_unregister(pre_cac_adapter->dev); + osif_vdev_sync_wait_for_ops(vdev_sync); + + wlan_hdd_release_intf_addr(hdd_ctx, pre_cac_adapter->mac_addr.bytes); + hdd_close_adapter(hdd_ctx, pre_cac_adapter, true); + + osif_vdev_sync_trans_stop(vdev_sync); + osif_vdev_sync_destroy(vdev_sync); +} + QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx, struct hdd_adapter *adapter) { @@ -7176,11 +7204,23 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx, ucfg_ipa_flush(hdd_ctx->pdev); - /* don't flush pre-cac destroy if we are destroying pre-cac */ - sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(adapter); - if (!wlan_sap_is_pre_cac_context(sap_ctx) && - (hdd_ctx->sap_pre_cac_work.fn)) - cds_flush_work(&hdd_ctx->sap_pre_cac_work); + if (!adapter->is_pre_cac_adapter) { + /** + * don't flush pre-cac destroy if we are destroying + * pre-cac adapter + */ + sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(adapter); + if (!wlan_sap_is_pre_cac_context(sap_ctx) && + (hdd_ctx->sap_pre_cac_work.fn)) + cds_flush_work(&hdd_ctx->sap_pre_cac_work); + + hdd_close_pre_cac_adapter(hdd_ctx); + + } else { + if (wlan_sap_set_pre_cac_status( + WLAN_HDD_GET_SAP_CTX_PTR(adapter), false)) + hdd_err("Failed to set is_pre_cac_on to false"); + } /* fallthrough */ diff --git a/core/hdd/src/wlan_hdd_sap_cond_chan_switch.c b/core/hdd/src/wlan_hdd_sap_cond_chan_switch.c index eade0bdbdac4..e8c6d4323c78 100644 --- a/core/hdd/src/wlan_hdd_sap_cond_chan_switch.c +++ b/core/hdd/src/wlan_hdd_sap_cond_chan_switch.c @@ -165,7 +165,7 @@ static int __wlan_hdd_request_pre_cac(struct hdd_context *hdd_ctx, uint32_t chan_freq, struct hdd_adapter **out_adapter) { - uint8_t *mac_addr; + uint8_t *mac_addr = NULL; uint32_t pre_cac_chan_freq = 0; int ret; struct hdd_adapter *ap_adapter, *pre_cac_adapter; @@ -216,12 +216,6 @@ static int __wlan_hdd_request_pre_cac(struct hdd_context *hdd_ctx, return -EINVAL; } - mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_SAP_MODE); - if (!mac_addr) { - hdd_err("can't add virtual intf: Not getting valid mac addr"); - return -EINVAL; - } - hdd_debug("channel: %d", chan_freq); ret = wlan_hdd_validate_and_get_pre_cac_ch( @@ -233,28 +227,42 @@ static int __wlan_hdd_request_pre_cac(struct hdd_context *hdd_ctx, hdd_debug("starting pre cac SAP adapter"); - /* Starting a SAP adapter: - * Instead of opening an adapter, we could just do a SME open session - * for AP type. But, start BSS would still need an adapter. - * So, this option is not taken. - * - * hdd open adapter is going to register this precac interface with - * user space. This interface though exposed to user space will be in - * DOWN state. Consideration was done to avoid this registration to the - * user space. But, as part of SAP operations multiple events are sent - * to user space. Some of these events received from unregistered - * interface was causing crashes. So, retaining the registration. - * - * So, this interface would remain registered and will remain in DOWN - * state for the CAC duration. We will add notes in the feature - * announcement to not use this temporary interface for any activity - * from user space. - */ - pre_cac_adapter = hdd_open_adapter(hdd_ctx, QDF_SAP_MODE, "precac%d", - mac_addr, NET_NAME_UNKNOWN, true); + pre_cac_adapter = hdd_get_adapter_by_iface_name(hdd_ctx, + SAP_PRE_CAC_IFNAME); if (!pre_cac_adapter) { - hdd_err("error opening the pre cac adapter"); - goto release_intf_addr_and_return_failure; + mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_SAP_MODE); + if (!mac_addr) { + hdd_err("can't add virtual intf: Not getting valid mac addr"); + return -EINVAL; + } + + /** + * Starting a SAP adapter: + * Instead of opening an adapter, we could just do a SME open + * session for AP type. But, start BSS would still need an + * adapter. So, this option is not taken. + * + * hdd open adapter is going to register this precac interface + * with user space. This interface though exposed to user space + * will be in DOWN state. Consideration was done to avoid this + * registration to the user space. But, as part of SAP + * operations multiple events are sent to user space. Some of + * these events received from unregistered interface was + * causing crashes. So, retaining the registration. + * + * So, this interface would remain registered and will remain + * in DOWN state for the CAC duration. We will add notes in the + * feature announcement to not use this temporary interface for + * any activity from user space. + */ + pre_cac_adapter = hdd_open_adapter(hdd_ctx, QDF_SAP_MODE, + SAP_PRE_CAC_IFNAME, mac_addr, + NET_NAME_UNKNOWN, true); + + if (!pre_cac_adapter) { + hdd_err("error opening the pre cac adapter"); + goto release_intf_addr_and_return_failure; + } } /* @@ -370,6 +378,7 @@ static int __wlan_hdd_request_pre_cac(struct hdd_context *hdd_ctx, } ap_adapter->pre_cac_freq = pre_cac_chan_freq; + pre_cac_adapter->is_pre_cac_adapter = true; *out_adapter = pre_cac_adapter; @@ -388,7 +397,8 @@ release_intf_addr_and_return_failure: * adapter which is trying to come wouldn't get valid * mac address. Remember we have limited pool of mac addresses */ - wlan_hdd_release_intf_addr(hdd_ctx, mac_addr); + if (mac_addr) + wlan_hdd_release_intf_addr(hdd_ctx, mac_addr); return -EINVAL; } diff --git a/core/sap/inc/sap_api.h b/core/sap/inc/sap_api.h index 7a7906287e31..be1a703a482f 100644 --- a/core/sap/inc/sap_api.h +++ b/core/sap/inc/sap_api.h @@ -67,6 +67,8 @@ extern "C" { #define SAP_DEFAULT_5GHZ_CHANNEL (40) #define SAP_CHANNEL_NOT_SELECTED (0) +#define SAP_PRE_CAC_IFNAME "precac" + /*-------------------------------------------------------------------------- * reasonCode taken from 802.11 standard. * ------------------------------------------------------------------------*/ @@ -832,6 +834,7 @@ QDF_STATUS wlan_sap_update_next_channel(struct sap_context *sap_ctx, uint8_t channel, enum phy_ch_width chan_bw); +#ifdef FEATURE_SAP_COND_CHAN_SWITCH /** * wlan_sap_set_pre_cac_status() - Set the pre cac status * @sap_ctx: SAP context @@ -855,6 +858,20 @@ QDF_STATUS wlan_sap_set_pre_cac_status(struct sap_context *sap_ctx, */ QDF_STATUS wlan_sap_set_chan_before_pre_cac(struct sap_context *sap_ctx, uint8_t chan_before_pre_cac); +#else +static inline QDF_STATUS +wlan_sap_set_pre_cac_status(struct sap_context *sap_ctx, bool status) +{ + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS +wlan_sap_set_chan_before_pre_cac(struct sap_context *sap_ctx, + uint8_t chan_before_pre_cac) +{ + return QDF_STATUS_SUCCESS; +} +#endif /** * wlan_sap_set_pre_cac_complete_status() - Sets pre cac complete status