1daeccac2SArend van Spriel // SPDX-License-Identifier: ISC 205491d2cSKalle Valo /* 305491d2cSKalle Valo * Copyright (c) 2012 Broadcom Corporation 405491d2cSKalle Valo */ 505491d2cSKalle Valo 605491d2cSKalle Valo 705491d2cSKalle Valo #ifndef FWEH_H_ 805491d2cSKalle Valo #define FWEH_H_ 905491d2cSKalle Valo 10*5f60d5f6SAl Viro #include <linux/unaligned.h> 1105491d2cSKalle Valo #include <linux/skbuff.h> 1205491d2cSKalle Valo #include <linux/if_ether.h> 1305491d2cSKalle Valo #include <linux/if.h> 1405491d2cSKalle Valo 1505491d2cSKalle Valo /* formward declarations */ 1605491d2cSKalle Valo struct brcmf_pub; 1705491d2cSKalle Valo struct brcmf_if; 1805491d2cSKalle Valo struct brcmf_cfg80211_info; 1905491d2cSKalle Valo 20edec4282SArend van Spriel #define BRCMF_ABSTRACT_EVENT_BIT BIT(31) 21edec4282SArend van Spriel #define BRCMF_ABSTRACT_ENUM_DEF(_id, _val) \ 22edec4282SArend van Spriel BRCMF_ENUM_DEF(_id, (BRCMF_ABSTRACT_EVENT_BIT | (_val))) 23edec4282SArend van Spriel 2405491d2cSKalle Valo /* list of firmware events */ 2505491d2cSKalle Valo #define BRCMF_FWEH_EVENT_ENUM_DEFLIST \ 2605491d2cSKalle Valo BRCMF_ENUM_DEF(SET_SSID, 0) \ 2705491d2cSKalle Valo BRCMF_ENUM_DEF(JOIN, 1) \ 2805491d2cSKalle Valo BRCMF_ENUM_DEF(START, 2) \ 2905491d2cSKalle Valo BRCMF_ENUM_DEF(AUTH, 3) \ 3005491d2cSKalle Valo BRCMF_ENUM_DEF(AUTH_IND, 4) \ 3105491d2cSKalle Valo BRCMF_ENUM_DEF(DEAUTH, 5) \ 3205491d2cSKalle Valo BRCMF_ENUM_DEF(DEAUTH_IND, 6) \ 3305491d2cSKalle Valo BRCMF_ENUM_DEF(ASSOC, 7) \ 3405491d2cSKalle Valo BRCMF_ENUM_DEF(ASSOC_IND, 8) \ 3505491d2cSKalle Valo BRCMF_ENUM_DEF(REASSOC, 9) \ 3605491d2cSKalle Valo BRCMF_ENUM_DEF(REASSOC_IND, 10) \ 3705491d2cSKalle Valo BRCMF_ENUM_DEF(DISASSOC, 11) \ 3805491d2cSKalle Valo BRCMF_ENUM_DEF(DISASSOC_IND, 12) \ 3905491d2cSKalle Valo BRCMF_ENUM_DEF(QUIET_START, 13) \ 4005491d2cSKalle Valo BRCMF_ENUM_DEF(QUIET_END, 14) \ 4105491d2cSKalle Valo BRCMF_ENUM_DEF(BEACON_RX, 15) \ 4205491d2cSKalle Valo BRCMF_ENUM_DEF(LINK, 16) \ 4305491d2cSKalle Valo BRCMF_ENUM_DEF(MIC_ERROR, 17) \ 4405491d2cSKalle Valo BRCMF_ENUM_DEF(NDIS_LINK, 18) \ 4505491d2cSKalle Valo BRCMF_ENUM_DEF(ROAM, 19) \ 4605491d2cSKalle Valo BRCMF_ENUM_DEF(TXFAIL, 20) \ 4705491d2cSKalle Valo BRCMF_ENUM_DEF(PMKID_CACHE, 21) \ 4805491d2cSKalle Valo BRCMF_ENUM_DEF(RETROGRADE_TSF, 22) \ 4905491d2cSKalle Valo BRCMF_ENUM_DEF(PRUNE, 23) \ 5005491d2cSKalle Valo BRCMF_ENUM_DEF(AUTOAUTH, 24) \ 5105491d2cSKalle Valo BRCMF_ENUM_DEF(EAPOL_MSG, 25) \ 5205491d2cSKalle Valo BRCMF_ENUM_DEF(SCAN_COMPLETE, 26) \ 5305491d2cSKalle Valo BRCMF_ENUM_DEF(ADDTS_IND, 27) \ 5405491d2cSKalle Valo BRCMF_ENUM_DEF(DELTS_IND, 28) \ 5505491d2cSKalle Valo BRCMF_ENUM_DEF(BCNSENT_IND, 29) \ 5605491d2cSKalle Valo BRCMF_ENUM_DEF(BCNRX_MSG, 30) \ 5705491d2cSKalle Valo BRCMF_ENUM_DEF(BCNLOST_MSG, 31) \ 5805491d2cSKalle Valo BRCMF_ENUM_DEF(ROAM_PREP, 32) \ 5905491d2cSKalle Valo BRCMF_ENUM_DEF(PFN_NET_FOUND, 33) \ 6005491d2cSKalle Valo BRCMF_ENUM_DEF(PFN_NET_LOST, 34) \ 6105491d2cSKalle Valo BRCMF_ENUM_DEF(RESET_COMPLETE, 35) \ 6205491d2cSKalle Valo BRCMF_ENUM_DEF(JOIN_START, 36) \ 6305491d2cSKalle Valo BRCMF_ENUM_DEF(ROAM_START, 37) \ 6405491d2cSKalle Valo BRCMF_ENUM_DEF(ASSOC_START, 38) \ 6505491d2cSKalle Valo BRCMF_ENUM_DEF(IBSS_ASSOC, 39) \ 6605491d2cSKalle Valo BRCMF_ENUM_DEF(RADIO, 40) \ 6705491d2cSKalle Valo BRCMF_ENUM_DEF(PSM_WATCHDOG, 41) \ 6805491d2cSKalle Valo BRCMF_ENUM_DEF(PROBREQ_MSG, 44) \ 6905491d2cSKalle Valo BRCMF_ENUM_DEF(SCAN_CONFIRM_IND, 45) \ 7005491d2cSKalle Valo BRCMF_ENUM_DEF(PSK_SUP, 46) \ 7105491d2cSKalle Valo BRCMF_ENUM_DEF(COUNTRY_CODE_CHANGED, 47) \ 7205491d2cSKalle Valo BRCMF_ENUM_DEF(EXCEEDED_MEDIUM_TIME, 48) \ 7305491d2cSKalle Valo BRCMF_ENUM_DEF(ICV_ERROR, 49) \ 7405491d2cSKalle Valo BRCMF_ENUM_DEF(UNICAST_DECODE_ERROR, 50) \ 7505491d2cSKalle Valo BRCMF_ENUM_DEF(MULTICAST_DECODE_ERROR, 51) \ 7605491d2cSKalle Valo BRCMF_ENUM_DEF(TRACE, 52) \ 7705491d2cSKalle Valo BRCMF_ENUM_DEF(IF, 54) \ 7805491d2cSKalle Valo BRCMF_ENUM_DEF(P2P_DISC_LISTEN_COMPLETE, 55) \ 7905491d2cSKalle Valo BRCMF_ENUM_DEF(RSSI, 56) \ 8005491d2cSKalle Valo BRCMF_ENUM_DEF(EXTLOG_MSG, 58) \ 8105491d2cSKalle Valo BRCMF_ENUM_DEF(ACTION_FRAME, 59) \ 8205491d2cSKalle Valo BRCMF_ENUM_DEF(ACTION_FRAME_COMPLETE, 60) \ 8305491d2cSKalle Valo BRCMF_ENUM_DEF(PRE_ASSOC_IND, 61) \ 8405491d2cSKalle Valo BRCMF_ENUM_DEF(PRE_REASSOC_IND, 62) \ 8505491d2cSKalle Valo BRCMF_ENUM_DEF(CHANNEL_ADOPTED, 63) \ 8605491d2cSKalle Valo BRCMF_ENUM_DEF(AP_STARTED, 64) \ 8705491d2cSKalle Valo BRCMF_ENUM_DEF(DFS_AP_STOP, 65) \ 8805491d2cSKalle Valo BRCMF_ENUM_DEF(DFS_AP_RESUME, 66) \ 8905491d2cSKalle Valo BRCMF_ENUM_DEF(ESCAN_RESULT, 69) \ 9005491d2cSKalle Valo BRCMF_ENUM_DEF(ACTION_FRAME_OFF_CHAN_COMPLETE, 70) \ 9105491d2cSKalle Valo BRCMF_ENUM_DEF(PROBERESP_MSG, 71) \ 9205491d2cSKalle Valo BRCMF_ENUM_DEF(P2P_PROBEREQ_MSG, 72) \ 9305491d2cSKalle Valo BRCMF_ENUM_DEF(DCS_REQUEST, 73) \ 9405491d2cSKalle Valo BRCMF_ENUM_DEF(FIFO_CREDIT_MAP, 74) \ 9505491d2cSKalle Valo BRCMF_ENUM_DEF(ACTION_FRAME_RX, 75) \ 9605491d2cSKalle Valo BRCMF_ENUM_DEF(TDLS_PEER_EVENT, 92) \ 9705491d2cSKalle Valo BRCMF_ENUM_DEF(BCMC_CREDIT_SUPPORT, 127) 9805491d2cSKalle Valo 9905491d2cSKalle Valo #define BRCMF_ENUM_DEF(id, val) \ 10005491d2cSKalle Valo BRCMF_E_##id = (val), 10105491d2cSKalle Valo 10205491d2cSKalle Valo /* firmware event codes sent by the dongle */ 10305491d2cSKalle Valo enum brcmf_fweh_event_code { 10405491d2cSKalle Valo BRCMF_FWEH_EVENT_ENUM_DEFLIST 10505491d2cSKalle Valo }; 10605491d2cSKalle Valo #undef BRCMF_ENUM_DEF 10705491d2cSKalle Valo 10805491d2cSKalle Valo /* flags field values in struct brcmf_event_msg */ 10905491d2cSKalle Valo #define BRCMF_EVENT_MSG_LINK 0x01 11005491d2cSKalle Valo #define BRCMF_EVENT_MSG_FLUSHTXQ 0x02 11105491d2cSKalle Valo #define BRCMF_EVENT_MSG_GROUP 0x04 11205491d2cSKalle Valo 11305491d2cSKalle Valo /* status field values in struct brcmf_event_msg */ 11405491d2cSKalle Valo #define BRCMF_E_STATUS_SUCCESS 0 11505491d2cSKalle Valo #define BRCMF_E_STATUS_FAIL 1 11605491d2cSKalle Valo #define BRCMF_E_STATUS_TIMEOUT 2 11705491d2cSKalle Valo #define BRCMF_E_STATUS_NO_NETWORKS 3 11805491d2cSKalle Valo #define BRCMF_E_STATUS_ABORT 4 11905491d2cSKalle Valo #define BRCMF_E_STATUS_NO_ACK 5 12005491d2cSKalle Valo #define BRCMF_E_STATUS_UNSOLICITED 6 12105491d2cSKalle Valo #define BRCMF_E_STATUS_ATTEMPT 7 12205491d2cSKalle Valo #define BRCMF_E_STATUS_PARTIAL 8 12305491d2cSKalle Valo #define BRCMF_E_STATUS_NEWSCAN 9 12405491d2cSKalle Valo #define BRCMF_E_STATUS_NEWASSOC 10 12505491d2cSKalle Valo #define BRCMF_E_STATUS_11HQUIET 11 12605491d2cSKalle Valo #define BRCMF_E_STATUS_SUPPRESS 12 12705491d2cSKalle Valo #define BRCMF_E_STATUS_NOCHANS 13 12805491d2cSKalle Valo #define BRCMF_E_STATUS_CS_ABORT 15 12905491d2cSKalle Valo #define BRCMF_E_STATUS_ERROR 16 13005491d2cSKalle Valo 131b8a64f0eSArend van Spriel /* status field values for PSK_SUP event */ 132b8a64f0eSArend van Spriel #define BRCMF_E_STATUS_FWSUP_WAIT_M1 4 133b8a64f0eSArend van Spriel #define BRCMF_E_STATUS_FWSUP_PREP_M2 5 134b8a64f0eSArend van Spriel #define BRCMF_E_STATUS_FWSUP_COMPLETED 6 135b8a64f0eSArend van Spriel #define BRCMF_E_STATUS_FWSUP_TIMEOUT 7 136b8a64f0eSArend van Spriel #define BRCMF_E_STATUS_FWSUP_WAIT_M3 8 137b8a64f0eSArend van Spriel #define BRCMF_E_STATUS_FWSUP_PREP_M4 9 138b8a64f0eSArend van Spriel #define BRCMF_E_STATUS_FWSUP_WAIT_G1 10 139b8a64f0eSArend van Spriel #define BRCMF_E_STATUS_FWSUP_PREP_G2 11 140b8a64f0eSArend van Spriel 14105491d2cSKalle Valo /* reason field values in struct brcmf_event_msg */ 14205491d2cSKalle Valo #define BRCMF_E_REASON_INITIAL_ASSOC 0 14305491d2cSKalle Valo #define BRCMF_E_REASON_LOW_RSSI 1 14405491d2cSKalle Valo #define BRCMF_E_REASON_DEAUTH 2 14505491d2cSKalle Valo #define BRCMF_E_REASON_DISASSOC 3 14605491d2cSKalle Valo #define BRCMF_E_REASON_BCNS_LOST 4 14705491d2cSKalle Valo #define BRCMF_E_REASON_MINTXRATE 9 14805491d2cSKalle Valo #define BRCMF_E_REASON_TXFAIL 10 14905491d2cSKalle Valo 15005491d2cSKalle Valo #define BRCMF_E_REASON_LINK_BSSCFG_DIS 4 15105491d2cSKalle Valo #define BRCMF_E_REASON_FAST_ROAM_FAILED 5 15205491d2cSKalle Valo #define BRCMF_E_REASON_DIRECTED_ROAM 6 15305491d2cSKalle Valo #define BRCMF_E_REASON_TSPEC_REJECTED 7 15405491d2cSKalle Valo #define BRCMF_E_REASON_BETTER_AP 8 15505491d2cSKalle Valo 15605491d2cSKalle Valo #define BRCMF_E_REASON_TDLS_PEER_DISCOVERED 0 15705491d2cSKalle Valo #define BRCMF_E_REASON_TDLS_PEER_CONNECTED 1 15805491d2cSKalle Valo #define BRCMF_E_REASON_TDLS_PEER_DISCONNECTED 2 15905491d2cSKalle Valo 160b8a64f0eSArend van Spriel /* reason field values for PSK_SUP event */ 161b8a64f0eSArend van Spriel #define BRCMF_E_REASON_FWSUP_OTHER 0 162b8a64f0eSArend van Spriel #define BRCMF_E_REASON_FWSUP_DECRYPT_KEY_DATA 1 163b8a64f0eSArend van Spriel #define BRCMF_E_REASON_FWSUP_BAD_UCAST_WEP128 2 164b8a64f0eSArend van Spriel #define BRCMF_E_REASON_FWSUP_BAD_UCAST_WEP40 3 165b8a64f0eSArend van Spriel #define BRCMF_E_REASON_FWSUP_UNSUP_KEY_LEN 4 166b8a64f0eSArend van Spriel #define BRCMF_E_REASON_FWSUP_PW_KEY_CIPHER 5 167b8a64f0eSArend van Spriel #define BRCMF_E_REASON_FWSUP_MSG3_TOO_MANY_IE 6 168b8a64f0eSArend van Spriel #define BRCMF_E_REASON_FWSUP_MSG3_IE_MISMATCH 7 169b8a64f0eSArend van Spriel #define BRCMF_E_REASON_FWSUP_NO_INSTALL_FLAG 8 170b8a64f0eSArend van Spriel #define BRCMF_E_REASON_FWSUP_MSG3_NO_GTK 9 171b8a64f0eSArend van Spriel #define BRCMF_E_REASON_FWSUP_GRP_KEY_CIPHER 10 172b8a64f0eSArend van Spriel #define BRCMF_E_REASON_FWSUP_GRP_MSG1_NO_GTK 11 173b8a64f0eSArend van Spriel #define BRCMF_E_REASON_FWSUP_GTK_DECRYPT_FAIL 12 174b8a64f0eSArend van Spriel #define BRCMF_E_REASON_FWSUP_SEND_FAIL 13 175b8a64f0eSArend van Spriel #define BRCMF_E_REASON_FWSUP_DEAUTH 14 176b8a64f0eSArend van Spriel #define BRCMF_E_REASON_FWSUP_WPA_PSK_TMO 15 177b8a64f0eSArend van Spriel #define BRCMF_E_REASON_FWSUP_WPA_PSK_M1_TMO 16 178b8a64f0eSArend van Spriel #define BRCMF_E_REASON_FWSUP_WPA_PSK_M3_TMO 17 179b8a64f0eSArend van Spriel 18005491d2cSKalle Valo /* action field values for brcmf_ifevent */ 18105491d2cSKalle Valo #define BRCMF_E_IF_ADD 1 18205491d2cSKalle Valo #define BRCMF_E_IF_DEL 2 18305491d2cSKalle Valo #define BRCMF_E_IF_CHANGE 3 18405491d2cSKalle Valo 18505491d2cSKalle Valo /* flag field values for brcmf_ifevent */ 18605491d2cSKalle Valo #define BRCMF_E_IF_FLAG_NOIF 1 18705491d2cSKalle Valo 18805491d2cSKalle Valo /* role field values for brcmf_ifevent */ 18905491d2cSKalle Valo #define BRCMF_E_IF_ROLE_STA 0 19005491d2cSKalle Valo #define BRCMF_E_IF_ROLE_AP 1 19105491d2cSKalle Valo #define BRCMF_E_IF_ROLE_WDS 2 19205491d2cSKalle Valo #define BRCMF_E_IF_ROLE_P2P_GO 3 19305491d2cSKalle Valo #define BRCMF_E_IF_ROLE_P2P_CLIENT 4 19405491d2cSKalle Valo 19505491d2cSKalle Valo /** 19605491d2cSKalle Valo * definitions for event packet validation. 19705491d2cSKalle Valo */ 19805491d2cSKalle Valo #define BRCM_OUI "\x00\x10\x18" 19905491d2cSKalle Valo #define BCMILCP_BCM_SUBTYPE_EVENT 1 200a4176ec3SArend van Spriel #define BCMILCP_SUBTYPE_VENDOR_LONG 32769 20105491d2cSKalle Valo 20205491d2cSKalle Valo /** 2030aedbcafSHante Meuleman * struct brcm_ethhdr - broadcom specific ether header. 2040aedbcafSHante Meuleman * 2050aedbcafSHante Meuleman * @subtype: subtype for this packet. 2060aedbcafSHante Meuleman * @length: TODO: length of appended data. 2070aedbcafSHante Meuleman * @version: version indication. 2080aedbcafSHante Meuleman * @oui: OUI of this packet. 2090aedbcafSHante Meuleman * @usr_subtype: subtype for this OUI. 2100aedbcafSHante Meuleman */ 2110aedbcafSHante Meuleman struct brcm_ethhdr { 2120aedbcafSHante Meuleman __be16 subtype; 2130aedbcafSHante Meuleman __be16 length; 2140aedbcafSHante Meuleman u8 version; 2150aedbcafSHante Meuleman u8 oui[3]; 2160aedbcafSHante Meuleman __be16 usr_subtype; 2170aedbcafSHante Meuleman } __packed; 2180aedbcafSHante Meuleman 2190aedbcafSHante Meuleman struct brcmf_event_msg_be { 2200aedbcafSHante Meuleman __be16 version; 2210aedbcafSHante Meuleman __be16 flags; 2220aedbcafSHante Meuleman __be32 event_type; 2230aedbcafSHante Meuleman __be32 status; 2240aedbcafSHante Meuleman __be32 reason; 2250aedbcafSHante Meuleman __be32 auth_type; 2260aedbcafSHante Meuleman __be32 datalen; 2270aedbcafSHante Meuleman u8 addr[ETH_ALEN]; 2280aedbcafSHante Meuleman char ifname[IFNAMSIZ]; 2290aedbcafSHante Meuleman u8 ifidx; 2300aedbcafSHante Meuleman u8 bsscfgidx; 2310aedbcafSHante Meuleman } __packed; 2320aedbcafSHante Meuleman 2330aedbcafSHante Meuleman /** 2340aedbcafSHante Meuleman * struct brcmf_event - contents of broadcom event packet. 2350aedbcafSHante Meuleman * 2360aedbcafSHante Meuleman * @eth: standard ether header. 2370aedbcafSHante Meuleman * @hdr: broadcom specific ether header. 2380aedbcafSHante Meuleman * @msg: common part of the actual event message. 2390aedbcafSHante Meuleman */ 2400aedbcafSHante Meuleman struct brcmf_event { 2410aedbcafSHante Meuleman struct ethhdr eth; 2420aedbcafSHante Meuleman struct brcm_ethhdr hdr; 2430aedbcafSHante Meuleman struct brcmf_event_msg_be msg; 2440aedbcafSHante Meuleman } __packed; 2450aedbcafSHante Meuleman 2460aedbcafSHante Meuleman /** 24705491d2cSKalle Valo * struct brcmf_event_msg - firmware event message. 24805491d2cSKalle Valo * 24905491d2cSKalle Valo * @version: version information. 25005491d2cSKalle Valo * @flags: event flags. 25105491d2cSKalle Valo * @event_code: firmware event code. 25205491d2cSKalle Valo * @status: status information. 25305491d2cSKalle Valo * @reason: reason code. 25405491d2cSKalle Valo * @auth_type: authentication type. 2552359dd09SMatteo Croce * @datalen: length of event data buffer. 25605491d2cSKalle Valo * @addr: ether address. 25705491d2cSKalle Valo * @ifname: interface name. 25805491d2cSKalle Valo * @ifidx: interface index. 25905491d2cSKalle Valo * @bsscfgidx: bsscfg index. 26005491d2cSKalle Valo */ 26105491d2cSKalle Valo struct brcmf_event_msg { 26205491d2cSKalle Valo u16 version; 26305491d2cSKalle Valo u16 flags; 26405491d2cSKalle Valo u32 event_code; 26505491d2cSKalle Valo u32 status; 26605491d2cSKalle Valo u32 reason; 26705491d2cSKalle Valo s32 auth_type; 26805491d2cSKalle Valo u32 datalen; 26905491d2cSKalle Valo u8 addr[ETH_ALEN]; 27005491d2cSKalle Valo char ifname[IFNAMSIZ]; 27105491d2cSKalle Valo u8 ifidx; 27205491d2cSKalle Valo u8 bsscfgidx; 27305491d2cSKalle Valo }; 27405491d2cSKalle Valo 27505491d2cSKalle Valo struct brcmf_if_event { 27605491d2cSKalle Valo u8 ifidx; 27705491d2cSKalle Valo u8 action; 27805491d2cSKalle Valo u8 flags; 27937a869ecSHante Meuleman u8 bsscfgidx; 28005491d2cSKalle Valo u8 role; 28105491d2cSKalle Valo }; 28205491d2cSKalle Valo 28305491d2cSKalle Valo typedef int (*brcmf_fweh_handler_t)(struct brcmf_if *ifp, 28405491d2cSKalle Valo const struct brcmf_event_msg *evtmsg, 28505491d2cSKalle Valo void *data); 28605491d2cSKalle Valo 28705491d2cSKalle Valo /** 288edec4282SArend van Spriel * struct brcmf_fweh_event_map_item - fweh event and firmware event pair. 289edec4282SArend van Spriel * 290edec4282SArend van Spriel * @code: fweh event code as used by higher layers. 291edec4282SArend van Spriel * @fwevt_code: firmware event code as used by firmware. 292edec4282SArend van Spriel * 293edec4282SArend van Spriel * This mapping is needed when a functionally identical event has a 294edec4282SArend van Spriel * different numerical definition between vendors. When such mapping 295edec4282SArend van Spriel * is needed the higher layer event code should not collide with the 296edec4282SArend van Spriel * firmware event. 297edec4282SArend van Spriel */ 298edec4282SArend van Spriel struct brcmf_fweh_event_map_item { 299edec4282SArend van Spriel enum brcmf_fweh_event_code code; 300edec4282SArend van Spriel u32 fwevt_code; 301edec4282SArend van Spriel }; 302edec4282SArend van Spriel 303edec4282SArend van Spriel /** 304edec4282SArend van Spriel * struct brcmf_fweh_event_map - mapping between firmware event and fweh event. 305edec4282SArend van Spriel * 306edec4282SArend van Spriel * @n_items: number of mapping items. 307edec4282SArend van Spriel * @items: array of fweh event and firmware event pairs. 308edec4282SArend van Spriel */ 309edec4282SArend van Spriel struct brcmf_fweh_event_map { 310edec4282SArend van Spriel u32 n_items; 311edec4282SArend van Spriel const struct brcmf_fweh_event_map_item items[] __counted_by(n_items); 312edec4282SArend van Spriel }; 313edec4282SArend van Spriel 314edec4282SArend van Spriel /** 31505491d2cSKalle Valo * struct brcmf_fweh_info - firmware event handling information. 31605491d2cSKalle Valo * 31705491d2cSKalle Valo * @p2pdev_setup_ongoing: P2P device creation in progress. 31805491d2cSKalle Valo * @event_work: event worker. 31905491d2cSKalle Valo * @evt_q_lock: lock for event queue protection. 32005491d2cSKalle Valo * @event_q: event queue. 321edec4282SArend van Spriel * @event_mask_len: length of @event_mask used to enable firmware events. 322edec4282SArend van Spriel * @event_mask: byte array used in 'event_msgs' iovar command. 323edec4282SArend van Spriel * @event_map: mapping between fweh event and firmware event which 324edec4282SArend van Spriel * may be provided by vendor-specific module for events that need 325edec4282SArend van Spriel * mapping. 326edec4282SArend van Spriel * @num_event_codes: number of firmware events supported by firmware which 327edec4282SArend van Spriel * does a minimum length check for the @event_mask. This value is to 328edec4282SArend van Spriel * be provided by vendor-specific module determining @event_mask_len 329edec4282SArend van Spriel * and consequently the allocation size for @event_mask. 330edec4282SArend van Spriel * @evt_handler: event handler registry indexed by firmware event code. 33105491d2cSKalle Valo */ 33205491d2cSKalle Valo struct brcmf_fweh_info { 333edec4282SArend van Spriel struct brcmf_pub *drvr; 33405491d2cSKalle Valo bool p2pdev_setup_ongoing; 33505491d2cSKalle Valo struct work_struct event_work; 33605491d2cSKalle Valo spinlock_t evt_q_lock; 33705491d2cSKalle Valo struct list_head event_q; 338edec4282SArend van Spriel uint event_mask_len; 339edec4282SArend van Spriel u8 *event_mask; 340edec4282SArend van Spriel struct brcmf_fweh_event_map *event_map; 341edec4282SArend van Spriel uint num_event_codes; 342edec4282SArend van Spriel brcmf_fweh_handler_t evt_handler[] __counted_by(num_event_codes); 34305491d2cSKalle Valo }; 34405491d2cSKalle Valo 345e1c122d5SRafał Miłecki const char *brcmf_fweh_event_name(enum brcmf_fweh_event_code code); 346e1c122d5SRafał Miłecki 347edec4282SArend van Spriel int brcmf_fweh_attach(struct brcmf_pub *drvr); 34805491d2cSKalle Valo void brcmf_fweh_detach(struct brcmf_pub *drvr); 34905491d2cSKalle Valo int brcmf_fweh_register(struct brcmf_pub *drvr, enum brcmf_fweh_event_code code, 35005491d2cSKalle Valo int (*handler)(struct brcmf_if *ifp, 35105491d2cSKalle Valo const struct brcmf_event_msg *evtmsg, 35205491d2cSKalle Valo void *data)); 35305491d2cSKalle Valo void brcmf_fweh_unregister(struct brcmf_pub *drvr, 35405491d2cSKalle Valo enum brcmf_fweh_event_code code); 35505491d2cSKalle Valo int brcmf_fweh_activate_events(struct brcmf_if *ifp); 35605491d2cSKalle Valo void brcmf_fweh_process_event(struct brcmf_pub *drvr, 3570aedbcafSHante Meuleman struct brcmf_event *event_packet, 358c597ede4SSebastian Andrzej Siewior u32 packet_len, gfp_t gfp); 35905491d2cSKalle Valo void brcmf_fweh_p2pdev_setup(struct brcmf_if *ifp, bool ongoing); 36005491d2cSKalle Valo 36105491d2cSKalle Valo static inline void brcmf_fweh_process_skb(struct brcmf_pub *drvr, 362c597ede4SSebastian Andrzej Siewior struct sk_buff *skb, u16 stype, 363c597ede4SSebastian Andrzej Siewior gfp_t gfp) 36405491d2cSKalle Valo { 36505491d2cSKalle Valo struct brcmf_event *event_packet; 366a4176ec3SArend van Spriel u16 subtype, usr_stype; 36705491d2cSKalle Valo 36805491d2cSKalle Valo /* only process events when protocol matches */ 36905491d2cSKalle Valo if (skb->protocol != cpu_to_be16(ETH_P_LINK_CTL)) 37005491d2cSKalle Valo return; 37105491d2cSKalle Valo 3720aedbcafSHante Meuleman if ((skb->len + ETH_HLEN) < sizeof(*event_packet)) 3730aedbcafSHante Meuleman return; 3740aedbcafSHante Meuleman 37505491d2cSKalle Valo event_packet = (struct brcmf_event *)skb_mac_header(skb); 376a4176ec3SArend van Spriel 377a4176ec3SArend van Spriel /* check subtype if needed */ 378a4176ec3SArend van Spriel if (unlikely(stype)) { 379a4176ec3SArend van Spriel subtype = get_unaligned_be16(&event_packet->hdr.subtype); 380a4176ec3SArend van Spriel if (subtype != stype) 381a4176ec3SArend van Spriel return; 382a4176ec3SArend van Spriel } 383a4176ec3SArend van Spriel 384a4176ec3SArend van Spriel /* check for BRCM oui match */ 3850aedbcafSHante Meuleman if (memcmp(BRCM_OUI, &event_packet->hdr.oui[0], 3860aedbcafSHante Meuleman sizeof(event_packet->hdr.oui))) 38705491d2cSKalle Valo return; 38805491d2cSKalle Valo 38905491d2cSKalle Valo /* final match on usr_subtype */ 3900aedbcafSHante Meuleman usr_stype = get_unaligned_be16(&event_packet->hdr.usr_subtype); 39105491d2cSKalle Valo if (usr_stype != BCMILCP_BCM_SUBTYPE_EVENT) 39205491d2cSKalle Valo return; 39305491d2cSKalle Valo 394c597ede4SSebastian Andrzej Siewior brcmf_fweh_process_event(drvr, event_packet, skb->len + ETH_HLEN, gfp); 39505491d2cSKalle Valo } 39605491d2cSKalle Valo 39705491d2cSKalle Valo #endif /* FWEH_H_ */ 398