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
policy_mgr_ll_lt_sap_get_valid_freq(struct wlan_objmgr_psoc * psoc,struct wlan_objmgr_pdev * pdev,uint8_t vdev_id,qdf_freq_t sap_ch_freq,uint8_t cc_switch_mode,qdf_freq_t * new_sap_freq,bool * is_ll_lt_sap_present)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
wlan_policy_mgr_get_ll_lt_sap_vdev_id(struct wlan_objmgr_psoc * psoc)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
__policy_mgr_is_ll_lt_sap_restart_required(struct wlan_objmgr_psoc * psoc,const char * func)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
policy_mgr_ll_lt_sap_get_restart_freq_for_concurent_sap(struct policy_mgr_psoc_priv_obj * pm_ctx,uint8_t vdev_id,qdf_freq_t curr_freq,bool ll_lt_sap_enabled)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
policy_mgr_ll_lt_sap_restart_concurrent_sap(struct wlan_objmgr_psoc * psoc,bool is_ll_lt_sap_enabled)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