diff --git a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h index f781f19f3fed..b8de57b5dede 100644 --- a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h +++ b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h @@ -1338,6 +1338,7 @@ struct policy_mgr_sme_cbacks { * @hdd_is_chan_switch_in_progress: Check if in any adater channel switch is in * progress * @wlan_hdd_set_sap_csa_reason: Set the sap csa reason in cases like NAN. + * @hdd_get_ap_6ghz_capable: get ap vdev 6ghz capable info from hdd ap adapter. */ struct policy_mgr_hdd_cbacks { void (*sap_restart_chan_switch_cb)(struct wlan_objmgr_psoc *psoc, @@ -1356,6 +1357,8 @@ struct policy_mgr_hdd_cbacks { bool (*hdd_is_cac_in_progress)(void); void (*wlan_hdd_set_sap_csa_reason)(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, uint8_t reason); + uint32_t (*hdd_get_ap_6ghz_capable)(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id); }; @@ -3162,18 +3165,89 @@ QDF_STATUS policy_mgr_get_hw_mode_from_idx( * @psoc: Pointer to soc * @mode: new connection mode * - * Current PORed 6ghz connection is STA, SAP. + * Current PORed 6ghz connection modes are STA, SAP. * * Return: true if supports else false. */ bool policy_mgr_is_6ghz_conc_mode_supported( struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode); + +/** + * policy_mgr_init_ap_6ghz_capable - Init 6Ghz capable flags + * @psoc: PSOC object information + * @vdev_id: vdev id + * @ap_6ghz_capable: vdev 6ghz capable flag + * + * Init 6Ghz capable flags for active connection in policy mgr conn table + * + * Return: void + */ +void policy_mgr_init_ap_6ghz_capable(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + enum conn_6ghz_flag ap_6ghz_capable); + +/** + * policy_mgr_set_ap_6ghz_capable - Set 6Ghz capable flags to connection list + * @psoc: PSOC object information + * @vdev_id: vdev id + * @set: set or clear + * @ap_6ghz_capable: vdev 6ghz capable flag + * + * Set/Clear 6Ghz capable flags for active connection in policy mgr conn table + * + * Return: void + */ +void policy_mgr_set_ap_6ghz_capable(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + bool set, + enum conn_6ghz_flag ap_6ghz_capable); + +/** + * policy_mgr_get_ap_6ghz_capable - Get 6Ghz capable info for a vdev + * @psoc: PSOC object information + * @vdev_id: vdev id + * @conn_flag: output conntion flags + * + * Get 6Ghz capable flag for ap vdev (SAP). When SAP on 5G, for same reason + * the AP needs to be moved to 6G and this API will be called to check whether + * AP is 6Ghz capable or not. + * AP is allowed on 6G band only when all of below statements are true: + * a. SAP config includes WPA3 security - SAE,OWE,SuiteB. + * b. SAP is configured by ACS range which includes any 6G channel or + configured by 6G Fixed channel. + * c. SAP has no legacy clients (client doesn't support 6G band). + * legacy client (non 6ghz capable): association request frame has no + * 6G band global operating Class. + * + * Return: true if AP is 6ghz capable + */ +bool policy_mgr_get_ap_6ghz_capable( + struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, uint32_t *conn_flag); #else static inline bool policy_mgr_is_6ghz_conc_mode_supported( struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode) { return false; } + +static inline void policy_mgr_init_ap_6ghz_capable( + struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, + enum conn_6ghz_flag ap_6ghz_capable) +{} + +static inline +void policy_mgr_set_ap_6ghz_capable(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + bool set, + enum conn_6ghz_flag ap_6ghz_capable) +{} + +static inline bool policy_mgr_get_ap_6ghz_capable( + struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, uint32_t *conn_flag) +{ + return false; +} + #endif /** diff --git a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_public_struct.h b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_public_struct.h index 5a31643671dd..c8ba7f8e05f2 100644 --- a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_public_struct.h +++ b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_public_struct.h @@ -1013,6 +1013,31 @@ enum dbs_support { ENABLE_DBS_CXN_AND_DISABLE_SIMULTANEOUS_SCAN, }; +/** + * enum conn_6ghz_flag - structure to define connection 6ghz capable info + * in policy mgr conn info struct + * + * @CONN_6GHZ_FLAG_VALID: The 6ghz flag is valid (has been initialized) + * @CONN_6GHZ_FLAG_ACS_OR_USR_ALLOWED: AP is configured in 6ghz band capable + * by user: + * a. ACS channel range includes 6ghz. + * b. SAP is started in 6ghz fix channel. + * @CONN_6GHZ_FLAG_SECURITY_ALLOWED: AP has security mode which is permitted in + * 6ghz band. + * @CONN_6GHZ_FLAG_NO_LEGACY_CLIENT: AP has no legacy client connected + */ +enum conn_6ghz_flag { + CONN_6GHZ_FLAG_VALID = 0x0001, + CONN_6GHZ_FLAG_ACS_OR_USR_ALLOWED = 0x0002, + CONN_6GHZ_FLAG_SECURITY_ALLOWED = 0x0004, + CONN_6GHZ_FLAG_NO_LEGACY_CLIENT = 0x0008, +}; + +#define CONN_6GHZ_CAPABLIE (CONN_6GHZ_FLAG_VALID | \ + CONN_6GHZ_FLAG_ACS_OR_USR_ALLOWED | \ + CONN_6GHZ_FLAG_SECURITY_ALLOWED | \ + CONN_6GHZ_FLAG_NO_LEGACY_CLIENT) + /** * struct policy_mgr_conc_connection_info - information of all existing * connections in the wlan system @@ -1026,6 +1051,7 @@ enum dbs_support { * @vdev_id: vdev id of the connection * @in_use: if the table entry is active * @ch_flagext: Channel extension flags. + * @conn_6ghz_flag: connection 6ghz capable flags */ struct policy_mgr_conc_connection_info { enum policy_mgr_con_mode mode; @@ -1037,6 +1063,7 @@ struct policy_mgr_conc_connection_info { uint32_t vdev_id; bool in_use; uint16_t ch_flagext; + enum conn_6ghz_flag conn_6ghz_flag; }; /** @@ -1233,10 +1260,12 @@ struct dbs_nss { * @mac_id: The HW mac it is running * @vdev_id: vdev id * @channel: channel of the connection + * @ch_freq: channel freq in Mhz */ struct connection_info { uint8_t mac_id; uint8_t vdev_id; uint8_t channel; + uint32_t ch_freq; }; #endif /* __WLAN_POLICY_MGR_PUBLIC_STRUCT_H */ diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c index 23cbf7fb0f3e..c03d95a8d164 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c @@ -1852,6 +1852,84 @@ static bool policy_mgr_valid_sta_channel_check(struct wlan_objmgr_psoc *psoc, return true; } +/** + * policy_mgr_select_2g_chan() - select 2G usable channel for SAP + * @psoc: psoc object + * + * Select active 2G home channel or select safe 2G channel. + * + * return: uint32 chan freq + */ +static uint32_t policy_mgr_select_2g_chan(struct wlan_objmgr_psoc *psoc) +{ + uint8_t count, i; + struct connection_info info[MAX_NUMBER_OF_CONC_CONNECTIONS]; + struct regulatory_channel band_2g_list[NUM_24GHZ_CHANNELS]; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid context"); + return 0; + } + + count = policy_mgr_get_connection_info(psoc, info); + for (i = 0; i < count; i++) { + if (WLAN_REG_IS_24GHZ_CH_FREQ(info[i].ch_freq)) + return info[i].ch_freq; + } + + count = wlan_reg_get_band_channel_list(pm_ctx->pdev, BIT(REG_BAND_2G), + band_2g_list); + for (i = 0; i < count; i++) { + if (policy_mgr_is_safe_channel(psoc, + band_2g_list[i].center_freq)) + return band_2g_list[i].center_freq; + } + + return PM_24_GHZ_CH_FREQ_6; +} + +/** + * policy_mgr_check_6ghz_sap_conc() - check sap force scc to 6ghz + * @psoc: psoc object + * @con_ch_freq: concurrency channel + * @sap_ch_freq: SAP starting channel + * @sap_vdev_id: sap vdev id + * + * Validate whether SAP can be forced scc to 6ghz band or not. + * If not, select 2G band channel for DBS hw + * or keep SAP starting channel not changed for non-DBS hw. + * + * return: QDF_STATUS_SUCCESS + */ +static QDF_STATUS policy_mgr_check_6ghz_sap_conc( + struct wlan_objmgr_psoc *psoc, uint32_t *con_ch_freq, + uint32_t sap_ch_freq, uint8_t sap_vdev_id) +{ + uint32_t ch_freq = *con_ch_freq; + + if (ch_freq && WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq) && + !WLAN_REG_IS_6GHZ_CHAN_FREQ(sap_ch_freq) && + !policy_mgr_get_ap_6ghz_capable(psoc, sap_vdev_id, NULL)) { + policy_mgr_debug("sap %d not support 6ghz freq %d", + sap_vdev_id, ch_freq); + if (policy_mgr_is_hw_dbs_capable(psoc)) { + ch_freq = policy_mgr_select_2g_chan(psoc); + policy_mgr_debug("select 2G ch %d to achieve DBS", + ch_freq); + } else { + /* Keep MCC 2G(or 5G) + 6G for non-DBS chip*/ + ch_freq = 0; + policy_mgr_debug("do not force SCC for non-dbs hw"); + } + } + if (ch_freq != sap_ch_freq) + *con_ch_freq = ch_freq; + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS policy_mgr_valid_sap_conc_channel_check( struct wlan_objmgr_psoc *psoc, uint32_t *con_ch_freq, uint32_t sap_ch_freq, uint8_t sap_vdev_id) @@ -1883,10 +1961,14 @@ QDF_STATUS policy_mgr_valid_sap_conc_channel_check( */ if (!ch_freq && sap_ch_freq != policy_mgr_mode_specific_get_channel(psoc, - PM_STA_MODE)) + PM_STA_MODE)) { return QDF_STATUS_SUCCESS; - else if (!ch_freq) + } else if (!ch_freq) { ch_freq = sap_ch_freq; + } else if (ch_freq && WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq)) { + return policy_mgr_check_6ghz_sap_conc( + psoc, con_ch_freq, sap_ch_freq, sap_vdev_id); + } sta_sap_scc_on_dfs_chan = policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc); diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c index 41e39270308f..d0ceb52e3ba8 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c @@ -1634,6 +1634,7 @@ void policy_mgr_incr_active_session(struct wlan_objmgr_psoc *psoc, uint8_t session_id) { struct policy_mgr_psoc_priv_obj *pm_ctx; + uint32_t conn_6ghz_flag = 0; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -1661,6 +1662,9 @@ void policy_mgr_incr_active_session(struct wlan_objmgr_psoc *psoc, if (mode != QDF_NAN_DISC_MODE && pm_ctx->dp_cbacks.hdd_v2_flow_pool_map) pm_ctx->dp_cbacks.hdd_v2_flow_pool_map(session_id); + if (mode == QDF_SAP_MODE) + policy_mgr_get_ap_6ghz_capable(psoc, session_id, + &conn_6ghz_flag); policy_mgr_debug("No.# of active sessions for mode %d = %d", mode, pm_ctx->no_of_active_sessions[mode]); @@ -1696,6 +1700,9 @@ void policy_mgr_incr_active_session(struct wlan_objmgr_psoc *psoc, if (pm_ctx->dp_cbacks.hdd_set_rx_mode_rps_cb) pm_ctx->dp_cbacks.hdd_set_rx_mode_rps_cb(true); } + if (mode == QDF_SAP_MODE) + policy_mgr_init_ap_6ghz_capable(psoc, session_id, + conn_6ghz_flag); policy_mgr_dump_current_concurrency(psoc); @@ -2198,6 +2205,62 @@ bool policy_mgr_is_6ghz_conc_mode_supported( } #endif +/** + * policy_mgr_is_6g_channel_allowed() - Check new 6Ghz connection + * allowed or not + * @psoc: Pointer to soc + * @mode: new connection mode + * @ch_freq: channel freq + * + * 1. Only STA/SAP are allowed on 6Ghz. + * 2. If there is DFS beacon entity existing on 5G band, 5G+6G MCC is not + * allowed. + * + * Return: true if supports else false. + */ +static bool policy_mgr_is_6g_channel_allowed( + struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, + uint32_t ch_freq) +{ + uint32_t conn_index = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + struct policy_mgr_conc_connection_info *conn; + bool is_dfs; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return false; + } + if (!WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq)) + return true; + + /* Only STA/SAP is supported on 6Ghz currently */ + if (!policy_mgr_is_6ghz_conc_mode_supported(psoc, mode)) + return false; + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; + conn_index++) { + conn = &pm_conc_connection_list[conn_index]; + if (!conn->in_use) + continue; + is_dfs = (conn->ch_flagext & + (IEEE80211_CHAN_DFS | IEEE80211_CHAN_DFS_CFREQ2)) && + WLAN_REG_IS_5GHZ_CH_FREQ(conn->freq); + if ((conn->mode == PM_SAP_MODE || + conn->mode == PM_P2P_GO_MODE) && + is_dfs && ch_freq != conn->freq) { + policy_mgr_err("don't allow MCC if SAP/GO on DFS channel"); + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + return false; + } + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + return true; +} + bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, uint32_t ch_freq, @@ -2263,6 +2326,9 @@ bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, if (!policy_mgr_is_5g_channel_allowed(psoc, ch_freq, list, PM_SAP_MODE)) goto done; + if (!policy_mgr_is_6g_channel_allowed(psoc, mode, + ch_freq)) + goto done; sta_sap_scc_on_dfs_chan = policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc); @@ -3811,7 +3877,7 @@ uint32_t policy_mgr_get_connection_info(struct wlan_objmgr_psoc *psoc, policy_mgr_err("Invalid Context"); return count; } - + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; conn_index++) { if (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { @@ -3822,9 +3888,12 @@ uint32_t policy_mgr_get_connection_info(struct wlan_objmgr_psoc *psoc, info[count].channel = wlan_reg_freq_to_chan( pm_ctx->pdev, pm_conc_connection_list[conn_index].freq); + info[count].ch_freq = + pm_conc_connection_list[conn_index].freq; count++; } } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); return count; } @@ -3931,6 +4000,125 @@ bool policy_mgr_sta_sap_scc_on_lte_coex_chan( return scc_lte_coex; } +#if defined(CONFIG_BAND_6GHZ) && defined(WLAN_FEATURE_11AX) +void policy_mgr_init_ap_6ghz_capable(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + enum conn_6ghz_flag ap_6ghz_capable) +{ + struct policy_mgr_conc_connection_info *conn_info; + uint32_t conn_index; + struct policy_mgr_psoc_priv_obj *pm_ctx; + enum conn_6ghz_flag conn_6ghz_flag = 0; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; + conn_index++) { + conn_info = &pm_conc_connection_list[conn_index]; + if (conn_info->in_use && PM_SAP_MODE == conn_info->mode && + vdev_id == conn_info->vdev_id) { + conn_info->conn_6ghz_flag = ap_6ghz_capable; + conn_info->conn_6ghz_flag |= CONN_6GHZ_FLAG_VALID; + conn_6ghz_flag = conn_info->conn_6ghz_flag; + break; + } + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + policy_mgr_debug("vdev %d init conn_6ghz_flag %x new %x", + vdev_id, ap_6ghz_capable, conn_6ghz_flag); +} + +void policy_mgr_set_ap_6ghz_capable(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + bool set, + enum conn_6ghz_flag ap_6ghz_capable) +{ + struct policy_mgr_conc_connection_info *conn_info; + uint32_t conn_index; + struct policy_mgr_psoc_priv_obj *pm_ctx; + enum conn_6ghz_flag conn_6ghz_flag = 0; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; + conn_index++) { + conn_info = &pm_conc_connection_list[conn_index]; + if (conn_info->in_use && PM_SAP_MODE == conn_info->mode && + vdev_id == conn_info->vdev_id) { + if (set) + conn_info->conn_6ghz_flag |= ap_6ghz_capable; + else + conn_info->conn_6ghz_flag &= ~ap_6ghz_capable; + conn_info->conn_6ghz_flag |= CONN_6GHZ_FLAG_VALID; + conn_6ghz_flag = conn_info->conn_6ghz_flag; + break; + } + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + policy_mgr_debug("vdev %d %s conn_6ghz_flag %x new %x", + vdev_id, set ? "set" : "clr", + ap_6ghz_capable, conn_6ghz_flag); +} + +bool policy_mgr_get_ap_6ghz_capable(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, + uint32_t *conn_flag) +{ + struct policy_mgr_conc_connection_info *conn_info; + uint32_t conn_index; + struct policy_mgr_psoc_priv_obj *pm_ctx; + enum conn_6ghz_flag conn_6ghz_flag = 0; + bool is_6g_allowed = false; + + if (conn_flag) + *conn_flag = 0; + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return false; + } + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; + conn_index++) { + conn_info = &pm_conc_connection_list[conn_index]; + if (conn_info->in_use && PM_SAP_MODE == conn_info->mode && + vdev_id == conn_info->vdev_id) { + conn_6ghz_flag = conn_info->conn_6ghz_flag; + break; + } + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + /* If the vdev connection is not active, policy mgr will query legacy + * hdd to get sap acs and security information. + * The assumption is no legacy client connected for non active + * connection. + */ + if (!(conn_6ghz_flag & CONN_6GHZ_FLAG_VALID) && + pm_ctx->hdd_cbacks.hdd_get_ap_6ghz_capable) + conn_6ghz_flag = pm_ctx->hdd_cbacks.hdd_get_ap_6ghz_capable( + psoc, vdev_id) | + CONN_6GHZ_FLAG_NO_LEGACY_CLIENT; + + if ((conn_6ghz_flag & CONN_6GHZ_CAPABLIE) == CONN_6GHZ_CAPABLIE) + is_6g_allowed = true; + policy_mgr_debug("vdev %d conn_6ghz_flag %x 6ghz %s", vdev_id, + conn_6ghz_flag, is_6g_allowed ? "allowed" : "deny"); + if (conn_flag) + *conn_flag = conn_6ghz_flag; + + return is_6g_allowed; +} +#endif + bool policy_mgr_is_valid_for_channel_switch(struct wlan_objmgr_psoc *psoc, uint32_t ch_freq) { diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_init_deinit.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_init_deinit.c index e2f4aaed7d31..5f7c1531c835 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_init_deinit.c +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_init_deinit.c @@ -635,6 +635,8 @@ QDF_STATUS policy_mgr_register_hdd_cb(struct wlan_objmgr_psoc *psoc, hdd_cbacks->hdd_is_chan_switch_in_progress; pm_ctx->hdd_cbacks.hdd_is_cac_in_progress = hdd_cbacks->hdd_is_cac_in_progress; + pm_ctx->hdd_cbacks.hdd_get_ap_6ghz_capable = + hdd_cbacks->hdd_get_ap_6ghz_capable; return QDF_STATUS_SUCCESS; } @@ -655,6 +657,7 @@ QDF_STATUS policy_mgr_deregister_hdd_cb(struct wlan_objmgr_psoc *psoc) pm_ctx->hdd_cbacks.hdd_get_device_mode = NULL; pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress = NULL; pm_ctx->hdd_cbacks.hdd_is_cac_in_progress = NULL; + pm_ctx->hdd_cbacks.hdd_get_ap_6ghz_capable = NULL; return QDF_STATUS_SUCCESS; } diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index 895f571fcb91..15a2ae304fb7 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -3198,6 +3198,90 @@ sap_restart: return QDF_STATUS_SUCCESS; } + +#if defined(CONFIG_BAND_6GHZ) && defined(WLAN_FEATURE_11AX) +uint32_t hdd_get_ap_6ghz_capable(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) +{ + struct wlan_objmgr_vdev *vdev; + uint32_t keymgmt; + struct hdd_adapter *ap_adapter; + struct hdd_ap_ctx *ap_ctx; + struct sap_context *sap_context; + struct sap_config *sap_config; + uint32_t capable = 0; + + if (!psoc) { + hdd_err("PSOC is NULL"); + return 0; + } + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, + WLAN_HDD_ID_OBJ_MGR); + if (!vdev) { + hdd_err("vdev is NULL %d", vdev_id); + return 0; + } + + ap_adapter = wlan_hdd_get_adapter_from_vdev( + psoc, vdev_id); + if (!ap_adapter) { + hdd_err("ap_adapter is NULL %d", vdev_id); + wlan_objmgr_vdev_release_ref(vdev, WLAN_HDD_ID_OBJ_MGR); + return 0; + } + if (ap_adapter->device_mode != QDF_SAP_MODE) { + hdd_err("unexpected device mode %d", ap_adapter->device_mode); + wlan_objmgr_vdev_release_ref(vdev, WLAN_HDD_ID_OBJ_MGR); + return 0; + } + ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter); + sap_config = &ap_ctx->sap_config; + sap_context = ap_ctx->sap_context; + if (QDF_IS_STATUS_ERROR(wlansap_context_get(sap_context))) { + hdd_err("sap_context is get failed %d", vdev_id); + wlan_objmgr_vdev_release_ref(vdev, WLAN_HDD_ID_OBJ_MGR); + return 0; + } + /* SAP is allowed on 6GHz with explicit indication from user space: + * a. SAP is started on 6Ghz already. + * b. SAP is configured on 6Ghz fixed channel from userspace. + * c. SAP is configured by ACS range which includes any 6Ghz channel. + */ + if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) { + if (WLAN_REG_IS_6GHZ_CHAN_FREQ( + ap_ctx->operating_chan_freq)) + capable |= CONN_6GHZ_FLAG_ACS_OR_USR_ALLOWED; + } else { + if (WLAN_REG_IS_6GHZ_CHAN_FREQ(sap_config->chan_freq)) + capable |= CONN_6GHZ_FLAG_ACS_OR_USR_ALLOWED; + else if (sap_context && WLAN_REG_IS_6GHZ_CHAN_FREQ( + sap_context->chan_freq)) + capable |= CONN_6GHZ_FLAG_ACS_OR_USR_ALLOWED; + } + if (wlansap_is_6ghz_included_in_acs_range(sap_context)) + capable |= CONN_6GHZ_FLAG_ACS_OR_USR_ALLOWED; + + keymgmt = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_KEY_MGMT); + if (!keymgmt || (keymgmt & (1 << WLAN_CRYPTO_KEY_MGMT_NONE | + 1 << WLAN_CRYPTO_KEY_MGMT_SAE | + 1 << WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B | + 1 << WLAN_CRYPTO_KEY_MGMT_IEEE8021X_SUITE_B_192 | + 1 << WLAN_CRYPTO_KEY_MGMT_OWE))) { + capable |= CONN_6GHZ_FLAG_SECURITY_ALLOWED; + } + capable |= CONN_6GHZ_FLAG_VALID; + hdd_debug("vdev_id %d keymgmt 0x%08x capable 0x%x", + vdev_id, keymgmt, capable); + wlansap_context_put(sap_context); + wlan_objmgr_vdev_release_ref(vdev, WLAN_HDD_ID_OBJ_MGR); + + return capable; +} +#else +uint32_t hdd_get_ap_6ghz_capable(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) +{ + return 0; +} +#endif #endif #ifdef WLAN_FEATURE_TSF_PTP diff --git a/core/hdd/src/wlan_hdd_hostapd.h b/core/hdd/src/wlan_hdd_hostapd.h index beee7edb862e..c957b9669ee8 100644 --- a/core/hdd/src/wlan_hdd_hostapd.h +++ b/core/hdd/src/wlan_hdd_hostapd.h @@ -109,6 +109,19 @@ void hdd_sap_restart_chan_switch_cb(struct wlan_objmgr_psoc *psoc, QDF_STATUS wlan_hdd_get_channel_for_sap_restart( struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, uint32_t *ch_freq); + +/** + * hdd_get_ap_6ghz_capable() - Get ap vdev 6ghz capable flags + * @psoc: PSOC object information + * @vdev_id: vdev id + * + * This function gets 6ghz capable information based on hdd ap adapter + * context. + * + * Return: uint32_t, vdev 6g capable flags from enum conn_6ghz_flag + */ +uint32_t hdd_get_ap_6ghz_capable(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id); #endif /** diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 8d6bf1871635..729508f749bf 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -2992,6 +2992,7 @@ static void hdd_register_policy_manager_callback( hdd_is_cac_in_progress; hdd_cbacks.wlan_hdd_set_sap_csa_reason = wlan_hdd_set_sap_csa_reason; + hdd_cbacks.hdd_get_ap_6ghz_capable = hdd_get_ap_6ghz_capable; if (QDF_STATUS_SUCCESS != policy_mgr_register_hdd_cb(psoc, &hdd_cbacks)) { diff --git a/core/mac/src/pe/lim/lim_assoc_utils.c b/core/mac/src/pe/lim/lim_assoc_utils.c index b3742ef7d06c..3c53a565dc02 100644 --- a/core/mac/src/pe/lim/lim_assoc_utils.c +++ b/core/mac/src/pe/lim/lim_assoc_utils.c @@ -3196,6 +3196,7 @@ lim_delete_dph_hash_entry(struct mac_context *mac_ctx, tSirMacAddr sta_addr, if (dph_delete_hash_entry(mac_ctx, sta_addr, sta_id, &session_entry->dph.dphHashTable) != QDF_STATUS_SUCCESS) pe_err("error deleting hash entry"); + lim_ap_check_6g_compatible_peer(mac_ctx, session_entry); } /** diff --git a/core/mac/src/pe/lim/lim_process_assoc_req_frame.c b/core/mac/src/pe/lim/lim_process_assoc_req_frame.c index 7882d1d64e1e..11eb8680f293 100644 --- a/core/mac/src/pe/lim/lim_process_assoc_req_frame.c +++ b/core/mac/src/pe/lim/lim_process_assoc_req_frame.c @@ -1807,6 +1807,7 @@ static bool lim_update_sta_ds(struct mac_context *mac_ctx, tpSirMacMgmtHdr hdr, sta_ds->timingMeasCap = 0; pe_debug("ExtCap not present"); } + lim_ap_check_6g_compatible_peer(mac_ctx, session); return true; } diff --git a/core/mac/src/pe/lim/lim_utils.c b/core/mac/src/pe/lim/lim_utils.c index e4afeffd765d..1f03bf8b0f77 100644 --- a/core/mac/src/pe/lim/lim_utils.c +++ b/core/mac/src/pe/lim/lim_utils.c @@ -6585,6 +6585,64 @@ void lim_update_last_processed_frame(last_processed_msg *last_processed_frm, last_processed_frm->seq_num = seq_num; } +#if defined(CONFIG_BAND_6GHZ) && defined(WLAN_FEATURE_11AX) +static bool lim_support_6ghz_band_op_class(struct mac_context *mac_ctx, + tDot11fIESuppOperatingClasses * + op_class_ie) +{ + uint16_t i; + + if (!op_class_ie->present) + return false; + for (i = 0; i < op_class_ie->num_classes; i++) { + if (wlan_reg_is_6ghz_op_class(mac_ctx->pdev, + op_class_ie->classes[i])) + break; + } + if (i < op_class_ie->num_classes) + return true; + + return false; +} + +void lim_ap_check_6g_compatible_peer(struct mac_context *mac_ctx, + struct pe_session *session) +{ + uint16_t i; + tpDphHashNode sta_ds; + bool legacy_client_present = false; + + if (!LIM_IS_AP_ROLE(session)) + return; + + for (i = 1; i < session->dph.dphHashTable.size; i++) { + sta_ds = dph_get_hash_entry(mac_ctx, i, + &session->dph.dphHashTable); + if (!sta_ds) + continue; + if (sta_ds->staType != STA_ENTRY_PEER) + continue; + if (!lim_support_6ghz_band_op_class( + mac_ctx, &sta_ds->supp_operating_classes)) { + legacy_client_present = true; + pe_debug("peer %pM 6ghz not supported", + sta_ds->staAddr); + break; + } + pe_debug("peer %pM 6ghz supported", + sta_ds->staAddr); + } + if (legacy_client_present) + policy_mgr_set_ap_6ghz_capable( + mac_ctx->psoc, session->vdev_id, false, + CONN_6GHZ_FLAG_NO_LEGACY_CLIENT); + else + policy_mgr_set_ap_6ghz_capable( + mac_ctx->psoc, session->vdev_id, true, + CONN_6GHZ_FLAG_NO_LEGACY_CLIENT); +} +#endif + #ifdef WLAN_FEATURE_11AX void lim_add_he_cap(tpAddStaParams add_sta_params, tpSirAssocReq assoc_req) { diff --git a/core/mac/src/pe/lim/lim_utils.h b/core/mac/src/pe/lim/lim_utils.h index fb61ecdd8468..cead953dc9fd 100644 --- a/core/mac/src/pe/lim/lim_utils.h +++ b/core/mac/src/pe/lim/lim_utils.h @@ -1901,4 +1901,19 @@ QDF_STATUS lim_pre_vdev_start(struct mac_context *mac, QDF_STATUS lim_set_ch_phy_mode(struct wlan_objmgr_vdev *vdev, uint8_t dot11mode); +#if defined(CONFIG_BAND_6GHZ) && defined(WLAN_FEATURE_11AX) +/** + * lim_ap_check_6g_compatible_peer() - check all client support 6Ghz band + * @mac_ctx: mac context + * @session: pe session + * + * Return: void + */ +void lim_ap_check_6g_compatible_peer(struct mac_context *mac_ctx, + struct pe_session *session); +#else +static inline void lim_ap_check_6g_compatible_peer( + struct mac_context *mac_ctx, struct pe_session *session) +{} +#endif #endif /* __LIM_UTILS_H */ diff --git a/core/sap/inc/sap_api.h b/core/sap/inc/sap_api.h index e445a4df98a0..aa6f90234939 100644 --- a/core/sap/inc/sap_api.h +++ b/core/sap/inc/sap_api.h @@ -1445,6 +1445,15 @@ QDF_STATUS wlansap_filter_ch_based_acs(struct sap_context *sap_ctx, uint32_t *ch_freq_list, uint32_t *ch_cnt); +/** + * wlansap_is_6ghz_included_in_acs_range() - check 6ghz channel included in + * ACS range + * @sap_ctx: sap context + * + * Return: QDF_STATUS + */ +bool wlansap_is_6ghz_included_in_acs_range(struct sap_context *sap_ctx); + /** * wlansap_get_safe_channel_from_pcl_and_acs_range() - Get safe channel for SAP * restart diff --git a/core/sap/src/sap_module.c b/core/sap/src/sap_module.c index 5c1c85bfd409..31e6c0fe2353 100644 --- a/core/sap/src/sap_module.c +++ b/core/sap/src/sap_module.c @@ -2959,6 +2959,25 @@ QDF_STATUS wlansap_filter_ch_based_acs(struct sap_context *sap_ctx, return QDF_STATUS_SUCCESS; } +bool wlansap_is_6ghz_included_in_acs_range(struct sap_context *sap_ctx) +{ + uint32_t i; + uint32_t *ch_freq_list; + + if (!sap_ctx || !sap_ctx->acs_cfg || + !sap_ctx->acs_cfg->master_freq_list || + !sap_ctx->acs_cfg->master_ch_list_count) { + sap_err("NULL parameters"); + return false; + } + ch_freq_list = sap_ctx->acs_cfg->master_freq_list; + for (i = 0; i < sap_ctx->acs_cfg->master_ch_list_count; i++) { + if (WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq_list[i])) + return true; + } + return false; +} + #if defined(FEATURE_WLAN_CH_AVOID) /** * wlansap_get_safe_channel() - Get safe channel from current regulatory