blob: 9d8f4c882298dc272a165369359b63345f5f76d0 [file] [log] [blame]
Krunal Sonic4e35922017-02-01 14:59:01 -08001/*
2 * Copyright (c) 2017 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: wlan_serialization_main.c
21 * This file defines the important functions pertinent to
22 * serialization to initialize and de-initialize the
23 * component.
24 */
25#include "qdf_status.h"
26#include "qdf_list.h"
27#include "wlan_objmgr_cmn.h"
28#include "wlan_objmgr_global_obj.h"
29#include "wlan_objmgr_psoc_obj.h"
30#include "wlan_serialization_main_i.h"
31#include "wlan_serialization_rules_i.h"
Krunal Soni16641b12017-02-01 16:07:09 -080032#include "wlan_serialization_utils_i.h"
Krunal Sonic4e35922017-02-01 14:59:01 -080033
Krunal Sonibe546452017-08-28 11:28:25 -070034struct serialization_legacy_callback ser_legacy_cb;
35
Krunal Sonic4e35922017-02-01 14:59:01 -080036QDF_STATUS wlan_serialization_psoc_close(struct wlan_objmgr_psoc *psoc)
37{
38 QDF_STATUS status;
39 struct wlan_serialization_psoc_priv_obj *ser_soc_obj =
40 wlan_serialization_get_psoc_priv_obj(psoc);
41
Krunal Soni8a583432017-02-05 15:54:02 -080042 if (!ser_soc_obj) {
43 serialization_err("invalid ser_soc_obj");
44 return QDF_STATUS_E_FAILURE;
45 }
Krunal Soni16641b12017-02-01 16:07:09 -080046 /* clean up all timers before exiting */
47 status = wlan_serialization_cleanup_all_timers(ser_soc_obj);
48 if (status != QDF_STATUS_SUCCESS)
49 serialization_err("ser cleanning up all timer failed");
50
Krunal Sonic4e35922017-02-01 14:59:01 -080051 qdf_mem_free(ser_soc_obj->timers);
52 ser_soc_obj->timers = NULL;
53 ser_soc_obj->max_active_cmds = 0;
Krunal Sonic4e35922017-02-01 14:59:01 -080054
55 return status;
56}
57
58QDF_STATUS wlan_serialization_psoc_open(struct wlan_objmgr_psoc *psoc)
59{
60 uint8_t pdev_count;
Krunal Sonic4e35922017-02-01 14:59:01 -080061 struct wlan_serialization_psoc_priv_obj *ser_soc_obj =
62 wlan_serialization_get_psoc_priv_obj(psoc);
63
Krunal Soni8a583432017-02-05 15:54:02 -080064 if (!ser_soc_obj) {
65 serialization_err("invalid ser_soc_obj");
66 return QDF_STATUS_E_FAILURE;
67 }
Krunal Sonic4e35922017-02-01 14:59:01 -080068 /* TODO:Get WLAN_SERIALIZATION_MAX_ACTIVE_SCAN_CMDS frm service ready */
69 pdev_count = wlan_psoc_get_pdev_count(psoc);
70 ser_soc_obj->max_active_cmds = WLAN_SERIALIZATION_MAX_ACTIVE_SCAN_CMDS +
71 pdev_count;
72 ser_soc_obj->timers =
73 qdf_mem_malloc(sizeof(struct wlan_serialization_timer) *
74 ser_soc_obj->max_active_cmds);
75 if (NULL == ser_soc_obj->timers) {
76 serialization_alert("Mem alloc failed for ser timers");
77 return QDF_STATUS_E_NOMEM;
78 }
Krunal Sonic4e35922017-02-01 14:59:01 -080079
Anish Nataraj089fd7c2017-02-17 18:47:19 +053080 return QDF_STATUS_SUCCESS;
Krunal Sonic4e35922017-02-01 14:59:01 -080081}
82
Krunal Sonibe546452017-08-28 11:28:25 -070083/**
84 * wlan_serialization_psoc_obj_create_notification() - PSOC obj create callback
85 * @psoc: PSOC object
86 * @arg_list: Variable argument list
87 *
88 * This callback is registered with object manager during initialization and
89 * when obj manager gets its turn to create the object, it would notify each
90 * component with the corresponding callback registered to inform the
91 * completion of the creation of the respective object.
92 *
93 * Return: QDF Status
94 */
95static QDF_STATUS wlan_serialization_psoc_obj_create_notification(
Krunal Sonic4e35922017-02-01 14:59:01 -080096 struct wlan_objmgr_psoc *psoc, void *arg_list)
97{
98 struct wlan_serialization_psoc_priv_obj *soc_ser_obj;
99
100 soc_ser_obj =
101 qdf_mem_malloc(sizeof(*soc_ser_obj));
102 if (NULL == soc_ser_obj) {
103 serialization_alert("Mem alloc failed for ser psoc priv obj");
104 return QDF_STATUS_E_NOMEM;
105 }
106 wlan_objmgr_psoc_component_obj_attach(psoc,
Krunal Soni8a583432017-02-05 15:54:02 -0800107 WLAN_UMAC_COMP_SERIALIZATION, soc_ser_obj,
Krunal Sonic4e35922017-02-01 14:59:01 -0800108 QDF_STATUS_SUCCESS);
109 serialization_info("ser psoc obj created");
110
111 return QDF_STATUS_SUCCESS;
112}
113
114/**
115 * wlan_serialization_destroy_cmd_pool() - Destroy the global cmd pool
116 * @ser_pdev_obj: Serialization private pdev object
117 *
118 * Return: None
119 */
120static void wlan_serialization_destroy_cmd_pool(
121 struct wlan_serialization_pdev_priv_obj *ser_pdev_obj)
122{
123
124 qdf_list_node_t *node = NULL;
Krunal Soni16641b12017-02-01 16:07:09 -0800125 struct wlan_serialization_command_list *cmd_list;
Krunal Sonic4e35922017-02-01 14:59:01 -0800126
127 while (!qdf_list_empty(&ser_pdev_obj->global_cmd_pool_list)) {
128 qdf_list_remove_front(&ser_pdev_obj->global_cmd_pool_list,
129 &node);
Krunal Soni16641b12017-02-01 16:07:09 -0800130 cmd_list = (struct wlan_serialization_command_list *)node;
Krunal Sonic4e35922017-02-01 14:59:01 -0800131 serialization_info("Node being freed from global pool %p",
Krunal Soni16641b12017-02-01 16:07:09 -0800132 cmd_list);
133 qdf_mem_free(cmd_list);
Krunal Sonic4e35922017-02-01 14:59:01 -0800134
135 }
136 qdf_list_destroy(&ser_pdev_obj->global_cmd_pool_list);
137}
138
139/**
140 * wlan_serialization_create_cmd_pool() - Create the global cmd pool
141 * @pdev: PDEV Object
142 * @ser_pdev_obj: Serialization private pdev object
143 *
144 * Global command pool of memory is created here.
145 * It is safe to allocate memory individually for each command rather than
146 * requesting for a huge chunk of memory at once.
147 *
148 * The individual command nodes allocated above will keep moving between
149 * the active, pending and global pool lists dynamically, but all the
150 * memory will be freed during driver unload only.
151 *
152 * Return: QDF Status
153 */
154static QDF_STATUS
155wlan_serialization_create_cmd_pool(struct wlan_objmgr_pdev *pdev,
156 struct wlan_serialization_pdev_priv_obj *ser_pdev_obj)
157{
158 struct wlan_serialization_command_list *cmd_list_ptr;
159 uint8_t i;
160
161 for (i = 0; i < WLAN_SERIALIZATION_MAX_GLOBAL_POOL_CMDS; i++) {
162 cmd_list_ptr = qdf_mem_malloc(sizeof(*cmd_list_ptr));
163 if (NULL == cmd_list_ptr) {
164 serialization_alert("Mem alloc failed for cmd node");
165 wlan_serialization_destroy_cmd_pool(ser_pdev_obj);
166 return QDF_STATUS_E_NOMEM;
167 }
168 qdf_list_insert_back(
169 &ser_pdev_obj->global_cmd_pool_list,
170 &cmd_list_ptr->node);
171 serialization_info("Created node at %p and inserted to pool",
172 cmd_list_ptr);
173 }
174
175 return QDF_STATUS_SUCCESS;
176}
177
Krunal Sonibe546452017-08-28 11:28:25 -0700178
179/**
180 * wlan_serialization_pdev_obj_create_notification() - PDEV obj create callback
181 * @pdev: PDEV object
182 * @arg_list: Variable argument list
183 *
184 * This callback is registered with object manager during initialization and
185 * when obj manager gets its turn to create the object, it would notify each
186 * component with the corresponding callback registered to inform the
187 * completion of the creation of the respective object.
188 *
189 * Return: QDF Status
190 */
191static QDF_STATUS wlan_serialization_pdev_obj_create_notification(
Krunal Sonic4e35922017-02-01 14:59:01 -0800192 struct wlan_objmgr_pdev *pdev, void *arg_list)
193{
194 struct wlan_serialization_pdev_priv_obj *ser_pdev_obj;
195 QDF_STATUS status;
196
197 ser_pdev_obj =
198 qdf_mem_malloc(sizeof(*ser_pdev_obj));
199 if (NULL == ser_pdev_obj) {
200 serialization_alert("Mem alloc failed for ser pdev obj");
201 return QDF_STATUS_E_NOMEM;
202 }
203 qdf_list_create(&ser_pdev_obj->active_list,
204 WLAN_SERIALIZATION_MAX_ACTIVE_CMDS);
205 qdf_list_create(&ser_pdev_obj->pending_list,
206 WLAN_SERIALIZATION_MAX_GLOBAL_POOL_CMDS);
207 qdf_list_create(&ser_pdev_obj->active_scan_list,
208 WLAN_SERIALIZATION_MAX_ACTIVE_SCAN_CMDS);
209 qdf_list_create(&ser_pdev_obj->pending_scan_list,
210 WLAN_SERIALIZATION_MAX_GLOBAL_POOL_CMDS);
211 qdf_list_create(&ser_pdev_obj->global_cmd_pool_list,
212 WLAN_SERIALIZATION_MAX_GLOBAL_POOL_CMDS);
213 status = wlan_serialization_create_cmd_pool(pdev, ser_pdev_obj);
214 if (status != QDF_STATUS_SUCCESS) {
215 serialization_err("ser_pdev_obj failed status %d", status);
216 return status;
217 }
218 status = wlan_objmgr_pdev_component_obj_attach(pdev,
Krunal Soni8a583432017-02-05 15:54:02 -0800219 WLAN_UMAC_COMP_SERIALIZATION, ser_pdev_obj,
Krunal Sonic4e35922017-02-01 14:59:01 -0800220 QDF_STATUS_SUCCESS);
221 if (status != QDF_STATUS_SUCCESS) {
222 serialization_err("serialization pdev obj attach failed");
223 return status;
224 }
225
226 return status;
227}
228
Krunal Sonibe546452017-08-28 11:28:25 -0700229/**
230 * wlan_serialization_psoc_obj_destroy_notification() - PSOC obj delete callback
231 * @psoc: PSOC object
232 * @arg_list: Variable argument list
233 *
234 * This callback is registered with object manager during initialization and
235 * when obj manager gets its turn to delete the object, it would notify each
236 * component with the corresponding callback registered to inform the
237 * completion of the deletion of the respective object.
238 *
239 * Return: QDF Status
240 */
241static QDF_STATUS wlan_serialization_psoc_obj_destroy_notification(
Krunal Sonic4e35922017-02-01 14:59:01 -0800242 struct wlan_objmgr_psoc *psoc, void *arg_list)
243{
244 QDF_STATUS status;
245 struct wlan_serialization_psoc_priv_obj *ser_soc_obj =
246 wlan_serialization_get_psoc_priv_obj(psoc);
247
248 if (NULL == ser_soc_obj) {
Krunal Soni8a583432017-02-05 15:54:02 -0800249 serialization_err("invalid ser_soc_obj");
Krunal Sonic4e35922017-02-01 14:59:01 -0800250 return QDF_STATUS_E_FAULT;
251 }
252 status = wlan_objmgr_psoc_component_obj_detach(psoc,
253 WLAN_UMAC_COMP_SERIALIZATION,
254 ser_soc_obj);
255 if (status != QDF_STATUS_SUCCESS)
256 serialization_err("ser psoc private obj detach failed");
257 serialization_info("ser psoc obj deleted with status %d", status);
258 qdf_mem_free(ser_soc_obj);
259
260 return status;
261}
262
Krunal Sonibe546452017-08-28 11:28:25 -0700263/**
264 * wlan_serialization_pdev_obj_destroy_notification() - PDEV obj delete callback
265 * @pdev: PDEV object
266 * @arg_list: Variable argument list
267 *
268 * This callback is registered with object manager during initialization and
269 * when obj manager gets its turn to delete the object, it would notify each
270 * component with the corresponding callback registered to inform the
271 * completion of the deletion of the respective object.
272 *
273 * Return: QDF Status
274 */
275static QDF_STATUS wlan_serialization_pdev_obj_destroy_notification(
Krunal Sonic4e35922017-02-01 14:59:01 -0800276 struct wlan_objmgr_pdev *pdev, void *arg_list)
277{
278 QDF_STATUS status;
279 struct wlan_serialization_pdev_priv_obj *ser_pdev_obj =
280 wlan_serialization_get_pdev_priv_obj(pdev);
281
282 status = wlan_objmgr_pdev_component_obj_detach(pdev,
Krunal Soni8a583432017-02-05 15:54:02 -0800283 WLAN_UMAC_COMP_SERIALIZATION, ser_pdev_obj);
Krunal Sonic4e35922017-02-01 14:59:01 -0800284 wlan_serialization_destroy_list(ser_pdev_obj,
285 &ser_pdev_obj->active_list);
286 wlan_serialization_destroy_list(ser_pdev_obj,
287 &ser_pdev_obj->pending_list);
288 wlan_serialization_destroy_list(ser_pdev_obj,
289 &ser_pdev_obj->active_scan_list);
290 wlan_serialization_destroy_list(ser_pdev_obj,
291 &ser_pdev_obj->pending_scan_list);
292 wlan_serialization_destroy_cmd_pool(ser_pdev_obj);
293 serialization_info("ser pdev obj deleted with status %d", status);
294 qdf_mem_free(ser_pdev_obj);
295
296 return status;
297}
298
Krunal Sonibe546452017-08-28 11:28:25 -0700299/**
300 * wlan_serialization_vdev_obj_create_notification() - VDEV obj create callback
301 * @vdev: VDEV object
302 * @arg_list: Variable argument list
303 *
304 * This callback is registered with object manager during initialization and
305 * when obj manager gets its turn to create the object, it would notify each
306 * component with the corresponding callback registered to inform the
307 * completion of the creation of the respective object.
308 *
309 * Return: QDF Status
310 */
311static QDF_STATUS wlan_serialization_vdev_obj_create_notification(
312 struct wlan_objmgr_vdev *vdev, void *arg_list)
313{
314 return QDF_STATUS_SUCCESS;
315}
316
317/**
318 * wlan_serialization_vdev_obj_destroy_notification() - vdev obj delete callback
319 * @vdev: VDEV object
320 * @arg_list: Variable argument list
321 *
322 * This callback is registered with object manager during initialization and
323 * when obj manager gets its turn to delete the object, it would notify each
324 * component with the corresponding callback registered to inform the
325 * completion of the deletion of the respective object.
326 *
327 * Return: QDF Status
328 */
329static QDF_STATUS wlan_serialization_vdev_obj_destroy_notification(
330 struct wlan_objmgr_vdev *vdev, void *arg_list)
331{
332 uint8_t vdev_id = wlan_vdev_get_id(vdev);
333
334 if (!ser_legacy_cb.serialization_purge_cmd_list)
335 return QDF_STATUS_SUCCESS;
336
337 serialization_debug("for vdev_id[%d] vdev[%p] flush all cmds",
338 vdev_id, vdev);
339 ser_legacy_cb.serialization_purge_cmd_list(wlan_vdev_get_psoc(vdev),
340 vdev, false, false, false, false, true);
341
342 return QDF_STATUS_SUCCESS;
343}
344
Krunal Sonic4e35922017-02-01 14:59:01 -0800345QDF_STATUS wlan_serialization_init(void)
346{
347 QDF_STATUS status = QDF_STATUS_SUCCESS;
348
349 status = wlan_objmgr_register_psoc_create_handler(
350 WLAN_UMAC_COMP_SERIALIZATION,
351 wlan_serialization_psoc_obj_create_notification, NULL);
352 if (status != QDF_STATUS_SUCCESS) {
353 serialization_err("Failed to reg soc ser obj create handler");
354 goto err_psoc_create;
355 }
356
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530357 status = wlan_objmgr_register_psoc_destroy_handler(
Krunal Sonic4e35922017-02-01 14:59:01 -0800358 WLAN_UMAC_COMP_SERIALIZATION,
359 wlan_serialization_psoc_obj_destroy_notification, NULL);
360 if (status != QDF_STATUS_SUCCESS) {
361 serialization_err("Failed to reg soc ser obj delete handler");
362 goto err_psoc_delete;
363 }
364
365 status = wlan_objmgr_register_pdev_create_handler(
366 WLAN_UMAC_COMP_SERIALIZATION,
367 wlan_serialization_pdev_obj_create_notification, NULL);
368 if (status != QDF_STATUS_SUCCESS) {
369 serialization_err("Failed to reg pdev ser obj create handler");
370 goto err_pdev_create;
371 }
372
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530373 status = wlan_objmgr_register_pdev_destroy_handler(
Krunal Sonic4e35922017-02-01 14:59:01 -0800374 WLAN_UMAC_COMP_SERIALIZATION,
375 wlan_serialization_pdev_obj_destroy_notification, NULL);
376 if (status != QDF_STATUS_SUCCESS) {
377 serialization_err("Failed to reg pdev ser obj delete handler");
378 goto err_pdev_delete;
379 }
380
Krunal Sonibe546452017-08-28 11:28:25 -0700381 status = wlan_objmgr_register_vdev_create_handler(
382 WLAN_UMAC_COMP_SERIALIZATION,
383 wlan_serialization_vdev_obj_create_notification, NULL);
384 if (status != QDF_STATUS_SUCCESS) {
385 serialization_err("Failed to reg vdev ser obj create handler");
386 goto err_vdev_create;
387 }
388
389 status = wlan_objmgr_register_vdev_destroy_handler(
390 WLAN_UMAC_COMP_SERIALIZATION,
391 wlan_serialization_vdev_obj_destroy_notification, NULL);
392 if (status != QDF_STATUS_SUCCESS) {
393 serialization_err("Failed to reg vdev ser obj delete handler");
394 goto err_vdev_delete;
395 }
Krunal Sonic4e35922017-02-01 14:59:01 -0800396 serialization_info("serialization handlers registered with obj mgr");
Krunal Sonibe546452017-08-28 11:28:25 -0700397 /*
398 * Initialize the structure so all callbacks are registered
399 * initially as NULL.
400 */
401 qdf_mem_zero(&ser_legacy_cb, sizeof(ser_legacy_cb));
Krunal Sonic4e35922017-02-01 14:59:01 -0800402
403 return QDF_STATUS_SUCCESS;
404
Krunal Sonibe546452017-08-28 11:28:25 -0700405err_vdev_delete:
406 wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_SERIALIZATION,
407 wlan_serialization_vdev_obj_create_notification, NULL);
408err_vdev_create:
409 wlan_objmgr_unregister_pdev_destroy_handler(
410 WLAN_UMAC_COMP_SERIALIZATION,
411 wlan_serialization_pdev_obj_destroy_notification, NULL);
Krunal Sonic4e35922017-02-01 14:59:01 -0800412err_pdev_delete:
413 wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_SERIALIZATION,
414 wlan_serialization_pdev_obj_create_notification, NULL);
415err_pdev_create:
Krunal Sonibe546452017-08-28 11:28:25 -0700416 wlan_objmgr_unregister_psoc_destroy_handler(
417 WLAN_UMAC_COMP_SERIALIZATION,
Krunal Sonic4e35922017-02-01 14:59:01 -0800418 wlan_serialization_psoc_obj_destroy_notification, NULL);
419err_psoc_delete:
420 wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_SERIALIZATION,
421 wlan_serialization_psoc_obj_create_notification, NULL);
422err_psoc_create:
423 return status;
424
425}
426
427QDF_STATUS wlan_serialization_deinit(void)
428{
429 QDF_STATUS status;
430 QDF_STATUS ret_status = QDF_STATUS_SUCCESS;
431
432 status = wlan_objmgr_unregister_psoc_create_handler(
433 WLAN_UMAC_COMP_SERIALIZATION,
434 wlan_serialization_psoc_obj_create_notification,
435 NULL);
436 if (status != QDF_STATUS_SUCCESS) {
437 serialization_err("unreg fail for psoc ser obj create notf:%d",
438 status);
439 ret_status = QDF_STATUS_E_FAILURE;
440 }
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530441 status = wlan_objmgr_unregister_psoc_destroy_handler(
Krunal Sonic4e35922017-02-01 14:59:01 -0800442 WLAN_UMAC_COMP_SERIALIZATION,
443 wlan_serialization_psoc_obj_destroy_notification,
444 NULL);
445 if (status != QDF_STATUS_SUCCESS) {
446 serialization_err("unreg fail for psoc ser obj destroy notf:%d",
447 status);
448 ret_status = QDF_STATUS_E_FAILURE;
449 }
450
451 status = wlan_objmgr_unregister_pdev_create_handler(
452 WLAN_UMAC_COMP_SERIALIZATION,
453 wlan_serialization_pdev_obj_create_notification,
454 NULL);
455 if (status != QDF_STATUS_SUCCESS) {
456 serialization_err("unreg fail for pdev ser obj create notf:%d",
457 status);
458 ret_status = QDF_STATUS_E_FAILURE;
459 }
460
Srinivas Pitla10aa60c2017-02-08 12:55:16 +0530461 status = wlan_objmgr_unregister_pdev_destroy_handler(
Krunal Sonic4e35922017-02-01 14:59:01 -0800462 WLAN_UMAC_COMP_SERIALIZATION,
463 wlan_serialization_pdev_obj_destroy_notification,
464 NULL);
465 if (status != QDF_STATUS_SUCCESS) {
466 serialization_err("unreg fail for pdev ser destory notf:%d",
467 status);
468 ret_status = QDF_STATUS_E_FAILURE;
469 }
470
471 serialization_alert("deregistered callbacks with obj mgr successfully");
Krunal Sonibe546452017-08-28 11:28:25 -0700472 /*
473 * Initialize the structure so all callbacks are registered
474 * initially as NULL.
475 */
476 qdf_mem_zero(&ser_legacy_cb, sizeof(ser_legacy_cb));
Krunal Sonic4e35922017-02-01 14:59:01 -0800477
478 return ret_status;
479}