Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: ISC
0002 /*
0003  * Copyright (c) 2012 Broadcom Corporation
0004  */
0005 
0006 
0007 #ifndef FWEH_H_
0008 #define FWEH_H_
0009 
0010 #include <asm/unaligned.h>
0011 #include <linux/skbuff.h>
0012 #include <linux/if_ether.h>
0013 #include <linux/if.h>
0014 
0015 /* formward declarations */
0016 struct brcmf_pub;
0017 struct brcmf_if;
0018 struct brcmf_cfg80211_info;
0019 
0020 /* list of firmware events */
0021 #define BRCMF_FWEH_EVENT_ENUM_DEFLIST \
0022     BRCMF_ENUM_DEF(SET_SSID, 0) \
0023     BRCMF_ENUM_DEF(JOIN, 1) \
0024     BRCMF_ENUM_DEF(START, 2) \
0025     BRCMF_ENUM_DEF(AUTH, 3) \
0026     BRCMF_ENUM_DEF(AUTH_IND, 4) \
0027     BRCMF_ENUM_DEF(DEAUTH, 5) \
0028     BRCMF_ENUM_DEF(DEAUTH_IND, 6) \
0029     BRCMF_ENUM_DEF(ASSOC, 7) \
0030     BRCMF_ENUM_DEF(ASSOC_IND, 8) \
0031     BRCMF_ENUM_DEF(REASSOC, 9) \
0032     BRCMF_ENUM_DEF(REASSOC_IND, 10) \
0033     BRCMF_ENUM_DEF(DISASSOC, 11) \
0034     BRCMF_ENUM_DEF(DISASSOC_IND, 12) \
0035     BRCMF_ENUM_DEF(QUIET_START, 13) \
0036     BRCMF_ENUM_DEF(QUIET_END, 14) \
0037     BRCMF_ENUM_DEF(BEACON_RX, 15) \
0038     BRCMF_ENUM_DEF(LINK, 16) \
0039     BRCMF_ENUM_DEF(MIC_ERROR, 17) \
0040     BRCMF_ENUM_DEF(NDIS_LINK, 18) \
0041     BRCMF_ENUM_DEF(ROAM, 19) \
0042     BRCMF_ENUM_DEF(TXFAIL, 20) \
0043     BRCMF_ENUM_DEF(PMKID_CACHE, 21) \
0044     BRCMF_ENUM_DEF(RETROGRADE_TSF, 22) \
0045     BRCMF_ENUM_DEF(PRUNE, 23) \
0046     BRCMF_ENUM_DEF(AUTOAUTH, 24) \
0047     BRCMF_ENUM_DEF(EAPOL_MSG, 25) \
0048     BRCMF_ENUM_DEF(SCAN_COMPLETE, 26) \
0049     BRCMF_ENUM_DEF(ADDTS_IND, 27) \
0050     BRCMF_ENUM_DEF(DELTS_IND, 28) \
0051     BRCMF_ENUM_DEF(BCNSENT_IND, 29) \
0052     BRCMF_ENUM_DEF(BCNRX_MSG, 30) \
0053     BRCMF_ENUM_DEF(BCNLOST_MSG, 31) \
0054     BRCMF_ENUM_DEF(ROAM_PREP, 32) \
0055     BRCMF_ENUM_DEF(PFN_NET_FOUND, 33) \
0056     BRCMF_ENUM_DEF(PFN_NET_LOST, 34) \
0057     BRCMF_ENUM_DEF(RESET_COMPLETE, 35) \
0058     BRCMF_ENUM_DEF(JOIN_START, 36) \
0059     BRCMF_ENUM_DEF(ROAM_START, 37) \
0060     BRCMF_ENUM_DEF(ASSOC_START, 38) \
0061     BRCMF_ENUM_DEF(IBSS_ASSOC, 39) \
0062     BRCMF_ENUM_DEF(RADIO, 40) \
0063     BRCMF_ENUM_DEF(PSM_WATCHDOG, 41) \
0064     BRCMF_ENUM_DEF(PROBREQ_MSG, 44) \
0065     BRCMF_ENUM_DEF(SCAN_CONFIRM_IND, 45) \
0066     BRCMF_ENUM_DEF(PSK_SUP, 46) \
0067     BRCMF_ENUM_DEF(COUNTRY_CODE_CHANGED, 47) \
0068     BRCMF_ENUM_DEF(EXCEEDED_MEDIUM_TIME, 48) \
0069     BRCMF_ENUM_DEF(ICV_ERROR, 49) \
0070     BRCMF_ENUM_DEF(UNICAST_DECODE_ERROR, 50) \
0071     BRCMF_ENUM_DEF(MULTICAST_DECODE_ERROR, 51) \
0072     BRCMF_ENUM_DEF(TRACE, 52) \
0073     BRCMF_ENUM_DEF(IF, 54) \
0074     BRCMF_ENUM_DEF(P2P_DISC_LISTEN_COMPLETE, 55) \
0075     BRCMF_ENUM_DEF(RSSI, 56) \
0076     BRCMF_ENUM_DEF(EXTLOG_MSG, 58) \
0077     BRCMF_ENUM_DEF(ACTION_FRAME, 59) \
0078     BRCMF_ENUM_DEF(ACTION_FRAME_COMPLETE, 60) \
0079     BRCMF_ENUM_DEF(PRE_ASSOC_IND, 61) \
0080     BRCMF_ENUM_DEF(PRE_REASSOC_IND, 62) \
0081     BRCMF_ENUM_DEF(CHANNEL_ADOPTED, 63) \
0082     BRCMF_ENUM_DEF(AP_STARTED, 64) \
0083     BRCMF_ENUM_DEF(DFS_AP_STOP, 65) \
0084     BRCMF_ENUM_DEF(DFS_AP_RESUME, 66) \
0085     BRCMF_ENUM_DEF(ESCAN_RESULT, 69) \
0086     BRCMF_ENUM_DEF(ACTION_FRAME_OFF_CHAN_COMPLETE, 70) \
0087     BRCMF_ENUM_DEF(PROBERESP_MSG, 71) \
0088     BRCMF_ENUM_DEF(P2P_PROBEREQ_MSG, 72) \
0089     BRCMF_ENUM_DEF(DCS_REQUEST, 73) \
0090     BRCMF_ENUM_DEF(FIFO_CREDIT_MAP, 74) \
0091     BRCMF_ENUM_DEF(ACTION_FRAME_RX, 75) \
0092     BRCMF_ENUM_DEF(TDLS_PEER_EVENT, 92) \
0093     BRCMF_ENUM_DEF(BCMC_CREDIT_SUPPORT, 127)
0094 
0095 #define BRCMF_ENUM_DEF(id, val) \
0096     BRCMF_E_##id = (val),
0097 
0098 /* firmware event codes sent by the dongle */
0099 enum brcmf_fweh_event_code {
0100     BRCMF_FWEH_EVENT_ENUM_DEFLIST
0101     /* this determines event mask length which must match
0102      * minimum length check in device firmware so it is
0103      * hard-coded here.
0104      */
0105     BRCMF_E_LAST = 139
0106 };
0107 #undef BRCMF_ENUM_DEF
0108 
0109 #define BRCMF_EVENTING_MASK_LEN     DIV_ROUND_UP(BRCMF_E_LAST, 8)
0110 
0111 /* flags field values in struct brcmf_event_msg */
0112 #define BRCMF_EVENT_MSG_LINK        0x01
0113 #define BRCMF_EVENT_MSG_FLUSHTXQ    0x02
0114 #define BRCMF_EVENT_MSG_GROUP       0x04
0115 
0116 /* status field values in struct brcmf_event_msg */
0117 #define BRCMF_E_STATUS_SUCCESS          0
0118 #define BRCMF_E_STATUS_FAIL         1
0119 #define BRCMF_E_STATUS_TIMEOUT          2
0120 #define BRCMF_E_STATUS_NO_NETWORKS      3
0121 #define BRCMF_E_STATUS_ABORT            4
0122 #define BRCMF_E_STATUS_NO_ACK           5
0123 #define BRCMF_E_STATUS_UNSOLICITED      6
0124 #define BRCMF_E_STATUS_ATTEMPT          7
0125 #define BRCMF_E_STATUS_PARTIAL          8
0126 #define BRCMF_E_STATUS_NEWSCAN          9
0127 #define BRCMF_E_STATUS_NEWASSOC         10
0128 #define BRCMF_E_STATUS_11HQUIET         11
0129 #define BRCMF_E_STATUS_SUPPRESS         12
0130 #define BRCMF_E_STATUS_NOCHANS          13
0131 #define BRCMF_E_STATUS_CS_ABORT         15
0132 #define BRCMF_E_STATUS_ERROR            16
0133 
0134 /* status field values for PSK_SUP event */
0135 #define BRCMF_E_STATUS_FWSUP_WAIT_M1        4
0136 #define BRCMF_E_STATUS_FWSUP_PREP_M2        5
0137 #define BRCMF_E_STATUS_FWSUP_COMPLETED      6
0138 #define BRCMF_E_STATUS_FWSUP_TIMEOUT        7
0139 #define BRCMF_E_STATUS_FWSUP_WAIT_M3        8
0140 #define BRCMF_E_STATUS_FWSUP_PREP_M4        9
0141 #define BRCMF_E_STATUS_FWSUP_WAIT_G1        10
0142 #define BRCMF_E_STATUS_FWSUP_PREP_G2        11
0143 
0144 /* reason field values in struct brcmf_event_msg */
0145 #define BRCMF_E_REASON_INITIAL_ASSOC        0
0146 #define BRCMF_E_REASON_LOW_RSSI         1
0147 #define BRCMF_E_REASON_DEAUTH           2
0148 #define BRCMF_E_REASON_DISASSOC         3
0149 #define BRCMF_E_REASON_BCNS_LOST        4
0150 #define BRCMF_E_REASON_MINTXRATE        9
0151 #define BRCMF_E_REASON_TXFAIL           10
0152 
0153 #define BRCMF_E_REASON_LINK_BSSCFG_DIS      4
0154 #define BRCMF_E_REASON_FAST_ROAM_FAILED     5
0155 #define BRCMF_E_REASON_DIRECTED_ROAM        6
0156 #define BRCMF_E_REASON_TSPEC_REJECTED       7
0157 #define BRCMF_E_REASON_BETTER_AP        8
0158 
0159 #define BRCMF_E_REASON_TDLS_PEER_DISCOVERED 0
0160 #define BRCMF_E_REASON_TDLS_PEER_CONNECTED  1
0161 #define BRCMF_E_REASON_TDLS_PEER_DISCONNECTED   2
0162 
0163 /* reason field values for PSK_SUP event */
0164 #define BRCMF_E_REASON_FWSUP_OTHER      0
0165 #define BRCMF_E_REASON_FWSUP_DECRYPT_KEY_DATA   1
0166 #define BRCMF_E_REASON_FWSUP_BAD_UCAST_WEP128   2
0167 #define BRCMF_E_REASON_FWSUP_BAD_UCAST_WEP40    3
0168 #define BRCMF_E_REASON_FWSUP_UNSUP_KEY_LEN  4
0169 #define BRCMF_E_REASON_FWSUP_PW_KEY_CIPHER  5
0170 #define BRCMF_E_REASON_FWSUP_MSG3_TOO_MANY_IE   6
0171 #define BRCMF_E_REASON_FWSUP_MSG3_IE_MISMATCH   7
0172 #define BRCMF_E_REASON_FWSUP_NO_INSTALL_FLAG    8
0173 #define BRCMF_E_REASON_FWSUP_MSG3_NO_GTK    9
0174 #define BRCMF_E_REASON_FWSUP_GRP_KEY_CIPHER 10
0175 #define BRCMF_E_REASON_FWSUP_GRP_MSG1_NO_GTK    11
0176 #define BRCMF_E_REASON_FWSUP_GTK_DECRYPT_FAIL   12
0177 #define BRCMF_E_REASON_FWSUP_SEND_FAIL      13
0178 #define BRCMF_E_REASON_FWSUP_DEAUTH     14
0179 #define BRCMF_E_REASON_FWSUP_WPA_PSK_TMO    15
0180 #define BRCMF_E_REASON_FWSUP_WPA_PSK_M1_TMO 16
0181 #define BRCMF_E_REASON_FWSUP_WPA_PSK_M3_TMO 17
0182 
0183 /* action field values for brcmf_ifevent */
0184 #define BRCMF_E_IF_ADD              1
0185 #define BRCMF_E_IF_DEL              2
0186 #define BRCMF_E_IF_CHANGE           3
0187 
0188 /* flag field values for brcmf_ifevent */
0189 #define BRCMF_E_IF_FLAG_NOIF            1
0190 
0191 /* role field values for brcmf_ifevent */
0192 #define BRCMF_E_IF_ROLE_STA         0
0193 #define BRCMF_E_IF_ROLE_AP          1
0194 #define BRCMF_E_IF_ROLE_WDS         2
0195 #define BRCMF_E_IF_ROLE_P2P_GO          3
0196 #define BRCMF_E_IF_ROLE_P2P_CLIENT      4
0197 
0198 /**
0199  * definitions for event packet validation.
0200  */
0201 #define BRCM_OUI                "\x00\x10\x18"
0202 #define BCMILCP_BCM_SUBTYPE_EVENT       1
0203 #define BCMILCP_SUBTYPE_VENDOR_LONG     32769
0204 
0205 /**
0206  * struct brcm_ethhdr - broadcom specific ether header.
0207  *
0208  * @subtype: subtype for this packet.
0209  * @length: TODO: length of appended data.
0210  * @version: version indication.
0211  * @oui: OUI of this packet.
0212  * @usr_subtype: subtype for this OUI.
0213  */
0214 struct brcm_ethhdr {
0215     __be16 subtype;
0216     __be16 length;
0217     u8 version;
0218     u8 oui[3];
0219     __be16 usr_subtype;
0220 } __packed;
0221 
0222 struct brcmf_event_msg_be {
0223     __be16 version;
0224     __be16 flags;
0225     __be32 event_type;
0226     __be32 status;
0227     __be32 reason;
0228     __be32 auth_type;
0229     __be32 datalen;
0230     u8 addr[ETH_ALEN];
0231     char ifname[IFNAMSIZ];
0232     u8 ifidx;
0233     u8 bsscfgidx;
0234 } __packed;
0235 
0236 /**
0237  * struct brcmf_event - contents of broadcom event packet.
0238  *
0239  * @eth: standard ether header.
0240  * @hdr: broadcom specific ether header.
0241  * @msg: common part of the actual event message.
0242  */
0243 struct brcmf_event {
0244     struct ethhdr eth;
0245     struct brcm_ethhdr hdr;
0246     struct brcmf_event_msg_be msg;
0247 } __packed;
0248 
0249 /**
0250  * struct brcmf_event_msg - firmware event message.
0251  *
0252  * @version: version information.
0253  * @flags: event flags.
0254  * @event_code: firmware event code.
0255  * @status: status information.
0256  * @reason: reason code.
0257  * @auth_type: authentication type.
0258  * @datalen: length of event data buffer.
0259  * @addr: ether address.
0260  * @ifname: interface name.
0261  * @ifidx: interface index.
0262  * @bsscfgidx: bsscfg index.
0263  */
0264 struct brcmf_event_msg {
0265     u16 version;
0266     u16 flags;
0267     u32 event_code;
0268     u32 status;
0269     u32 reason;
0270     s32 auth_type;
0271     u32 datalen;
0272     u8 addr[ETH_ALEN];
0273     char ifname[IFNAMSIZ];
0274     u8 ifidx;
0275     u8 bsscfgidx;
0276 };
0277 
0278 struct brcmf_if_event {
0279     u8 ifidx;
0280     u8 action;
0281     u8 flags;
0282     u8 bsscfgidx;
0283     u8 role;
0284 };
0285 
0286 typedef int (*brcmf_fweh_handler_t)(struct brcmf_if *ifp,
0287                     const struct brcmf_event_msg *evtmsg,
0288                     void *data);
0289 
0290 /**
0291  * struct brcmf_fweh_info - firmware event handling information.
0292  *
0293  * @p2pdev_setup_ongoing: P2P device creation in progress.
0294  * @event_work: event worker.
0295  * @evt_q_lock: lock for event queue protection.
0296  * @event_q: event queue.
0297  * @evt_handler: registered event handlers.
0298  */
0299 struct brcmf_fweh_info {
0300     bool p2pdev_setup_ongoing;
0301     struct work_struct event_work;
0302     spinlock_t evt_q_lock;
0303     struct list_head event_q;
0304     int (*evt_handler[BRCMF_E_LAST])(struct brcmf_if *ifp,
0305                      const struct brcmf_event_msg *evtmsg,
0306                      void *data);
0307 };
0308 
0309 const char *brcmf_fweh_event_name(enum brcmf_fweh_event_code code);
0310 
0311 void brcmf_fweh_attach(struct brcmf_pub *drvr);
0312 void brcmf_fweh_detach(struct brcmf_pub *drvr);
0313 int brcmf_fweh_register(struct brcmf_pub *drvr, enum brcmf_fweh_event_code code,
0314             int (*handler)(struct brcmf_if *ifp,
0315                        const struct brcmf_event_msg *evtmsg,
0316                        void *data));
0317 void brcmf_fweh_unregister(struct brcmf_pub *drvr,
0318                enum brcmf_fweh_event_code code);
0319 int brcmf_fweh_activate_events(struct brcmf_if *ifp);
0320 void brcmf_fweh_process_event(struct brcmf_pub *drvr,
0321                   struct brcmf_event *event_packet,
0322                   u32 packet_len, gfp_t gfp);
0323 void brcmf_fweh_p2pdev_setup(struct brcmf_if *ifp, bool ongoing);
0324 
0325 static inline void brcmf_fweh_process_skb(struct brcmf_pub *drvr,
0326                       struct sk_buff *skb, u16 stype,
0327                       gfp_t gfp)
0328 {
0329     struct brcmf_event *event_packet;
0330     u16 subtype, usr_stype;
0331 
0332     /* only process events when protocol matches */
0333     if (skb->protocol != cpu_to_be16(ETH_P_LINK_CTL))
0334         return;
0335 
0336     if ((skb->len + ETH_HLEN) < sizeof(*event_packet))
0337         return;
0338 
0339     event_packet = (struct brcmf_event *)skb_mac_header(skb);
0340 
0341     /* check subtype if needed */
0342     if (unlikely(stype)) {
0343         subtype = get_unaligned_be16(&event_packet->hdr.subtype);
0344         if (subtype != stype)
0345             return;
0346     }
0347 
0348     /* check for BRCM oui match */
0349     if (memcmp(BRCM_OUI, &event_packet->hdr.oui[0],
0350            sizeof(event_packet->hdr.oui)))
0351         return;
0352 
0353     /* final match on usr_subtype */
0354     usr_stype = get_unaligned_be16(&event_packet->hdr.usr_subtype);
0355     if (usr_stype != BCMILCP_BCM_SUBTYPE_EVENT)
0356         return;
0357 
0358     brcmf_fweh_process_event(drvr, event_packet, skb->len + ETH_HLEN, gfp);
0359 }
0360 
0361 #endif /* FWEH_H_ */