1 /* 2 * Copyright (c) 2017-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 * DOC: wlan_serialization_legacy_api.c 20 * This file provides prototypes of the routines needed for the 21 * legacy mcl serialization to utilize the services provided by the 22 * serialization component. 23 */ 24 25 #include "wlan_serialization_legacy_api.h" 26 #include "wlan_serialization_main_i.h" 27 #include "wlan_serialization_utils_i.h" 28 #include "wlan_objmgr_vdev_obj.h" 29 #include "wlan_serialization_internal_i.h" 30 #include "wlan_serialization_scan_i.h" 31 #include "wlan_serialization_non_scan_i.h" 32 33 static struct wlan_objmgr_pdev *wlan_serialization_get_first_pdev( 34 struct wlan_objmgr_psoc *psoc) 35 { 36 struct wlan_objmgr_pdev *pdev; 37 uint8_t i = 0; 38 39 if (!psoc) { 40 ser_err("invalid psoc"); 41 return NULL; 42 } 43 for (i = 0; i < WLAN_UMAC_MAX_PDEVS; i++) { 44 pdev = wlan_objmgr_get_pdev_by_id(psoc, i, 45 WLAN_SERIALIZATION_ID); 46 if (pdev) 47 break; 48 } 49 50 return pdev; 51 } 52 53 static struct wlan_ser_pdev_obj * 54 wlan_serialization_get_pdev_priv_obj_using_psoc(struct wlan_objmgr_psoc *psoc) 55 { 56 struct wlan_objmgr_pdev *pdev = NULL; 57 struct wlan_ser_pdev_obj *ser_pdev_obj; 58 59 if (!psoc) { 60 ser_err("invalid psoc"); 61 return NULL; 62 } 63 64 pdev = wlan_serialization_get_first_pdev(psoc); 65 if (!pdev) { 66 ser_err("invalid pdev"); 67 return NULL; 68 } 69 70 ser_pdev_obj = wlan_serialization_get_pdev_obj(pdev); 71 wlan_objmgr_pdev_release_ref(pdev, WLAN_SERIALIZATION_ID); 72 if (!ser_pdev_obj) { 73 ser_err("invalid ser_pdev_obj"); 74 return NULL; 75 } 76 77 return ser_pdev_obj; 78 } 79 80 uint32_t wlan_serialization_get_active_list_count( 81 struct wlan_objmgr_psoc *psoc, 82 uint8_t is_cmd_from_active_scan_queue) 83 { 84 struct wlan_ser_pdev_obj *ser_pdev_obj; 85 qdf_list_t *queue; 86 struct wlan_serialization_pdev_queue *pdev_queue; 87 uint32_t count; 88 89 ser_pdev_obj = wlan_serialization_get_pdev_priv_obj_using_psoc(psoc); 90 if (!ser_pdev_obj) { 91 ser_err("invalid ser_pdev_obj"); 92 return 0; 93 } 94 95 if (is_cmd_from_active_scan_queue) 96 pdev_queue = &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_SCAN]; 97 else 98 pdev_queue = 99 &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_NON_SCAN]; 100 101 wlan_serialization_acquire_lock(&pdev_queue->pdev_queue_lock); 102 queue = &pdev_queue->active_list; 103 count = qdf_list_size(queue); 104 wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock); 105 106 return count; 107 } 108 109 uint32_t wlan_serialization_get_pending_list_count( 110 struct wlan_objmgr_psoc *psoc, 111 uint8_t is_cmd_from_pending_scan_queue) 112 { 113 struct wlan_ser_pdev_obj *ser_pdev_obj; 114 qdf_list_t *queue; 115 uint32_t count = 0; 116 struct wlan_serialization_pdev_queue *pdev_queue; 117 118 ser_pdev_obj = wlan_serialization_get_pdev_priv_obj_using_psoc(psoc); 119 if (!ser_pdev_obj) { 120 ser_err("invalid ser_pdev_obj"); 121 return 0; 122 } 123 124 if (is_cmd_from_pending_scan_queue) 125 pdev_queue = &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_SCAN]; 126 else 127 pdev_queue = 128 &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_NON_SCAN]; 129 queue = &pdev_queue->pending_list; 130 wlan_serialization_acquire_lock(&pdev_queue->pdev_queue_lock); 131 count = qdf_list_size(queue); 132 wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock); 133 134 return count; 135 } 136 137 struct wlan_serialization_command* 138 wlan_serialization_peek_head_active_cmd_using_psoc( 139 struct wlan_objmgr_psoc *psoc, 140 uint8_t is_cmd_from_active_scan_queue) 141 { 142 struct wlan_ser_pdev_obj *ser_pdev_obj; 143 struct wlan_serialization_command_list *cmd_list = NULL; 144 struct wlan_serialization_command *cmd = NULL; 145 qdf_list_node_t *nnode = NULL; 146 qdf_list_t *queue; 147 struct wlan_serialization_pdev_queue *pdev_queue; 148 149 ser_pdev_obj = wlan_serialization_get_pdev_priv_obj_using_psoc(psoc); 150 if (!ser_pdev_obj) { 151 ser_err("invalid ser_pdev_obj"); 152 return NULL; 153 } 154 155 if (is_cmd_from_active_scan_queue) 156 pdev_queue = &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_SCAN]; 157 else 158 pdev_queue = 159 &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_NON_SCAN]; 160 queue = &pdev_queue->active_list; 161 if (wlan_serialization_list_empty(queue)) { 162 ser_err("Empty Queue"); 163 goto end; 164 } 165 166 if (QDF_STATUS_SUCCESS != wlan_serialization_get_cmd_from_queue(queue, 167 &nnode)) { 168 ser_err("Can't get command from queue"); 169 goto end; 170 } 171 172 cmd_list = qdf_container_of(nnode, 173 struct wlan_serialization_command_list, pdev_node); 174 cmd = &cmd_list->cmd; 175 ser_debug("cmd_type[%d], cmd_id[%d]", 176 cmd_list->cmd.cmd_type, cmd_list->cmd.cmd_id); 177 178 end: 179 return cmd; 180 } 181 182 struct wlan_serialization_command* 183 wlan_serialization_peek_head_pending_cmd_using_psoc( 184 struct wlan_objmgr_psoc *psoc, 185 uint8_t is_cmd_from_pending_scan_queue) 186 { 187 struct wlan_ser_pdev_obj *ser_pdev_obj; 188 struct wlan_serialization_command_list *cmd_list = NULL; 189 struct wlan_serialization_command *cmd = NULL; 190 qdf_list_node_t *nnode = NULL; 191 qdf_list_t *queue; 192 struct wlan_serialization_pdev_queue *pdev_queue; 193 194 ser_pdev_obj = wlan_serialization_get_pdev_priv_obj_using_psoc(psoc); 195 if (!ser_pdev_obj) { 196 ser_err("invalid ser_pdev_obj"); 197 return NULL; 198 } 199 if (is_cmd_from_pending_scan_queue) 200 pdev_queue = &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_SCAN]; 201 else 202 pdev_queue = 203 &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_NON_SCAN]; 204 queue = &pdev_queue->pending_list; 205 if (wlan_serialization_list_empty(queue)) { 206 ser_err("Empty Queue"); 207 goto end; 208 } 209 210 if (QDF_STATUS_SUCCESS != wlan_serialization_get_cmd_from_queue( 211 queue, 212 &nnode)) { 213 ser_err("Can't get command from queue"); 214 goto end; 215 } 216 cmd_list = qdf_container_of(nnode, 217 struct wlan_serialization_command_list, pdev_node); 218 cmd = &cmd_list->cmd; 219 ser_debug("cmd_type[%d] cmd_id[%d]matched", 220 cmd_list->cmd.cmd_type, cmd_list->cmd.cmd_id); 221 222 end: 223 return cmd; 224 } 225 226 static struct wlan_serialization_command* 227 wlan_serialization_get_list_next_node(qdf_list_t *queue, 228 struct wlan_serialization_command *cmd, 229 struct wlan_ser_pdev_obj *ser_pdev_obj) 230 { 231 struct wlan_serialization_command_list *cmd_list = NULL; 232 qdf_list_node_t *pnode = NULL, *nnode = NULL; 233 bool found = false; 234 uint32_t i = 0; 235 QDF_STATUS status; 236 struct wlan_serialization_command *ret_cmd = NULL; 237 238 i = wlan_serialization_list_size(queue); 239 if (i == 0) { 240 ser_err("Empty Queue"); 241 return NULL; 242 } 243 while (i--) { 244 if (!cmd_list) 245 status = wlan_serialization_peek_front(queue, &nnode); 246 else 247 status = wlan_serialization_peek_next(queue, pnode, 248 &nnode); 249 250 if ((status != QDF_STATUS_SUCCESS) || found) 251 break; 252 253 pnode = nnode; 254 cmd_list = qdf_container_of( 255 nnode, 256 struct wlan_serialization_command_list, 257 pdev_node); 258 if (wlan_serialization_match_cmd_id_type( 259 nnode, cmd, WLAN_SER_PDEV_NODE) && 260 wlan_serialization_match_cmd_vdev(nnode, 261 cmd->vdev, 262 WLAN_SER_PDEV_NODE)) { 263 found = true; 264 } 265 nnode = NULL; 266 } 267 if (nnode && found) { 268 cmd_list = qdf_container_of( 269 nnode, 270 struct wlan_serialization_command_list, 271 pdev_node); 272 ret_cmd = &cmd_list->cmd; 273 } 274 if (!found) { 275 ser_err("Can't locate next command"); 276 return NULL; 277 } 278 if (!nnode) { 279 ser_debug("next node is empty, so fine"); 280 return NULL; 281 } 282 283 return ret_cmd; 284 } 285 286 struct wlan_serialization_command* 287 wlan_serialization_get_active_list_next_node_using_psoc( 288 struct wlan_objmgr_psoc *psoc, 289 struct wlan_serialization_command *prev_cmd, 290 uint8_t is_cmd_for_active_scan_queue) 291 { 292 struct wlan_ser_pdev_obj *ser_pdev_obj; 293 qdf_list_t *queue; 294 struct wlan_serialization_pdev_queue *pdev_queue; 295 296 if (!prev_cmd) { 297 ser_err("invalid prev_cmd"); 298 return NULL; 299 } 300 301 ser_pdev_obj = wlan_serialization_get_pdev_priv_obj_using_psoc(psoc); 302 if (!ser_pdev_obj) { 303 ser_err("invalid ser_pdev_obj"); 304 return NULL; 305 } 306 307 if (is_cmd_for_active_scan_queue) 308 pdev_queue = &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_SCAN]; 309 else 310 pdev_queue = 311 &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_NON_SCAN]; 312 queue = &pdev_queue->active_list; 313 return wlan_serialization_get_list_next_node(queue, prev_cmd, 314 ser_pdev_obj); 315 } 316 317 struct wlan_serialization_command* 318 wlan_serialization_get_pending_list_next_node_using_psoc( 319 struct wlan_objmgr_psoc *psoc, 320 struct wlan_serialization_command *prev_cmd, 321 uint8_t is_cmd_for_pending_scan_queue) 322 { 323 struct wlan_ser_pdev_obj *ser_pdev_obj; 324 qdf_list_t *queue; 325 struct wlan_serialization_pdev_queue *pdev_queue; 326 327 if (!prev_cmd) { 328 ser_err("invalid prev_cmd"); 329 return NULL; 330 } 331 332 ser_pdev_obj = wlan_serialization_get_pdev_priv_obj_using_psoc(psoc); 333 if (!ser_pdev_obj) { 334 ser_err("invalid ser_pdev_obj"); 335 return NULL; 336 } 337 if (is_cmd_for_pending_scan_queue) 338 pdev_queue = &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_SCAN]; 339 else 340 pdev_queue = 341 &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_NON_SCAN]; 342 queue = &pdev_queue->pending_list; 343 return wlan_serialization_get_list_next_node(queue, prev_cmd, 344 ser_pdev_obj); 345 } 346