linux/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2012 Broadcom Corporation
   3 *
   4 * Permission to use, copy, modify, and/or distribute this software for any
   5 * purpose with or without fee is hereby granted, provided that the above
   6 * copyright notice and this permission notice appear in all copies.
   7 *
   8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15 */
  16
  17
  18#ifndef FWEH_H_
  19#define FWEH_H_
  20
  21#include <asm/unaligned.h>
  22#include <linux/skbuff.h>
  23#include <linux/if_ether.h>
  24#include <linux/if.h>
  25
  26/* formward declarations */
  27struct brcmf_pub;
  28struct brcmf_if;
  29struct brcmf_cfg80211_info;
  30
  31/* list of firmware events */
  32#define BRCMF_FWEH_EVENT_ENUM_DEFLIST \
  33        BRCMF_ENUM_DEF(SET_SSID, 0) \
  34        BRCMF_ENUM_DEF(JOIN, 1) \
  35        BRCMF_ENUM_DEF(START, 2) \
  36        BRCMF_ENUM_DEF(AUTH, 3) \
  37        BRCMF_ENUM_DEF(AUTH_IND, 4) \
  38        BRCMF_ENUM_DEF(DEAUTH, 5) \
  39        BRCMF_ENUM_DEF(DEAUTH_IND, 6) \
  40        BRCMF_ENUM_DEF(ASSOC, 7) \
  41        BRCMF_ENUM_DEF(ASSOC_IND, 8) \
  42        BRCMF_ENUM_DEF(REASSOC, 9) \
  43        BRCMF_ENUM_DEF(REASSOC_IND, 10) \
  44        BRCMF_ENUM_DEF(DISASSOC, 11) \
  45        BRCMF_ENUM_DEF(DISASSOC_IND, 12) \
  46        BRCMF_ENUM_DEF(QUIET_START, 13) \
  47        BRCMF_ENUM_DEF(QUIET_END, 14) \
  48        BRCMF_ENUM_DEF(BEACON_RX, 15) \
  49        BRCMF_ENUM_DEF(LINK, 16) \
  50        BRCMF_ENUM_DEF(MIC_ERROR, 17) \
  51        BRCMF_ENUM_DEF(NDIS_LINK, 18) \
  52        BRCMF_ENUM_DEF(ROAM, 19) \
  53        BRCMF_ENUM_DEF(TXFAIL, 20) \
  54        BRCMF_ENUM_DEF(PMKID_CACHE, 21) \
  55        BRCMF_ENUM_DEF(RETROGRADE_TSF, 22) \
  56        BRCMF_ENUM_DEF(PRUNE, 23) \
  57        BRCMF_ENUM_DEF(AUTOAUTH, 24) \
  58        BRCMF_ENUM_DEF(EAPOL_MSG, 25) \
  59        BRCMF_ENUM_DEF(SCAN_COMPLETE, 26) \
  60        BRCMF_ENUM_DEF(ADDTS_IND, 27) \
  61        BRCMF_ENUM_DEF(DELTS_IND, 28) \
  62        BRCMF_ENUM_DEF(BCNSENT_IND, 29) \
  63        BRCMF_ENUM_DEF(BCNRX_MSG, 30) \
  64        BRCMF_ENUM_DEF(BCNLOST_MSG, 31) \
  65        BRCMF_ENUM_DEF(ROAM_PREP, 32) \
  66        BRCMF_ENUM_DEF(PFN_NET_FOUND, 33) \
  67        BRCMF_ENUM_DEF(PFN_NET_LOST, 34) \
  68        BRCMF_ENUM_DEF(RESET_COMPLETE, 35) \
  69        BRCMF_ENUM_DEF(JOIN_START, 36) \
  70        BRCMF_ENUM_DEF(ROAM_START, 37) \
  71        BRCMF_ENUM_DEF(ASSOC_START, 38) \
  72        BRCMF_ENUM_DEF(IBSS_ASSOC, 39) \
  73        BRCMF_ENUM_DEF(RADIO, 40) \
  74        BRCMF_ENUM_DEF(PSM_WATCHDOG, 41) \
  75        BRCMF_ENUM_DEF(PROBREQ_MSG, 44) \
  76        BRCMF_ENUM_DEF(SCAN_CONFIRM_IND, 45) \
  77        BRCMF_ENUM_DEF(PSK_SUP, 46) \
  78        BRCMF_ENUM_DEF(COUNTRY_CODE_CHANGED, 47) \
  79        BRCMF_ENUM_DEF(EXCEEDED_MEDIUM_TIME, 48) \
  80        BRCMF_ENUM_DEF(ICV_ERROR, 49) \
  81        BRCMF_ENUM_DEF(UNICAST_DECODE_ERROR, 50) \
  82        BRCMF_ENUM_DEF(MULTICAST_DECODE_ERROR, 51) \
  83        BRCMF_ENUM_DEF(TRACE, 52) \
  84        BRCMF_ENUM_DEF(IF, 54) \
  85        BRCMF_ENUM_DEF(P2P_DISC_LISTEN_COMPLETE, 55) \
  86        BRCMF_ENUM_DEF(RSSI, 56) \
  87        BRCMF_ENUM_DEF(EXTLOG_MSG, 58) \
  88        BRCMF_ENUM_DEF(ACTION_FRAME, 59) \
  89        BRCMF_ENUM_DEF(ACTION_FRAME_COMPLETE, 60) \
  90        BRCMF_ENUM_DEF(PRE_ASSOC_IND, 61) \
  91        BRCMF_ENUM_DEF(PRE_REASSOC_IND, 62) \
  92        BRCMF_ENUM_DEF(CHANNEL_ADOPTED, 63) \
  93        BRCMF_ENUM_DEF(AP_STARTED, 64) \
  94        BRCMF_ENUM_DEF(DFS_AP_STOP, 65) \
  95        BRCMF_ENUM_DEF(DFS_AP_RESUME, 66) \
  96        BRCMF_ENUM_DEF(ESCAN_RESULT, 69) \
  97        BRCMF_ENUM_DEF(ACTION_FRAME_OFF_CHAN_COMPLETE, 70) \
  98        BRCMF_ENUM_DEF(PROBERESP_MSG, 71) \
  99        BRCMF_ENUM_DEF(P2P_PROBEREQ_MSG, 72) \
 100        BRCMF_ENUM_DEF(DCS_REQUEST, 73) \
 101        BRCMF_ENUM_DEF(FIFO_CREDIT_MAP, 74) \
 102        BRCMF_ENUM_DEF(ACTION_FRAME_RX, 75) \
 103        BRCMF_ENUM_DEF(TDLS_PEER_EVENT, 92) \
 104        BRCMF_ENUM_DEF(BCMC_CREDIT_SUPPORT, 127)
 105
 106#define BRCMF_ENUM_DEF(id, val) \
 107        BRCMF_E_##id = (val),
 108
 109/* firmware event codes sent by the dongle */
 110enum brcmf_fweh_event_code {
 111        BRCMF_FWEH_EVENT_ENUM_DEFLIST
 112        /* this determines event mask length which must match
 113         * minimum length check in device firmware so it is
 114         * hard-coded here.
 115         */
 116        BRCMF_E_LAST = 139
 117};
 118#undef BRCMF_ENUM_DEF
 119
 120#define BRCMF_EVENTING_MASK_LEN         DIV_ROUND_UP(BRCMF_E_LAST, 8)
 121
 122/* flags field values in struct brcmf_event_msg */
 123#define BRCMF_EVENT_MSG_LINK            0x01
 124#define BRCMF_EVENT_MSG_FLUSHTXQ        0x02
 125#define BRCMF_EVENT_MSG_GROUP           0x04
 126
 127/* status field values in struct brcmf_event_msg */
 128#define BRCMF_E_STATUS_SUCCESS                  0
 129#define BRCMF_E_STATUS_FAIL                     1
 130#define BRCMF_E_STATUS_TIMEOUT                  2
 131#define BRCMF_E_STATUS_NO_NETWORKS              3
 132#define BRCMF_E_STATUS_ABORT                    4
 133#define BRCMF_E_STATUS_NO_ACK                   5
 134#define BRCMF_E_STATUS_UNSOLICITED              6
 135#define BRCMF_E_STATUS_ATTEMPT                  7
 136#define BRCMF_E_STATUS_PARTIAL                  8
 137#define BRCMF_E_STATUS_NEWSCAN                  9
 138#define BRCMF_E_STATUS_NEWASSOC                 10
 139#define BRCMF_E_STATUS_11HQUIET                 11
 140#define BRCMF_E_STATUS_SUPPRESS                 12
 141#define BRCMF_E_STATUS_NOCHANS                  13
 142#define BRCMF_E_STATUS_CS_ABORT                 15
 143#define BRCMF_E_STATUS_ERROR                    16
 144
 145/* status field values for PSK_SUP event */
 146#define BRCMF_E_STATUS_FWSUP_WAIT_M1            4
 147#define BRCMF_E_STATUS_FWSUP_PREP_M2            5
 148#define BRCMF_E_STATUS_FWSUP_COMPLETED          6
 149#define BRCMF_E_STATUS_FWSUP_TIMEOUT            7
 150#define BRCMF_E_STATUS_FWSUP_WAIT_M3            8
 151#define BRCMF_E_STATUS_FWSUP_PREP_M4            9
 152#define BRCMF_E_STATUS_FWSUP_WAIT_G1            10
 153#define BRCMF_E_STATUS_FWSUP_PREP_G2            11
 154
 155/* reason field values in struct brcmf_event_msg */
 156#define BRCMF_E_REASON_INITIAL_ASSOC            0
 157#define BRCMF_E_REASON_LOW_RSSI                 1
 158#define BRCMF_E_REASON_DEAUTH                   2
 159#define BRCMF_E_REASON_DISASSOC                 3
 160#define BRCMF_E_REASON_BCNS_LOST                4
 161#define BRCMF_E_REASON_MINTXRATE                9
 162#define BRCMF_E_REASON_TXFAIL                   10
 163
 164#define BRCMF_E_REASON_LINK_BSSCFG_DIS          4
 165#define BRCMF_E_REASON_FAST_ROAM_FAILED         5
 166#define BRCMF_E_REASON_DIRECTED_ROAM            6
 167#define BRCMF_E_REASON_TSPEC_REJECTED           7
 168#define BRCMF_E_REASON_BETTER_AP                8
 169
 170#define BRCMF_E_REASON_TDLS_PEER_DISCOVERED     0
 171#define BRCMF_E_REASON_TDLS_PEER_CONNECTED      1
 172#define BRCMF_E_REASON_TDLS_PEER_DISCONNECTED   2
 173
 174/* reason field values for PSK_SUP event */
 175#define BRCMF_E_REASON_FWSUP_OTHER              0
 176#define BRCMF_E_REASON_FWSUP_DECRYPT_KEY_DATA   1
 177#define BRCMF_E_REASON_FWSUP_BAD_UCAST_WEP128   2
 178#define BRCMF_E_REASON_FWSUP_BAD_UCAST_WEP40    3
 179#define BRCMF_E_REASON_FWSUP_UNSUP_KEY_LEN      4
 180#define BRCMF_E_REASON_FWSUP_PW_KEY_CIPHER      5
 181#define BRCMF_E_REASON_FWSUP_MSG3_TOO_MANY_IE   6
 182#define BRCMF_E_REASON_FWSUP_MSG3_IE_MISMATCH   7
 183#define BRCMF_E_REASON_FWSUP_NO_INSTALL_FLAG    8
 184#define BRCMF_E_REASON_FWSUP_MSG3_NO_GTK        9
 185#define BRCMF_E_REASON_FWSUP_GRP_KEY_CIPHER     10
 186#define BRCMF_E_REASON_FWSUP_GRP_MSG1_NO_GTK    11
 187#define BRCMF_E_REASON_FWSUP_GTK_DECRYPT_FAIL   12
 188#define BRCMF_E_REASON_FWSUP_SEND_FAIL          13
 189#define BRCMF_E_REASON_FWSUP_DEAUTH             14
 190#define BRCMF_E_REASON_FWSUP_WPA_PSK_TMO        15
 191#define BRCMF_E_REASON_FWSUP_WPA_PSK_M1_TMO     16
 192#define BRCMF_E_REASON_FWSUP_WPA_PSK_M3_TMO     17
 193
 194/* action field values for brcmf_ifevent */
 195#define BRCMF_E_IF_ADD                          1
 196#define BRCMF_E_IF_DEL                          2
 197#define BRCMF_E_IF_CHANGE                       3
 198
 199/* flag field values for brcmf_ifevent */
 200#define BRCMF_E_IF_FLAG_NOIF                    1
 201
 202/* role field values for brcmf_ifevent */
 203#define BRCMF_E_IF_ROLE_STA                     0
 204#define BRCMF_E_IF_ROLE_AP                      1
 205#define BRCMF_E_IF_ROLE_WDS                     2
 206#define BRCMF_E_IF_ROLE_P2P_GO                  3
 207#define BRCMF_E_IF_ROLE_P2P_CLIENT              4
 208
 209/**
 210 * definitions for event packet validation.
 211 */
 212#define BRCM_OUI                                "\x00\x10\x18"
 213#define BCMILCP_BCM_SUBTYPE_EVENT               1
 214
 215
 216/**
 217 * struct brcm_ethhdr - broadcom specific ether header.
 218 *
 219 * @subtype: subtype for this packet.
 220 * @length: TODO: length of appended data.
 221 * @version: version indication.
 222 * @oui: OUI of this packet.
 223 * @usr_subtype: subtype for this OUI.
 224 */
 225struct brcm_ethhdr {
 226        __be16 subtype;
 227        __be16 length;
 228        u8 version;
 229        u8 oui[3];
 230        __be16 usr_subtype;
 231} __packed;
 232
 233struct brcmf_event_msg_be {
 234        __be16 version;
 235        __be16 flags;
 236        __be32 event_type;
 237        __be32 status;
 238        __be32 reason;
 239        __be32 auth_type;
 240        __be32 datalen;
 241        u8 addr[ETH_ALEN];
 242        char ifname[IFNAMSIZ];
 243        u8 ifidx;
 244        u8 bsscfgidx;
 245} __packed;
 246
 247/**
 248 * struct brcmf_event - contents of broadcom event packet.
 249 *
 250 * @eth: standard ether header.
 251 * @hdr: broadcom specific ether header.
 252 * @msg: common part of the actual event message.
 253 */
 254struct brcmf_event {
 255        struct ethhdr eth;
 256        struct brcm_ethhdr hdr;
 257        struct brcmf_event_msg_be msg;
 258} __packed;
 259
 260/**
 261 * struct brcmf_event_msg - firmware event message.
 262 *
 263 * @version: version information.
 264 * @flags: event flags.
 265 * @event_code: firmware event code.
 266 * @status: status information.
 267 * @reason: reason code.
 268 * @auth_type: authentication type.
 269 * @datalen: lenght of event data buffer.
 270 * @addr: ether address.
 271 * @ifname: interface name.
 272 * @ifidx: interface index.
 273 * @bsscfgidx: bsscfg index.
 274 */
 275struct brcmf_event_msg {
 276        u16 version;
 277        u16 flags;
 278        u32 event_code;
 279        u32 status;
 280        u32 reason;
 281        s32 auth_type;
 282        u32 datalen;
 283        u8 addr[ETH_ALEN];
 284        char ifname[IFNAMSIZ];
 285        u8 ifidx;
 286        u8 bsscfgidx;
 287};
 288
 289struct brcmf_if_event {
 290        u8 ifidx;
 291        u8 action;
 292        u8 flags;
 293        u8 bsscfgidx;
 294        u8 role;
 295};
 296
 297typedef int (*brcmf_fweh_handler_t)(struct brcmf_if *ifp,
 298                                    const struct brcmf_event_msg *evtmsg,
 299                                    void *data);
 300
 301/**
 302 * struct brcmf_fweh_info - firmware event handling information.
 303 *
 304 * @p2pdev_setup_ongoing: P2P device creation in progress.
 305 * @event_work: event worker.
 306 * @evt_q_lock: lock for event queue protection.
 307 * @event_q: event queue.
 308 * @evt_handler: registered event handlers.
 309 */
 310struct brcmf_fweh_info {
 311        bool p2pdev_setup_ongoing;
 312        struct work_struct event_work;
 313        spinlock_t evt_q_lock;
 314        struct list_head event_q;
 315        int (*evt_handler[BRCMF_E_LAST])(struct brcmf_if *ifp,
 316                                         const struct brcmf_event_msg *evtmsg,
 317                                         void *data);
 318};
 319
 320const char *brcmf_fweh_event_name(enum brcmf_fweh_event_code code);
 321
 322void brcmf_fweh_attach(struct brcmf_pub *drvr);
 323void brcmf_fweh_detach(struct brcmf_pub *drvr);
 324int brcmf_fweh_register(struct brcmf_pub *drvr, enum brcmf_fweh_event_code code,
 325                        int (*handler)(struct brcmf_if *ifp,
 326                                       const struct brcmf_event_msg *evtmsg,
 327                                       void *data));
 328void brcmf_fweh_unregister(struct brcmf_pub *drvr,
 329                           enum brcmf_fweh_event_code code);
 330int brcmf_fweh_activate_events(struct brcmf_if *ifp);
 331void brcmf_fweh_process_event(struct brcmf_pub *drvr,
 332                              struct brcmf_event *event_packet,
 333                              u32 packet_len);
 334void brcmf_fweh_p2pdev_setup(struct brcmf_if *ifp, bool ongoing);
 335
 336static inline void brcmf_fweh_process_skb(struct brcmf_pub *drvr,
 337                                          struct sk_buff *skb)
 338{
 339        struct brcmf_event *event_packet;
 340        u16 usr_stype;
 341
 342        /* only process events when protocol matches */
 343        if (skb->protocol != cpu_to_be16(ETH_P_LINK_CTL))
 344                return;
 345
 346        if ((skb->len + ETH_HLEN) < sizeof(*event_packet))
 347                return;
 348
 349        /* check for BRCM oui match */
 350        event_packet = (struct brcmf_event *)skb_mac_header(skb);
 351        if (memcmp(BRCM_OUI, &event_packet->hdr.oui[0],
 352                   sizeof(event_packet->hdr.oui)))
 353                return;
 354
 355        /* final match on usr_subtype */
 356        usr_stype = get_unaligned_be16(&event_packet->hdr.usr_subtype);
 357        if (usr_stype != BCMILCP_BCM_SUBTYPE_EVENT)
 358                return;
 359
 360        brcmf_fweh_process_event(drvr, event_packet, skb->len + ETH_HLEN);
 361}
 362
 363#endif /* FWEH_H_ */
 364