xref: /wlan-dirver/qca-wifi-host-cmn/umac/mlme/vdev_mgr/core/src/vdev_mgr_ops.c (revision 8ddef7dd9a290d4a9b1efd5d3efacf51d78a1a0d)
1 /*
2  * Copyright (c) 2019 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 /**
20  * DOC: vdev_mgr_ops.c
21  *
22  * This file provide API definitions for filling data structures
23  * and sending vdev mgmt commands to target_if/mlme
24  */
25 #include "vdev_mgr_ops.h"
26 #include <wlan_objmgr_vdev_obj.h>
27 #include <wlan_vdev_mlme_api.h>
28 #include <wlan_mlme_dbg.h>
29 #include <wlan_vdev_mgr_tgt_if_tx_api.h>
30 #include <target_if.h>
31 #include <init_deinit_lmac.h>
32 #include <wlan_lmac_if_api.h>
33 #include <wlan_reg_services_api.h>
34 #include <wlan_dfs_tgt_api.h>
35 #include <wlan_vdev_mgr_ucfg_api.h>
36 
37 static QDF_STATUS vdev_mgr_create_param_update(
38 					struct vdev_mlme_obj *mlme_obj,
39 					struct vdev_create_params *param)
40 {
41 	struct wlan_objmgr_pdev *pdev;
42 	struct wlan_objmgr_vdev *vdev;
43 	struct vdev_mlme_mbss_11ax *mbss;
44 
45 	vdev = mlme_obj->vdev;
46 	if (!vdev) {
47 		mlme_err("VDEV is NULL");
48 		return QDF_STATUS_E_INVAL;
49 	}
50 
51 	pdev = wlan_vdev_get_pdev(vdev);
52 	if (!pdev) {
53 		mlme_err("PDEV is NULL");
54 		return QDF_STATUS_E_INVAL;
55 	}
56 
57 	mbss = &mlme_obj->mgmt.mbss_11ax;
58 	param->pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
59 	param->vdev_id = wlan_vdev_get_id(vdev);
60 	param->nss_2g = mlme_obj->mgmt.generic.nss_2g;
61 	param->nss_5g = mlme_obj->mgmt.generic.nss_5g;
62 	param->type = mlme_obj->mgmt.generic.type;
63 	param->subtype = mlme_obj->mgmt.generic.subtype;
64 	param->mbssid_flags = mbss->mbssid_flags;
65 	param->vdevid_trans = mbss->vdevid_trans;
66 
67 	return QDF_STATUS_SUCCESS;
68 }
69 
70 QDF_STATUS vdev_mgr_create_send(struct vdev_mlme_obj *mlme_obj)
71 {
72 	QDF_STATUS status;
73 	struct vdev_create_params param = {0};
74 
75 	if (!mlme_obj) {
76 		mlme_err("VDEV_MLME is NULL");
77 		return QDF_STATUS_E_INVAL;
78 	}
79 
80 	status = vdev_mgr_create_param_update(mlme_obj, &param);
81 	if (QDF_IS_STATUS_ERROR(status)) {
82 		mlme_err("Param Update Error: %d", status);
83 		return status;
84 	}
85 
86 	status = tgt_vdev_mgr_create_send(mlme_obj, &param);
87 
88 	return status;
89 }
90 
91 static QDF_STATUS vdev_mgr_start_param_update(
92 					struct vdev_mlme_obj *mlme_obj,
93 					struct vdev_start_params *param)
94 {
95 	struct wlan_channel *bss_chan;
96 	uint32_t dfs_reg;
97 	uint64_t chan_flags;
98 	uint16_t chan_flags_ext;
99 	bool set_agile = false, dfs_set_cfreq2 = false;
100 	struct wlan_objmgr_vdev *vdev;
101 	struct wlan_objmgr_pdev *pdev;
102 
103 	vdev = mlme_obj->vdev;
104 	if (!vdev) {
105 		mlme_err("VDEV is NULL");
106 		return QDF_STATUS_E_INVAL;
107 	}
108 
109 	pdev = wlan_vdev_get_pdev(vdev);
110 	if (!pdev) {
111 		mlme_err("PDEV is NULL");
112 		return QDF_STATUS_E_INVAL;
113 	}
114 
115 	if (wlan_objmgr_pdev_try_get_ref(pdev, WLAN_MLME_SB_ID) !=
116 							QDF_STATUS_SUCCESS) {
117 		mlme_err("Failed to get pdev reference");
118 		return QDF_STATUS_E_FAILURE;
119 	}
120 
121 	bss_chan = wlan_vdev_mlme_get_bss_chan(vdev);
122 	param->vdev_id = wlan_vdev_get_id(vdev);
123 	chan_flags = mlme_obj->mgmt.generic.chan_flags;
124 	chan_flags_ext = mlme_obj->mgmt.generic.chan_flags_ext;
125 
126 	tgt_dfs_set_current_channel(pdev, bss_chan->ch_freq,
127 				    chan_flags, chan_flags_ext,
128 				    bss_chan->ch_ieee,
129 				    bss_chan->ch_freq_seg1,
130 				    bss_chan->ch_freq_seg2);
131 
132 	param->beacon_interval = mlme_obj->proto.generic.beacon_interval;
133 	param->dtim_period = mlme_obj->proto.generic.dtim_period;
134 	param->disable_hw_ack = mlme_obj->mgmt.generic.disable_hw_ack;
135 	param->preferred_rx_streams =
136 		mlme_obj->mgmt.chainmask_info.num_rx_chain;
137 	param->preferred_tx_streams =
138 		mlme_obj->mgmt.chainmask_info.num_tx_chain;
139 
140 	wlan_reg_get_dfs_region(pdev, &dfs_reg);
141 	param->regdomain = dfs_reg;
142 	param->he_ops = mlme_obj->proto.he_ops_info.he_ops;
143 
144 	param->channel.chan_id = bss_chan->ch_ieee;
145 	param->channel.pwr = mlme_obj->mgmt.generic.tx_power;
146 	param->channel.mhz = bss_chan->ch_freq;
147 	param->channel.half_rate = mlme_obj->mgmt.rate_info.half_rate;
148 	param->channel.quarter_rate = mlme_obj->mgmt.rate_info.quarter_rate;
149 	param->channel.dfs_set = mlme_obj->mgmt.generic.dfs_set;
150 	param->channel.dfs_set_cfreq2 = mlme_obj->mgmt.generic.dfs_set_cfreq2;
151 	param->channel.is_chan_passive =
152 		mlme_obj->mgmt.generic.is_chan_passive;
153 	param->channel.allow_ht = mlme_obj->proto.ht_info.allow_ht;
154 	param->channel.allow_vht = mlme_obj->proto.vht_info.allow_vht;
155 	param->channel.phy_mode = bss_chan->ch_phymode;
156 	param->channel.cfreq1 = mlme_obj->mgmt.generic.cfreq1;
157 	param->channel.cfreq2 = mlme_obj->mgmt.generic.cfreq2;
158 	param->channel.maxpower = mlme_obj->mgmt.generic.maxpower;
159 	param->channel.minpower = mlme_obj->mgmt.generic.minpower;
160 	param->channel.maxregpower = mlme_obj->mgmt.generic.maxregpower;
161 	param->channel.antennamax = mlme_obj->mgmt.generic.antennamax;
162 	param->channel.reg_class_id = mlme_obj->mgmt.generic.reg_class_id;
163 	param->bcn_tx_rate_code = mlme_obj->mgmt.rate_info.bcn_tx_rate;
164 	param->ldpc_rx_enabled = mlme_obj->proto.generic.ldpc;
165 	wlan_vdev_mlme_get_ssid(vdev, param->ssid.mac_ssid,
166 				&param->ssid.length);
167 
168 	if (bss_chan->ch_phymode == WLAN_PHYMODE_11AXA_HE80_80) {
169 		tgt_dfs_find_vht80_chan_for_precac(pdev,
170 						   param->channel.phy_mode,
171 						   bss_chan->ch_freq_seg1,
172 						   &param->channel.cfreq1,
173 						   &param->channel.cfreq2,
174 						   &param->channel.phy_mode,
175 						   &dfs_set_cfreq2,
176 						   &set_agile);
177 
178 		param->channel.dfs_set_cfreq2 = dfs_set_cfreq2;
179 		param->channel.set_agile = set_agile;
180 	}
181 
182 	wlan_objmgr_pdev_release_ref(pdev, WLAN_MLME_SB_ID);
183 	return QDF_STATUS_SUCCESS;
184 }
185 
186 QDF_STATUS vdev_mgr_start_send(
187 			struct vdev_mlme_obj *mlme_obj,
188 			bool restart)
189 {
190 	QDF_STATUS status;
191 	struct vdev_start_params param = {0};
192 
193 	if (!mlme_obj) {
194 		mlme_err("VDEV_MLME is NULL");
195 		return QDF_STATUS_E_INVAL;
196 	}
197 
198 	status = vdev_mgr_start_param_update(mlme_obj, &param);
199 	if (QDF_IS_STATUS_ERROR(status)) {
200 		mlme_err("Param Update Error: %d", status);
201 		return status;
202 	}
203 
204 	param.is_restart = restart;
205 	status = tgt_vdev_mgr_start_send(mlme_obj, &param);
206 
207 	return status;
208 }
209 
210 static QDF_STATUS vdev_mgr_delete_param_update(
211 					struct vdev_mlme_obj *mlme_obj,
212 					struct vdev_delete_params *param)
213 {
214 	struct wlan_objmgr_vdev *vdev;
215 
216 	vdev = mlme_obj->vdev;
217 	if (!vdev) {
218 		mlme_err("VDEV is NULL");
219 		return QDF_STATUS_E_INVAL;
220 	}
221 
222 	param->vdev_id = wlan_vdev_get_id(vdev);
223 	return QDF_STATUS_SUCCESS;
224 }
225 
226 QDF_STATUS vdev_mgr_delete_send(struct vdev_mlme_obj *mlme_obj)
227 {
228 	QDF_STATUS status;
229 	struct vdev_delete_params param;
230 
231 	if (!mlme_obj) {
232 		mlme_err("VDEV_MLME is NULL");
233 		return QDF_STATUS_E_INVAL;
234 	}
235 
236 	status = vdev_mgr_delete_param_update(mlme_obj, &param);
237 	if (QDF_IS_STATUS_ERROR(status)) {
238 		mlme_err("Param Update Error: %d", status);
239 		return status;
240 	}
241 
242 	status = tgt_vdev_mgr_delete_send(mlme_obj, &param);
243 
244 	return status;
245 }
246 
247 static QDF_STATUS vdev_mgr_stop_param_update(
248 				struct vdev_mlme_obj *mlme_obj,
249 				struct vdev_stop_params *param)
250 {
251 	struct wlan_objmgr_vdev *vdev;
252 
253 	vdev = mlme_obj->vdev;
254 	if (!vdev) {
255 		mlme_err("VDEV is NULL");
256 		return QDF_STATUS_E_INVAL;
257 	}
258 
259 	param->vdev_id = wlan_vdev_get_id(vdev);
260 
261 	return QDF_STATUS_SUCCESS;
262 }
263 
264 QDF_STATUS vdev_mgr_stop_send(struct vdev_mlme_obj *mlme_obj)
265 {
266 	QDF_STATUS status;
267 	struct vdev_stop_params param = {0};
268 
269 	if (!mlme_obj) {
270 		mlme_err("VDEV_MLME is NULL");
271 		return QDF_STATUS_E_INVAL;
272 	}
273 
274 	status = vdev_mgr_stop_param_update(mlme_obj, &param);
275 	if (QDF_IS_STATUS_ERROR(status)) {
276 		mlme_err("Param Update Error: %d", status);
277 		return status;
278 	}
279 
280 	status = tgt_vdev_mgr_stop_send(mlme_obj, &param);
281 
282 	return status;
283 }
284 
285 static QDF_STATUS vdev_mgr_config_ratemask_update(
286 				struct vdev_mlme_obj *mlme_obj,
287 				struct config_ratemask_params *param)
288 {
289 	struct wlan_objmgr_vdev *vdev;
290 
291 	vdev = mlme_obj->vdev;
292 	param->vdev_id = wlan_vdev_get_id(vdev);
293 	param->type = mlme_obj->mgmt.rate_info.type;
294 	param->lower32 = mlme_obj->mgmt.rate_info.lower32;
295 	param->higher32 = mlme_obj->mgmt.rate_info.higher32;
296 	param->lower32_2 = mlme_obj->mgmt.rate_info.lower32_2;
297 
298 	return QDF_STATUS_SUCCESS;
299 }
300 
301 static QDF_STATUS vdev_mgr_bcn_tmpl_param_update(
302 				struct vdev_mlme_obj *mlme_obj,
303 				struct beacon_tmpl_params *param)
304 {
305 	return QDF_STATUS_SUCCESS;
306 }
307 
308 static QDF_STATUS vdev_mgr_sta_ps_param_update(
309 				struct vdev_mlme_obj *mlme_obj,
310 				struct sta_ps_params *param)
311 {
312 	struct wlan_objmgr_vdev *vdev;
313 
314 	vdev = mlme_obj->vdev;
315 	param->vdev_id = wlan_vdev_get_id(vdev);
316 	param->param_id = WLAN_MLME_CFG_UAPSD;
317 	param->value = mlme_obj->proto.sta.uapsd_cfg;
318 	return QDF_STATUS_SUCCESS;
319 }
320 
321 static QDF_STATUS vdev_mgr_up_param_update(
322 				struct vdev_mlme_obj *mlme_obj,
323 				struct vdev_up_params *param)
324 {
325 	struct vdev_mlme_mbss_11ax *mbss;
326 	struct wlan_objmgr_vdev *vdev;
327 
328 	vdev = mlme_obj->vdev;
329 	param->vdev_id = wlan_vdev_get_id(vdev);
330 	param->assoc_id = mlme_obj->proto.sta.assoc_id;
331 	mbss = &mlme_obj->mgmt.mbss_11ax;
332 	if (mbss->profile_idx) {
333 		param->profile_idx = mbss->profile_idx;
334 		param->profile_num = mbss->profile_num;
335 		qdf_mem_copy(param->trans_bssid, mbss->trans_bssid,
336 			     QDF_MAC_ADDR_SIZE);
337 	}
338 
339 	return QDF_STATUS_SUCCESS;
340 }
341 
342 QDF_STATUS vdev_mgr_up_send(struct vdev_mlme_obj *mlme_obj)
343 {
344 	QDF_STATUS status;
345 	struct vdev_up_params param = {0};
346 	struct config_ratemask_params rm_param = {0};
347 	struct sta_ps_params ps_param = {0};
348 	struct beacon_tmpl_params bcn_tmpl_param = {0};
349 	enum QDF_OPMODE opmode;
350 	struct wlan_objmgr_vdev *vdev;
351 
352 	if (!mlme_obj) {
353 		mlme_err("VDEV_MLME is NULL");
354 		return QDF_STATUS_E_INVAL;
355 	}
356 
357 	vdev = mlme_obj->vdev;
358 	if (!vdev) {
359 		mlme_err("VDEV is NULL");
360 		return QDF_STATUS_E_INVAL;
361 	}
362 
363 	vdev_mgr_up_param_update(mlme_obj, &param);
364 	vdev_mgr_bcn_tmpl_param_update(mlme_obj, &bcn_tmpl_param);
365 
366 	opmode = wlan_vdev_mlme_get_opmode(vdev);
367 	if (opmode == QDF_STA_MODE) {
368 		vdev_mgr_sta_ps_param_update(mlme_obj, &ps_param);
369 		status = tgt_vdev_mgr_sta_ps_param_send(mlme_obj, &ps_param);
370 
371 	} else if (opmode == QDF_SAP_MODE) {
372 		vdev_mgr_config_ratemask_update(mlme_obj, &rm_param);
373 		status = tgt_vdev_mgr_config_ratemask_cmd_send(mlme_obj,
374 							       &rm_param);
375 	}
376 
377 	status = tgt_vdev_mgr_beacon_tmpl_send(mlme_obj, &bcn_tmpl_param);
378 	if (QDF_IS_STATUS_ERROR(status))
379 		return status;
380 
381 	status = tgt_vdev_mgr_up_send(mlme_obj, &param);
382 
383 	return status;
384 }
385 
386 static QDF_STATUS vdev_mgr_down_param_update(
387 					struct vdev_mlme_obj *mlme_obj,
388 					struct vdev_down_params *param)
389 {
390 	struct wlan_objmgr_vdev *vdev;
391 
392 	vdev = mlme_obj->vdev;
393 	if (!vdev) {
394 		mlme_err("VDEV is NULL");
395 		return QDF_STATUS_E_INVAL;
396 	}
397 
398 	param->vdev_id = wlan_vdev_get_id(vdev);
399 
400 	return QDF_STATUS_SUCCESS;
401 }
402 
403 QDF_STATUS vdev_mgr_down_send(struct vdev_mlme_obj *mlme_obj)
404 {
405 	QDF_STATUS status;
406 	struct vdev_down_params param = {0};
407 
408 	if (!mlme_obj) {
409 		mlme_err("VDEV_MLME is NULL");
410 		return QDF_STATUS_E_INVAL;
411 	}
412 
413 	status = vdev_mgr_down_param_update(mlme_obj, &param);
414 	if (QDF_IS_STATUS_ERROR(status)) {
415 		mlme_err("Param Update Error: %d", status);
416 		return status;
417 	}
418 
419 	status = tgt_vdev_mgr_down_send(mlme_obj, &param);
420 
421 	return status;
422 }
423 
424 static QDF_STATUS vdev_mgr_peer_flush_tids_param_update(
425 					struct vdev_mlme_obj *mlme_obj,
426 					struct peer_flush_params *param,
427 					uint8_t *mac,
428 					uint32_t peer_tid_bitmap)
429 {
430 	struct wlan_objmgr_vdev *vdev;
431 
432 	vdev = mlme_obj->vdev;
433 	if (!vdev) {
434 		mlme_err("VDEV is NULL");
435 		return QDF_STATUS_E_INVAL;
436 	}
437 
438 	param->vdev_id = wlan_vdev_get_id(vdev);
439 	param->peer_tid_bitmap = peer_tid_bitmap;
440 	qdf_mem_copy(param->peer_mac, mac, sizeof(*mac));
441 	return QDF_STATUS_SUCCESS;
442 }
443 
444 QDF_STATUS vdev_mgr_peer_flush_tids_send(struct vdev_mlme_obj *mlme_obj,
445 					 uint8_t *mac,
446 					 uint32_t peer_tid_bitmap)
447 {
448 	QDF_STATUS status;
449 	struct peer_flush_params param = {0};
450 
451 	if (!mlme_obj || !mac) {
452 		mlme_err("Invalid input");
453 		return QDF_STATUS_E_INVAL;
454 	}
455 
456 	status = vdev_mgr_peer_flush_tids_param_update(mlme_obj, &param,
457 						       mac, peer_tid_bitmap);
458 	if (QDF_IS_STATUS_ERROR(status)) {
459 		mlme_err("Param Update Error: %d", status);
460 		return status;
461 	}
462 
463 	status = tgt_vdev_mgr_peer_flush_tids_send(mlme_obj, &param);
464 
465 	return status;
466 }
467 
468 static QDF_STATUS vdev_mgr_multiple_restart_param_update(
469 				struct wlan_objmgr_pdev *pdev,
470 				struct mlme_channel_param *chan,
471 				uint32_t disable_hw_ack,
472 				uint32_t *vdev_ids,
473 				uint32_t num_vdevs,
474 				struct multiple_vdev_restart_params *param)
475 {
476 	param->pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
477 	param->requestor_id = MULTIPLE_VDEV_RESTART_REQ_ID;
478 	param->disable_hw_ack = disable_hw_ack;
479 	param->cac_duration_ms = WLAN_DFS_WAIT_MS;
480 	param->num_vdevs = num_vdevs;
481 
482 	qdf_mem_copy(param->vdev_ids, vdev_ids,
483 		     sizeof(uint32_t) * (param->num_vdevs));
484 	qdf_mem_copy(&param->ch_param, chan,
485 		     sizeof(struct mlme_channel_param));
486 
487 	return QDF_STATUS_SUCCESS;
488 }
489 
490 QDF_STATUS vdev_mgr_multiple_restart_send(struct wlan_objmgr_pdev *pdev,
491 					  struct mlme_channel_param *chan,
492 					  uint32_t disable_hw_ack,
493 					  uint32_t *vdev_ids,
494 					  uint32_t num_vdevs)
495 {
496 	struct multiple_vdev_restart_params param = {0};
497 
498 	vdev_mgr_multiple_restart_param_update(pdev, chan,
499 					       disable_hw_ack,
500 					       vdev_ids, num_vdevs,
501 					       &param);
502 
503 	return tgt_vdev_mgr_multiple_vdev_restart_send(pdev, &param);
504 }
505 
506 qdf_export_symbol(vdev_mgr_multiple_restart_send);
507