int brcmf_c_host_event(struct brcmf_info *drvr_priv, int *ifidx, void *pktdata, struct brcmf_event_msg *event, void **data_ptr) { /* check whether packet is a BRCM event pkt */ struct brcmf_event *pvt_data = (struct brcmf_event *) pktdata; char *event_data; u32 type, status; u16 flags; int evlen; if (memcmp(BRCM_OUI, &pvt_data->hdr.oui[0], DOT11_OUI_LEN)) { BRCMF_ERROR(("%s: mismatched OUI, bailing\n", __func__)); return -EBADE; } /* BRCM event pkt may be unaligned - use xxx_ua to load user_subtype. */ if (get_unaligned_be16(&pvt_data->hdr.usr_subtype) != BCMILCP_BCM_SUBTYPE_EVENT) { BRCMF_ERROR(("%s: mismatched subtype, bailing\n", __func__)); return -EBADE; } *data_ptr = &pvt_data[1]; event_data = *data_ptr; /* memcpy since BRCM event pkt may be unaligned. */ memcpy(event, &pvt_data->msg, sizeof(struct brcmf_event_msg)); type = get_unaligned_be32(&event->event_type); flags = get_unaligned_be16(&event->flags); status = get_unaligned_be32(&event->status); evlen = get_unaligned_be32(&event->datalen) + sizeof(struct brcmf_event); switch (type) { case BRCMF_E_IF: { struct brcmf_if_event *ifevent = (struct brcmf_if_event *) event_data; BRCMF_TRACE(("%s: if event\n", __func__)); if (ifevent->ifidx > 0 && ifevent->ifidx < BRCMF_MAX_IFS) { if (ifevent->action == BRCMF_E_IF_ADD) brcmf_add_if(drvr_priv, ifevent->ifidx, NULL, event->ifname, pvt_data->eth.h_dest, ifevent->flags, ifevent->bssidx); else brcmf_del_if(drvr_priv, ifevent->ifidx); } else { BRCMF_ERROR(("%s: Invalid ifidx %d for %s\n", __func__, ifevent->ifidx, event->ifname)); } } /* send up the if event: btamp user needs it */ *ifidx = brcmf_ifname2idx(drvr_priv, event->ifname); break; /* These are what external supplicant/authenticator wants */ case BRCMF_E_LINK: case BRCMF_E_ASSOC_IND: case BRCMF_E_REASSOC_IND: case BRCMF_E_DISASSOC_IND: case BRCMF_E_MIC_ERROR: default: /* Fall through: this should get _everything_ */ *ifidx = brcmf_ifname2idx(drvr_priv, event->ifname); BRCMF_TRACE(("%s: MAC event %d, flags %x, status %x\n", __func__, type, flags, status)); /* put it back to BRCMF_E_NDIS_LINK */ if (type == BRCMF_E_NDIS_LINK) { u32 temp; temp = get_unaligned_be32(&event->event_type); BRCMF_TRACE(("Converted to WLC_E_LINK type %d\n", temp)); temp = be32_to_cpu(BRCMF_E_NDIS_LINK); memcpy((void *)(&pvt_data->msg.event_type), &temp, sizeof(pvt_data->msg.event_type)); } break; } #ifdef SHOW_EVENTS brcmf_c_show_host_event(event, event_data); #endif /* SHOW_EVENTS */ return 0; }
int brcmf_c_host_event(struct brcmf_pub *drvr, int *ifidx, void *pktdata, struct brcmf_event_msg *event, void **data_ptr) { struct brcmf_event *pvt_data = (struct brcmf_event *) pktdata; struct brcmf_if_event *ifevent; char *event_data; u32 type, status; u16 flags; int evlen; if (memcmp(BRCM_OUI, &pvt_data->hdr.oui[0], DOT11_OUI_LEN)) { brcmf_dbg(ERROR, "mismatched OUI, bailing\n"); return -EBADE; } if (get_unaligned_be16(&pvt_data->hdr.usr_subtype) != BCMILCP_BCM_SUBTYPE_EVENT) { brcmf_dbg(ERROR, "mismatched subtype, bailing\n"); return -EBADE; } *data_ptr = &pvt_data[1]; event_data = *data_ptr; memcpy(event, &pvt_data->msg, sizeof(struct brcmf_event_msg)); type = get_unaligned_be32(&event->event_type); flags = get_unaligned_be16(&event->flags); status = get_unaligned_be32(&event->status); evlen = get_unaligned_be32(&event->datalen) + sizeof(struct brcmf_event); switch (type) { case BRCMF_E_IF: ifevent = (struct brcmf_if_event *) event_data; brcmf_dbg(TRACE, "if event\n"); if (ifevent->ifidx > 0 && ifevent->ifidx < BRCMF_MAX_IFS) { if (ifevent->action == BRCMF_E_IF_ADD) brcmf_add_if(drvr->dev, ifevent->ifidx, event->ifname, pvt_data->eth.h_dest); else brcmf_del_if(drvr, ifevent->ifidx); } else { brcmf_dbg(ERROR, "Invalid ifidx %d for %s\n", ifevent->ifidx, event->ifname); } *ifidx = brcmf_ifname2idx(drvr, event->ifname); break; case BRCMF_E_LINK: case BRCMF_E_ASSOC_IND: case BRCMF_E_REASSOC_IND: case BRCMF_E_DISASSOC_IND: case BRCMF_E_MIC_ERROR: default: *ifidx = brcmf_ifname2idx(drvr, event->ifname); brcmf_dbg(TRACE, "MAC event %d, flags %x, status %x\n", type, flags, status); if (type == BRCMF_E_NDIS_LINK) { u32 temp1; __be32 temp2; temp1 = get_unaligned_be32(&event->event_type); brcmf_dbg(TRACE, "Converted to WLC_E_LINK type %d\n", temp1); temp2 = cpu_to_be32(BRCMF_E_NDIS_LINK); memcpy((void *)(&pvt_data->msg.event_type), &temp2, sizeof(pvt_data->msg.event_type)); } break; } #ifdef DEBUG brcmf_c_show_host_event(event, event_data); #endif return 0; }