fweh.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  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. #ifndef FWEH_H_
  17. #define FWEH_H_
  18. #include <asm/unaligned.h>
  19. #include <linux/skbuff.h>
  20. #include <linux/if_ether.h>
  21. #include <linux/if.h>
  22. /* formward declarations */
  23. struct brcmf_pub;
  24. struct brcmf_if;
  25. struct brcmf_cfg80211_info;
  26. struct brcmf_event;
  27. /* firmware event codes sent by the dongle */
  28. enum brcmf_fweh_event_code {
  29. BRCMF_E_SET_SSID = 0,
  30. BRCMF_E_JOIN = 1,
  31. BRCMF_E_START = 2,
  32. BRCMF_E_AUTH = 3,
  33. BRCMF_E_AUTH_IND = 4,
  34. BRCMF_E_DEAUTH = 5,
  35. BRCMF_E_DEAUTH_IND = 6,
  36. BRCMF_E_ASSOC = 7,
  37. BRCMF_E_ASSOC_IND = 8,
  38. BRCMF_E_REASSOC = 9,
  39. BRCMF_E_REASSOC_IND = 10,
  40. BRCMF_E_DISASSOC = 11,
  41. BRCMF_E_DISASSOC_IND = 12,
  42. BRCMF_E_QUIET_START = 13,
  43. BRCMF_E_QUIET_END = 14,
  44. BRCMF_E_BEACON_RX = 15,
  45. BRCMF_E_LINK = 16,
  46. BRCMF_E_MIC_ERROR = 17,
  47. BRCMF_E_NDIS_LINK = 18,
  48. BRCMF_E_ROAM = 19,
  49. BRCMF_E_TXFAIL = 20,
  50. BRCMF_E_PMKID_CACHE = 21,
  51. BRCMF_E_RETROGRADE_TSF = 22,
  52. BRCMF_E_PRUNE = 23,
  53. BRCMF_E_AUTOAUTH = 24,
  54. BRCMF_E_EAPOL_MSG = 25,
  55. BRCMF_E_SCAN_COMPLETE = 26,
  56. BRCMF_E_ADDTS_IND = 27,
  57. BRCMF_E_DELTS_IND = 28,
  58. BRCMF_E_BCNSENT_IND = 29,
  59. BRCMF_E_BCNRX_MSG = 30,
  60. BRCMF_E_BCNLOST_MSG = 31,
  61. BRCMF_E_ROAM_PREP = 32,
  62. BRCMF_E_PFN_NET_FOUND = 33,
  63. BRCMF_E_PFN_NET_LOST = 34,
  64. BRCMF_E_RESET_COMPLETE = 35,
  65. BRCMF_E_JOIN_START = 36,
  66. BRCMF_E_ROAM_START = 37,
  67. BRCMF_E_ASSOC_START = 38,
  68. BRCMF_E_IBSS_ASSOC = 39,
  69. BRCMF_E_RADIO = 40,
  70. BRCMF_E_PSM_WATCHDOG = 41,
  71. BRCMF_E_PROBREQ_MSG = 44,
  72. BRCMF_E_SCAN_CONFIRM_IND = 45,
  73. BRCMF_E_PSK_SUP = 46,
  74. BRCMF_E_COUNTRY_CODE_CHANGED = 47,
  75. BRCMF_E_EXCEEDED_MEDIUM_TIME = 48,
  76. BRCMF_E_ICV_ERROR = 49,
  77. BRCMF_E_UNICAST_DECODE_ERROR = 50,
  78. BRCMF_E_MULTICAST_DECODE_ERROR = 51,
  79. BRCMF_E_TRACE = 52,
  80. BRCMF_E_IF = 54,
  81. BRCMF_E_RSSI = 56,
  82. BRCMF_E_PFN_SCAN_COMPLETE = 57,
  83. BRCMF_E_EXTLOG_MSG = 58,
  84. BRCMF_E_ACTION_FRAME = 59,
  85. BRCMF_E_ACTION_FRAME_COMPLETE = 60,
  86. BRCMF_E_PRE_ASSOC_IND = 61,
  87. BRCMF_E_PRE_REASSOC_IND = 62,
  88. BRCMF_E_CHANNEL_ADOPTED = 63,
  89. BRCMF_E_AP_STARTED = 64,
  90. BRCMF_E_DFS_AP_STOP = 65,
  91. BRCMF_E_DFS_AP_RESUME = 66,
  92. BRCMF_E_ESCAN_RESULT = 69,
  93. BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE = 70,
  94. BRCMF_E_DCS_REQUEST = 73,
  95. BRCMF_E_FIFO_CREDIT_MAP = 74,
  96. BRCMF_E_LAST
  97. };
  98. /* flags field values in struct brcmf_event_msg */
  99. #define BRCMF_EVENT_MSG_LINK 0x01
  100. #define BRCMF_EVENT_MSG_FLUSHTXQ 0x02
  101. #define BRCMF_EVENT_MSG_GROUP 0x04
  102. /**
  103. * definitions for event packet validation.
  104. */
  105. #define BRCMF_EVENT_OUI_OFFSET 19
  106. #define BRCM_OUI "\x00\x10\x18"
  107. #define DOT11_OUI_LEN 3
  108. #define BCMILCP_BCM_SUBTYPE_EVENT 1
  109. /**
  110. * struct brcmf_event_msg - firmware event message.
  111. *
  112. * @version: version information.
  113. * @flags: event flags.
  114. * @event_code: firmware event code.
  115. * @status: status information.
  116. * @reason: reason code.
  117. * @auth_type: authentication type.
  118. * @datalen: lenght of event data buffer.
  119. * @addr: ether address.
  120. * @ifname: interface name.
  121. * @ifidx: interface index.
  122. * @bsscfgidx: bsscfg index.
  123. */
  124. struct brcmf_event_msg {
  125. u16 version;
  126. u16 flags;
  127. u32 event_code;
  128. u32 status;
  129. u32 reason;
  130. s32 auth_type;
  131. u32 datalen;
  132. u8 addr[ETH_ALEN];
  133. char ifname[IFNAMSIZ];
  134. u8 ifidx;
  135. u8 bsscfgidx;
  136. };
  137. typedef int (*brcmf_fweh_handler_t)(struct brcmf_if *ifp,
  138. const struct brcmf_event_msg *evtmsg,
  139. void *data);
  140. /**
  141. * struct brcmf_fweh_info - firmware event handling information.
  142. *
  143. * @event_work: event worker.
  144. * @evt_q_lock: lock for event queue protection.
  145. * @event_q: event queue.
  146. * @evt_handler: registered event handlers.
  147. */
  148. struct brcmf_fweh_info {
  149. struct work_struct event_work;
  150. struct spinlock evt_q_lock;
  151. struct list_head event_q;
  152. int (*evt_handler[BRCMF_E_LAST])(struct brcmf_if *ifp,
  153. const struct brcmf_event_msg *evtmsg,
  154. void *data);
  155. };
  156. void brcmf_fweh_attach(struct brcmf_pub *drvr);
  157. void brcmf_fweh_detach(struct brcmf_pub *drvr);
  158. int brcmf_fweh_register(struct brcmf_pub *drvr, enum brcmf_fweh_event_code code,
  159. int (*handler)(struct brcmf_if *ifp,
  160. const struct brcmf_event_msg *evtmsg,
  161. void *data));
  162. void brcmf_fweh_unregister(struct brcmf_pub *drvr,
  163. enum brcmf_fweh_event_code code);
  164. int brcmf_fweh_activate_events(struct brcmf_if *ifp);
  165. void brcmf_fweh_process_event(struct brcmf_pub *drvr,
  166. struct brcmf_event *event_packet, u8 *ifidx);
  167. static inline void brcmf_fweh_process_skb(struct brcmf_pub *drvr,
  168. struct sk_buff *skb, u8 *ifidx)
  169. {
  170. struct brcmf_event *event_packet;
  171. u8 *data;
  172. u16 usr_stype;
  173. /* only process events when protocol matches */
  174. if (skb->protocol != cpu_to_be16(ETH_P_LINK_CTL))
  175. return;
  176. /* check for BRCM oui match */
  177. event_packet = (struct brcmf_event *)skb_mac_header(skb);
  178. data = (u8 *)event_packet;
  179. data += BRCMF_EVENT_OUI_OFFSET;
  180. if (memcmp(BRCM_OUI, data, DOT11_OUI_LEN))
  181. return;
  182. /* final match on usr_subtype */
  183. data += DOT11_OUI_LEN;
  184. usr_stype = get_unaligned_be16(data);
  185. if (usr_stype != BCMILCP_BCM_SUBTYPE_EVENT)
  186. return;
  187. brcmf_fweh_process_event(drvr, event_packet, ifidx);
  188. }
  189. #endif /* FWEH_H_ */