1 /* 2 * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 /** 18 * DOC: contains policy manager ll_sap definitions specific to the ll_sap module 19 */ 20 21 #include "wlan_policy_mgr_ll_sap.h" 22 #include "wlan_policy_mgr_public_struct.h" 23 #include "wlan_policy_mgr_api.h" 24 #include "wlan_policy_mgr_i.h" 25 #include "wlan_cmn.h" 26 #include "wlan_ll_sap_api.h" 27 28 void policy_mgr_ll_lt_sap_get_valid_freq(struct wlan_objmgr_psoc *psoc, 29 struct wlan_objmgr_pdev *pdev, 30 uint8_t vdev_id, 31 qdf_freq_t sap_ch_freq, 32 uint8_t cc_switch_mode, 33 qdf_freq_t *new_sap_freq, 34 bool *is_ll_lt_sap_present) 35 { 36 enum sap_csa_reason_code csa_reason; 37 enum policy_mgr_con_mode conn_mode; 38 qdf_freq_t ll_lt_sap_freq = 0; 39 *is_ll_lt_sap_present = false; 40 41 /* If Vdev is ll_lt_sap, check if the frequency on which it is 42 * coming up is correct, else, get new frequency 43 */ 44 if (policy_mgr_is_vdev_ll_lt_sap(psoc, vdev_id)) { 45 *new_sap_freq = wlan_get_ll_lt_sap_restart_freq(pdev, 46 sap_ch_freq, 47 vdev_id, 48 &csa_reason); 49 *is_ll_lt_sap_present = true; 50 } 51 52 ll_lt_sap_freq = policy_mgr_get_ll_lt_sap_freq(psoc); 53 if (!ll_lt_sap_freq) 54 return; 55 56 conn_mode = policy_mgr_get_mode_by_vdev_id(psoc, vdev_id); 57 58 if (conn_mode == PM_SAP_MODE) { 59 /* If ll_lt_sap and concurrent SAP are on same MAC, 60 * update the frequency of concurrent SAP, else return. 61 */ 62 if (!policy_mgr_are_2_freq_on_same_mac(psoc, sap_ch_freq, 63 ll_lt_sap_freq)) 64 return; 65 goto policy_mgr_check_scc; 66 } else if (conn_mode == PM_P2P_GO_MODE) { 67 /* If ll_lt_sap and P2P_GO are in SCC, 68 * update the frequency of concurrent GO else, return. 69 */ 70 if (ll_lt_sap_freq != sap_ch_freq) 71 return; 72 goto policy_mgr_check_scc; 73 } else { 74 policy_mgr_debug("Invalid con mode %d vdev %d", conn_mode, 75 vdev_id); 76 return; 77 } 78 79 policy_mgr_check_scc: 80 policy_mgr_check_scc_channel(psoc, new_sap_freq, sap_ch_freq, vdev_id, 81 cc_switch_mode); 82 policy_mgr_debug("vdev_id %d old_freq %d new_freq %d", vdev_id, 83 sap_ch_freq, *new_sap_freq); 84 } 85 86 uint8_t wlan_policy_mgr_get_ll_lt_sap_vdev_id(struct wlan_objmgr_psoc *psoc) 87 { 88 uint8_t ll_lt_sap_cnt; 89 uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS]; 90 91 ll_lt_sap_cnt = policy_mgr_get_mode_specific_conn_info(psoc, NULL, 92 vdev_id_list, 93 PM_LL_LT_SAP_MODE); 94 95 /* Currently only 1 ll_lt_sap is supported */ 96 if (!ll_lt_sap_cnt) 97 return WLAN_INVALID_VDEV_ID; 98 99 return vdev_id_list[0]; 100 } 101 102 bool __policy_mgr_is_ll_lt_sap_restart_required(struct wlan_objmgr_psoc *psoc, 103 const char *func) 104 { 105 qdf_freq_t ll_lt_sap_freq = 0; 106 uint8_t scc_vdev_id; 107 bool is_scc = false; 108 uint8_t conn_idx = 0; 109 struct policy_mgr_psoc_priv_obj *pm_ctx; 110 111 pm_ctx = policy_mgr_get_context(psoc); 112 if (!pm_ctx) { 113 policy_mgr_err("Invalid pm ctx"); 114 return false; 115 } 116 117 ll_lt_sap_freq = policy_mgr_get_ll_lt_sap_freq(psoc); 118 119 if (!ll_lt_sap_freq) 120 return false; 121 122 /* 123 * Restart ll_lt_sap if any other interface is present in SCC 124 * with LL_LT_SAP. 125 */ 126 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 127 for (conn_idx = 0; conn_idx < MAX_NUMBER_OF_CONC_CONNECTIONS; 128 conn_idx++) { 129 if (pm_conc_connection_list[conn_idx].mode == 130 PM_LL_LT_SAP_MODE) 131 continue; 132 133 if (ll_lt_sap_freq == pm_conc_connection_list[conn_idx].freq) { 134 scc_vdev_id = pm_conc_connection_list[conn_idx].vdev_id; 135 is_scc = true; 136 break; 137 } 138 } 139 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 140 141 if (is_scc) { 142 uint8_t ll_lt_sap_vdev_id = 143 wlan_policy_mgr_get_ll_lt_sap_vdev_id(psoc); 144 145 policymgr_nofl_debug("%s ll_lt_sap vdev %d with freq %d is in scc with vdev %d", 146 func, ll_lt_sap_vdev_id, ll_lt_sap_freq, 147 scc_vdev_id); 148 return true; 149 } 150 151 return false; 152 } 153 154 /** 155 * policy_mgr_ll_lt_sap_get_restart_freq_for_concurent_sap() - Get restart frequency 156 * for concurrent SAP which is in concurrency with LL_LT_SAP 157 * @pm_ctx: Policy manager context 158 * @vdev_id: Vdev id of the SAP for which restart freq is required 159 * @curr_freq: Current frequency of the SAP for which restart freq is required 160 * @ll_lt_sap_enabled: Indicates if ll_lt_sap is getting enabled or disabled 161 * 162 * This API returns user configured frequency if ll_lt_sap is going down and 163 * if ll_lt_sap is coming up it returns frequency according to ll_lt_sap 164 * concurrency. 165 * 166 * Return: Restart frequency 167 */ 168 static qdf_freq_t 169 policy_mgr_ll_lt_sap_get_restart_freq_for_concurent_sap( 170 struct policy_mgr_psoc_priv_obj *pm_ctx, 171 uint8_t vdev_id, 172 qdf_freq_t curr_freq, 173 bool ll_lt_sap_enabled) 174 { 175 qdf_freq_t user_config_freq; 176 uint8_t i; 177 QDF_STATUS status; 178 uint32_t channel_list[NUM_CHANNELS]; 179 uint32_t num_channels; 180 qdf_freq_t restart_freq = 0; 181 182 /* 183 * If ll_lt_sap is getting disabled, return user configured frequency 184 * for concurrent SAP restart, if user configured frequency is not valid 185 * frequency, remain on the same frequency and do not restart the SAP 186 */ 187 if (!ll_lt_sap_enabled) { 188 user_config_freq = policy_mgr_get_user_config_sap_freq( 189 pm_ctx->psoc, 190 vdev_id); 191 if (wlan_reg_is_enable_in_secondary_list_for_freq( 192 pm_ctx->pdev, 193 user_config_freq) && 194 policy_mgr_is_safe_channel(pm_ctx->psoc, user_config_freq)) 195 return user_config_freq; 196 return curr_freq; 197 } 198 199 status = policy_mgr_get_valid_chans(pm_ctx->psoc, channel_list, 200 &num_channels); 201 if (QDF_IS_STATUS_ERROR(status)) { 202 policy_mgr_err("Error in getting valid channels"); 203 return curr_freq; 204 } 205 206 /* return first valid 2.4 GHz frequency */ 207 for (i = 0; i < num_channels; i++) { 208 if (wlan_reg_is_24ghz_ch_freq(channel_list[i])) { 209 if (!restart_freq) 210 restart_freq = channel_list[i]; 211 /* Prefer SCC frequency */ 212 if (policy_mgr_get_connection_count_with_ch_freq( 213 channel_list[i])) { 214 restart_freq = channel_list[i]; 215 break; 216 } 217 } 218 } 219 return restart_freq; 220 } 221 222 void policy_mgr_ll_lt_sap_restart_concurrent_sap(struct wlan_objmgr_psoc *psoc, 223 bool is_ll_lt_sap_enabled) 224 { 225 struct policy_mgr_psoc_priv_obj *pm_ctx; 226 struct policy_mgr_conc_connection_info sap_info = {0}; 227 qdf_freq_t restart_freq; 228 struct ch_params ch_params = {0}; 229 uint8_t i; 230 enum sap_csa_reason_code csa_reason; 231 232 pm_ctx = policy_mgr_get_context(psoc); 233 if (!pm_ctx) { 234 policy_mgr_err("Invalid pm context"); 235 return; 236 } 237 238 qdf_mem_zero(&sap_info, sizeof(sap_info)); 239 240 qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); 241 for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { 242 if (!pm_conc_connection_list[i].in_use) 243 continue; 244 if (PM_SAP_MODE == pm_conc_connection_list[i].mode || 245 PM_LL_LT_SAP_MODE == pm_conc_connection_list[i].mode) { 246 qdf_mem_copy(&sap_info, &pm_conc_connection_list[i], 247 sizeof(sap_info)); 248 break; 249 } 250 } 251 qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); 252 253 /* No concurrent SAP or ll_lt_sap present, return */ 254 if (!sap_info.in_use) 255 return; 256 257 if (sap_info.mode == PM_SAP_MODE) { 258 /* 259 * For SBS case, no need to restart concurrent SAP as LL_LT_SAP 260 * and concurrent SAP can be on different MACs 261 */ 262 if (policy_mgr_is_hw_sbs_capable(psoc)) 263 return; 264 265 /* 266 * If concurrent SAP is 2.4 GHz and ll_lt_sap is getting enabled 267 * then there is no need to restart the concurrent SAP 268 */ 269 if (is_ll_lt_sap_enabled && 270 wlan_reg_is_24ghz_ch_freq(sap_info.freq)) 271 return; 272 273 /* 274 * If concurrent SAP is 5 GHz/6 GHz and ll_lt_sap is getting 275 * disabled then there is no need to restart the concurrent SAP 276 */ 277 else if (!is_ll_lt_sap_enabled && 278 (wlan_reg_is_5ghz_ch_freq(sap_info.freq) || 279 wlan_reg_is_6ghz_chan_freq(sap_info.freq))) 280 return; 281 282 restart_freq = 283 policy_mgr_ll_lt_sap_get_restart_freq_for_concurent_sap( 284 pm_ctx, 285 sap_info.vdev_id, 286 sap_info.freq, 287 is_ll_lt_sap_enabled); 288 csa_reason = CSA_REASON_CONCURRENT_LL_LT_SAP_EVENT; 289 } else { 290 restart_freq = wlan_get_ll_lt_sap_restart_freq(pm_ctx->pdev, 291 sap_info.freq, 292 sap_info.vdev_id, 293 &csa_reason); 294 } 295 296 if (pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress && 297 pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress()) { 298 policy_mgr_debug("channel switch is already in progress"); 299 return; 300 } 301 302 if (!restart_freq) { 303 policy_mgr_err("Restart freq not found for vdev %d", 304 sap_info.vdev_id); 305 return; 306 } 307 if (restart_freq == sap_info.freq) { 308 policy_mgr_debug("vdev %d restart freq %d same as current freq", 309 sap_info.vdev_id, restart_freq); 310 return; 311 } 312 ch_params.ch_width = policy_mgr_get_ch_width(sap_info.bw); 313 wlan_reg_set_channel_params_for_pwrmode(pm_ctx->pdev, restart_freq, 314 0, &ch_params, 315 REG_CURRENT_PWR_MODE); 316 policy_mgr_debug("Restart SAP vdev %d with %d freq width %d", 317 sap_info.vdev_id, restart_freq, ch_params.ch_width); 318 319 if (pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason) 320 pm_ctx->hdd_cbacks.wlan_hdd_set_sap_csa_reason(psoc, 321 sap_info.vdev_id, 322 csa_reason); 323 324 policy_mgr_change_sap_channel_with_csa(psoc, sap_info.vdev_id, 325 restart_freq, 326 ch_params.ch_width, true); 327 } 328