Lines Matching +full:event +full:-

1 // SPDX-License-Identifier: ISC
20 * struct brcmf_fweh_queue_item - event item on event queue.
23 * @code: event code.
24 * @ifidx: interface index related to this event.
26 * @emsg: common parameters of the firmware event message.
28 * @data: event specific data part of the firmware event.
41 * struct brcmf_fweh_event_name - code, name mapping entry.
52 /* array for mapping code to event name */
59 * brcmf_fweh_event_name() - returns name for given event code.
80 * brcmf_fweh_queue_event() - create and queue event.
82 * @fweh: firmware event handling info.
83 * @event: event queue entry.
86 struct brcmf_fweh_queue_item *event) in brcmf_fweh_queue_event() argument
90 spin_lock_irqsave(&fweh->evt_q_lock, flags); in brcmf_fweh_queue_event()
91 list_add_tail(&event->q, &fweh->event_q); in brcmf_fweh_queue_event()
92 spin_unlock_irqrestore(&fweh->evt_q_lock, flags); in brcmf_fweh_queue_event()
93 schedule_work(&fweh->event_work); in brcmf_fweh_queue_event()
103 int err = -EINVAL; in brcmf_fweh_call_event_handler()
106 fweh = ifp->drvr->fweh; in brcmf_fweh_call_event_handler()
108 /* handle the event if valid interface and handler */ in brcmf_fweh_call_event_handler()
109 if (fweh->evt_handler[fwcode]) in brcmf_fweh_call_event_handler()
110 err = fweh->evt_handler[fwcode](ifp, emsg, data); in brcmf_fweh_call_event_handler()
120 * brcmf_fweh_handle_if_event() - handle IF event.
123 * @emsg: event message object.
124 * @data: event object.
134 brcmf_dbg(EVENT, "action: %u ifidx: %u bsscfgidx: %u flags: %u role: %u\n", in brcmf_fweh_handle_if_event()
135 ifevent->action, ifevent->ifidx, ifevent->bsscfgidx, in brcmf_fweh_handle_if_event()
136 ifevent->flags, ifevent->role); in brcmf_fweh_handle_if_event()
138 /* The P2P Device interface event must not be ignored contrary to what in brcmf_fweh_handle_if_event()
143 is_p2pdev = ((ifevent->flags & BRCMF_E_IF_FLAG_NOIF) && in brcmf_fweh_handle_if_event()
144 (ifevent->role == BRCMF_E_IF_ROLE_P2P_CLIENT || in brcmf_fweh_handle_if_event()
145 ((ifevent->role == BRCMF_E_IF_ROLE_STA) && in brcmf_fweh_handle_if_event()
146 (drvr->fweh->p2pdev_setup_ongoing)))); in brcmf_fweh_handle_if_event()
147 if (!is_p2pdev && (ifevent->flags & BRCMF_E_IF_FLAG_NOIF)) { in brcmf_fweh_handle_if_event()
148 brcmf_dbg(EVENT, "event can be ignored\n"); in brcmf_fweh_handle_if_event()
151 if (ifevent->ifidx >= BRCMF_MAX_IFS) { in brcmf_fweh_handle_if_event()
152 bphy_err(drvr, "invalid interface index: %u\n", ifevent->ifidx); in brcmf_fweh_handle_if_event()
156 ifp = drvr->iflist[ifevent->bsscfgidx]; in brcmf_fweh_handle_if_event()
158 if (ifevent->action == BRCMF_E_IF_ADD) { in brcmf_fweh_handle_if_event()
159 brcmf_dbg(EVENT, "adding %s (%pM)\n", emsg->ifname, in brcmf_fweh_handle_if_event()
160 emsg->addr); in brcmf_fweh_handle_if_event()
161 ifp = brcmf_add_if(drvr, ifevent->bsscfgidx, ifevent->ifidx, in brcmf_fweh_handle_if_event()
162 is_p2pdev, emsg->ifname, emsg->addr); in brcmf_fweh_handle_if_event()
167 if (!drvr->fweh->evt_handler[BRCMF_E_IF]) in brcmf_fweh_handle_if_event()
172 if (ifp && ifevent->action == BRCMF_E_IF_CHANGE) in brcmf_fweh_handle_if_event()
175 brcmf_fweh_call_event_handler(drvr, ifp, emsg->event_code, emsg, in brcmf_fweh_handle_if_event()
178 if (ifp && ifevent->action == BRCMF_E_IF_DEL) { in brcmf_fweh_handle_if_event()
179 bool armed = brcmf_cfg80211_vif_event_armed(drvr->config); in brcmf_fweh_handle_if_event()
181 /* Default handling in case no-one waits for this event */ in brcmf_fweh_handle_if_event()
197 if (fweh->event_map) { in brcmf_fweh_map_event_code()
198 for (i = 0; i < fweh->event_map->n_items; i++) { in brcmf_fweh_map_event_code()
199 if (fweh->event_map->items[i].code == code) { in brcmf_fweh_map_event_code()
200 *fw_code = fweh->event_map->items[i].fwevt_code; in brcmf_fweh_map_event_code()
216 if (fweh->event_map) { in brcmf_fweh_map_fwevt_code()
217 for (i = 0; i < fweh->event_map->n_items; i++) { in brcmf_fweh_map_fwevt_code()
218 if (fweh->event_map->items[i].fwevt_code == fw_code) { in brcmf_fweh_map_fwevt_code()
219 *code = fweh->event_map->items[i].code; in brcmf_fweh_map_fwevt_code()
227 * brcmf_fweh_dequeue_event() - get event from the queue.
229 * @fweh: firmware event handling info.
234 struct brcmf_fweh_queue_item *event = NULL; in brcmf_fweh_dequeue_event() local
237 spin_lock_irqsave(&fweh->evt_q_lock, flags); in brcmf_fweh_dequeue_event()
238 if (!list_empty(&fweh->event_q)) { in brcmf_fweh_dequeue_event()
239 event = list_first_entry(&fweh->event_q, in brcmf_fweh_dequeue_event()
241 list_del(&event->q); in brcmf_fweh_dequeue_event()
243 spin_unlock_irqrestore(&fweh->evt_q_lock, flags); in brcmf_fweh_dequeue_event()
245 return event; in brcmf_fweh_dequeue_event()
249 * brcmf_fweh_event_worker() - firmware event worker.
258 struct brcmf_fweh_queue_item *event; in brcmf_fweh_event_worker() local
264 drvr = fweh->drvr; in brcmf_fweh_event_worker()
266 while ((event = brcmf_fweh_dequeue_event(fweh))) { in brcmf_fweh_event_worker()
269 brcmf_fweh_map_fwevt_code(fweh, event->code, &code); in brcmf_fweh_event_worker()
270 brcmf_dbg(EVENT, "event %s (%u:%u) ifidx %u bsscfg %u addr %pM\n", in brcmf_fweh_event_worker()
271 brcmf_fweh_event_name(code), code, event->code, in brcmf_fweh_event_worker()
272 event->emsg.ifidx, event->emsg.bsscfgidx, in brcmf_fweh_event_worker()
273 event->emsg.addr); in brcmf_fweh_event_worker()
274 if (event->emsg.bsscfgidx >= BRCMF_MAX_IFS) { in brcmf_fweh_event_worker()
276 event->emsg.bsscfgidx); in brcmf_fweh_event_worker()
280 /* convert event message */ in brcmf_fweh_event_worker()
281 emsg_be = &event->emsg; in brcmf_fweh_event_worker()
282 emsg.version = be16_to_cpu(emsg_be->version); in brcmf_fweh_event_worker()
283 emsg.flags = be16_to_cpu(emsg_be->flags); in brcmf_fweh_event_worker()
285 emsg.status = be32_to_cpu(emsg_be->status); in brcmf_fweh_event_worker()
286 emsg.reason = be32_to_cpu(emsg_be->reason); in brcmf_fweh_event_worker()
287 emsg.auth_type = be32_to_cpu(emsg_be->auth_type); in brcmf_fweh_event_worker()
288 emsg.datalen = be32_to_cpu(emsg_be->datalen); in brcmf_fweh_event_worker()
289 memcpy(emsg.addr, emsg_be->addr, ETH_ALEN); in brcmf_fweh_event_worker()
290 memcpy(emsg.ifname, emsg_be->ifname, sizeof(emsg.ifname)); in brcmf_fweh_event_worker()
291 emsg.ifidx = emsg_be->ifidx; in brcmf_fweh_event_worker()
292 emsg.bsscfgidx = emsg_be->bsscfgidx; in brcmf_fweh_event_worker()
294 brcmf_dbg(EVENT, " version %u flags %u status %u reason %u\n", in brcmf_fweh_event_worker()
296 brcmf_dbg_hex_dump(BRCMF_EVENT_ON(), event->data, in brcmf_fweh_event_worker()
298 "event payload, len=%d\n", emsg.datalen); in brcmf_fweh_event_worker()
300 /* special handling of interface event */ in brcmf_fweh_event_worker()
301 if (event->code == BRCMF_E_IF) { in brcmf_fweh_event_worker()
302 brcmf_fweh_handle_if_event(drvr, &emsg, event->data); in brcmf_fweh_event_worker()
306 if (event->code == BRCMF_E_TDLS_PEER_EVENT) in brcmf_fweh_event_worker()
307 ifp = drvr->iflist[0]; in brcmf_fweh_event_worker()
309 ifp = drvr->iflist[emsg.bsscfgidx]; in brcmf_fweh_event_worker()
310 err = brcmf_fweh_call_event_handler(drvr, ifp, event->code, in brcmf_fweh_event_worker()
311 &emsg, event->data); in brcmf_fweh_event_worker()
313 bphy_err(drvr, "event handler failed (%d)\n", in brcmf_fweh_event_worker()
314 event->code); in brcmf_fweh_event_worker()
318 kfree(event); in brcmf_fweh_event_worker()
323 * brcmf_fweh_p2pdev_setup() - P2P device setup ongoing (or not).
330 ifp->drvr->fweh->p2pdev_setup_ongoing = ongoing; in brcmf_fweh_p2pdev_setup()
334 * brcmf_fweh_attach() - initialize firmware event handling.
347 fweh = drvr->fweh; in brcmf_fweh_attach()
348 fweh->drvr = drvr; in brcmf_fweh_attach()
350 fweh->event_mask_len = DIV_ROUND_UP(fweh->num_event_codes, 8); in brcmf_fweh_attach()
351 fweh->event_mask = kzalloc(fweh->event_mask_len, GFP_KERNEL); in brcmf_fweh_attach()
352 if (!fweh->event_mask) in brcmf_fweh_attach()
353 return -ENOMEM; in brcmf_fweh_attach()
355 INIT_WORK(&fweh->event_work, brcmf_fweh_event_worker); in brcmf_fweh_attach()
356 spin_lock_init(&fweh->evt_q_lock); in brcmf_fweh_attach()
357 INIT_LIST_HEAD(&fweh->event_q); in brcmf_fweh_attach()
362 * brcmf_fweh_detach() - cleanup firmware event handling.
368 struct brcmf_fweh_info *fweh = drvr->fweh; in brcmf_fweh_detach()
374 if (fweh->event_work.func) { in brcmf_fweh_detach()
375 cancel_work_sync(&fweh->event_work); in brcmf_fweh_detach()
376 WARN_ON(!list_empty(&fweh->event_q)); in brcmf_fweh_detach()
378 drvr->fweh = NULL; in brcmf_fweh_detach()
379 kfree(fweh->event_mask); in brcmf_fweh_detach()
384 * brcmf_fweh_register() - register handler for given event code.
387 * @code: event code.
388 * @handler: handler for the given event code.
393 struct brcmf_fweh_info *fweh = drvr->fweh; in brcmf_fweh_register()
398 if (fweh->evt_handler[evt_handler_idx]) { in brcmf_fweh_register()
399 bphy_err(drvr, "event code %d already registered\n", code); in brcmf_fweh_register()
400 return -ENOSPC; in brcmf_fweh_register()
403 fweh->evt_handler[evt_handler_idx] = handler; in brcmf_fweh_register()
404 brcmf_dbg(TRACE, "event handler registered for %s\n", in brcmf_fweh_register()
410 * brcmf_fweh_unregister() - remove handler for given code.
413 * @code: event code.
420 brcmf_dbg(TRACE, "event handler cleared for %s\n", in brcmf_fweh_unregister()
422 brcmf_fweh_map_event_code(drvr->fweh, code, &evt_handler_idx); in brcmf_fweh_unregister()
423 drvr->fweh->evt_handler[evt_handler_idx] = NULL; in brcmf_fweh_unregister()
427 * brcmf_fweh_activate_events() - enables firmware events registered.
433 struct brcmf_fweh_info *fweh = ifp->drvr->fweh; in brcmf_fweh_activate_events()
437 memset(fweh->event_mask, 0, fweh->event_mask_len); in brcmf_fweh_activate_events()
438 for (i = 0; i < fweh->num_event_codes; i++) { in brcmf_fweh_activate_events()
439 if (fweh->evt_handler[i]) { in brcmf_fweh_activate_events()
441 brcmf_dbg(EVENT, "enable event %s\n", in brcmf_fweh_activate_events()
443 setbit(fweh->event_mask, i); in brcmf_fweh_activate_events()
447 /* want to handle IF event as well */ in brcmf_fweh_activate_events()
448 brcmf_dbg(EVENT, "enable event IF\n"); in brcmf_fweh_activate_events()
449 setbit(fweh->event_mask, BRCMF_E_IF); in brcmf_fweh_activate_events()
451 err = brcmf_fil_iovar_data_set(ifp, "event_msgs", fweh->event_mask, in brcmf_fweh_activate_events()
452 fweh->event_mask_len); in brcmf_fweh_activate_events()
454 bphy_err(fweh->drvr, "Set event_msgs error (%d)\n", err); in brcmf_fweh_activate_events()
460 * brcmf_fweh_process_event() - process skb as firmware event.
463 * @event_packet: event packet to process.
467 * If the packet buffer contains a firmware event message it will
468 * dispatch the event to a registered handler (using worker).
475 struct brcmf_fweh_info *fweh = drvr->fweh; in brcmf_fweh_process_event()
476 struct brcmf_fweh_queue_item *event; in brcmf_fweh_process_event() local
480 /* get event info */ in brcmf_fweh_process_event()
481 fwevt_idx = get_unaligned_be32(&event_packet->msg.event_type); in brcmf_fweh_process_event()
482 datalen = get_unaligned_be32(&event_packet->msg.datalen); in brcmf_fweh_process_event()
485 if (fwevt_idx >= fweh->num_event_codes) in brcmf_fweh_process_event()
488 if (fwevt_idx != BRCMF_E_IF && !fweh->evt_handler[fwevt_idx]) in brcmf_fweh_process_event()
495 event = kzalloc(struct_size(event, data, datalen), gfp); in brcmf_fweh_process_event()
496 if (!event) in brcmf_fweh_process_event()
499 event->code = fwevt_idx; in brcmf_fweh_process_event()
500 event->datalen = datalen; in brcmf_fweh_process_event()
501 event->ifidx = event_packet->msg.ifidx; in brcmf_fweh_process_event()
503 /* use memcpy to get aligned event message */ in brcmf_fweh_process_event()
504 memcpy(&event->emsg, &event_packet->msg, sizeof(event->emsg)); in brcmf_fweh_process_event()
505 memcpy(event->data, data, datalen); in brcmf_fweh_process_event()
506 memcpy(event->ifaddr, event_packet->eth.h_dest, ETH_ALEN); in brcmf_fweh_process_event()
508 brcmf_fweh_queue_event(fweh, event); in brcmf_fweh_process_event()