1 /*
2 * Copyright 2023, Cypress Semiconductor Corporation (an Infineon company)
3 * SPDX-License-Identifier: Apache-2.0
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 #include "whd_int.h"
19 #include "whd_cdc_bdc.h"
20 #include "whd_events_int.h"
21 #include "cyabs_rtos.h"
22 #include "whd_network_types.h"
23 #include "whd_types_int.h"
24 #include "whd_wlioctl.h"
25 #include "whd_thread_internal.h"
26 #include "whd_buffer_api.h"
27
28 /******************************************************
29 * Constants
30 ******************************************************/
31 /******************************************************
32 * Macros
33 ******************************************************/
34 /* bit map related macros */
35 #define NBBY 8 /* 8 bits per byte */
36 #define setbit(a, i) ( ( (uint8_t *)a )[(int)(i) / (int)(NBBY)] |= (uint8_t)(1 << ( (i) % NBBY ) ) )
37 #define clrbit(a, i) ( ( (uint8_t *)a )[(int)(i) / (int)(NBBY)] &= (uint8_t) ~(1 << ( (i) % NBBY ) ) )
38 #define isset(a, i) ( ( (const uint8_t *)a )[(int)(i) / (int)(NBBY)]& (1 << ( (i) % NBBY ) ) )
39 #define isclr(a, i) ( ( ( (const uint8_t *)a )[(int)(i) / (int)(NBBY)]& (1 << ( (i) % NBBY ) ) ) == 0 )
40
41 /******************************************************
42 * Local Structures
43 ******************************************************/
44
45 /******************************************************
46 * Static Variables
47 ******************************************************/
48
49 /******************************************************
50 * Static Function Prototypes
51 ******************************************************/
52 /* helper function for event messages ext API */
53 static uint8_t *whd_management_alloc_event_msgs_buffer(whd_interface_t ifp, whd_buffer_t *buffer);
54 static uint8_t whd_find_number_of_events(const whd_event_num_t *event_nums);
55
56 /******************************************************
57 * Static Functions
58 ******************************************************/
59
whd_find_number_of_events(const whd_event_num_t * event_nums)60 static uint8_t whd_find_number_of_events(const whd_event_num_t *event_nums)
61 {
62 uint8_t count = 0;
63
64 while (*event_nums != WLC_E_NONE)
65 {
66 count++;
67 event_nums++;
68
69 if (count >= WHD_MAX_EVENT_SUBSCRIPTION)
70 return 0;
71 }
72 return count + 1;
73 }
74
75 /**
76 * Registers locally a handler to receive event callbacks.
77 * Does not notify Wi-Fi about event subscription change.
78 * Can be used to refresh local callbacks (e.g. after deep-sleep)
79 * if Wi-Fi is already notified about them.
80 *
81 * This function registers a callback handler to be notified when
82 * a particular event is received.
83 *
84 * @note : Currently there is a limit to the number of simultaneously
85 * registered events
86 *
87 * @param ifp Pointer to handle instance of whd interface
88 * @param event_nums An array of event types that is to trigger the handler.
89 * The array must be terminated with a WLC_E_NONE event
90 * See @ref whd_event_num_t for available events
91 * @param handler_func A function pointer to the new handler callback,
92 * or NULL if callbacks are to be disabled for the given event type
93 * @param handler_user_data A pointer value which will be passed to the event handler function
94 * at the time an event is triggered (NULL is allowed)
95 * @param[out] *event_index entry where the event handler is registered in the list
96 *
97 * @return WHD result code
98 */
whd_management_set_event_handler_locally(whd_interface_t ifp,const whd_event_num_t * event_nums,whd_event_handler_t handler_func,void * handler_user_data,uint16_t * event_index)99 whd_result_t whd_management_set_event_handler_locally(whd_interface_t ifp, const whd_event_num_t *event_nums,
100 whd_event_handler_t handler_func,
101 void *handler_user_data, uint16_t *event_index)
102 {
103 uint16_t entry = (uint16_t)0xFF;
104 uint16_t i;
105 whd_driver_t whd_driver = ifp->whd_driver;
106 whd_cdc_bdc_info_t *cdc_bdc_info = &whd_driver->cdc_bdc_info;
107 uint8_t num_of_events;
108 num_of_events = whd_find_number_of_events(event_nums);
109
110 if (num_of_events <= 1)
111 {
112 WPRINT_WHD_ERROR( ("Exceeded the maximum event subscription/no event subscribed\n") );
113 return WHD_UNFINISHED;
114 }
115
116 /* Find an existing matching entry OR the next empty entry */
117 for (i = 0; i < (uint16_t)WHD_EVENT_HANDLER_LIST_SIZE; i++)
118 {
119 /* Find a matching event list OR the first empty event entry */
120 if (!(memcmp(cdc_bdc_info->whd_event_list[i].events, event_nums,
121 num_of_events * (sizeof(whd_event_num_t) ) ) ) )
122 {
123 /* Check if all the data already matches */
124 if ( (cdc_bdc_info->whd_event_list[i].handler == handler_func) &&
125 (cdc_bdc_info->whd_event_list[i].handler_user_data == handler_user_data) &&
126 (cdc_bdc_info->whd_event_list[i].ifidx == ifp->ifidx) )
127 {
128 /* send back the entry where the handler is added */
129 *event_index = i;
130 return WHD_SUCCESS;
131 }
132 }
133 else if ( (entry == (uint16_t)0xFF) && (cdc_bdc_info->whd_event_list[i].event_set == WHD_FALSE) )
134 {
135 entry = i;
136 }
137 }
138
139 /* Check if handler function was provided */
140 if (handler_func != NULL)
141 {
142 /* Check if an empty entry was not found */
143 if (entry == (uint16_t)0xFF)
144 {
145 WPRINT_WHD_DEBUG( ("Out of space in event handlers table - try increasing WHD_EVENT_HANDLER_LIST_SIZE\n") );
146 return WHD_OUT_OF_EVENT_HANDLER_SPACE;
147 }
148
149 /* Add the new handler in at the free space */
150 memcpy (cdc_bdc_info->whd_event_list[entry].events, event_nums, num_of_events * (sizeof(whd_event_num_t) ) );
151 cdc_bdc_info->whd_event_list[entry].handler = handler_func;
152 cdc_bdc_info->whd_event_list[entry].handler_user_data = handler_user_data;
153 cdc_bdc_info->whd_event_list[entry].ifidx = ifp->ifidx;
154 cdc_bdc_info->whd_event_list[entry].event_set = WHD_TRUE;
155
156 /* send back the entry where the handler is added */
157 *event_index = entry;
158 }
159 else
160 {
161 WPRINT_WHD_ERROR( ("Event handler callback function is NULL/not provided to register\n") );
162 return WHD_BADARG;
163 }
164
165 return WHD_SUCCESS;
166 }
167
168 /* Registers locally a handler to receive error callbacks.
169 * Does not notify Wi-Fi about event subscription change.
170 * Can be used to refresh local callbacks (e.g. after deep-sleep)
171 * if Wi-Fi is already notified about them.
172 *
173 * This function registers a callback handler to be notified when
174 * a particular event is received.
175 *
176 * @note : Currently there is a limit to the number of simultaneously
177 * registered events
178 *
179 * @param whd_driver Pointer to handle instance of driver
180 * @param error_nums An error types that is to trigger the handler.
181 * See @ref whd_error_num_t for available events
182 * @param handler_func A function pointer to the new handler callback,
183 * or NULL if callbacks are to be disabled for the given event type
184 * @param handler_user_data A pointer value which will be passed to the event handler function
185 * at the time an event is triggered (NULL is allowed)
186 * @param[out] *error_index entry where the error handler is registered in the list
187 *
188 * @return WHD result code
189 */
whd_set_error_handler_locally(whd_driver_t whd_driver,const uint8_t * error_nums,whd_error_handler_t handler_func,void * handler_user_data,uint16_t * error_index)190 whd_result_t whd_set_error_handler_locally(whd_driver_t whd_driver, const uint8_t *error_nums,
191 whd_error_handler_t handler_func,
192 void *handler_user_data, uint16_t *error_index)
193 {
194 uint16_t entry = (uint16_t)0xFF;
195 uint16_t i;
196 whd_result_t res;
197 whd_error_info_t *error_info = &whd_driver->error_info;
198
199
200 /* Find an existing matching entry OR the next empty entry */
201 for (i = 0; i < (uint16_t)WHD_EVENT_HANDLER_LIST_SIZE; i++)
202 {
203 uint8_t events = error_info->whd_event_list[i].events;
204 /* Find a matching event list OR the first empty event entry */
205 if (events & *error_nums)
206 {
207 /* Check if all the data already matches */
208 if (error_info->whd_event_list[i].handler != NULL)
209 {
210 handler_func = error_info->whd_event_list[i].handler;
211 handler_user_data = error_info->whd_event_list[i].handler_user_data;
212 res = cy_rtos_get_semaphore(&error_info->event_list_mutex, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE);
213 if (res != WHD_SUCCESS)
214 {
215 return res;
216 }
217 handler_func(whd_driver, error_nums, NULL, handler_user_data);
218 CHECK_RETURN(cy_rtos_set_semaphore(&error_info->event_list_mutex, WHD_FALSE) );
219 return WHD_SUCCESS;
220 }
221 }
222 else if ( (entry == (uint16_t)0xFF) && (error_info->whd_event_list[i].event_set == WHD_FALSE) )
223 {
224 entry = i;
225 }
226 }
227 /* Check if handler function was provided */
228 if (handler_func != NULL)
229 {
230 /* Check if an empty entry was not found */
231 if (entry == (uint16_t)0xFF)
232 {
233 WPRINT_WHD_DEBUG( ("Out of space in error handlers table - try increasing WHD_EVENT_HANDLER_LIST_SIZE\n") );
234 return WHD_OUT_OF_EVENT_HANDLER_SPACE;
235 }
236 /* Add the new handler in at the free space */
237 error_info->whd_event_list[entry].events = *error_nums;
238 error_info->whd_event_list[entry].handler = handler_func;
239 error_info->whd_event_list[entry].handler_user_data = handler_user_data;
240 error_info->whd_event_list[entry].event_set = WHD_TRUE;
241 /* send back the entry where the handler is added */
242 *error_index = entry;
243 }
244 else
245 {
246 WPRINT_WHD_ERROR( ("Error handler callback function is NULL/not provided to register\n") );
247 return WHD_BADARG;
248 }
249
250 return WHD_SUCCESS;
251 }
252
253 /* allocates memory for the needed iovar and returns a pointer to the event mask */
whd_management_alloc_event_msgs_buffer(whd_interface_t ifp,whd_buffer_t * buffer)254 static uint8_t *whd_management_alloc_event_msgs_buffer(whd_interface_t ifp, whd_buffer_t *buffer)
255 {
256 uint16_t i;
257 uint16_t j;
258 whd_bool_t use_extended_evt = WHD_FALSE;
259 uint32_t max_event = 0;
260 eventmsgs_ext_t *eventmsgs_ext_data = NULL;
261 uint32_t *data = NULL;
262 whd_driver_t whd_driver = ifp->whd_driver;
263 whd_cdc_bdc_info_t *cdc_bdc_info = &whd_driver->cdc_bdc_info;
264
265 /* Check to see if event that's set requires more than 128 bit */
266 for (i = 0; i < (uint16_t)WHD_EVENT_HANDLER_LIST_SIZE; i++)
267 {
268 if (cdc_bdc_info->whd_event_list[i].event_set)
269 {
270 for (j = 0; cdc_bdc_info->whd_event_list[i].events[j] != WLC_E_NONE; j++)
271 {
272 uint32_t event_value = cdc_bdc_info->whd_event_list[i].events[j];
273 if (event_value > 127)
274 {
275 use_extended_evt = WHD_TRUE;
276 if (event_value > max_event)
277 {
278 max_event = event_value;
279 }
280 /* keep going to get highest value */
281 }
282 }
283 }
284 }
285
286 if (WHD_FALSE == use_extended_evt)
287 {
288 /* use old iovar for backwards compat */
289 data = (uint32_t *)whd_cdc_get_iovar_buffer(whd_driver, buffer, (uint16_t)WL_EVENTING_MASK_LEN + 4,
290 "bsscfg:" IOVAR_STR_EVENT_MSGS);
291
292 if (NULL == data)
293 {
294 return NULL;
295 }
296
297 data[0] = ifp->bsscfgidx;
298
299 return (uint8_t *)&data[1];
300 }
301 else
302 {
303 uint8_t mask_len = (uint8_t)( (max_event + 8) / 8 );
304 data =
305 (uint32_t *)whd_cdc_get_iovar_buffer(whd_driver, buffer,
306 (uint16_t)(sizeof(eventmsgs_ext_t) + mask_len + 4),
307 "bsscfg:" IOVAR_STR_EVENT_MSGS_EXT);
308
309 if (NULL == data)
310 {
311 return NULL;
312 }
313
314 data[0] = ifp->bsscfgidx;
315
316 eventmsgs_ext_data = (eventmsgs_ext_t *)&data[1];
317
318 memset(eventmsgs_ext_data, 0, sizeof(*eventmsgs_ext_data) );
319 eventmsgs_ext_data->ver = EVENTMSGS_VER;
320 eventmsgs_ext_data->command = EVENTMSGS_SET_MASK;
321 eventmsgs_ext_data->len = mask_len;
322 return eventmsgs_ext_data->mask;
323 }
324 }
325
326 /**
327 * Registers a handler to receive event callbacks.
328 * Subscribe locally and notify Wi-Fi about subscription.
329 *
330 * This function registers a callback handler to be notified when
331 * a particular event is received.
332 *
333 * @note : Currently there is a limit to the number of simultaneously
334 * registered events
335 *
336 * @param ifp Pointer to handle instance of whd interface
337 * @param event_nums An array of event types that is to trigger the handler.
338 * The array must be terminated with a WLC_E_NONE event
339 * See @ref whd_event_num_t for available events
340 * @param handler_func A function pointer to the new handler callback
341 * @param handler_user_data A pointer value which will be passed to the event handler function
342 * at the time an event is triggered (NULL is allowed)
343 * @param[out] *event_index entry where the event handler is registered in the list
344 *
345 * @return WHD result code
346 */
whd_management_set_event_handler(whd_interface_t ifp,const whd_event_num_t * event_nums,whd_event_handler_t handler_func,void * handler_user_data,uint16_t * event_index)347 whd_result_t whd_management_set_event_handler(whd_interface_t ifp, const whd_event_num_t *event_nums,
348 whd_event_handler_t handler_func,
349 void *handler_user_data, uint16_t *event_index)
350 {
351 whd_buffer_t buffer;
352 uint8_t *event_mask;
353 uint16_t i;
354 uint16_t j;
355 whd_result_t res;
356 whd_driver_t whd_driver;
357 whd_cdc_bdc_info_t *cdc_bdc_info;
358 whd_interface_t prim_ifp;
359
360 if (ifp == NULL)
361 {
362 return WHD_UNKNOWN_INTERFACE;
363 }
364
365 if (!event_nums || !event_index)
366 {
367 WPRINT_WHD_ERROR( ("Event list to be registered is NULL/Event index is NULL") );
368 return WHD_BADARG;
369 }
370
371 whd_driver = ifp->whd_driver;
372 cdc_bdc_info = &whd_driver->cdc_bdc_info;
373 prim_ifp = whd_get_primary_interface(whd_driver);
374
375 if (prim_ifp == NULL)
376 {
377 return WHD_UNKNOWN_INTERFACE;
378 }
379
380 /* Acquire mutex preventing multiple threads accessing the handler at the same time */
381 res = cy_rtos_get_semaphore(&cdc_bdc_info->event_list_mutex, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE);
382 if (res != WHD_SUCCESS)
383 {
384 return res;
385 }
386
387 /* Set event handler locally */
388 res = whd_management_set_event_handler_locally(ifp, event_nums, handler_func, handler_user_data, event_index);
389 if (res != WHD_SUCCESS)
390 {
391 WPRINT_WHD_ERROR( ("Error in setting event handler locally, %s failed at %d \n", __func__, __LINE__) );
392 goto set_event_handler_exit;
393 }
394
395 /* Send the new event mask value to the wifi chip */
396 event_mask = whd_management_alloc_event_msgs_buffer(ifp, &buffer);
397
398 if (NULL == event_mask)
399 {
400 res = WHD_BUFFER_UNAVAILABLE_PERMANENT;
401 WPRINT_WHD_ERROR( ("Buffer unavailable permanently, %s failed at %d \n", __func__, __LINE__) );
402 goto set_event_handler_exit;
403 }
404
405 /* Keep the wlan awake while we set the event_msgs */
406 WHD_WLAN_KEEP_AWAKE(whd_driver);
407
408 /* Set the event bits for each event from every handler */
409 memset(event_mask, 0, (size_t)WL_EVENTING_MASK_LEN);
410 for (i = 0; i < (uint16_t)WHD_EVENT_HANDLER_LIST_SIZE; i++)
411 {
412 if (cdc_bdc_info->whd_event_list[i].event_set)
413 {
414 for (j = 0; cdc_bdc_info->whd_event_list[i].events[j] != WLC_E_NONE; j++)
415 {
416 setbit(event_mask, cdc_bdc_info->whd_event_list[i].events[j]);
417 }
418 }
419 }
420
421 res = whd_cdc_send_iovar(prim_ifp, CDC_SET, buffer, 0);
422 if (res != WHD_SUCCESS)
423 {
424 WPRINT_WHD_ERROR( ("%s: send event_msgs(iovar) failed\n", __func__) );
425 }
426
427 /* set the event_list_mutex here after sending iovar.
428 * we get event_list_mutex -> ioctl_mutex, make sure we didn't have any thread, having ioctl_mutex -> event_list_mutex path.
429 * Otherwise it may cause deadlock
430 */
431 CHECK_RETURN(cy_rtos_set_semaphore(&cdc_bdc_info->event_list_mutex, WHD_FALSE) );
432
433 /* The wlan chip can sleep from now on */
434 WHD_WLAN_LET_SLEEP(whd_driver);
435 return WHD_SUCCESS;
436
437 set_event_handler_exit:
438 CHECK_RETURN(cy_rtos_set_semaphore(&cdc_bdc_info->event_list_mutex, WHD_FALSE) );
439 return res;
440 }
441
whd_wifi_set_event_handler(whd_interface_t ifp,const uint32_t * event_type,whd_event_handler_t handler_func,void * handler_user_data,uint16_t * event_index)442 whd_result_t whd_wifi_set_event_handler(whd_interface_t ifp, const uint32_t *event_type,
443 whd_event_handler_t handler_func,
444 void *handler_user_data, uint16_t *event_index)
445 {
446 whd_buffer_t buffer;
447 uint8_t *event_mask;
448 uint16_t i;
449 uint16_t j;
450 whd_result_t res;
451 whd_driver_t whd_driver;
452 whd_cdc_bdc_info_t *cdc_bdc_info;
453 whd_interface_t prim_ifp;
454
455 if (ifp == NULL)
456 {
457 return WHD_UNKNOWN_INTERFACE;
458 }
459
460 if (!event_type || !event_index)
461 {
462 WPRINT_WHD_ERROR( ("Event list to be registered is NULL/Event index is NULL") );
463 return WHD_BADARG;
464 }
465
466 whd_driver = ifp->whd_driver;
467 cdc_bdc_info = &whd_driver->cdc_bdc_info;
468 prim_ifp = whd_get_primary_interface(whd_driver);
469
470 if (prim_ifp == NULL)
471 {
472 return WHD_UNKNOWN_INTERFACE;
473 }
474
475 /* Acquire mutex preventing multiple threads accessing the handler at the same time */
476 res = cy_rtos_get_semaphore(&cdc_bdc_info->event_list_mutex, CY_RTOS_NEVER_TIMEOUT, WHD_FALSE);
477 if (res != WHD_SUCCESS)
478 {
479 return res;
480 }
481
482 /* Set event handler locally */
483 res = whd_management_set_event_handler_locally(ifp, (whd_event_num_t *)event_type, handler_func, handler_user_data,
484 event_index);
485 if (res != WHD_SUCCESS)
486 {
487 WPRINT_WHD_ERROR( ("Error in setting event handler locally, %s failed at %d \n", __func__, __LINE__) );
488 goto set_event_handler_exit;
489 }
490
491 /* Send the new event mask value to the wifi chip */
492 event_mask = whd_management_alloc_event_msgs_buffer(ifp, &buffer);
493
494 if (NULL == event_mask)
495 {
496 res = WHD_BUFFER_UNAVAILABLE_PERMANENT;
497 WPRINT_WHD_ERROR( ("Buffer unavailable permanently, %s failed at %d \n", __func__, __LINE__) );
498 goto set_event_handler_exit;
499 }
500
501 /* Keep the wlan awake while we set the event_msgs */
502 WHD_WLAN_KEEP_AWAKE(whd_driver);
503
504 /* Set the event bits for each event from every handler */
505 memset(event_mask, 0, (size_t)WL_EVENTING_MASK_LEN);
506 for (i = 0; i < (uint16_t)WHD_EVENT_HANDLER_LIST_SIZE; i++)
507 {
508 if (cdc_bdc_info->whd_event_list[i].event_set)
509 {
510 for (j = 0; cdc_bdc_info->whd_event_list[i].events[j] != WLC_E_NONE; j++)
511 {
512 setbit(event_mask, cdc_bdc_info->whd_event_list[i].events[j]);
513 }
514 }
515 }
516
517 res = whd_cdc_send_iovar(prim_ifp, CDC_SET, buffer, 0);
518 if (res != WHD_SUCCESS)
519 {
520 WPRINT_WHD_ERROR( ("%s: send event_msgs(iovar) failed\n", __func__) );
521 }
522
523 /* set the event_list_mutex here after sending iovar.
524 * we get event_list_mutex -> ioctl_mutex, make sure we didn't have any thread, having ioctl_mutex -> event_list_mutex path.
525 * Otherwise it may cause deadlock
526 */
527 CHECK_RETURN(cy_rtos_set_semaphore(&cdc_bdc_info->event_list_mutex, WHD_FALSE) );
528
529 /* The wlan chip can sleep from now on */
530 WHD_WLAN_LET_SLEEP(whd_driver);
531 return WHD_SUCCESS;
532
533 set_event_handler_exit:
534 CHECK_RETURN(cy_rtos_set_semaphore(&cdc_bdc_info->event_list_mutex, WHD_FALSE) );
535 return res;
536 }
537
538 /**
539 * Registers a handler to receive error callbacks.
540 * Subscribe locally and notify Wi-Fi about subscription.
541 *
542 * This function registers a callback handler to be notified when
543 * a particular event is received.
544 *
545 * @note : Currently there is a limit to the number of simultaneously
546 * registered events
547 *
548 * @param ifp Pointer to handle instance of whd interface
549 * @param event_nums An numbers of event type that is to trigger the handler.
550 * See @ref whd_error_num_t for available events
551 * @param handler_func A function pointer to the new handler callback
552 * @param handler_user_data A pointer value which will be passed to the event handler function
553 * at the time an event is triggered (NULL is allowed)
554 * @param[out] *error_index entry where the error handler is registered in the list
555 *
556 * @return WHD result code
557 */
whd_wifi_set_error_handler(whd_interface_t ifp,const uint8_t * error_nums,whd_error_handler_t handler_func,void * handler_user_data,uint16_t * error_index)558 whd_result_t whd_wifi_set_error_handler(whd_interface_t ifp, const uint8_t *error_nums,
559 whd_error_handler_t handler_func,
560 void *handler_user_data, uint16_t *error_index)
561 {
562 whd_result_t res;
563 whd_driver_t whd_driver;
564 whd_interface_t prim_ifp;
565 if (ifp == NULL)
566 {
567 return WHD_UNKNOWN_INTERFACE;
568 }
569
570 if (!error_nums || !error_index)
571 {
572 WPRINT_WHD_ERROR( ("Error list to be registered is NULL/Error index is NULL \n") );
573 return WHD_BADARG;
574 }
575
576 whd_driver = ifp->whd_driver;
577 prim_ifp = whd_get_primary_interface(whd_driver);
578 if (prim_ifp == NULL)
579 {
580 return WHD_UNKNOWN_INTERFACE;
581 }
582
583 /* Set event handler locally */
584 res = whd_set_error_handler_locally(whd_driver, error_nums, handler_func, handler_user_data,
585 error_index);
586 if (res != WHD_SUCCESS)
587 {
588 WPRINT_WHD_ERROR( ("Error in setting event handler locally, %s failed at %d \n", __func__, __LINE__) );
589 return res;
590 }
591
592
593 return WHD_SUCCESS;
594
595 }
596
whd_wifi_deregister_event_handler(whd_interface_t ifp,uint16_t event_index)597 uint32_t whd_wifi_deregister_event_handler(whd_interface_t ifp, uint16_t event_index)
598 {
599 whd_driver_t whd_driver;
600 whd_cdc_bdc_info_t *cdc_bdc_info;
601
602 if (ifp == NULL)
603 {
604 return WHD_UNKNOWN_INTERFACE;
605 }
606
607 whd_driver = ifp->whd_driver;
608 cdc_bdc_info = &whd_driver->cdc_bdc_info;
609
610 if (event_index < WHD_EVENT_HANDLER_LIST_SIZE)
611 {
612 memset(cdc_bdc_info->whd_event_list[event_index].events, 0xFF,
613 (sizeof(cdc_bdc_info->whd_event_list[event_index].events) ) );
614 cdc_bdc_info->whd_event_list[event_index].handler = NULL;
615 cdc_bdc_info->whd_event_list[event_index].handler_user_data = NULL;
616 cdc_bdc_info->whd_event_list[event_index].event_set = WHD_FALSE;
617 return WHD_SUCCESS;
618 }
619 if (event_index == 0xFF)
620 {
621 WPRINT_WHD_INFO( ("Event handler not registered \n") );
622 return WHD_SUCCESS;
623 }
624 WPRINT_WHD_DEBUG( ("Invalid event index received to deregister the event handler \n") );
625 return WHD_BADARG;
626 }
627
whd_wifi_deregister_error_handler(whd_interface_t ifp,uint16_t error_index)628 uint32_t whd_wifi_deregister_error_handler(whd_interface_t ifp, uint16_t error_index)
629 {
630 whd_driver_t whd_driver;
631 whd_error_info_t *error_info;
632
633 if (ifp == NULL)
634 {
635 return WHD_UNKNOWN_INTERFACE;
636 }
637
638 whd_driver = ifp->whd_driver;
639 error_info = &whd_driver->error_info;
640
641 if (error_index < WHD_EVENT_HANDLER_LIST_SIZE)
642 {
643 error_info->whd_event_list[error_index].events = 0;
644 error_info->whd_event_list[error_index].handler = NULL;
645 error_info->whd_event_list[error_index].handler_user_data = NULL;
646 error_info->whd_event_list[error_index].event_set = WHD_FALSE;
647 return WHD_SUCCESS;
648 }
649 if (error_index == 0xFF)
650 {
651 WPRINT_WHD_INFO( ("Error handler not registered \n") );
652 return WHD_SUCCESS;
653 }
654 WPRINT_WHD_DEBUG( ("Invalid error index received to deregister the event handler \n") );
655 return WHD_BADARG;
656 }
657
658