Lines Matching +full:event +full:-
1 // SPDX-License-Identifier: ISC
19 * struct brcmf_fweh_queue_item - event item on event queue.
22 * @code: event code.
23 * @ifidx: interface index related to this event.
25 * @emsg: common parameters of the firmware event message.
27 * @data: event specific data part of the firmware event.
40 * struct brcmf_fweh_event_name - code, name mapping entry.
51 /* array for mapping code to event name */
58 * brcmf_fweh_event_name() - returns name for given event code.
79 * brcmf_fweh_queue_event() - create and queue event.
81 * @fweh: firmware event handling info.
82 * @event: event queue entry.
85 struct brcmf_fweh_queue_item *event) in brcmf_fweh_queue_event() argument
89 spin_lock_irqsave(&fweh->evt_q_lock, flags); in brcmf_fweh_queue_event()
90 list_add_tail(&event->q, &fweh->event_q); in brcmf_fweh_queue_event()
91 spin_unlock_irqrestore(&fweh->evt_q_lock, flags); in brcmf_fweh_queue_event()
92 schedule_work(&fweh->event_work); in brcmf_fweh_queue_event()
102 int err = -EINVAL; in brcmf_fweh_call_event_handler()
105 fweh = &ifp->drvr->fweh; in brcmf_fweh_call_event_handler()
107 /* handle the event if valid interface and handler */ in brcmf_fweh_call_event_handler()
108 if (fweh->evt_handler[code]) in brcmf_fweh_call_event_handler()
109 err = fweh->evt_handler[code](ifp, emsg, data); in brcmf_fweh_call_event_handler()
111 bphy_err(drvr, "unhandled event %d ignored\n", code); in brcmf_fweh_call_event_handler()
119 * brcmf_fweh_handle_if_event() - handle IF event.
122 * @emsg: event message object.
123 * @data: event object.
133 brcmf_dbg(EVENT, "action: %u ifidx: %u bsscfgidx: %u flags: %u role: %u\n", in brcmf_fweh_handle_if_event()
134 ifevent->action, ifevent->ifidx, ifevent->bsscfgidx, in brcmf_fweh_handle_if_event()
135 ifevent->flags, ifevent->role); in brcmf_fweh_handle_if_event()
137 /* The P2P Device interface event must not be ignored contrary to what in brcmf_fweh_handle_if_event()
142 is_p2pdev = ((ifevent->flags & BRCMF_E_IF_FLAG_NOIF) && in brcmf_fweh_handle_if_event()
143 (ifevent->role == BRCMF_E_IF_ROLE_P2P_CLIENT || in brcmf_fweh_handle_if_event()
144 ((ifevent->role == BRCMF_E_IF_ROLE_STA) && in brcmf_fweh_handle_if_event()
145 (drvr->fweh.p2pdev_setup_ongoing)))); in brcmf_fweh_handle_if_event()
146 if (!is_p2pdev && (ifevent->flags & BRCMF_E_IF_FLAG_NOIF)) { in brcmf_fweh_handle_if_event()
147 brcmf_dbg(EVENT, "event can be ignored\n"); in brcmf_fweh_handle_if_event()
150 if (ifevent->ifidx >= BRCMF_MAX_IFS) { in brcmf_fweh_handle_if_event()
151 bphy_err(drvr, "invalid interface index: %u\n", ifevent->ifidx); in brcmf_fweh_handle_if_event()
155 ifp = drvr->iflist[ifevent->bsscfgidx]; in brcmf_fweh_handle_if_event()
157 if (ifevent->action == BRCMF_E_IF_ADD) { in brcmf_fweh_handle_if_event()
158 brcmf_dbg(EVENT, "adding %s (%pM)\n", emsg->ifname, in brcmf_fweh_handle_if_event()
159 emsg->addr); in brcmf_fweh_handle_if_event()
160 ifp = brcmf_add_if(drvr, ifevent->bsscfgidx, ifevent->ifidx, in brcmf_fweh_handle_if_event()
161 is_p2pdev, emsg->ifname, emsg->addr); in brcmf_fweh_handle_if_event()
166 if (!drvr->fweh.evt_handler[BRCMF_E_IF]) in brcmf_fweh_handle_if_event()
171 if (ifp && ifevent->action == BRCMF_E_IF_CHANGE) in brcmf_fweh_handle_if_event()
174 brcmf_fweh_call_event_handler(drvr, ifp, emsg->event_code, emsg, in brcmf_fweh_handle_if_event()
177 if (ifp && ifevent->action == BRCMF_E_IF_DEL) { in brcmf_fweh_handle_if_event()
178 bool armed = brcmf_cfg80211_vif_event_armed(drvr->config); in brcmf_fweh_handle_if_event()
180 /* Default handling in case no-one waits for this event */ in brcmf_fweh_handle_if_event()
187 * brcmf_fweh_dequeue_event() - get event from the queue.
189 * @fweh: firmware event handling info.
194 struct brcmf_fweh_queue_item *event = NULL; in brcmf_fweh_dequeue_event() local
197 spin_lock_irqsave(&fweh->evt_q_lock, flags); in brcmf_fweh_dequeue_event()
198 if (!list_empty(&fweh->event_q)) { in brcmf_fweh_dequeue_event()
199 event = list_first_entry(&fweh->event_q, in brcmf_fweh_dequeue_event()
201 list_del(&event->q); in brcmf_fweh_dequeue_event()
203 spin_unlock_irqrestore(&fweh->evt_q_lock, flags); in brcmf_fweh_dequeue_event()
205 return event; in brcmf_fweh_dequeue_event()
209 * brcmf_fweh_event_worker() - firmware event worker.
218 struct brcmf_fweh_queue_item *event; in brcmf_fweh_event_worker() local
226 while ((event = brcmf_fweh_dequeue_event(fweh))) { in brcmf_fweh_event_worker()
227 brcmf_dbg(EVENT, "event %s (%u) ifidx %u bsscfg %u addr %pM\n", in brcmf_fweh_event_worker()
228 brcmf_fweh_event_name(event->code), event->code, in brcmf_fweh_event_worker()
229 event->emsg.ifidx, event->emsg.bsscfgidx, in brcmf_fweh_event_worker()
230 event->emsg.addr); in brcmf_fweh_event_worker()
231 if (event->emsg.bsscfgidx >= BRCMF_MAX_IFS) { in brcmf_fweh_event_worker()
232 bphy_err(drvr, "invalid bsscfg index: %u\n", event->emsg.bsscfgidx); in brcmf_fweh_event_worker()
236 /* convert event message */ in brcmf_fweh_event_worker()
237 emsg_be = &event->emsg; in brcmf_fweh_event_worker()
238 emsg.version = be16_to_cpu(emsg_be->version); in brcmf_fweh_event_worker()
239 emsg.flags = be16_to_cpu(emsg_be->flags); in brcmf_fweh_event_worker()
240 emsg.event_code = event->code; in brcmf_fweh_event_worker()
241 emsg.status = be32_to_cpu(emsg_be->status); in brcmf_fweh_event_worker()
242 emsg.reason = be32_to_cpu(emsg_be->reason); in brcmf_fweh_event_worker()
243 emsg.auth_type = be32_to_cpu(emsg_be->auth_type); in brcmf_fweh_event_worker()
244 emsg.datalen = be32_to_cpu(emsg_be->datalen); in brcmf_fweh_event_worker()
245 memcpy(emsg.addr, emsg_be->addr, ETH_ALEN); in brcmf_fweh_event_worker()
246 memcpy(emsg.ifname, emsg_be->ifname, sizeof(emsg.ifname)); in brcmf_fweh_event_worker()
247 emsg.ifidx = emsg_be->ifidx; in brcmf_fweh_event_worker()
248 emsg.bsscfgidx = emsg_be->bsscfgidx; in brcmf_fweh_event_worker()
250 brcmf_dbg(EVENT, " version %u flags %u status %u reason %u\n", in brcmf_fweh_event_worker()
252 brcmf_dbg_hex_dump(BRCMF_EVENT_ON(), event->data, in brcmf_fweh_event_worker()
254 "event payload, len=%d\n", emsg.datalen); in brcmf_fweh_event_worker()
256 /* special handling of interface event */ in brcmf_fweh_event_worker()
257 if (event->code == BRCMF_E_IF) { in brcmf_fweh_event_worker()
258 brcmf_fweh_handle_if_event(drvr, &emsg, event->data); in brcmf_fweh_event_worker()
262 if (event->code == BRCMF_E_TDLS_PEER_EVENT) in brcmf_fweh_event_worker()
263 ifp = drvr->iflist[0]; in brcmf_fweh_event_worker()
265 ifp = drvr->iflist[emsg.bsscfgidx]; in brcmf_fweh_event_worker()
266 err = brcmf_fweh_call_event_handler(drvr, ifp, event->code, in brcmf_fweh_event_worker()
267 &emsg, event->data); in brcmf_fweh_event_worker()
269 bphy_err(drvr, "event handler failed (%d)\n", in brcmf_fweh_event_worker()
270 event->code); in brcmf_fweh_event_worker()
274 kfree(event); in brcmf_fweh_event_worker()
279 * brcmf_fweh_p2pdev_setup() - P2P device setup ongoing (or not).
286 ifp->drvr->fweh.p2pdev_setup_ongoing = ongoing; in brcmf_fweh_p2pdev_setup()
290 * brcmf_fweh_attach() - initialize firmware event handling.
296 struct brcmf_fweh_info *fweh = &drvr->fweh; in brcmf_fweh_attach()
297 INIT_WORK(&fweh->event_work, brcmf_fweh_event_worker); in brcmf_fweh_attach()
298 spin_lock_init(&fweh->evt_q_lock); in brcmf_fweh_attach()
299 INIT_LIST_HEAD(&fweh->event_q); in brcmf_fweh_attach()
303 * brcmf_fweh_detach() - cleanup firmware event handling.
309 struct brcmf_fweh_info *fweh = &drvr->fweh; in brcmf_fweh_detach()
312 if (fweh->event_work.func) { in brcmf_fweh_detach()
313 cancel_work_sync(&fweh->event_work); in brcmf_fweh_detach()
314 WARN_ON(!list_empty(&fweh->event_q)); in brcmf_fweh_detach()
315 memset(fweh->evt_handler, 0, sizeof(fweh->evt_handler)); in brcmf_fweh_detach()
320 * brcmf_fweh_register() - register handler for given event code.
323 * @code: event code.
324 * @handler: handler for the given event code.
329 if (drvr->fweh.evt_handler[code]) { in brcmf_fweh_register()
330 bphy_err(drvr, "event code %d already registered\n", code); in brcmf_fweh_register()
331 return -ENOSPC; in brcmf_fweh_register()
333 drvr->fweh.evt_handler[code] = handler; in brcmf_fweh_register()
334 brcmf_dbg(TRACE, "event handler registered for %s\n", in brcmf_fweh_register()
340 * brcmf_fweh_unregister() - remove handler for given code.
343 * @code: event code.
348 brcmf_dbg(TRACE, "event handler cleared for %s\n", in brcmf_fweh_unregister()
350 drvr->fweh.evt_handler[code] = NULL; in brcmf_fweh_unregister()
354 * brcmf_fweh_activate_events() - enables firmware events registered.
360 struct brcmf_pub *drvr = ifp->drvr; in brcmf_fweh_activate_events()
366 if (ifp->drvr->fweh.evt_handler[i]) { in brcmf_fweh_activate_events()
367 brcmf_dbg(EVENT, "enable event %s\n", in brcmf_fweh_activate_events()
373 /* want to handle IF event as well */ in brcmf_fweh_activate_events()
374 brcmf_dbg(EVENT, "enable event IF\n"); in brcmf_fweh_activate_events()
386 * brcmf_fweh_process_event() - process skb as firmware event.
389 * @event_packet: event packet to process.
393 * If the packet buffer contains a firmware event message it will
394 * dispatch the event to a registered handler (using worker).
401 struct brcmf_fweh_info *fweh = &drvr->fweh; in brcmf_fweh_process_event()
402 struct brcmf_fweh_queue_item *event; in brcmf_fweh_process_event() local
406 /* get event info */ in brcmf_fweh_process_event()
407 code = get_unaligned_be32(&event_packet->msg.event_type); in brcmf_fweh_process_event()
408 datalen = get_unaligned_be32(&event_packet->msg.datalen); in brcmf_fweh_process_event()
414 if (code != BRCMF_E_IF && !fweh->evt_handler[code]) in brcmf_fweh_process_event()
421 event = kzalloc(sizeof(*event) + datalen, gfp); in brcmf_fweh_process_event()
422 if (!event) in brcmf_fweh_process_event()
425 event->code = code; in brcmf_fweh_process_event()
426 event->ifidx = event_packet->msg.ifidx; in brcmf_fweh_process_event()
428 /* use memcpy to get aligned event message */ in brcmf_fweh_process_event()
429 memcpy(&event->emsg, &event_packet->msg, sizeof(event->emsg)); in brcmf_fweh_process_event()
430 memcpy(event->data, data, datalen); in brcmf_fweh_process_event()
431 event->datalen = datalen; in brcmf_fweh_process_event()
432 memcpy(event->ifaddr, event_packet->eth.h_dest, ETH_ALEN); in brcmf_fweh_process_event()
434 brcmf_fweh_queue_event(fweh, event); in brcmf_fweh_process_event()