xref: /wlan-dirver/qca-wifi-host-cmn/umac/mlme/vdev_mgr/core/src/vdev_mgr_ops.c (revision dd4dc88b837a295134aa9869114a2efee0f4894b)
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_dfs_utils_api.h>
36 #include <wlan_vdev_mgr_ucfg_api.h>
37 
38 static QDF_STATUS vdev_mgr_create_param_update(
39 					struct vdev_mlme_obj *mlme_obj,
40 					struct vdev_create_params *param)
41 {
42 	struct wlan_objmgr_pdev *pdev;
43 	struct wlan_objmgr_vdev *vdev;
44 	struct vdev_mlme_mbss_11ax *mbss;
45 
46 	vdev = mlme_obj->vdev;
47 	if (!vdev) {
48 		mlme_err("VDEV is NULL");
49 		return QDF_STATUS_E_INVAL;
50 	}
51 
52 	pdev = wlan_vdev_get_pdev(vdev);
53 	if (!pdev) {
54 		mlme_err("PDEV is NULL");
55 		return QDF_STATUS_E_INVAL;
56 	}
57 
58 	mbss = &mlme_obj->mgmt.mbss_11ax;
59 	param->pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
60 	param->vdev_id = wlan_vdev_get_id(vdev);
61 	param->nss_2g = mlme_obj->proto.generic.nss_2g;
62 	param->nss_5g = mlme_obj->proto.generic.nss_5g;
63 	param->type = mlme_obj->mgmt.generic.type;
64 	param->subtype = mlme_obj->mgmt.generic.subtype;
65 	param->mbssid_flags = mbss->mbssid_flags;
66 	param->vdevid_trans = mbss->vdevid_trans;
67 
68 	return QDF_STATUS_SUCCESS;
69 }
70 
71 QDF_STATUS vdev_mgr_create_send(struct vdev_mlme_obj *mlme_obj)
72 {
73 	QDF_STATUS status;
74 	struct vdev_create_params param = {0};
75 
76 	if (!mlme_obj) {
77 		mlme_err("VDEV_MLME is NULL");
78 		return QDF_STATUS_E_INVAL;
79 	}
80 
81 	status = vdev_mgr_create_param_update(mlme_obj, &param);
82 	if (QDF_IS_STATUS_ERROR(status)) {
83 		mlme_err("Param Update Error: %d", status);
84 		return status;
85 	}
86 
87 	status = tgt_vdev_mgr_create_send(mlme_obj, &param);
88 
89 	return status;
90 }
91 
92 static QDF_STATUS vdev_mgr_start_param_update(
93 					struct vdev_mlme_obj *mlme_obj,
94 					struct vdev_start_params *param)
95 {
96 	struct wlan_channel *des_chan;
97 	uint32_t dfs_reg;
98 	bool set_agile = false, dfs_set_cfreq2 = false;
99 	struct wlan_objmgr_vdev *vdev;
100 	struct wlan_objmgr_pdev *pdev;
101 
102 	vdev = mlme_obj->vdev;
103 	if (!vdev) {
104 		mlme_err("VDEV is NULL");
105 		return QDF_STATUS_E_INVAL;
106 	}
107 
108 	pdev = wlan_vdev_get_pdev(vdev);
109 	if (!pdev) {
110 		mlme_err("PDEV is NULL");
111 		return QDF_STATUS_E_INVAL;
112 	}
113 
114 	if (wlan_objmgr_pdev_try_get_ref(pdev, WLAN_MLME_SB_ID) !=
115 							QDF_STATUS_SUCCESS) {
116 		mlme_err("Failed to get pdev reference");
117 		return QDF_STATUS_E_FAILURE;
118 	}
119 
120 	des_chan = wlan_vdev_mlme_get_des_chan(vdev);
121 	param->vdev_id = wlan_vdev_get_id(vdev);
122 
123 	tgt_dfs_set_current_channel(pdev, des_chan->ch_freq,
124 				    des_chan->ch_flags,
125 				    des_chan->ch_flagext,
126 				    des_chan->ch_ieee,
127 				    des_chan->ch_freq_seg1,
128 				    des_chan->ch_freq_seg2);
129 
130 	param->beacon_interval = mlme_obj->proto.generic.beacon_interval;
131 	param->dtim_period = mlme_obj->proto.generic.dtim_period;
132 	param->disable_hw_ack = mlme_obj->mgmt.generic.disable_hw_ack;
133 	param->preferred_rx_streams =
134 		mlme_obj->mgmt.chainmask_info.num_rx_chain;
135 	param->preferred_tx_streams =
136 		mlme_obj->mgmt.chainmask_info.num_tx_chain;
137 
138 	wlan_reg_get_dfs_region(pdev, &dfs_reg);
139 	param->regdomain = dfs_reg;
140 	param->he_ops = mlme_obj->proto.he_ops_info.he_ops;
141 
142 	param->channel.chan_id = des_chan->ch_ieee;
143 	param->channel.pwr = mlme_obj->mgmt.generic.tx_power;
144 	param->channel.mhz = des_chan->ch_freq;
145 	param->channel.half_rate = mlme_obj->mgmt.rate_info.half_rate;
146 	param->channel.quarter_rate = mlme_obj->mgmt.rate_info.quarter_rate;
147 	param->channel.dfs_set = utils_is_dfs_ch(pdev, param->channel.chan_id);
148 	param->channel.dfs_set_cfreq2 = utils_is_dfs_cfreq2_ch(pdev);
149 	param->channel.is_chan_passive =
150 		utils_is_dfs_ch(pdev, param->channel.chan_id);
151 	param->channel.allow_ht = mlme_obj->proto.ht_info.allow_ht;
152 	param->channel.allow_vht = mlme_obj->proto.vht_info.allow_vht;
153 	param->channel.phy_mode = mlme_obj->mgmt.generic.phy_mode;
154 	param->channel.cfreq1 = des_chan->ch_cfreq1;
155 	param->channel.cfreq2 = des_chan->ch_cfreq2;
156 	param->channel.maxpower = mlme_obj->mgmt.generic.maxpower;
157 	param->channel.minpower = mlme_obj->mgmt.generic.minpower;
158 	param->channel.maxregpower = mlme_obj->mgmt.generic.maxregpower;
159 	param->channel.antennamax = mlme_obj->mgmt.generic.antennamax;
160 	param->channel.reg_class_id = mlme_obj->mgmt.generic.reg_class_id;
161 	param->bcn_tx_rate_code = mlme_obj->mgmt.rate_info.bcn_tx_rate;
162 	param->ldpc_rx_enabled = mlme_obj->proto.generic.ldpc;
163 	wlan_vdev_mlme_get_ssid(vdev, param->ssid.mac_ssid,
164 				&param->ssid.length);
165 
166 	if (des_chan->ch_phymode == WLAN_PHYMODE_11AC_VHT80 ||
167 	    des_chan->ch_phymode == WLAN_PHYMODE_11AXA_HE80) {
168 		tgt_dfs_find_vht80_chan_for_precac(pdev,
169 						   des_chan->ch_phymode,
170 						   des_chan->ch_freq_seg1,
171 						   &param->channel.cfreq1,
172 						   &param->channel.cfreq2,
173 						   &param->channel.phy_mode,
174 						   &dfs_set_cfreq2,
175 						   &set_agile);
176 
177 		param->channel.dfs_set_cfreq2 = dfs_set_cfreq2;
178 		param->channel.set_agile = set_agile;
179 	}
180 
181 	wlan_objmgr_pdev_release_ref(pdev, WLAN_MLME_SB_ID);
182 	return QDF_STATUS_SUCCESS;
183 }
184 
185 QDF_STATUS vdev_mgr_start_send(
186 			struct vdev_mlme_obj *mlme_obj,
187 			bool restart)
188 {
189 	QDF_STATUS status;
190 	struct vdev_start_params param = {0};
191 
192 	if (!mlme_obj) {
193 		mlme_err("VDEV_MLME is NULL");
194 		return QDF_STATUS_E_INVAL;
195 	}
196 
197 	status = vdev_mgr_start_param_update(mlme_obj, &param);
198 	if (QDF_IS_STATUS_ERROR(status)) {
199 		mlme_err("Param Update Error: %d", status);
200 		return status;
201 	}
202 
203 	param.is_restart = restart;
204 	status = tgt_vdev_mgr_start_send(mlme_obj, &param);
205 
206 	return status;
207 }
208 
209 static QDF_STATUS vdev_mgr_delete_param_update(
210 					struct vdev_mlme_obj *mlme_obj,
211 					struct vdev_delete_params *param)
212 {
213 	struct wlan_objmgr_vdev *vdev;
214 
215 	vdev = mlme_obj->vdev;
216 	if (!vdev) {
217 		mlme_err("VDEV is NULL");
218 		return QDF_STATUS_E_INVAL;
219 	}
220 
221 	param->vdev_id = wlan_vdev_get_id(vdev);
222 	return QDF_STATUS_SUCCESS;
223 }
224 
225 QDF_STATUS vdev_mgr_delete_send(struct vdev_mlme_obj *mlme_obj)
226 {
227 	QDF_STATUS status;
228 	struct vdev_delete_params param;
229 
230 	if (!mlme_obj) {
231 		mlme_err("VDEV_MLME is NULL");
232 		return QDF_STATUS_E_INVAL;
233 	}
234 
235 	status = vdev_mgr_delete_param_update(mlme_obj, &param);
236 	if (QDF_IS_STATUS_ERROR(status)) {
237 		mlme_err("Param Update Error: %d", status);
238 		return status;
239 	}
240 
241 	status = tgt_vdev_mgr_delete_send(mlme_obj, &param);
242 
243 	return status;
244 }
245 
246 static QDF_STATUS vdev_mgr_stop_param_update(
247 				struct vdev_mlme_obj *mlme_obj,
248 				struct vdev_stop_params *param)
249 {
250 	struct wlan_objmgr_vdev *vdev;
251 
252 	vdev = mlme_obj->vdev;
253 	if (!vdev) {
254 		mlme_err("VDEV is NULL");
255 		return QDF_STATUS_E_INVAL;
256 	}
257 
258 	param->vdev_id = wlan_vdev_get_id(vdev);
259 
260 	return QDF_STATUS_SUCCESS;
261 }
262 
263 QDF_STATUS vdev_mgr_stop_send(struct vdev_mlme_obj *mlme_obj)
264 {
265 	QDF_STATUS status;
266 	struct vdev_stop_params param = {0};
267 
268 	if (!mlme_obj) {
269 		mlme_err("VDEV_MLME is NULL");
270 		return QDF_STATUS_E_INVAL;
271 	}
272 
273 	status = vdev_mgr_stop_param_update(mlme_obj, &param);
274 	if (QDF_IS_STATUS_ERROR(status)) {
275 		mlme_err("Param Update Error: %d", status);
276 		return status;
277 	}
278 
279 	status = tgt_vdev_mgr_stop_send(mlme_obj, &param);
280 
281 	return status;
282 }
283 
284 static QDF_STATUS vdev_mgr_bcn_tmpl_param_update(
285 				struct vdev_mlme_obj *mlme_obj,
286 				struct beacon_tmpl_params *param)
287 {
288 	return QDF_STATUS_SUCCESS;
289 }
290 
291 static QDF_STATUS vdev_mgr_sta_ps_param_update(
292 				struct vdev_mlme_obj *mlme_obj,
293 				struct sta_ps_params *param)
294 {
295 	struct wlan_objmgr_vdev *vdev;
296 
297 	vdev = mlme_obj->vdev;
298 	param->vdev_id = wlan_vdev_get_id(vdev);
299 	param->param_id = WLAN_MLME_CFG_UAPSD;
300 	param->value = mlme_obj->proto.sta.uapsd_cfg;
301 	return QDF_STATUS_SUCCESS;
302 }
303 
304 static QDF_STATUS vdev_mgr_up_param_update(
305 				struct vdev_mlme_obj *mlme_obj,
306 				struct vdev_up_params *param)
307 {
308 	struct vdev_mlme_mbss_11ax *mbss;
309 	struct wlan_objmgr_vdev *vdev;
310 
311 	vdev = mlme_obj->vdev;
312 	param->vdev_id = wlan_vdev_get_id(vdev);
313 	param->assoc_id = mlme_obj->proto.sta.assoc_id;
314 	mbss = &mlme_obj->mgmt.mbss_11ax;
315 	if (mbss->profile_idx) {
316 		param->profile_idx = mbss->profile_idx;
317 		param->profile_num = mbss->profile_num;
318 		qdf_mem_copy(param->trans_bssid, mbss->trans_bssid,
319 			     QDF_MAC_ADDR_SIZE);
320 	}
321 
322 	return QDF_STATUS_SUCCESS;
323 }
324 
325 QDF_STATUS vdev_mgr_up_send(struct vdev_mlme_obj *mlme_obj)
326 {
327 	QDF_STATUS status;
328 	struct vdev_up_params param = {0};
329 	struct sta_ps_params ps_param = {0};
330 	struct beacon_tmpl_params bcn_tmpl_param = {0};
331 	enum QDF_OPMODE opmode;
332 	struct wlan_objmgr_vdev *vdev;
333 
334 	if (!mlme_obj) {
335 		mlme_err("VDEV_MLME is NULL");
336 		return QDF_STATUS_E_INVAL;
337 	}
338 
339 	vdev = mlme_obj->vdev;
340 	if (!vdev) {
341 		mlme_err("VDEV is NULL");
342 		return QDF_STATUS_E_INVAL;
343 	}
344 
345 	vdev_mgr_up_param_update(mlme_obj, &param);
346 	vdev_mgr_bcn_tmpl_param_update(mlme_obj, &bcn_tmpl_param);
347 
348 	opmode = wlan_vdev_mlme_get_opmode(vdev);
349 	if (opmode == QDF_STA_MODE) {
350 		vdev_mgr_sta_ps_param_update(mlme_obj, &ps_param);
351 		status = tgt_vdev_mgr_sta_ps_param_send(mlme_obj, &ps_param);
352 
353 	}
354 
355 	status = tgt_vdev_mgr_beacon_tmpl_send(mlme_obj, &bcn_tmpl_param);
356 	if (QDF_IS_STATUS_ERROR(status))
357 		return status;
358 
359 	status = tgt_vdev_mgr_up_send(mlme_obj, &param);
360 
361 	return status;
362 }
363 
364 static QDF_STATUS vdev_mgr_down_param_update(
365 					struct vdev_mlme_obj *mlme_obj,
366 					struct vdev_down_params *param)
367 {
368 	struct wlan_objmgr_vdev *vdev;
369 
370 	vdev = mlme_obj->vdev;
371 	if (!vdev) {
372 		mlme_err("VDEV is NULL");
373 		return QDF_STATUS_E_INVAL;
374 	}
375 
376 	param->vdev_id = wlan_vdev_get_id(vdev);
377 
378 	return QDF_STATUS_SUCCESS;
379 }
380 
381 QDF_STATUS vdev_mgr_down_send(struct vdev_mlme_obj *mlme_obj)
382 {
383 	QDF_STATUS status;
384 	struct vdev_down_params param = {0};
385 
386 	if (!mlme_obj) {
387 		mlme_err("VDEV_MLME is NULL");
388 		return QDF_STATUS_E_INVAL;
389 	}
390 
391 	status = vdev_mgr_down_param_update(mlme_obj, &param);
392 	if (QDF_IS_STATUS_ERROR(status)) {
393 		mlme_err("Param Update Error: %d", status);
394 		return status;
395 	}
396 
397 	status = tgt_vdev_mgr_down_send(mlme_obj, &param);
398 
399 	return status;
400 }
401 
402 static QDF_STATUS vdev_mgr_peer_flush_tids_param_update(
403 					struct vdev_mlme_obj *mlme_obj,
404 					struct peer_flush_params *param,
405 					uint8_t *mac,
406 					uint32_t peer_tid_bitmap)
407 {
408 	struct wlan_objmgr_vdev *vdev;
409 
410 	vdev = mlme_obj->vdev;
411 	if (!vdev) {
412 		mlme_err("VDEV is NULL");
413 		return QDF_STATUS_E_INVAL;
414 	}
415 
416 	param->vdev_id = wlan_vdev_get_id(vdev);
417 	param->peer_tid_bitmap = peer_tid_bitmap;
418 	qdf_mem_copy(param->peer_mac, mac, QDF_MAC_ADDR_SIZE);
419 	return QDF_STATUS_SUCCESS;
420 }
421 
422 QDF_STATUS vdev_mgr_peer_flush_tids_send(struct vdev_mlme_obj *mlme_obj,
423 					 uint8_t *mac,
424 					 uint32_t peer_tid_bitmap)
425 {
426 	QDF_STATUS status;
427 	struct peer_flush_params param = {0};
428 
429 	if (!mlme_obj || !mac) {
430 		mlme_err("Invalid input");
431 		return QDF_STATUS_E_INVAL;
432 	}
433 
434 	status = vdev_mgr_peer_flush_tids_param_update(mlme_obj, &param,
435 						       mac, peer_tid_bitmap);
436 	if (QDF_IS_STATUS_ERROR(status)) {
437 		mlme_err("Param Update Error: %d", status);
438 		return status;
439 	}
440 
441 	status = tgt_vdev_mgr_peer_flush_tids_send(mlme_obj, &param);
442 
443 	return status;
444 }
445 
446 static QDF_STATUS vdev_mgr_multiple_restart_param_update(
447 				struct wlan_objmgr_pdev *pdev,
448 				struct mlme_channel_param *chan,
449 				uint32_t disable_hw_ack,
450 				uint32_t *vdev_ids,
451 				uint32_t num_vdevs,
452 				struct multiple_vdev_restart_params *param)
453 {
454 	param->pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
455 	param->requestor_id = MULTIPLE_VDEV_RESTART_REQ_ID;
456 	param->disable_hw_ack = disable_hw_ack;
457 	param->cac_duration_ms = WLAN_DFS_WAIT_MS;
458 	param->num_vdevs = num_vdevs;
459 
460 	qdf_mem_copy(param->vdev_ids, vdev_ids,
461 		     sizeof(uint32_t) * (param->num_vdevs));
462 	qdf_mem_copy(&param->ch_param, chan,
463 		     sizeof(struct mlme_channel_param));
464 
465 	return QDF_STATUS_SUCCESS;
466 }
467 
468 QDF_STATUS vdev_mgr_multiple_restart_send(struct wlan_objmgr_pdev *pdev,
469 					  struct mlme_channel_param *chan,
470 					  uint32_t disable_hw_ack,
471 					  uint32_t *vdev_ids,
472 					  uint32_t num_vdevs)
473 {
474 	struct multiple_vdev_restart_params param = {0};
475 
476 	vdev_mgr_multiple_restart_param_update(pdev, chan,
477 					       disable_hw_ack,
478 					       vdev_ids, num_vdevs,
479 					       &param);
480 
481 	return tgt_vdev_mgr_multiple_vdev_restart_send(pdev, &param);
482 }
483 
484 qdf_export_symbol(vdev_mgr_multiple_restart_send);
485 
486 static QDF_STATUS vdev_mgr_set_custom_aggr_size_param_update(
487 				struct vdev_mlme_obj *mlme_obj,
488 				struct set_custom_aggr_size_params *param,
489 				bool is_amsdu)
490 {
491 	struct wlan_objmgr_vdev *vdev;
492 
493 	vdev = mlme_obj->vdev;
494 	if (!vdev) {
495 		mlme_err("VDEV is NULL");
496 		return QDF_STATUS_E_INVAL;
497 	}
498 
499 	param->aggr_type = is_amsdu ? WLAN_MLME_CUSTOM_AGGR_TYPE_AMSDU
500 				    : WLAN_MLME_CUSTOM_AGGR_TYPE_AMPDU;
501 	/*
502 	 * We are only setting TX params, therefore
503 	 * we are disabling rx_aggr_size
504 	 */
505 	param->rx_aggr_size_disable = true;
506 	param->tx_aggr_size = is_amsdu ? mlme_obj->mgmt.generic.amsdu
507 				       : mlme_obj->mgmt.generic.ampdu;
508 	param->vdev_id = wlan_vdev_get_id(vdev);
509 
510 	return QDF_STATUS_SUCCESS;
511 }
512 
513 QDF_STATUS vdev_mgr_set_custom_aggr_size_send(
514 				struct vdev_mlme_obj *vdev_mlme,
515 				bool is_amsdu)
516 {
517 	QDF_STATUS status;
518 	struct set_custom_aggr_size_params param = {0};
519 
520 	status = vdev_mgr_set_custom_aggr_size_param_update(vdev_mlme,
521 							    &param, is_amsdu);
522 	if (QDF_IS_STATUS_ERROR(status)) {
523 		mlme_err("Param Update Error: %d", status);
524 		return status;
525 	}
526 
527 	return tgt_vdev_mgr_set_custom_aggr_size_send(vdev_mlme, &param);
528 }
529