Commit | Line | Data |
---|---|---|
5c36b99a AS |
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 | ||
b6f06f6e | 21 | #include <asm/unaligned.h> |
5c36b99a AS |
22 | #include <linux/skbuff.h> |
23 | #include <linux/if_ether.h> | |
24 | #include <linux/if.h> | |
25 | ||
26 | /* formward declarations */ | |
27 | struct brcmf_pub; | |
28 | struct brcmf_if; | |
29 | struct brcmf_cfg80211_info; | |
30 | struct brcmf_event; | |
31 | ||
dc5cbdfd AS |
32 | /* list of firmware events */ |
33 | #define BRCMF_FWEH_EVENT_ENUM_DEFLIST \ | |
34 | BRCMF_ENUM_DEF(SET_SSID, 0) \ | |
35 | BRCMF_ENUM_DEF(JOIN, 1) \ | |
36 | BRCMF_ENUM_DEF(START, 2) \ | |
37 | BRCMF_ENUM_DEF(AUTH, 3) \ | |
38 | BRCMF_ENUM_DEF(AUTH_IND, 4) \ | |
39 | BRCMF_ENUM_DEF(DEAUTH, 5) \ | |
40 | BRCMF_ENUM_DEF(DEAUTH_IND, 6) \ | |
41 | BRCMF_ENUM_DEF(ASSOC, 7) \ | |
42 | BRCMF_ENUM_DEF(ASSOC_IND, 8) \ | |
43 | BRCMF_ENUM_DEF(REASSOC, 9) \ | |
44 | BRCMF_ENUM_DEF(REASSOC_IND, 10) \ | |
45 | BRCMF_ENUM_DEF(DISASSOC, 11) \ | |
46 | BRCMF_ENUM_DEF(DISASSOC_IND, 12) \ | |
47 | BRCMF_ENUM_DEF(QUIET_START, 13) \ | |
48 | BRCMF_ENUM_DEF(QUIET_END, 14) \ | |
49 | BRCMF_ENUM_DEF(BEACON_RX, 15) \ | |
50 | BRCMF_ENUM_DEF(LINK, 16) \ | |
51 | BRCMF_ENUM_DEF(MIC_ERROR, 17) \ | |
52 | BRCMF_ENUM_DEF(NDIS_LINK, 18) \ | |
53 | BRCMF_ENUM_DEF(ROAM, 19) \ | |
54 | BRCMF_ENUM_DEF(TXFAIL, 20) \ | |
55 | BRCMF_ENUM_DEF(PMKID_CACHE, 21) \ | |
56 | BRCMF_ENUM_DEF(RETROGRADE_TSF, 22) \ | |
57 | BRCMF_ENUM_DEF(PRUNE, 23) \ | |
58 | BRCMF_ENUM_DEF(AUTOAUTH, 24) \ | |
59 | BRCMF_ENUM_DEF(EAPOL_MSG, 25) \ | |
60 | BRCMF_ENUM_DEF(SCAN_COMPLETE, 26) \ | |
61 | BRCMF_ENUM_DEF(ADDTS_IND, 27) \ | |
62 | BRCMF_ENUM_DEF(DELTS_IND, 28) \ | |
63 | BRCMF_ENUM_DEF(BCNSENT_IND, 29) \ | |
64 | BRCMF_ENUM_DEF(BCNRX_MSG, 30) \ | |
65 | BRCMF_ENUM_DEF(BCNLOST_MSG, 31) \ | |
66 | BRCMF_ENUM_DEF(ROAM_PREP, 32) \ | |
67 | BRCMF_ENUM_DEF(PFN_NET_FOUND, 33) \ | |
68 | BRCMF_ENUM_DEF(PFN_NET_LOST, 34) \ | |
69 | BRCMF_ENUM_DEF(RESET_COMPLETE, 35) \ | |
70 | BRCMF_ENUM_DEF(JOIN_START, 36) \ | |
71 | BRCMF_ENUM_DEF(ROAM_START, 37) \ | |
72 | BRCMF_ENUM_DEF(ASSOC_START, 38) \ | |
73 | BRCMF_ENUM_DEF(IBSS_ASSOC, 39) \ | |
74 | BRCMF_ENUM_DEF(RADIO, 40) \ | |
75 | BRCMF_ENUM_DEF(PSM_WATCHDOG, 41) \ | |
76 | BRCMF_ENUM_DEF(PROBREQ_MSG, 44) \ | |
77 | BRCMF_ENUM_DEF(SCAN_CONFIRM_IND, 45) \ | |
78 | BRCMF_ENUM_DEF(PSK_SUP, 46) \ | |
79 | BRCMF_ENUM_DEF(COUNTRY_CODE_CHANGED, 47) \ | |
80 | BRCMF_ENUM_DEF(EXCEEDED_MEDIUM_TIME, 48) \ | |
81 | BRCMF_ENUM_DEF(ICV_ERROR, 49) \ | |
82 | BRCMF_ENUM_DEF(UNICAST_DECODE_ERROR, 50) \ | |
83 | BRCMF_ENUM_DEF(MULTICAST_DECODE_ERROR, 51) \ | |
84 | BRCMF_ENUM_DEF(TRACE, 52) \ | |
85 | BRCMF_ENUM_DEF(IF, 54) \ | |
0de8aace | 86 | BRCMF_ENUM_DEF(P2P_DISC_LISTEN_COMPLETE, 55) \ |
dc5cbdfd | 87 | BRCMF_ENUM_DEF(RSSI, 56) \ |
dc5cbdfd AS |
88 | BRCMF_ENUM_DEF(EXTLOG_MSG, 58) \ |
89 | BRCMF_ENUM_DEF(ACTION_FRAME, 59) \ | |
90 | BRCMF_ENUM_DEF(ACTION_FRAME_COMPLETE, 60) \ | |
91 | BRCMF_ENUM_DEF(PRE_ASSOC_IND, 61) \ | |
92 | BRCMF_ENUM_DEF(PRE_REASSOC_IND, 62) \ | |
93 | BRCMF_ENUM_DEF(CHANNEL_ADOPTED, 63) \ | |
94 | BRCMF_ENUM_DEF(AP_STARTED, 64) \ | |
95 | BRCMF_ENUM_DEF(DFS_AP_STOP, 65) \ | |
96 | BRCMF_ENUM_DEF(DFS_AP_RESUME, 66) \ | |
97 | BRCMF_ENUM_DEF(ESCAN_RESULT, 69) \ | |
98 | BRCMF_ENUM_DEF(ACTION_FRAME_OFF_CHAN_COMPLETE, 70) \ | |
0de8aace HM |
99 | BRCMF_ENUM_DEF(PROBERESP_MSG, 71) \ |
100 | BRCMF_ENUM_DEF(P2P_PROBEREQ_MSG, 72) \ | |
dc5cbdfd | 101 | BRCMF_ENUM_DEF(DCS_REQUEST, 73) \ |
0de8aace | 102 | BRCMF_ENUM_DEF(FIFO_CREDIT_MAP, 74) \ |
7d747037 | 103 | BRCMF_ENUM_DEF(ACTION_FRAME_RX, 75) \ |
70b7d94b | 104 | BRCMF_ENUM_DEF(TDLS_PEER_EVENT, 92) \ |
fc7c3ad5 | 105 | BRCMF_ENUM_DEF(BCMC_CREDIT_SUPPORT, 127) |
dc5cbdfd AS |
106 | |
107 | #define BRCMF_ENUM_DEF(id, val) \ | |
108 | BRCMF_E_##id = (val), | |
109 | ||
5c36b99a AS |
110 | /* firmware event codes sent by the dongle */ |
111 | enum brcmf_fweh_event_code { | |
dc5cbdfd | 112 | BRCMF_FWEH_EVENT_ENUM_DEFLIST |
fc7c3ad5 AS |
113 | /* this determines event mask length which must match |
114 | * minimum length check in device firmware so it is | |
115 | * hard-coded here. | |
116 | */ | |
117 | BRCMF_E_LAST = 139 | |
5c36b99a | 118 | }; |
dc5cbdfd | 119 | #undef BRCMF_ENUM_DEF |
5c36b99a | 120 | |
5af47fb3 | 121 | #define BRCMF_EVENTING_MASK_LEN DIV_ROUND_UP(BRCMF_E_LAST, 8) |
4cd0ea45 | 122 | |
5c36b99a AS |
123 | /* flags field values in struct brcmf_event_msg */ |
124 | #define BRCMF_EVENT_MSG_LINK 0x01 | |
125 | #define BRCMF_EVENT_MSG_FLUSHTXQ 0x02 | |
126 | #define BRCMF_EVENT_MSG_GROUP 0x04 | |
127 | ||
01376a07 AS |
128 | /* status field values in struct brcmf_event_msg */ |
129 | #define BRCMF_E_STATUS_SUCCESS 0 | |
130 | #define BRCMF_E_STATUS_FAIL 1 | |
131 | #define BRCMF_E_STATUS_TIMEOUT 2 | |
132 | #define BRCMF_E_STATUS_NO_NETWORKS 3 | |
133 | #define BRCMF_E_STATUS_ABORT 4 | |
134 | #define BRCMF_E_STATUS_NO_ACK 5 | |
135 | #define BRCMF_E_STATUS_UNSOLICITED 6 | |
136 | #define BRCMF_E_STATUS_ATTEMPT 7 | |
137 | #define BRCMF_E_STATUS_PARTIAL 8 | |
138 | #define BRCMF_E_STATUS_NEWSCAN 9 | |
139 | #define BRCMF_E_STATUS_NEWASSOC 10 | |
140 | #define BRCMF_E_STATUS_11HQUIET 11 | |
141 | #define BRCMF_E_STATUS_SUPPRESS 12 | |
142 | #define BRCMF_E_STATUS_NOCHANS 13 | |
143 | #define BRCMF_E_STATUS_CS_ABORT 15 | |
144 | #define BRCMF_E_STATUS_ERROR 16 | |
145 | ||
146 | /* reason field values in struct brcmf_event_msg */ | |
147 | #define BRCMF_E_REASON_INITIAL_ASSOC 0 | |
148 | #define BRCMF_E_REASON_LOW_RSSI 1 | |
149 | #define BRCMF_E_REASON_DEAUTH 2 | |
150 | #define BRCMF_E_REASON_DISASSOC 3 | |
151 | #define BRCMF_E_REASON_BCNS_LOST 4 | |
152 | #define BRCMF_E_REASON_MINTXRATE 9 | |
153 | #define BRCMF_E_REASON_TXFAIL 10 | |
154 | ||
155 | #define BRCMF_E_REASON_LINK_BSSCFG_DIS 4 | |
156 | #define BRCMF_E_REASON_FAST_ROAM_FAILED 5 | |
157 | #define BRCMF_E_REASON_DIRECTED_ROAM 6 | |
158 | #define BRCMF_E_REASON_TSPEC_REJECTED 7 | |
159 | #define BRCMF_E_REASON_BETTER_AP 8 | |
160 | ||
70b7d94b HM |
161 | #define BRCMF_E_REASON_TDLS_PEER_DISCOVERED 0 |
162 | #define BRCMF_E_REASON_TDLS_PEER_CONNECTED 1 | |
163 | #define BRCMF_E_REASON_TDLS_PEER_DISCONNECTED 2 | |
164 | ||
01376a07 AS |
165 | /* action field values for brcmf_ifevent */ |
166 | #define BRCMF_E_IF_ADD 1 | |
167 | #define BRCMF_E_IF_DEL 2 | |
168 | #define BRCMF_E_IF_CHANGE 3 | |
169 | ||
170 | /* flag field values for brcmf_ifevent */ | |
171 | #define BRCMF_E_IF_FLAG_NOIF 1 | |
172 | ||
173 | /* role field values for brcmf_ifevent */ | |
174 | #define BRCMF_E_IF_ROLE_STA 0 | |
175 | #define BRCMF_E_IF_ROLE_AP 1 | |
176 | #define BRCMF_E_IF_ROLE_WDS 2 | |
87c47903 AS |
177 | #define BRCMF_E_IF_ROLE_P2P_GO 3 |
178 | #define BRCMF_E_IF_ROLE_P2P_CLIENT 4 | |
01376a07 | 179 | |
5c36b99a AS |
180 | /** |
181 | * definitions for event packet validation. | |
182 | */ | |
183 | #define BRCMF_EVENT_OUI_OFFSET 19 | |
184 | #define BRCM_OUI "\x00\x10\x18" | |
185 | #define DOT11_OUI_LEN 3 | |
186 | #define BCMILCP_BCM_SUBTYPE_EVENT 1 | |
187 | ||
188 | ||
189 | /** | |
190 | * struct brcmf_event_msg - firmware event message. | |
191 | * | |
192 | * @version: version information. | |
193 | * @flags: event flags. | |
194 | * @event_code: firmware event code. | |
195 | * @status: status information. | |
196 | * @reason: reason code. | |
197 | * @auth_type: authentication type. | |
198 | * @datalen: lenght of event data buffer. | |
199 | * @addr: ether address. | |
200 | * @ifname: interface name. | |
201 | * @ifidx: interface index. | |
202 | * @bsscfgidx: bsscfg index. | |
203 | */ | |
204 | struct brcmf_event_msg { | |
205 | u16 version; | |
206 | u16 flags; | |
207 | u32 event_code; | |
208 | u32 status; | |
209 | u32 reason; | |
210 | s32 auth_type; | |
211 | u32 datalen; | |
212 | u8 addr[ETH_ALEN]; | |
213 | char ifname[IFNAMSIZ]; | |
214 | u8 ifidx; | |
215 | u8 bsscfgidx; | |
216 | }; | |
217 | ||
01376a07 AS |
218 | struct brcmf_if_event { |
219 | u8 ifidx; | |
220 | u8 action; | |
221 | u8 flags; | |
222 | u8 bssidx; | |
223 | u8 role; | |
224 | }; | |
225 | ||
5c36b99a AS |
226 | typedef int (*brcmf_fweh_handler_t)(struct brcmf_if *ifp, |
227 | const struct brcmf_event_msg *evtmsg, | |
228 | void *data); | |
229 | ||
230 | /** | |
231 | * struct brcmf_fweh_info - firmware event handling information. | |
232 | * | |
cb8dc71f | 233 | * @p2pdev_setup_ongoing: P2P device creation in progress. |
5c36b99a AS |
234 | * @event_work: event worker. |
235 | * @evt_q_lock: lock for event queue protection. | |
236 | * @event_q: event queue. | |
237 | * @evt_handler: registered event handlers. | |
238 | */ | |
239 | struct brcmf_fweh_info { | |
cb8dc71f | 240 | bool p2pdev_setup_ongoing; |
5c36b99a | 241 | struct work_struct event_work; |
f241b244 | 242 | spinlock_t evt_q_lock; |
5c36b99a AS |
243 | struct list_head event_q; |
244 | int (*evt_handler[BRCMF_E_LAST])(struct brcmf_if *ifp, | |
245 | const struct brcmf_event_msg *evtmsg, | |
246 | void *data); | |
247 | }; | |
248 | ||
249 | void brcmf_fweh_attach(struct brcmf_pub *drvr); | |
250 | void brcmf_fweh_detach(struct brcmf_pub *drvr); | |
251 | int brcmf_fweh_register(struct brcmf_pub *drvr, enum brcmf_fweh_event_code code, | |
252 | int (*handler)(struct brcmf_if *ifp, | |
253 | const struct brcmf_event_msg *evtmsg, | |
254 | void *data)); | |
255 | void brcmf_fweh_unregister(struct brcmf_pub *drvr, | |
256 | enum brcmf_fweh_event_code code); | |
257 | int brcmf_fweh_activate_events(struct brcmf_if *ifp); | |
258 | void brcmf_fweh_process_event(struct brcmf_pub *drvr, | |
deb09280 | 259 | struct brcmf_event *event_packet); |
cb8dc71f | 260 | void brcmf_fweh_p2pdev_setup(struct brcmf_if *ifp, bool ongoing); |
5c36b99a AS |
261 | |
262 | static inline void brcmf_fweh_process_skb(struct brcmf_pub *drvr, | |
deb09280 | 263 | struct sk_buff *skb) |
5c36b99a AS |
264 | { |
265 | struct brcmf_event *event_packet; | |
266 | u8 *data; | |
267 | u16 usr_stype; | |
268 | ||
269 | /* only process events when protocol matches */ | |
270 | if (skb->protocol != cpu_to_be16(ETH_P_LINK_CTL)) | |
271 | return; | |
272 | ||
273 | /* check for BRCM oui match */ | |
274 | event_packet = (struct brcmf_event *)skb_mac_header(skb); | |
275 | data = (u8 *)event_packet; | |
276 | data += BRCMF_EVENT_OUI_OFFSET; | |
277 | if (memcmp(BRCM_OUI, data, DOT11_OUI_LEN)) | |
278 | return; | |
279 | ||
280 | /* final match on usr_subtype */ | |
281 | data += DOT11_OUI_LEN; | |
282 | usr_stype = get_unaligned_be16(data); | |
283 | if (usr_stype != BCMILCP_BCM_SUBTYPE_EVENT) | |
284 | return; | |
285 | ||
deb09280 | 286 | brcmf_fweh_process_event(drvr, event_packet); |
5c36b99a AS |
287 | } |
288 | ||
289 | #endif /* FWEH_H_ */ |