blob: 373fe387a0f40666d21cfe20bed7b0211b0f0db2 [file] [log] [blame]
Varsha Mishrae58d93b2017-05-20 20:54:41 +05301/*
2 **************************************************************************
Kyle Swensonab36fae2021-05-21 08:38:22 -06003 * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
Varsha Mishrae58d93b2017-05-20 20:54:41 +05304 * 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 copies.
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14 **************************************************************************
15 */
16
17#include "nss_tx_rx_common.h"
Yu Huang8c107082017-07-24 14:58:26 -070018#include "nss_wifili_stats.h"
Sachin Shashidharc7b2e002018-08-20 13:52:51 -070019#include "nss_wifili_log.h"
Wayne Tanb6511182020-01-07 17:22:30 -080020#include "nss_wifili_strings.h"
Varsha Mishrae58d93b2017-05-20 20:54:41 +053021
22#define NSS_WIFILI_TX_TIMEOUT 1000 /* Millisecond to jiffies*/
Kyle Swensondd7b2962021-03-16 13:46:32 -060023#define NSS_WIFILI_INVALID_SCHEME_ID -1
24#define NSS_WIFILI_THREAD_SCHEME_ENTRY_MAX 4
25 /* Maximum number of thread scheme entries. */
26
27/*
28 * nss_wifili_thread_scheme_entry
29 * Details of thread scheme.
30 */
31struct nss_wifili_thread_scheme_entry {
32 int32_t radio_ifnum; /* Radio interface number. */
33 uint32_t radio_priority; /* Priority of radio. */
34 uint32_t scheme_priority; /* Priority of scheme. */
35 uint8_t scheme_index; /* Scheme index allocated to radio. */
36 bool allocated; /* Flag to check if scheme is allocated. */
37};
38
39/*
40 * nss_wifili_thread_scheme_db
41 * Wifili thread scheme database.
42 */
43struct nss_wifili_thread_scheme_db {
44 spinlock_t lock; /* Lock to protect from simultaneous access. */
45 uint32_t radio_count; /* Radio counter. */
46 struct nss_wifili_thread_scheme_entry nwtse[NSS_WIFILI_THREAD_SCHEME_ENTRY_MAX];
47 /* Metadata for each of scheme. */
48};
Varsha Mishrae58d93b2017-05-20 20:54:41 +053049
50/*
51 * nss_wifili_pvt
52 * Private data structure
53 */
54static struct nss_wifili_pvt {
55 struct semaphore sem;
56 struct completion complete;
57 int response;
58 void *cb;
59 void *app_data;
Kyle Swensonab36fae2021-05-21 08:38:22 -060060 spinlock_t lock;
Varsha Mishrae58d93b2017-05-20 20:54:41 +053061} wifili_pvt;
62
63/*
Kyle Swensondd7b2962021-03-16 13:46:32 -060064 * Scheme to radio mapping database
65 */
66static struct nss_wifili_thread_scheme_db ts_db[NSS_MAX_CORES];
67
68/*
Varsha Mishrae58d93b2017-05-20 20:54:41 +053069 * nss_wifili_handler()
70 * Handle NSS -> HLOS messages for wifi
71 */
72static void nss_wifili_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data)
73{
74 struct nss_wifili_msg *ntm = (struct nss_wifili_msg *)ncm;
75 void *ctx;
76 nss_wifili_msg_callback_t cb;
77
Kyle Swensondd7b2962021-03-16 13:46:32 -060078 nss_info("%px: NSS->HLOS message for wifili\n", nss_ctx);
Varsha Mishrae58d93b2017-05-20 20:54:41 +053079
80 /*
81 * The interface number shall be wifili soc interface or wifili radio interface
82 */
Subhranil Choudhury912f0682019-05-22 13:21:11 +053083 BUG_ON((nss_is_dynamic_interface(ncm->interface))
84 || ((ncm->interface != NSS_WIFILI_INTERNAL_INTERFACE)
85 && (ncm->interface != NSS_WIFILI_EXTERNAL_INTERFACE0)
86 && (ncm->interface != NSS_WIFILI_EXTERNAL_INTERFACE1)));
Varsha Mishrae58d93b2017-05-20 20:54:41 +053087
88 /*
Sachin Shashidharc7b2e002018-08-20 13:52:51 -070089 * Trace messages.
90 */
91 nss_wifili_log_rx_msg(ntm);
92
93 /*
Varsha Mishrae58d93b2017-05-20 20:54:41 +053094 * Is this a valid request/response packet?
95 */
96 if (ncm->type >= NSS_WIFILI_MAX_MSG) {
Kyle Swensondd7b2962021-03-16 13:46:32 -060097 nss_warning("%px: Received invalid message %d for wifili interface", nss_ctx, ncm->type);
Varsha Mishrae58d93b2017-05-20 20:54:41 +053098 return;
99 }
100
Kyle Swensondd7b2962021-03-16 13:46:32 -0600101 if ((nss_cmn_get_msg_len(ncm) > sizeof(struct nss_wifili_msg)) &&
102 ntm->cm.type != NSS_WIFILI_PEER_EXT_STATS_MSG) {
103 nss_warning("%px: Length of message is greater than required: %d", nss_ctx, nss_cmn_get_msg_len(ncm));
Varsha Mishrae58d93b2017-05-20 20:54:41 +0530104 return;
105 }
106
107 /*
108 * Snoop messages for local driver and handle
109 */
110 switch (ntm->cm.type) {
Aniruddha Paul1b170c22017-05-29 12:30:39 +0530111 case NSS_WIFILI_STATS_MSG:
Wayne Tanb6511182020-01-07 17:22:30 -0800112 /*
113 * Update WIFI driver statistics and send statistics notifications to the registered modules
114 */
Varsha Mishrae58d93b2017-05-20 20:54:41 +0530115 nss_wifili_stats_sync(nss_ctx, &ntm->msg.wlsoc_stats, ncm->interface);
Wayne Tanb6511182020-01-07 17:22:30 -0800116 nss_wifili_stats_notify(nss_ctx, ncm->interface);
Varsha Mishrae58d93b2017-05-20 20:54:41 +0530117 break;
118 }
119
120 /*
121 * Update the callback and app_data for notify messages, wifili sends all notify messages
122 * to the same callback/app_data.
123 */
Suruchi Agarwale4ad24a2018-06-11 12:03:46 +0530124 if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) {
Varsha Mishrae58d93b2017-05-20 20:54:41 +0530125 ncm->cb = (nss_ptr_t)nss_ctx->nss_top->wifili_msg_callback;
126 }
127
128 /*
129 * Log failures
130 */
131 nss_core_log_msg_failures(nss_ctx, ncm);
132
133 /*
134 * Do we have a call back
135 */
136 if (!ncm->cb) {
Kyle Swensondd7b2962021-03-16 13:46:32 -0600137 nss_info("%px: cb null for wifili interface %d", nss_ctx, ncm->interface);
Varsha Mishrae58d93b2017-05-20 20:54:41 +0530138 return;
139 }
140
141 /*
142 * Get callback & context
143 */
144 cb = (nss_wifili_msg_callback_t)ncm->cb;
145 ctx = nss_ctx->subsys_dp_register[ncm->interface].ndev;
146
147 /*
148 * call wifili msg callback
149 */
150 if (!ctx) {
Kyle Swensondd7b2962021-03-16 13:46:32 -0600151 nss_warning("%px: Event received for wifili interface %d before registration", nss_ctx, ncm->interface);
Varsha Mishrae58d93b2017-05-20 20:54:41 +0530152 return;
153 }
154
155 cb(ctx, ntm);
156}
157
158/*
159 * nss_wifili_callback()
160 * Callback to handle the completion of NSS->HLOS messages.
161 */
162static void nss_wifili_callback(void *app_data, struct nss_wifili_msg *nvm)
163{
164 nss_wifili_msg_callback_t callback = (nss_wifili_msg_callback_t)wifili_pvt.cb;
165 void *data = wifili_pvt.app_data;
166
167 wifili_pvt.response = NSS_TX_SUCCESS;
168 wifili_pvt.cb = NULL;
169 wifili_pvt.app_data = NULL;
170
171 if (nvm->cm.response != NSS_CMN_RESPONSE_ACK) {
172 nss_warning("wifili error response %d\n", nvm->cm.response);
173 wifili_pvt.response = nvm->cm.response;
174 }
175
176 if (callback) {
177 callback(data, nvm);
178 }
179 complete(&wifili_pvt.complete);
180}
181
182/*
183 * nss_wifili_tx_msg
184 * Transmit a wifili message to NSS FW
185 *
186 * NOTE: The caller is expected to handle synchronous wait for message
187 * response if needed.
188 */
189nss_tx_status_t nss_wifili_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_wifili_msg *msg)
190{
Varsha Mishrae58d93b2017-05-20 20:54:41 +0530191 struct nss_cmn_msg *ncm = &msg->cm;
Varsha Mishrae58d93b2017-05-20 20:54:41 +0530192
Sachin Shashidharc7b2e002018-08-20 13:52:51 -0700193 /*
194 * Trace messages.
195 */
196 nss_wifili_log_tx_msg(msg);
197
Varsha Mishrae58d93b2017-05-20 20:54:41 +0530198 if (ncm->type >= NSS_WIFILI_MAX_MSG) {
Kyle Swensondd7b2962021-03-16 13:46:32 -0600199 nss_warning("%px: wifili message type out of range: %d", nss_ctx, ncm->type);
Varsha Mishrae58d93b2017-05-20 20:54:41 +0530200 return NSS_TX_FAILURE;
201 }
202
Varsha Mishrae58d93b2017-05-20 20:54:41 +0530203 /*
Subhranil Choudhury912f0682019-05-22 13:21:11 +0530204 * The interface number shall be one of the wifili soc interfaces
Varsha Mishrae58d93b2017-05-20 20:54:41 +0530205 */
Subhranil Choudhury912f0682019-05-22 13:21:11 +0530206 if ((ncm->interface != NSS_WIFILI_INTERNAL_INTERFACE)
207 && (ncm->interface != NSS_WIFILI_EXTERNAL_INTERFACE0)
208 && (ncm->interface != NSS_WIFILI_EXTERNAL_INTERFACE1)) {
Kyle Swensondd7b2962021-03-16 13:46:32 -0600209 nss_warning("%px: tx request for interface that is not a wifili: %d", nss_ctx, ncm->interface);
Varsha Mishrae58d93b2017-05-20 20:54:41 +0530210 return NSS_TX_FAILURE;
211 }
212
Stephen Wang3e2dbd12018-03-14 17:28:17 -0700213 return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE);
Varsha Mishrae58d93b2017-05-20 20:54:41 +0530214}
215EXPORT_SYMBOL(nss_wifili_tx_msg);
216
217/*
218 * nss_wifili_tx_msg_sync()
219 * Transmit a wifili message to NSS firmware synchronously.
220 */
221nss_tx_status_t nss_wifili_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_wifili_msg *nvm)
222{
223 nss_tx_status_t status;
224 int ret = 0;
225
226 down(&wifili_pvt.sem);
227 wifili_pvt.cb = (void *)nvm->cm.cb;
228 wifili_pvt.app_data = (void *)nvm->cm.app_data;
229
230 nvm->cm.cb = (nss_ptr_t)nss_wifili_callback;
231 nvm->cm.app_data = (nss_ptr_t)NULL;
232
233 status = nss_wifili_tx_msg(nss_ctx, nvm);
234 if (status != NSS_TX_SUCCESS) {
Kyle Swensondd7b2962021-03-16 13:46:32 -0600235 nss_warning("%px: wifili_tx_msg failed\n", nss_ctx);
Varsha Mishrae58d93b2017-05-20 20:54:41 +0530236 up(&wifili_pvt.sem);
237 return status;
238 }
239
240 ret = wait_for_completion_timeout(&wifili_pvt.complete, msecs_to_jiffies(NSS_WIFILI_TX_TIMEOUT));
241 if (!ret) {
Kyle Swensondd7b2962021-03-16 13:46:32 -0600242 nss_warning("%px: wifili msg tx failed due to timeout\n", nss_ctx);
Varsha Mishrae58d93b2017-05-20 20:54:41 +0530243 wifili_pvt.response = NSS_TX_FAILURE;
244 }
245
246 status = wifili_pvt.response;
247 up(&wifili_pvt.sem);
248 return status;
249}
250EXPORT_SYMBOL(nss_wifili_tx_msg_sync);
251
252/*
253 * nss_wifili_get_context()
254 */
255struct nss_ctx_instance *nss_wifili_get_context(void)
256{
257 return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wifi_handler_id];
258}
259EXPORT_SYMBOL(nss_wifili_get_context);
260
261/*
syed touqeer pasha282abcb2019-11-26 15:19:37 +0530262 * nss_get_available_wifili_external_if()
263 * Check and return the available external interface
264 */
Kyle Swensonab36fae2021-05-21 08:38:22 -0600265nss_if_num_t nss_get_available_wifili_external_if(void)
syed touqeer pasha282abcb2019-11-26 15:19:37 +0530266{
267 struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wifi_handler_id];
268 /*
269 * Check if the external interface is registered.
270 * Return the interface number if not registered.
271 */
Kyle Swensonab36fae2021-05-21 08:38:22 -0600272 spin_lock_bh(&wifili_pvt.lock);
syed touqeer pasha282abcb2019-11-26 15:19:37 +0530273 if (!(nss_ctx->subsys_dp_register[NSS_WIFILI_EXTERNAL_INTERFACE0].ndev)) {
Kyle Swensonab36fae2021-05-21 08:38:22 -0600274 spin_unlock_bh(&wifili_pvt.lock);
syed touqeer pasha282abcb2019-11-26 15:19:37 +0530275 return NSS_WIFILI_EXTERNAL_INTERFACE0;
276 }
277
278 if (!(nss_ctx->subsys_dp_register[NSS_WIFILI_EXTERNAL_INTERFACE1].ndev)) {
Kyle Swensonab36fae2021-05-21 08:38:22 -0600279 spin_unlock_bh(&wifili_pvt.lock);
syed touqeer pasha282abcb2019-11-26 15:19:37 +0530280 return NSS_WIFILI_EXTERNAL_INTERFACE1;
281 }
282
Kyle Swensonab36fae2021-05-21 08:38:22 -0600283 spin_unlock_bh(&wifili_pvt.lock);
Kyle Swensondd7b2962021-03-16 13:46:32 -0600284 nss_warning("%px: No available external intefaces\n", nss_ctx);
syed touqeer pasha282abcb2019-11-26 15:19:37 +0530285
Kyle Swensonab36fae2021-05-21 08:38:22 -0600286 return -1;
syed touqeer pasha282abcb2019-11-26 15:19:37 +0530287}
288EXPORT_SYMBOL(nss_get_available_wifili_external_if);
289
290/*
Kyle Swensondd7b2962021-03-16 13:46:32 -0600291 * nss_wifili_get_radio_num()
292 * Get NSS wifili radio count.
293 *
294 * Wi-Fi host driver needs to know the current radio count
295 * to extract the radio priority from ini file.
296 */
297uint32_t nss_wifili_get_radio_num(struct nss_ctx_instance *nss_ctx)
298{
299 uint8_t core_id;
300 uint32_t radio_count;
301
302 nss_assert(nss_ctx);
303 nss_assert(nss_ctx->id < nss_top_main.num_nss);
304
305 core_id = nss_ctx->id;
306
307 spin_lock_bh(&ts_db[core_id].lock);
308 radio_count = ts_db[core_id].radio_count;
309 spin_unlock_bh(&ts_db[core_id].lock);
310
311 return radio_count;
312}
313EXPORT_SYMBOL(nss_wifili_get_radio_num);
314
315/*
316 * nss_wifili_thread_scheme_alloc()
317 * Allocate NSS worker thread scheme index.
318 *
319 * API does search on scheme database and returns scheme index based on
320 * priority of radio and free entry available.
321 * Wi-Fi driver fetches radio priority from ini file and calls this API
322 * to get the scheme index based on radio priority.
323 *
324 */
325uint8_t nss_wifili_thread_scheme_alloc(struct nss_ctx_instance *nss_ctx,
326 int32_t radio_ifnum,
327 enum nss_wifili_thread_scheme_priority radio_priority)
328{
329 uint8_t i;
330 uint8_t scheme_idx;
331 uint8_t core_id;
332 uint8_t next_avail_entry_idx = NSS_WIFILI_THREAD_SCHEME_ENTRY_MAX;
333
334 nss_assert(nss_ctx);
335 nss_assert(nss_ctx->id < nss_top_main.num_nss);
336
337 core_id = nss_ctx->id;
338
339 /*
340 * Iterate through scheme database and allocate
341 * scheme_id matching the priority requested.
342 */
343 spin_lock_bh(&ts_db[core_id].lock);
344 for (i = 0; i < NSS_WIFILI_THREAD_SCHEME_ENTRY_MAX; i++) {
345 if (ts_db[core_id].nwtse[i].allocated) {
346 continue;
347 }
348
349 if (radio_priority ==
350 ts_db[core_id].nwtse[i].scheme_priority) {
351 ts_db[core_id].nwtse[i].radio_ifnum = radio_ifnum;
352 ts_db[core_id].nwtse[i].radio_priority = radio_priority;
353 ts_db[core_id].nwtse[i].allocated = true;
354 ts_db[core_id].radio_count++;
355 scheme_idx = ts_db[core_id].nwtse[i].scheme_index;
356 spin_unlock_bh(&ts_db[core_id].lock);
357
358 nss_info("%px: Allocated scheme index:%d radio_ifnum:%d",
359 nss_ctx,
360 scheme_idx,
361 radio_ifnum);
362
363 return scheme_idx;
364 }
365
366 next_avail_entry_idx = i;
367 }
368
369 /*
370 * When radio priority does not match any of scheme entry priority
371 * and database has unallocated entries, provide available unallocated entry.
372 * This prevents any catastrophic failure during attach of Wi-Fi radio.
373 */
374 if (next_avail_entry_idx != NSS_WIFILI_THREAD_SCHEME_ENTRY_MAX) {
375
376 ts_db[core_id].nwtse[next_avail_entry_idx].radio_ifnum = radio_ifnum;
377 ts_db[core_id].nwtse[next_avail_entry_idx].radio_priority = radio_priority;
378 ts_db[core_id].nwtse[next_avail_entry_idx].allocated = true;
379 ts_db[core_id].radio_count++;
380 scheme_idx = ts_db[core_id].nwtse[next_avail_entry_idx].scheme_index;
381 spin_unlock_bh(&ts_db[core_id].lock);
382
383 nss_info("%px: Priority did not match for radio_ifnum:%d, allocated a next available scheme:%d",
384 nss_ctx,
385 radio_ifnum,
386 scheme_idx);
387
388 return scheme_idx;
389 }
390 spin_unlock_bh(&ts_db[core_id].lock);
391
392 nss_warning("%px: Could not find scheme - radio_ifnum:%d radio_map:%d\n",
393 nss_ctx,
394 radio_ifnum,
395 radio_priority);
396
397 return NSS_WIFILI_INVALID_SCHEME_ID;
398}
399EXPORT_SYMBOL(nss_wifili_thread_scheme_alloc);
400
401/*
402 * nss_wifili_thread_scheme_dealloc()
403 * Reset thread scheme metadata.
404 */
405void nss_wifili_thread_scheme_dealloc(struct nss_ctx_instance *nss_ctx,
406 int32_t radio_ifnum)
407{
408 uint32_t id;
409 uint8_t core_id;
410
411 nss_assert(nss_ctx);
412 nss_assert(nss_ctx->id < nss_top_main.num_nss);
413
414 core_id = nss_ctx->id;
415
416 /*
417 * Radio count cannot be zero here.
418 */
419 nss_assert(ts_db[core_id].radio_count);
420
421 spin_lock_bh(&ts_db[core_id].lock);
422 for (id = 0; id < NSS_WIFILI_THREAD_SCHEME_ENTRY_MAX; id++) {
423 if (ts_db[core_id].nwtse[id].radio_ifnum != radio_ifnum) {
424 continue;
425 }
426
427 ts_db[core_id].nwtse[id].radio_priority = 0;
428 ts_db[core_id].nwtse[id].allocated = false;
429 ts_db[core_id].nwtse[id].radio_ifnum = 0;
430 ts_db[core_id].radio_count--;
431 break;
432 }
433 spin_unlock_bh(&ts_db[core_id].lock);
434
435 if (id == NSS_WIFILI_THREAD_SCHEME_ENTRY_MAX) {
436 nss_warning("%px: Could not find scheme database with radio_ifnum:%d",
437 nss_ctx,
438 radio_ifnum);
439 }
440}
441EXPORT_SYMBOL(nss_wifili_thread_scheme_dealloc);
442
443/*
444 * nss_wifili_thread_scheme_db_init()
445 * Initialize thread scheme database.
446 */
447void nss_wifili_thread_scheme_db_init(uint8_t core_id)
448{
449 uint32_t id;
450
451 spin_lock_init(&ts_db[core_id].lock);
452
453 /*
454 * Iterate through scheme database and assign
455 * scheme_id and priority for each entry
456 */
457 ts_db[core_id].radio_count = 0;
458 for (id = 0; id < NSS_WIFILI_THREAD_SCHEME_ENTRY_MAX; id++) {
459 ts_db[core_id].nwtse[id].radio_priority = 0;
460 ts_db[core_id].nwtse[id].radio_ifnum = 0;
461 ts_db[core_id].nwtse[id].allocated = false;
462
463 switch (id) {
464 case 0:
465 ts_db[core_id].nwtse[id].scheme_priority = NSS_WIFILI_HIGH_PRIORITY_SCHEME;
466 ts_db[core_id].nwtse[id].scheme_index = NSS_WIFILI_THREAD_SCHEME_ID_0;
467 break;
468 case 1:
469 ts_db[core_id].nwtse[id].scheme_priority = NSS_WIFILI_LOW_PRIORITY_SCHEME;
470 ts_db[core_id].nwtse[id].scheme_index = NSS_WIFILI_THREAD_SCHEME_ID_1;
471 break;
472 case 2:
473 case 3:
474 ts_db[core_id].nwtse[id].scheme_priority = NSS_WIFILI_HIGH_PRIORITY_SCHEME;
475 ts_db[core_id].nwtse[id].scheme_index = NSS_WIFILI_THREAD_SCHEME_ID_2;
476 break;
477 default:
478 nss_warning("Invalid scheme index:%d", id);
479 }
480 }
481}
482
483/*
Varsha Mishrae58d93b2017-05-20 20:54:41 +0530484 * nss_wifili_msg_init()
485 * Initialize nss_wifili_msg.
486 */
487void nss_wifili_msg_init(struct nss_wifili_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, void *cb, void *app_data)
488{
489 nss_cmn_msg_init(&ncm->cm, if_num, type, len, cb, app_data);
490}
491EXPORT_SYMBOL(nss_wifili_msg_init);
492
493/*
494 ****************************************
495 * Register/Unregister/Miscellaneous APIs
496 ****************************************
497 */
498
499/*
500 * nss_register_wifili_if()
501 * Register wifili with nss driver
502 */
503struct nss_ctx_instance *nss_register_wifili_if(uint32_t if_num, nss_wifili_callback_t wifili_callback,
504 nss_wifili_callback_t wifili_ext_callback,
505 nss_wifili_msg_callback_t event_callback, struct net_device *netdev, uint32_t features)
506{
507 struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wifi_handler_id];
508
509 /*
510 * The interface number shall be wifili soc interface
511 */
Subhranil Choudhury912f0682019-05-22 13:21:11 +0530512 nss_assert((if_num == NSS_WIFILI_INTERNAL_INTERFACE)
513 || (if_num == NSS_WIFILI_EXTERNAL_INTERFACE0)
514 || (if_num == NSS_WIFILI_EXTERNAL_INTERFACE1));
Varsha Mishrae58d93b2017-05-20 20:54:41 +0530515
Kyle Swensondd7b2962021-03-16 13:46:32 -0600516 nss_info("nss_register_wifili_if if_num %d wifictx %px", if_num, netdev);
Varsha Mishrae58d93b2017-05-20 20:54:41 +0530517
Jackson Bockus7ca70ec2017-07-17 13:47:29 -0700518 nss_core_register_subsys_dp(nss_ctx, if_num, wifili_callback, wifili_ext_callback, NULL, netdev, features);
Varsha Mishrae58d93b2017-05-20 20:54:41 +0530519
520 nss_top_main.wifili_msg_callback = event_callback;
Varsha Mishrae58d93b2017-05-20 20:54:41 +0530521
522 return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wifi_handler_id];
523}
524EXPORT_SYMBOL(nss_register_wifili_if);
525
526/*
527 * nss_unregister_wifili_if()
528 * Unregister wifili with nss driver
529 */
530void nss_unregister_wifili_if(uint32_t if_num)
531{
532 struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wifi_handler_id];
533
534 /*
535 * The interface number shall be wifili soc interface
536 */
Subhranil Choudhury912f0682019-05-22 13:21:11 +0530537 nss_assert((if_num == NSS_WIFILI_INTERNAL_INTERFACE)
538 || (if_num == NSS_WIFILI_EXTERNAL_INTERFACE0)
539 || (if_num == NSS_WIFILI_EXTERNAL_INTERFACE1));
Varsha Mishrae58d93b2017-05-20 20:54:41 +0530540
Jackson Bockus7ca70ec2017-07-17 13:47:29 -0700541 nss_core_unregister_subsys_dp(nss_ctx, if_num);
Varsha Mishrae58d93b2017-05-20 20:54:41 +0530542}
543EXPORT_SYMBOL(nss_unregister_wifili_if);
544
545/*
546 * nss_register_wifili_radio_if()
547 * Register wifili radio with nss driver
548 */
549struct nss_ctx_instance *nss_register_wifili_radio_if(uint32_t if_num, nss_wifili_callback_t wifili_callback,
550 nss_wifili_callback_t wifili_ext_callback,
551 nss_wifili_msg_callback_t event_callback, struct net_device *netdev, uint32_t features)
552{
553 struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wifi_handler_id];
554
555 /*
556 * The interface number shall be wifili radio dynamic interface
557 */
558 nss_assert(nss_is_dynamic_interface(if_num));
Kyle Swensondd7b2962021-03-16 13:46:32 -0600559 nss_info("nss_register_wifili_if if_num %d wifictx %px", if_num, netdev);
Varsha Mishrae58d93b2017-05-20 20:54:41 +0530560
Jackson Bockus7ca70ec2017-07-17 13:47:29 -0700561 nss_core_register_subsys_dp(nss_ctx, if_num, wifili_callback, wifili_ext_callback, NULL, netdev, features);
Varsha Mishrae58d93b2017-05-20 20:54:41 +0530562
563 return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wifi_handler_id];
564}
565EXPORT_SYMBOL(nss_register_wifili_radio_if);
566
567/*
568 * nss_unregister_wifili_radio_if()
569 * Unregister wifili radio with nss driver
570 */
571void nss_unregister_wifili_radio_if(uint32_t if_num)
572{
573 struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wifi_handler_id];
574
575 /*
576 * The interface number shall be wifili radio dynamic interface
577 */
578 nss_assert(nss_is_dynamic_interface(if_num));
579
Jackson Bockus7ca70ec2017-07-17 13:47:29 -0700580 nss_core_unregister_subsys_dp(nss_ctx, if_num);
Varsha Mishrae58d93b2017-05-20 20:54:41 +0530581}
582EXPORT_SYMBOL(nss_unregister_wifili_radio_if);
583
584/*
585 * nss_wifili_register_handler()
586 * Register handle for notfication messages received on wifi interface
587 */
Aniruddha Paul1b170c22017-05-29 12:30:39 +0530588void nss_wifili_register_handler(void)
Varsha Mishrae58d93b2017-05-20 20:54:41 +0530589{
Thomas Wu91f4bdf2017-06-09 12:03:02 -0700590 struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wifi_handler_id];
591
Varsha Mishrae58d93b2017-05-20 20:54:41 +0530592 nss_info("nss_wifili_register_handler");
Subhranil Choudhury912f0682019-05-22 13:21:11 +0530593 nss_core_register_handler(nss_ctx, NSS_WIFILI_INTERNAL_INTERFACE, nss_wifili_handler, NULL);
594 nss_core_register_handler(nss_ctx, NSS_WIFILI_EXTERNAL_INTERFACE0, nss_wifili_handler, NULL);
595 nss_core_register_handler(nss_ctx, NSS_WIFILI_EXTERNAL_INTERFACE1, nss_wifili_handler, NULL);
Varsha Mishrae58d93b2017-05-20 20:54:41 +0530596
Yu Huang8c107082017-07-24 14:58:26 -0700597 nss_wifili_stats_dentry_create();
Wayne Tanb6511182020-01-07 17:22:30 -0800598 nss_wifili_strings_dentry_create();
Yu Huang8c107082017-07-24 14:58:26 -0700599
Varsha Mishrae58d93b2017-05-20 20:54:41 +0530600 sema_init(&wifili_pvt.sem, 1);
Kyle Swensonab36fae2021-05-21 08:38:22 -0600601 spin_lock_init(&wifili_pvt.lock);
Varsha Mishrae58d93b2017-05-20 20:54:41 +0530602 init_completion(&wifili_pvt.complete);
603}