blob: dcbb96efbce103d261a973b833aa42bb2d483105 [file] [log] [blame]
Srinivas Pitlafa5290f2016-10-17 16:40:37 +05301/*
Srinivas Pitla39a92222018-10-05 10:52:48 +05302 * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
Srinivas Pitlafa5290f2016-10-17 16:40:37 +05303 *
Srinivas Pitla39a92222018-10-05 10:52:48 +05304 * 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.
Srinivas Pitlafa5290f2016-10-17 16:40:37 +05307 *
Srinivas Pitla39a92222018-10-05 10:52:48 +05308 * 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
Srinivas Pitlafa5290f2016-10-17 16:40:37 +053016 */
17 /**
18 * DOC: Public APIs to perform operations on Global objects
19 */
20#include <wlan_objmgr_cmn.h>
21#include <wlan_objmgr_global_obj.h>
Srinivas Pitlafa5290f2016-10-17 16:40:37 +053022#include <wlan_objmgr_psoc_obj.h>
23#include <wlan_objmgr_pdev_obj.h>
24#include <wlan_objmgr_vdev_obj.h>
25#include <wlan_objmgr_peer_obj.h>
Srinivas Pitlafa5290f2016-10-17 16:40:37 +053026#include <qdf_mem.h>
Manikandan Mohan0f3c99b2018-03-01 16:22:44 -080027#include <qdf_module.h>
Srinivas Pitla7c2f9752017-01-05 13:11:40 +053028#include "wlan_objmgr_global_obj_i.h"
29#include "wlan_objmgr_psoc_obj_i.h"
30#include "wlan_objmgr_pdev_obj_i.h"
31#include "wlan_objmgr_vdev_obj_i.h"
Srinivas Pitlafa5290f2016-10-17 16:40:37 +053032
33/**
34 ** APIs to Create/Delete Global object APIs
35 */
36
37static QDF_STATUS wlan_objmgr_vdev_object_status(
38 struct wlan_objmgr_vdev *vdev)
39{
40 uint8_t id;
41 QDF_STATUS status = QDF_STATUS_SUCCESS;
42
43 wlan_vdev_obj_lock(vdev);
44
45 /* Iterate through all components to derive the object status */
46 for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
47 /* If component disabled, Ignore */
48 if (vdev->obj_status[id] == QDF_STATUS_COMP_DISABLED) {
49 continue;
50 /*
51 * If component operates in Async, status is Partially created,
52 * break
53 */
54 } else if (vdev->obj_status[id] == QDF_STATUS_COMP_ASYNC) {
Jeff Johnsondcb27692019-03-20 12:11:48 -070055 if (!vdev->vdev_comp_priv_obj[id]) {
Srinivas Pitlafa5290f2016-10-17 16:40:37 +053056 status = QDF_STATUS_COMP_ASYNC;
57 break;
58 }
59 /*
60 * If component failed to allocate its object, treat it as
61 * failure, complete object need to be cleaned up
62 */
63 } else if ((vdev->obj_status[id] == QDF_STATUS_E_NOMEM) ||
64 (vdev->obj_status[id] == QDF_STATUS_E_FAILURE)) {
65 status = QDF_STATUS_E_FAILURE;
66 break;
67 }
68 }
69 wlan_vdev_obj_unlock(vdev);
Srinivas Pitla10aa60c2017-02-08 12:55:16 +053070
Srinivas Pitlafa5290f2016-10-17 16:40:37 +053071 return status;
72}
73
Srinivas Pitla10aa60c2017-02-08 12:55:16 +053074static QDF_STATUS wlan_objmgr_vdev_obj_free(struct wlan_objmgr_vdev *vdev)
75{
76 struct wlan_objmgr_pdev *pdev;
Liangwei Dong94f906c2018-01-04 16:20:53 +080077 struct wlan_objmgr_psoc *psoc;
Srinivas Pitla10aa60c2017-02-08 12:55:16 +053078
Jeff Johnsondcb27692019-03-20 12:11:48 -070079 if (!vdev) {
Srinivas Pitla4a3f4862017-07-19 14:18:48 +053080 obj_mgr_err("vdev is NULL");
81 return QDF_STATUS_E_FAILURE;
Vivek2c86b212017-06-05 00:02:11 +053082 }
Srinivas Pitla10aa60c2017-02-08 12:55:16 +053083 /* if PDEV is NULL, return */
84 pdev = wlan_vdev_get_pdev(vdev);
Jeff Johnsondcb27692019-03-20 12:11:48 -070085 if (!pdev) {
Vivek8ed2fe92017-09-15 18:34:49 +053086 obj_mgr_err("pdev is NULL for vdev-id: %d",
87 vdev->vdev_objmgr.vdev_id);
Srinivas Pitla10aa60c2017-02-08 12:55:16 +053088 return QDF_STATUS_E_FAILURE;
89 }
Liangwei Dong94f906c2018-01-04 16:20:53 +080090 psoc = wlan_pdev_get_psoc(pdev);
Jeff Johnsondcb27692019-03-20 12:11:48 -070091 if (!psoc) {
Liangwei Dong94f906c2018-01-04 16:20:53 +080092 obj_mgr_err("psoc is NULL in pdev");
93 return QDF_STATUS_E_FAILURE;
94 }
Srinivas Pitla10aa60c2017-02-08 12:55:16 +053095
96 /* Detach VDEV from PDEV VDEV's list */
97 if (wlan_objmgr_pdev_vdev_detach(pdev, vdev) ==
98 QDF_STATUS_E_FAILURE)
99 return QDF_STATUS_E_FAILURE;
100
101 /* Detach VDEV from PSOC VDEV's list */
Liangwei Dong94f906c2018-01-04 16:20:53 +0800102 if (wlan_objmgr_psoc_vdev_detach(psoc, vdev) ==
103 QDF_STATUS_E_FAILURE)
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530104 return QDF_STATUS_E_FAILURE;
105
106 qdf_spinlock_destroy(&vdev->vdev_lock);
Abhijit Pradhan33731942018-02-02 20:35:34 +0530107
108 qdf_mem_free(vdev->vdev_mlme.bss_chan);
109 qdf_mem_free(vdev->vdev_mlme.des_chan);
Arun Kumar Khandavalli52ac4712019-05-13 15:21:48 +0530110 qdf_mem_free(vdev->vdev_nif.osdev);
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530111 qdf_mem_free(vdev);
112
113 return QDF_STATUS_SUCCESS;
114
115}
116
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530117struct wlan_objmgr_vdev *wlan_objmgr_vdev_obj_create(
118 struct wlan_objmgr_pdev *pdev,
119 struct wlan_vdev_create_params *params)
120{
121 struct wlan_objmgr_vdev *vdev;
122 struct wlan_objmgr_psoc *psoc;
123 uint8_t id;
124 wlan_objmgr_vdev_create_handler handler;
125 wlan_objmgr_vdev_status_handler stat_handler;
126 void *arg;
127 QDF_STATUS obj_status;
128
Jeff Johnsondcb27692019-03-20 12:11:48 -0700129 if (!pdev) {
Vivek2c86b212017-06-05 00:02:11 +0530130 obj_mgr_err("pdev is NULL");
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530131 return NULL;
132 }
133 psoc = wlan_pdev_get_psoc(pdev);
134 /* PSOC is NULL */
Jeff Johnsondcb27692019-03-20 12:11:48 -0700135 if (!psoc) {
Vivek8ed2fe92017-09-15 18:34:49 +0530136 obj_mgr_err("psoc is NULL for pdev-id:%d",
137 pdev->pdev_objmgr.wlan_pdev_id);
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530138 return NULL;
139 }
140 /* Allocate vdev object memory */
141 vdev = qdf_mem_malloc(sizeof(*vdev));
Madhvapathi Sriramb73fc282019-01-07 09:12:25 +0530142 if (!vdev)
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530143 return NULL;
Madhvapathi Sriramb73fc282019-01-07 09:12:25 +0530144
Srinivas Pitla86db6ab2018-01-16 10:20:38 +0530145 vdev->obj_state = WLAN_OBJ_STATE_ALLOCATED;
Abhijit Pradhan33731942018-02-02 20:35:34 +0530146
Srinivas Pitla39a92222018-10-05 10:52:48 +0530147 vdev->vdev_mlme.bss_chan = qdf_mem_malloc(sizeof(struct wlan_channel));
148 if (!vdev->vdev_mlme.bss_chan) {
Abhijit Pradhan33731942018-02-02 20:35:34 +0530149 qdf_mem_free(vdev);
150 return NULL;
151 }
152
Srinivas Pitla39a92222018-10-05 10:52:48 +0530153 vdev->vdev_mlme.des_chan = qdf_mem_malloc(sizeof(struct wlan_channel));
154 if (!vdev->vdev_mlme.des_chan) {
Abhijit Pradhan33731942018-02-02 20:35:34 +0530155 qdf_mem_free(vdev->vdev_mlme.bss_chan);
156 qdf_mem_free(vdev);
157 return NULL;
158 }
159
Zhu Jianmin8a8fa102018-03-01 16:59:10 +0800160 /* Initialize spinlock */
161 qdf_spinlock_create(&vdev->vdev_lock);
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530162 /* Attach VDEV to PSOC VDEV's list */
163 if (wlan_objmgr_psoc_vdev_attach(psoc, vdev) !=
164 QDF_STATUS_SUCCESS) {
Vivek8ed2fe92017-09-15 18:34:49 +0530165 obj_mgr_err("psoc vdev attach failed for vdev-id:%d",
166 vdev->vdev_objmgr.vdev_id);
Abhijit Pradhan33731942018-02-02 20:35:34 +0530167 qdf_mem_free(vdev->vdev_mlme.bss_chan);
168 qdf_mem_free(vdev->vdev_mlme.des_chan);
Zhu Jianmin8a8fa102018-03-01 16:59:10 +0800169 qdf_spinlock_destroy(&vdev->vdev_lock);
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530170 qdf_mem_free(vdev);
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530171 return NULL;
172 }
173 /* Store pdev in vdev */
174 wlan_vdev_set_pdev(vdev, pdev);
175 /* Attach vdev to PDEV */
176 if (wlan_objmgr_pdev_vdev_attach(pdev, vdev) !=
177 QDF_STATUS_SUCCESS) {
Vivek8ed2fe92017-09-15 18:34:49 +0530178 obj_mgr_err("pdev vdev attach failed for vdev-id:%d",
179 vdev->vdev_objmgr.vdev_id);
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530180 wlan_objmgr_psoc_vdev_detach(psoc, vdev);
Abhijit Pradhan33731942018-02-02 20:35:34 +0530181 qdf_mem_free(vdev->vdev_mlme.bss_chan);
182 qdf_mem_free(vdev->vdev_mlme.des_chan);
Zhu Jianmin8a8fa102018-03-01 16:59:10 +0800183 qdf_spinlock_destroy(&vdev->vdev_lock);
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530184 qdf_mem_free(vdev);
185 return NULL;
186 }
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530187 /* set opmode */
188 wlan_vdev_mlme_set_opmode(vdev, params->opmode);
189 /* set MAC address */
190 wlan_vdev_mlme_set_macaddr(vdev, params->macaddr);
191 /* set MAT address */
192 wlan_vdev_mlme_set_mataddr(vdev, params->mataddr);
193 /* Set create flags */
194 vdev->vdev_objmgr.c_flags = params->flags;
195 /* store os-specific pointer */
196 vdev->vdev_nif.osdev = params->osifp;
197 /* peer count to 0 */
198 vdev->vdev_objmgr.wlan_peer_count = 0;
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530199 qdf_atomic_init(&vdev->vdev_objmgr.ref_cnt);
Srinivas Pitla68564822017-06-28 12:33:07 +0530200 vdev->vdev_objmgr.print_cnt = 0;
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530201 wlan_objmgr_vdev_get_ref(vdev, WLAN_OBJMGR_ID);
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530202 /* Initialize max peer count based on opmode type */
203 if (wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE)
204 vdev->vdev_objmgr.max_peer_count = WLAN_UMAC_MAX_STA_PEERS;
205 else
Srinivas Pitla4a3f4862017-07-19 14:18:48 +0530206 vdev->vdev_objmgr.max_peer_count =
207 wlan_pdev_get_max_peer_count(pdev);
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530208
209 /* Initialize peer list */
210 qdf_list_create(&vdev->vdev_objmgr.wlan_peer_list,
Vivekadbfaa72018-05-11 13:02:00 +0530211 vdev->vdev_objmgr.max_peer_count +
212 WLAN_MAX_PDEV_TEMP_PEERS);
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530213 /* TODO init other parameters */
214
215 /* Invoke registered create handlers */
216 for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
217 handler = g_umac_glb_obj->vdev_create_handler[id];
218 arg = g_umac_glb_obj->vdev_create_handler_arg[id];
Jeff Johnsondcb27692019-03-20 12:11:48 -0700219 if (handler)
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530220 vdev->obj_status[id] = handler(vdev, arg);
221 else
222 vdev->obj_status[id] = QDF_STATUS_COMP_DISABLED;
223 }
224
225 /* Derive object status */
226 obj_status = wlan_objmgr_vdev_object_status(vdev);
227
228 if (obj_status == QDF_STATUS_SUCCESS) {
229 /* Object status is SUCCESS, Object is created */
230 vdev->obj_state = WLAN_OBJ_STATE_CREATED;
231 /* Invoke component registered status handlers */
232 for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
233 stat_handler = g_umac_glb_obj->vdev_status_handler[id];
234 arg = g_umac_glb_obj->vdev_status_handler_arg[id];
Jeff Johnsondcb27692019-03-20 12:11:48 -0700235 if (stat_handler) {
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530236 stat_handler(vdev, arg,
237 QDF_STATUS_SUCCESS);
238 }
239 }
240 /*
241 * Few components operates in Asynchrous communction, Object state
242 * partially created
243 */
244 } else if (obj_status == QDF_STATUS_COMP_ASYNC) {
245 vdev->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED;
246 /* Component object failed to be created, clean up the object */
247 } else if (obj_status == QDF_STATUS_E_FAILURE) {
248 /* Clean up the psoc */
249 wlan_objmgr_vdev_obj_delete(vdev);
Vivek8ed2fe92017-09-15 18:34:49 +0530250 obj_mgr_err("VDEV comp objects creation failed for vdev-id:%d",
251 vdev->vdev_objmgr.vdev_id);
Jeevan Kukkallie4541742019-06-06 18:28:43 +0530252 /*
253 * Set params osifp to NULL as it is freed during vdev obj
254 * delete, This prevents caller from performing double free.
255 */
256 params->osifp = NULL;
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530257 return NULL;
258 }
Dustin Brown72297392018-01-26 15:29:04 -0800259
260 obj_mgr_info("Created vdev %d", vdev->vdev_objmgr.vdev_id);
261
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530262 return vdev;
263}
Manikandan Mohan0f3c99b2018-03-01 16:22:44 -0800264qdf_export_symbol(wlan_objmgr_vdev_obj_create);
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530265
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530266static QDF_STATUS wlan_objmgr_vdev_obj_destroy(struct wlan_objmgr_vdev *vdev)
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530267{
268 uint8_t id;
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530269 wlan_objmgr_vdev_destroy_handler handler;
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530270 QDF_STATUS obj_status;
271 void *arg;
Vivek8ed2fe92017-09-15 18:34:49 +0530272 uint8_t vdev_id;
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530273
Jeff Johnsondcb27692019-03-20 12:11:48 -0700274 if (!vdev) {
Vivek2c86b212017-06-05 00:02:11 +0530275 obj_mgr_err("vdev is NULL");
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530276 return QDF_STATUS_E_FAILURE;
277 }
Amir Patelc8d752f2018-02-20 11:48:32 +0530278 wlan_objmgr_notify_destroy(vdev, WLAN_VDEV_OP);
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530279
Vivek8ed2fe92017-09-15 18:34:49 +0530280 vdev_id = wlan_vdev_get_id(vdev);
281
Vivek4ad877f2019-09-18 16:49:10 +0530282 wlan_print_vdev_info(vdev);
Yeshwanth Sriram Guntuka0ab053e2018-08-23 18:25:28 +0530283 obj_mgr_debug("Physically deleting vdev %d", vdev_id);
Dustin Brown72297392018-01-26 15:29:04 -0800284
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530285 if (vdev->obj_state != WLAN_OBJ_STATE_LOGICALLY_DELETED) {
Santosh Anbu4d62c9d2018-04-27 11:37:09 +0530286 obj_mgr_err("VDEV object delete is not invoked vdevid:%d objstate:%d",
287 wlan_vdev_get_id(vdev), vdev->obj_state);
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530288 WLAN_OBJMGR_BUG(0);
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530289 }
290
Abhijit Pradhan33731942018-02-02 20:35:34 +0530291 /* Invoke registered destroy handlers */
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530292 for (id = 0; id < WLAN_UMAC_MAX_COMPONENTS; id++) {
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530293 handler = g_umac_glb_obj->vdev_destroy_handler[id];
294 arg = g_umac_glb_obj->vdev_destroy_handler_arg[id];
Paul Zhangda522d82018-08-28 21:19:41 +0800295 if (handler &&
296 (vdev->obj_status[id] == QDF_STATUS_SUCCESS ||
297 vdev->obj_status[id] == QDF_STATUS_COMP_ASYNC))
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530298 vdev->obj_status[id] = handler(vdev, arg);
299 else
300 vdev->obj_status[id] = QDF_STATUS_COMP_DISABLED;
301 }
302 /* Derive object status */
303 obj_status = wlan_objmgr_vdev_object_status(vdev);
304
305 if (obj_status == QDF_STATUS_E_FAILURE) {
Vivek8ed2fe92017-09-15 18:34:49 +0530306 obj_mgr_err("VDEV object deletion failed: vdev-id: %d",
307 vdev_id);
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530308 /* Ideally should not happen */
309 /* This leads to memleak ??? how to handle */
310 QDF_BUG(0);
311 return QDF_STATUS_E_FAILURE;
312 }
313
314 /* Deletion is in progress */
315 if (obj_status == QDF_STATUS_COMP_ASYNC) {
316 vdev->obj_state = WLAN_OBJ_STATE_PARTIALLY_DELETED;
317 return QDF_STATUS_COMP_ASYNC;
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530318 }
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530319
320 /* Free VDEV object */
321 return wlan_objmgr_vdev_obj_free(vdev);
322}
323
324QDF_STATUS wlan_objmgr_vdev_obj_delete(struct wlan_objmgr_vdev *vdev)
325{
Vivek1312d702017-06-12 18:57:51 +0530326 uint8_t print_idx;
327
Jeff Johnsondcb27692019-03-20 12:11:48 -0700328 if (!vdev) {
Vivek2c86b212017-06-05 00:02:11 +0530329 obj_mgr_err("vdev is NULL");
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530330 return QDF_STATUS_E_FAILURE;
331 }
Vivek1312d702017-06-12 18:57:51 +0530332
Dustin Brown72297392018-01-26 15:29:04 -0800333 obj_mgr_info("Logically deleting vdev %d", vdev->vdev_objmgr.vdev_id);
334
Vivek1312d702017-06-12 18:57:51 +0530335 print_idx = qdf_get_pidx();
Abhinav Kumar97919572018-06-15 16:46:30 +0530336 wlan_objmgr_print_ref_ids(vdev->vdev_objmgr.ref_id_dbg,
337 QDF_TRACE_LEVEL_DEBUG);
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530338 /*
339 * Update VDEV object state to LOGICALLY DELETED
340 * It prevents further access of this object
341 */
342 wlan_vdev_obj_lock(vdev);
343 vdev->obj_state = WLAN_OBJ_STATE_LOGICALLY_DELETED;
344 wlan_vdev_obj_unlock(vdev);
Amir Patelc8d752f2018-02-20 11:48:32 +0530345 wlan_objmgr_notify_log_delete(vdev, WLAN_VDEV_OP);
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530346 wlan_objmgr_vdev_release_ref(vdev, WLAN_OBJMGR_ID);
347
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530348 return QDF_STATUS_SUCCESS;
349}
Manikandan Mohan0f3c99b2018-03-01 16:22:44 -0800350qdf_export_symbol(wlan_objmgr_vdev_obj_delete);
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530351
352/**
353 ** APIs to attach/detach component objects
354 */
355QDF_STATUS wlan_objmgr_vdev_component_obj_attach(
356 struct wlan_objmgr_vdev *vdev,
357 enum wlan_umac_comp_id id,
Soumya Bhatdd734872016-12-29 16:21:43 +0530358 void *comp_priv_obj,
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530359 QDF_STATUS status)
360{
361 wlan_objmgr_vdev_status_handler stat_handler;
362 void *arg;
363 uint8_t i;
364 QDF_STATUS obj_status;
365
366 /* component id is invalid */
367 if (id >= WLAN_UMAC_MAX_COMPONENTS)
368 return QDF_STATUS_MAXCOMP_FAIL;
369
370 wlan_vdev_obj_lock(vdev);
371 /* If there is a valid entry, return failure */
Jeff Johnsondcb27692019-03-20 12:11:48 -0700372 if (vdev->vdev_comp_priv_obj[id]) {
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530373 wlan_vdev_obj_unlock(vdev);
374 return QDF_STATUS_E_FAILURE;
375 }
376 /* Save component's pointer and status */
Soumya Bhatdd734872016-12-29 16:21:43 +0530377 vdev->vdev_comp_priv_obj[id] = comp_priv_obj;
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530378 vdev->obj_status[id] = status;
379 wlan_vdev_obj_unlock(vdev);
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530380 if (vdev->obj_state != WLAN_OBJ_STATE_PARTIALLY_CREATED)
381 return QDF_STATUS_SUCCESS;
382 /*
383 * If VDEV object status is partially created means, this API is
384 * invoked with differnt context, this block should be executed for
385 * async components only
386 */
387 /* Derive status */
388 obj_status = wlan_objmgr_vdev_object_status(vdev);
389 /* STATUS_SUCCESS means, object is CREATED */
390 if (obj_status == QDF_STATUS_SUCCESS)
391 vdev->obj_state = WLAN_OBJ_STATE_CREATED;
392 /*
393 * update state as CREATION failed, caller has to delete the
394 * VDEV object
395 */
396 else if (obj_status == QDF_STATUS_E_FAILURE)
397 vdev->obj_state = WLAN_OBJ_STATE_CREATION_FAILED;
398 /* Notify components about the CREATION success/failure */
399 if ((obj_status == QDF_STATUS_SUCCESS) ||
400 (obj_status == QDF_STATUS_E_FAILURE)) {
401 for (i = 0; i < WLAN_UMAC_MAX_COMPONENTS; i++) {
402 stat_handler = g_umac_glb_obj->vdev_status_handler[i];
403 arg = g_umac_glb_obj->vdev_status_handler_arg[i];
Jeff Johnsondcb27692019-03-20 12:11:48 -0700404 if (stat_handler)
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530405 stat_handler(vdev, arg, obj_status);
406 }
407 }
408 return QDF_STATUS_SUCCESS;
409}
Manikandan Mohan0f3c99b2018-03-01 16:22:44 -0800410qdf_export_symbol(wlan_objmgr_vdev_component_obj_attach);
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530411
412QDF_STATUS wlan_objmgr_vdev_component_obj_detach(
413 struct wlan_objmgr_vdev *vdev,
414 enum wlan_umac_comp_id id,
Soumya Bhatdd734872016-12-29 16:21:43 +0530415 void *comp_priv_obj)
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530416{
417 QDF_STATUS obj_status;
418
419 /* component id is invalid */
420 if (id >= WLAN_UMAC_MAX_COMPONENTS)
421 return QDF_STATUS_MAXCOMP_FAIL;
Srinivas Pitlaadbe5ca2017-05-10 12:43:35 +0530422
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530423 wlan_vdev_obj_lock(vdev);
424 /* If there is a valid entry, return failure */
Soumya Bhatdd734872016-12-29 16:21:43 +0530425 if (vdev->vdev_comp_priv_obj[id] != comp_priv_obj) {
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530426 vdev->obj_status[id] = QDF_STATUS_E_FAILURE;
427 wlan_vdev_obj_unlock(vdev);
428 return QDF_STATUS_E_FAILURE;
429 }
430 /* Reset pointers to NULL, update the status*/
Soumya Bhatdd734872016-12-29 16:21:43 +0530431 vdev->vdev_comp_priv_obj[id] = NULL;
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530432 vdev->obj_status[id] = QDF_STATUS_SUCCESS;
433 wlan_vdev_obj_unlock(vdev);
434
435 /**
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530436 *If VDEV object status is partially destroyed means, this API is
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530437 * invoked with differnt context, this block should be executed for
438 * async components only
439 */
440 if ((vdev->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED) ||
441 (vdev->obj_state == WLAN_OBJ_STATE_COMP_DEL_PROGRESS)) {
442 /* Derive object status */
443 obj_status = wlan_objmgr_vdev_object_status(vdev);
444 if (obj_status == QDF_STATUS_SUCCESS) {
445 /*
446 * Update the status as Deleted, if full object
447 * deletion is in progress
448 */
449 if (vdev->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED)
450 vdev->obj_state = WLAN_OBJ_STATE_DELETED;
451 /*
452 * Move to creation state, since this component
453 * deletion alone requested
454 */
455 else if (vdev->obj_state ==
456 WLAN_OBJ_STATE_COMP_DEL_PROGRESS)
457 vdev->obj_state = WLAN_OBJ_STATE_CREATED;
458 /* Object status is failure */
459 } else if (obj_status == QDF_STATUS_E_FAILURE) {
460 /*
461 * Update the status as Deletion failed, if full object
462 * deletion is in progress
463 */
464 if (vdev->obj_state == WLAN_OBJ_STATE_PARTIALLY_DELETED)
465 vdev->obj_state =
466 WLAN_OBJ_STATE_DELETION_FAILED;
467 /* Move to creation state, since this component
468 deletion alone requested (do not block other
469 components) */
470 else if (vdev->obj_state ==
471 WLAN_OBJ_STATE_COMP_DEL_PROGRESS)
472 vdev->obj_state = WLAN_OBJ_STATE_CREATED;
473 }
474 /* Delete vdev object */
475 if ((obj_status == QDF_STATUS_SUCCESS) &&
476 (vdev->obj_state == WLAN_OBJ_STATE_DELETED)) {
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530477 /* Free VDEV object */
478 return wlan_objmgr_vdev_obj_free(vdev);
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530479 }
480 }
481 return QDF_STATUS_SUCCESS;
482}
Manikandan Mohan0f3c99b2018-03-01 16:22:44 -0800483qdf_export_symbol(wlan_objmgr_vdev_component_obj_detach);
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530484
485/**
486 ** APIs to operations on vdev objects
487 */
488QDF_STATUS wlan_objmgr_iterate_peerobj_list(
489 struct wlan_objmgr_vdev *vdev,
490 wlan_objmgr_vdev_op_handler handler,
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530491 void *arg, wlan_objmgr_ref_dbgid dbg_id)
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530492{
493 qdf_list_t *peer_list = NULL;
494 struct wlan_objmgr_peer *peer = NULL;
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530495 struct wlan_objmgr_peer *peer_next = NULL;
Vivek8ed2fe92017-09-15 18:34:49 +0530496 uint8_t vdev_id;
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530497
Jeff Johnsondcb27692019-03-20 12:11:48 -0700498 if (!vdev) {
Vivek2c86b212017-06-05 00:02:11 +0530499 obj_mgr_err("VDEV is NULL");
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530500 return QDF_STATUS_E_FAILURE;
501 }
Vivek8ed2fe92017-09-15 18:34:49 +0530502 wlan_vdev_obj_lock(vdev);
503 vdev_id = wlan_vdev_get_id(vdev);
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530504
Srinivas Pitla86db6ab2018-01-16 10:20:38 +0530505 if (vdev->obj_state != WLAN_OBJ_STATE_CREATED) {
Vivek8ed2fe92017-09-15 18:34:49 +0530506 wlan_vdev_obj_unlock(vdev);
Srinivas Pitla86db6ab2018-01-16 10:20:38 +0530507 obj_mgr_err("VDEV is not in create state(:%d): vdev-id:%d",
508 vdev_id, vdev->obj_state);
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530509 return QDF_STATUS_E_FAILURE;
510 }
511 wlan_objmgr_vdev_get_ref(vdev, dbg_id);
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530512 peer_list = &vdev->vdev_objmgr.wlan_peer_list;
Jeff Johnsondcb27692019-03-20 12:11:48 -0700513 if (peer_list) {
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530514 /* Iterate through VDEV's peer list */
515 peer = wlan_vdev_peer_list_peek_head(peer_list);
Jeff Johnsondcb27692019-03-20 12:11:48 -0700516 while (peer) {
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530517 peer_next = wlan_peer_get_next_peer_of_vdev(peer_list,
518 peer);
519 if (wlan_objmgr_peer_try_get_ref(peer, dbg_id) ==
520 QDF_STATUS_SUCCESS) {
521 /* Invoke handler for operation */
522 handler(vdev, (void *)peer, arg);
523 wlan_objmgr_peer_release_ref(peer, dbg_id);
524 }
525 peer = peer_next;
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530526 }
527 }
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530528 wlan_objmgr_vdev_release_ref(vdev, dbg_id);
Vivek8ed2fe92017-09-15 18:34:49 +0530529 wlan_vdev_obj_unlock(vdev);
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530530 return QDF_STATUS_SUCCESS;
531}
532
Santosh Anbu261451a2019-05-06 23:47:08 +0530533/**
534 * wlan_obj_vdev_populate_logically_del_peerlist() - get peer
535 * from vdev peer list
536 * @obj_list: peer object list
537 * @vdev_obj: vdev object mgr substructure
538 * @dbg_id: id of the caller
539 *
540 * API to finds peer object pointer by vdev from peer hash list for a node
541 * which is in logically deleted state
542 *
543 * Caller to free the list allocated in this function
544 *
545 * Return: list of peer pointers
546 * NULL on FAILURE
547 */
548static qdf_list_t *wlan_obj_vdev_populate_logically_del_peerlist(
549 qdf_list_t *obj_list,
550 struct wlan_objmgr_vdev_objmgr *vdev_obj,
551 wlan_objmgr_ref_dbgid dbg_id)
552{
553 struct wlan_objmgr_peer *peer;
554 struct wlan_objmgr_peer *peer_next;
555 struct wlan_logically_del_peer *peer_list;
556 qdf_list_t *logical_del_peerlist;
557 bool lock_released = false;
558
559 logical_del_peerlist = qdf_mem_malloc(sizeof(*logical_del_peerlist));
560 if (!logical_del_peerlist)
561 return NULL;
562
563 qdf_list_create(logical_del_peerlist, vdev_obj->max_peer_count);
564
565 peer = wlan_vdev_peer_list_peek_head(obj_list);
566 while (peer) {
567 wlan_peer_obj_lock(peer);
568 peer_next = wlan_peer_get_next_peer_of_vdev(obj_list, peer);
569 if (peer->obj_state == WLAN_OBJ_STATE_LOGICALLY_DELETED &&
570 qdf_atomic_read(&peer->peer_objmgr.ref_cnt)) {
571 wlan_objmgr_peer_get_ref(peer, dbg_id);
572 wlan_peer_obj_unlock(peer);
573 lock_released = true;
574
575 peer_list = qdf_mem_malloc(sizeof(*peer_list));
576 if (!peer_list) {
577 wlan_objmgr_peer_release_ref(peer, dbg_id);
578 WLAN_OBJMGR_BUG(0);
579 break;
580 }
581
582 peer_list->peer = peer;
583 qdf_list_insert_front(logical_del_peerlist,
584 &peer_list->list);
585 }
586
587 if (!lock_released)
588 wlan_peer_obj_unlock(peer);
589
590 peer = peer_next;
591 lock_released = false;
592 }
593
594 /* Not found, return NULL */
595 if (qdf_list_empty(logical_del_peerlist)) {
596 qdf_mem_free(logical_del_peerlist);
597 return NULL;
598 }
599
600 return logical_del_peerlist;
601}
602
603qdf_list_t *wlan_objmgr_vdev_get_log_del_peer_list(
604 struct wlan_objmgr_vdev *vdev,
605 wlan_objmgr_ref_dbgid dbg_id)
606{
607 qdf_list_t *peer_list;
608 qdf_list_t *log_del_peer_list = NULL;
609
610 if (vdev->obj_state != WLAN_OBJ_STATE_CREATED) {
611 obj_mgr_err("Invalid state vdev:%d state:%d",
612 wlan_vdev_get_id(vdev), vdev->obj_state);
613 return NULL;
614 }
615
616 wlan_vdev_obj_lock(vdev);
617 if (vdev->vdev_objmgr.wlan_peer_count == 0) {
618 wlan_vdev_obj_unlock(vdev);
619 return NULL;
620 }
621
622 wlan_objmgr_vdev_get_ref(vdev, dbg_id);
623 peer_list = &vdev->vdev_objmgr.wlan_peer_list;
624 if (peer_list) {
625 log_del_peer_list =
626 wlan_obj_vdev_populate_logically_del_peerlist(
627 peer_list, &vdev->vdev_objmgr,
628 dbg_id);
629 }
630
631 wlan_objmgr_vdev_release_ref(vdev, dbg_id);
632 wlan_vdev_obj_unlock(vdev);
633
634 return log_del_peer_list;
635}
636
Soumya Bhatdd734872016-12-29 16:21:43 +0530637QDF_STATUS wlan_objmgr_trigger_vdev_comp_priv_object_creation(
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530638 struct wlan_objmgr_vdev *vdev,
639 enum wlan_umac_comp_id id)
640{
641 wlan_objmgr_vdev_create_handler handler;
642 void *arg;
643 QDF_STATUS obj_status = QDF_STATUS_SUCCESS;
644
645 /* Component id is invalid */
646 if (id >= WLAN_UMAC_MAX_COMPONENTS)
647 return QDF_STATUS_MAXCOMP_FAIL;
648
649 wlan_vdev_obj_lock(vdev);
650 /*
651 * If component object is already created, delete old
652 * component object, then invoke creation
653 */
Jeff Johnsondcb27692019-03-20 12:11:48 -0700654 if (vdev->vdev_comp_priv_obj[id]) {
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530655 wlan_vdev_obj_unlock(vdev);
656 return QDF_STATUS_E_FAILURE;
657 }
658 wlan_vdev_obj_unlock(vdev);
659
660 /* Invoke registered create handlers */
661 handler = g_umac_glb_obj->vdev_create_handler[id];
662 arg = g_umac_glb_obj->vdev_create_handler_arg[id];
Jeff Johnsondcb27692019-03-20 12:11:48 -0700663 if (handler)
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530664 vdev->obj_status[id] = handler(vdev, arg);
665 else
666 return QDF_STATUS_E_FAILURE;
667
668 /* If object status is created, then only handle this object status */
669 if (vdev->obj_state == WLAN_OBJ_STATE_CREATED) {
670 /* Derive object status */
671 obj_status = wlan_objmgr_vdev_object_status(vdev);
672 /* Move PDEV object state to Partially created state */
673 if (obj_status == QDF_STATUS_COMP_ASYNC) {
674 /*TODO atomic */
675 vdev->obj_state = WLAN_OBJ_STATE_PARTIALLY_CREATED;
676 }
677 }
678 return obj_status;
679}
680
Soumya Bhatdd734872016-12-29 16:21:43 +0530681QDF_STATUS wlan_objmgr_trigger_vdev_comp_priv_object_deletion(
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530682 struct wlan_objmgr_vdev *vdev,
683 enum wlan_umac_comp_id id)
684{
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530685 wlan_objmgr_vdev_destroy_handler handler;
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530686 void *arg;
687 QDF_STATUS obj_status = QDF_STATUS_SUCCESS;
688
689 /* component id is invalid */
690 if (id >= WLAN_UMAC_MAX_COMPONENTS)
691 return QDF_STATUS_MAXCOMP_FAIL;
692
693 wlan_vdev_obj_lock(vdev);
694 /* Component object was never created, invalid operation */
Jeff Johnsondcb27692019-03-20 12:11:48 -0700695 if (!vdev->vdev_comp_priv_obj[id]) {
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530696 wlan_vdev_obj_unlock(vdev);
697 return QDF_STATUS_E_FAILURE;
698 }
699 wlan_vdev_obj_unlock(vdev);
700
701 /* Invoke registered create handlers */
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530702 handler = g_umac_glb_obj->vdev_destroy_handler[id];
703 arg = g_umac_glb_obj->vdev_destroy_handler_arg[id];
Jeff Johnsondcb27692019-03-20 12:11:48 -0700704 if (handler)
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530705 vdev->obj_status[id] = handler(vdev, arg);
706 else
707 return QDF_STATUS_E_FAILURE;
708
709 /* If object status is created, then only handle this object status */
710 if (vdev->obj_state == WLAN_OBJ_STATE_CREATED) {
711 obj_status = wlan_objmgr_vdev_object_status(vdev);
712 /* move object state to DEL progress */
713 if (obj_status == QDF_STATUS_COMP_ASYNC)
714 vdev->obj_state = WLAN_OBJ_STATE_COMP_DEL_PROGRESS;
715 }
716 return obj_status;
717}
718
719
720
721static void wlan_obj_vdev_peerlist_add_tail(qdf_list_t *obj_list,
722 struct wlan_objmgr_peer *obj)
723{
724 qdf_list_insert_back(obj_list, &obj->vdev_peer);
725}
726
727static QDF_STATUS wlan_obj_vdev_peerlist_remove_peer(qdf_list_t *obj_list,
728 struct wlan_objmgr_peer *peer)
729{
730 qdf_list_node_t *vdev_node = NULL;
731
Jeff Johnsondcb27692019-03-20 12:11:48 -0700732 if (!peer)
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530733 return QDF_STATUS_E_FAILURE;
734 /* get vdev list node element */
735 vdev_node = &peer->vdev_peer;
736 /* list is empty, return failure */
737 if (qdf_list_remove_node(obj_list, vdev_node) != QDF_STATUS_SUCCESS)
738 return QDF_STATUS_E_FAILURE;
739
740 return QDF_STATUS_SUCCESS;
741}
742
743QDF_STATUS wlan_objmgr_vdev_peer_attach(struct wlan_objmgr_vdev *vdev,
744 struct wlan_objmgr_peer *peer)
745{
746 struct wlan_objmgr_vdev_objmgr *objmgr = &vdev->vdev_objmgr;
Srinivas Pitla4a3f4862017-07-19 14:18:48 +0530747 struct wlan_objmgr_pdev *pdev;
wadesong73deb9a2018-04-09 12:51:25 +0800748 enum QDF_OPMODE opmode;
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530749
750 wlan_vdev_obj_lock(vdev);
Srinivas Pitla4a3f4862017-07-19 14:18:48 +0530751 pdev = wlan_vdev_get_pdev(vdev);
Vivekadbfaa72018-05-11 13:02:00 +0530752 /* If Max VDEV peer count exceeds, return failure */
753 if (peer->peer_mlme.peer_type != WLAN_PEER_STA_TEMP) {
754 if (objmgr->wlan_peer_count >= objmgr->max_peer_count) {
755 wlan_vdev_obj_unlock(vdev);
756 return QDF_STATUS_E_FAILURE;
757 }
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530758 }
Srinivas Pitlafd368552018-04-04 14:21:12 +0530759 wlan_vdev_obj_unlock(vdev);
Srinivas Pitla9578a902018-03-20 20:57:32 +0530760
Vivekadbfaa72018-05-11 13:02:00 +0530761 /* If Max PDEV peer count exceeds, return failure */
Srinivas Pitla9578a902018-03-20 20:57:32 +0530762 wlan_pdev_obj_lock(pdev);
Vivekadbfaa72018-05-11 13:02:00 +0530763 if (peer->peer_mlme.peer_type == WLAN_PEER_STA_TEMP) {
764 if (wlan_pdev_get_temp_peer_count(pdev) >=
765 WLAN_MAX_PDEV_TEMP_PEERS) {
766 wlan_pdev_obj_unlock(pdev);
767 return QDF_STATUS_E_FAILURE;
768 }
769 } else {
770 if (wlan_pdev_get_peer_count(pdev) >=
Srinivas Pitla9578a902018-03-20 20:57:32 +0530771 wlan_pdev_get_max_peer_count(pdev)) {
Vivekadbfaa72018-05-11 13:02:00 +0530772 wlan_pdev_obj_unlock(pdev);
773 return QDF_STATUS_E_FAILURE;
774 }
Srinivas Pitla9578a902018-03-20 20:57:32 +0530775 }
776
Vivekadbfaa72018-05-11 13:02:00 +0530777 if (peer->peer_mlme.peer_type == WLAN_PEER_STA_TEMP)
778 wlan_pdev_incr_temp_peer_count(wlan_vdev_get_pdev(vdev));
779 else
780 wlan_pdev_incr_peer_count(wlan_vdev_get_pdev(vdev));
Srinivas Pitla9578a902018-03-20 20:57:32 +0530781 wlan_pdev_obj_unlock(pdev);
Srinivas Pitlafd368552018-04-04 14:21:12 +0530782
783 wlan_vdev_obj_lock(vdev);
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530784 /* Add peer to vdev's peer list */
785 wlan_obj_vdev_peerlist_add_tail(&objmgr->wlan_peer_list, peer);
786 objmgr->wlan_peer_count++;
787
Ashok Ponnaiahb6962212017-07-31 10:12:57 +0530788 if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer),
789 wlan_vdev_mlme_get_macaddr(vdev)) ==
790 QDF_STATUS_SUCCESS) {
791 /*
792 * if peer mac address and vdev mac address match, set
793 * this peer as self peer
794 */
795 wlan_vdev_set_selfpeer(vdev, peer);
wadesong73deb9a2018-04-09 12:51:25 +0800796 opmode = wlan_vdev_mlme_get_opmode(vdev);
Ashok Ponnaiahb6962212017-07-31 10:12:57 +0530797 /* For AP mode, self peer and BSS peer are same */
Alan Chenbf06e912019-07-22 11:23:25 -0700798 if ((opmode == QDF_SAP_MODE) ||
799 (opmode == QDF_P2P_GO_MODE) ||
800 (opmode == QDF_NDI_MODE))
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530801 wlan_vdev_set_bsspeer(vdev, peer);
802 }
Ashok Ponnaiahb6962212017-07-31 10:12:57 +0530803 /* set BSS peer for sta */
Bala Venkateshb9669102018-11-16 15:30:26 +0530804 if ((wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE ||
805 wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_CLIENT_MODE) &&
806 (wlan_peer_get_peer_type(peer) == WLAN_PEER_AP ||
807 wlan_peer_get_peer_type(peer) == WLAN_PEER_P2P_GO))
Ashok Ponnaiahb6962212017-07-31 10:12:57 +0530808 wlan_vdev_set_bsspeer(vdev, peer);
809
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530810 /* Increment vdev ref count to make sure it won't be destroyed before */
811 wlan_objmgr_vdev_get_ref(vdev, WLAN_OBJMGR_ID);
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530812 wlan_vdev_obj_unlock(vdev);
813 return QDF_STATUS_SUCCESS;
814}
815
816QDF_STATUS wlan_objmgr_vdev_peer_detach(struct wlan_objmgr_vdev *vdev,
817 struct wlan_objmgr_peer *peer)
818{
819 struct wlan_objmgr_vdev_objmgr *objmgr = &vdev->vdev_objmgr;
Srinivas Pitla9578a902018-03-20 20:57:32 +0530820 struct wlan_objmgr_pdev *pdev;
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530821
822 wlan_vdev_obj_lock(vdev);
823 /* if peer count is 0, return failure */
824 if (objmgr->wlan_peer_count == 0) {
825 wlan_vdev_obj_unlock(vdev);
826 return QDF_STATUS_E_FAILURE;
827 }
Mukul Sharmad10b2692017-02-17 22:33:13 +0530828
Abhinav Kumar8b51c232019-07-12 15:00:24 +0530829 if (wlan_vdev_get_selfpeer(vdev) == peer) {
830 /*
831 * There might be instances where new node is created
832 * before deleting existing node, in which case selfpeer
833 * will be pointing to the new node. So set selfpeer to
834 * NULL only if vdev->vdev_objmgr.self_peer is pointing
835 * to the peer processed for deletion
836 */
837 wlan_vdev_set_selfpeer(vdev, NULL);
838 }
Mukul Sharmad10b2692017-02-17 22:33:13 +0530839
Abhinav Kumar8b51c232019-07-12 15:00:24 +0530840 if (wlan_vdev_get_bsspeer(vdev) == peer) {
841 /*
842 * There might be instances where new node is created
843 * before deleting existing node, in which case bsspeer
844 * in vdev will be pointing to the new node. So set
845 * bsspeer to NULL only if vdev->vdev_objmgr.bss_peer is
846 * pointing to the peer processed for deletion
847 */
848 wlan_vdev_set_bsspeer(vdev, NULL);
Mukul Sharmad10b2692017-02-17 22:33:13 +0530849 }
850
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530851 /* remove peer from vdev's peer list */
852 if (wlan_obj_vdev_peerlist_remove_peer(&objmgr->wlan_peer_list, peer)
853 == QDF_STATUS_E_FAILURE) {
854 wlan_vdev_obj_unlock(vdev);
855 return QDF_STATUS_E_FAILURE;
856 }
857 /* decrement peer count */
858 objmgr->wlan_peer_count--;
Srinivas Pitla9578a902018-03-20 20:57:32 +0530859 /* decrement pdev peer count */
860 pdev = wlan_vdev_get_pdev(vdev);
Srinivas Pitlafd368552018-04-04 14:21:12 +0530861 wlan_vdev_obj_unlock(vdev);
862
Srinivas Pitla9578a902018-03-20 20:57:32 +0530863 wlan_pdev_obj_lock(pdev);
Vivekadbfaa72018-05-11 13:02:00 +0530864 if (peer->peer_mlme.peer_type == WLAN_PEER_STA_TEMP)
865 wlan_pdev_decr_temp_peer_count(pdev);
866 else
867 wlan_pdev_decr_peer_count(pdev);
Srinivas Pitla9578a902018-03-20 20:57:32 +0530868 wlan_pdev_obj_unlock(pdev);
869
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530870 /* decrement vdev ref count after peer released its reference */
871 wlan_objmgr_vdev_release_ref(vdev, WLAN_OBJMGR_ID);
Srinivas Pitlafa5290f2016-10-17 16:40:37 +0530872 return QDF_STATUS_SUCCESS;
873}
874
Abhishek Singh7528ff32019-05-01 09:54:48 +0530875struct wlan_objmgr_peer *wlan_objmgr_vdev_try_get_bsspeer(
876 struct wlan_objmgr_vdev *vdev,
877 wlan_objmgr_ref_dbgid id)
878{
879 struct wlan_objmgr_peer *peer;
880 QDF_STATUS status = QDF_STATUS_E_EMPTY;
881
882 if (!vdev)
883 return NULL;
884
885 wlan_vdev_obj_lock(vdev);
886 peer = wlan_vdev_get_bsspeer(vdev);
887 if (peer)
888 status = wlan_objmgr_peer_try_get_ref(peer, id);
889 wlan_vdev_obj_unlock(vdev);
890
891 if (QDF_IS_STATUS_SUCCESS(status))
892 return peer;
893
894 return NULL;
895}
896
Srinivas Pitla1a2ef8c2017-01-04 16:48:00 +0530897void *wlan_objmgr_vdev_get_comp_private_obj(
898 struct wlan_objmgr_vdev *vdev,
899 enum wlan_umac_comp_id id)
900{
901 void *comp_priv_obj;
902
Srinivas Pitla1a2ef8c2017-01-04 16:48:00 +0530903 /* component id is invalid */
904 if (id >= WLAN_UMAC_MAX_COMPONENTS) {
905 QDF_BUG(0);
906 return NULL;
907 }
908
Jeff Johnsondcb27692019-03-20 12:11:48 -0700909 if (!vdev) {
Srinivas Pitla1a2ef8c2017-01-04 16:48:00 +0530910 QDF_BUG(0);
911 return NULL;
912 }
913
914 comp_priv_obj = vdev->vdev_comp_priv_obj[id];
915
916 return comp_priv_obj;
917}
Manikandan Mohan0f3c99b2018-03-01 16:22:44 -0800918qdf_export_symbol(wlan_objmgr_vdev_get_comp_private_obj);
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530919
Vivek8ed2fe92017-09-15 18:34:49 +0530920void wlan_objmgr_vdev_get_ref(struct wlan_objmgr_vdev *vdev,
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530921 wlan_objmgr_ref_dbgid id)
922{
Jeff Johnsondcb27692019-03-20 12:11:48 -0700923 if (!vdev) {
Vivek8ed2fe92017-09-15 18:34:49 +0530924 obj_mgr_err("vdev obj is NULL for id:%d", id);
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530925 QDF_ASSERT(0);
Vivek8ed2fe92017-09-15 18:34:49 +0530926 return;
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530927 }
928 /* Increment ref count */
929 qdf_atomic_inc(&vdev->vdev_objmgr.ref_cnt);
Srinivas Pitla2f8f8b52017-02-08 12:55:36 +0530930 qdf_atomic_inc(&vdev->vdev_objmgr.ref_id_dbg[id]);
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530931
Vivek8ed2fe92017-09-15 18:34:49 +0530932 return;
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530933}
Manikandan Mohan0f3c99b2018-03-01 16:22:44 -0800934qdf_export_symbol(wlan_objmgr_vdev_get_ref);
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530935
936QDF_STATUS wlan_objmgr_vdev_try_get_ref(struct wlan_objmgr_vdev *vdev,
937 wlan_objmgr_ref_dbgid id)
938{
Vivek8ed2fe92017-09-15 18:34:49 +0530939 uint8_t vdev_id;
Vivek2c86b212017-06-05 00:02:11 +0530940
Jeff Johnsondcb27692019-03-20 12:11:48 -0700941 if (!vdev) {
Vivek8ed2fe92017-09-15 18:34:49 +0530942 obj_mgr_err("vdev obj is NULL for id:%d", id);
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530943 QDF_ASSERT(0);
944 return QDF_STATUS_E_FAILURE;
945 }
946
Vivek8ed2fe92017-09-15 18:34:49 +0530947 wlan_vdev_obj_lock(vdev);
948 vdev_id = wlan_vdev_get_id(vdev);
Srinivas Pitla86db6ab2018-01-16 10:20:38 +0530949 if (vdev->obj_state != WLAN_OBJ_STATE_CREATED) {
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530950 wlan_vdev_obj_unlock(vdev);
Srinivas Pitla68564822017-06-28 12:33:07 +0530951 if (vdev->vdev_objmgr.print_cnt++ <=
952 WLAN_OBJMGR_RATELIMIT_THRESH)
Srinivas Pitla86db6ab2018-01-16 10:20:38 +0530953 obj_mgr_err(
954 "[Ref id: %d] vdev(%d) is not in Created state(%d)",
955 id, vdev_id, vdev->obj_state);
Srinivas Pitla68564822017-06-28 12:33:07 +0530956
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530957 return QDF_STATUS_E_RESOURCES;
958 }
959
960 /* Increment ref count */
961 wlan_objmgr_vdev_get_ref(vdev, id);
Vivek8ed2fe92017-09-15 18:34:49 +0530962 wlan_vdev_obj_unlock(vdev);
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530963
964 return QDF_STATUS_SUCCESS;
965}
Manikandan Mohan0f3c99b2018-03-01 16:22:44 -0800966qdf_export_symbol(wlan_objmgr_vdev_try_get_ref);
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530967
Vivek8ed2fe92017-09-15 18:34:49 +0530968void wlan_objmgr_vdev_release_ref(struct wlan_objmgr_vdev *vdev,
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530969 wlan_objmgr_ref_dbgid id)
970{
Vivek8ed2fe92017-09-15 18:34:49 +0530971 uint8_t vdev_id;
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530972
Jeff Johnsondcb27692019-03-20 12:11:48 -0700973 if (!vdev) {
Vivek8ed2fe92017-09-15 18:34:49 +0530974 obj_mgr_err("vdev obj is NULL for id:%d", id);
Vivekea368412017-07-28 12:49:17 +0530975 QDF_ASSERT(0);
Vivek8ed2fe92017-09-15 18:34:49 +0530976 return;
Vivekea368412017-07-28 12:49:17 +0530977 }
Vivek2c86b212017-06-05 00:02:11 +0530978
Vivek8ed2fe92017-09-15 18:34:49 +0530979 vdev_id = wlan_vdev_get_id(vdev);
980
Srinivas Pitla2f8f8b52017-02-08 12:55:36 +0530981 if (!qdf_atomic_read(&vdev->vdev_objmgr.ref_id_dbg[id])) {
Santosh Anbu659379a2019-09-26 15:34:13 +0530982 obj_mgr_alert("vdev (id:%d)ref cnt was not taken by %d",
983 vdev_id, id);
Abhinav Kumar97919572018-06-15 16:46:30 +0530984 wlan_objmgr_print_ref_ids(vdev->vdev_objmgr.ref_id_dbg,
985 QDF_TRACE_LEVEL_FATAL);
Srinivas Pitla2f8f8b52017-02-08 12:55:36 +0530986 WLAN_OBJMGR_BUG(0);
Vivek16ad4752019-04-29 10:50:24 +0530987 return;
Srinivas Pitla2f8f8b52017-02-08 12:55:36 +0530988 }
989
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530990 if (!qdf_atomic_read(&vdev->vdev_objmgr.ref_cnt)) {
Santosh Anbu659379a2019-09-26 15:34:13 +0530991 obj_mgr_alert("vdev ref cnt is 0");
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530992 WLAN_OBJMGR_BUG(0);
Vivek8ed2fe92017-09-15 18:34:49 +0530993 return;
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530994 }
Srinivas Pitla2f8f8b52017-02-08 12:55:36 +0530995 qdf_atomic_dec(&vdev->vdev_objmgr.ref_id_dbg[id]);
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530996
997 /* Decrement ref count, free vdev, if ref count == 0 */
998 if (qdf_atomic_dec_and_test(&vdev->vdev_objmgr.ref_cnt))
999 wlan_objmgr_vdev_obj_destroy(vdev);
1000
Vivek8ed2fe92017-09-15 18:34:49 +05301001 return;
Srinivas Pitla10aa60c2017-02-08 12:55:16 +05301002}
Manikandan Mohan0f3c99b2018-03-01 16:22:44 -08001003qdf_export_symbol(wlan_objmgr_vdev_release_ref);
Rajeev Kumar Sirasanagandlad8d18f12017-06-08 18:12:50 +05301004
Srinivas Pitla77e17912018-04-11 21:59:08 +05301005struct wlan_objmgr_vdev *wlan_pdev_vdev_list_peek_active_head(
1006 struct wlan_objmgr_pdev *pdev,
1007 qdf_list_t *vdev_list, wlan_objmgr_ref_dbgid dbg_id)
1008{
1009 struct wlan_objmgr_vdev *vdev;
1010 qdf_list_node_t *node = NULL;
1011 qdf_list_node_t *prev_node = NULL;
1012
1013 wlan_pdev_obj_lock(pdev);
1014
1015 if (qdf_list_peek_front(vdev_list, &node) != QDF_STATUS_SUCCESS) {
1016 wlan_pdev_obj_unlock(pdev);
1017 return NULL;
1018 }
1019
1020 do {
1021 vdev = qdf_container_of(node, struct wlan_objmgr_vdev,
1022 vdev_node);
1023 if (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) ==
1024 QDF_STATUS_SUCCESS) {
1025 wlan_pdev_obj_unlock(pdev);
1026 return vdev;
1027 }
1028
1029 prev_node = node;
1030 } while (qdf_list_peek_next(vdev_list, prev_node, &node) ==
1031 QDF_STATUS_SUCCESS);
1032
1033 wlan_pdev_obj_unlock(pdev);
1034
1035 return NULL;
1036}
1037
bingsb2e00f92019-08-13 10:23:43 +08001038struct wlan_objmgr_vdev *wlan_pdev_peek_active_first_vdev(
1039 struct wlan_objmgr_pdev *pdev,
1040 wlan_objmgr_ref_dbgid dbg_id)
1041{
1042 struct wlan_objmgr_pdev_objmgr *objmgr = &pdev->pdev_objmgr;
1043 qdf_list_t *vdev_list;
1044
1045 /* VDEV list */
1046 vdev_list = &objmgr->wlan_vdev_list;
1047
1048 return wlan_pdev_vdev_list_peek_active_head(pdev, vdev_list,
1049 dbg_id);
1050}
1051
Srinivas Pitla77e17912018-04-11 21:59:08 +05301052struct wlan_objmgr_vdev *wlan_vdev_get_next_active_vdev_of_pdev(
1053 struct wlan_objmgr_pdev *pdev,
1054 qdf_list_t *vdev_list,
1055 struct wlan_objmgr_vdev *vdev,
1056 wlan_objmgr_ref_dbgid dbg_id)
1057{
1058 struct wlan_objmgr_vdev *vdev_next;
1059 qdf_list_node_t *node = &vdev->vdev_node;
1060 qdf_list_node_t *prev_node = NULL;
1061
Jeff Johnsondcb27692019-03-20 12:11:48 -07001062 if (!node)
Srinivas Pitla77e17912018-04-11 21:59:08 +05301063 return NULL;
1064
1065 wlan_pdev_obj_lock(pdev);
1066 prev_node = node;
1067 while (qdf_list_peek_next(vdev_list, prev_node, &node) ==
1068 QDF_STATUS_SUCCESS) {
1069 vdev_next = qdf_container_of(node, struct wlan_objmgr_vdev,
1070 vdev_node);
1071 if (wlan_objmgr_vdev_try_get_ref(vdev_next, dbg_id) ==
1072 QDF_STATUS_SUCCESS) {
1073 wlan_pdev_obj_unlock(pdev);
1074 return vdev_next;
1075 }
1076
1077 prev_node = node;
1078 }
1079 wlan_pdev_obj_unlock(pdev);
1080
1081 return NULL;
1082}
1083
Vivek4ad877f2019-09-18 16:49:10 +05301084#ifdef WLAN_OBJMGR_DEBUG
1085void wlan_print_vdev_info(struct wlan_objmgr_vdev *vdev)
1086{
1087 struct wlan_objmgr_vdev_objmgr *vdev_objmgr;
1088 uint32_t ref_cnt;
1089
1090 vdev_objmgr = &vdev->vdev_objmgr;
1091
1092 ref_cnt = qdf_atomic_read(&vdev_objmgr->ref_cnt);
1093
1094 obj_mgr_debug("vdev: %pK", vdev);
1095 obj_mgr_debug("vdev_id: %d", vdev_objmgr->vdev_id);
1096 obj_mgr_debug("print_cnt: %d", vdev_objmgr->print_cnt);
1097 obj_mgr_debug("wlan_pdev: %pK", vdev_objmgr->wlan_pdev);
1098 obj_mgr_debug("ref_cnt: %d", ref_cnt);
1099}
1100
1101qdf_export_symbol(wlan_print_vdev_info);
1102#endif
1103