2 * ---------------------------------------------------------------------------
6 * Code to generate iwevents.
8 * Copyright (C) 2006-2008 by Cambridge Silicon Radio Ltd.
10 * Refer to LICENSE.txt included with this source code for details on
13 * ---------------------------------------------------------------------------
15 #include <linux/types.h>
16 #include <linux/etherdevice.h>
17 #include <linux/if_arp.h>
18 #include "csr_wifi_hip_unifi.h"
19 #include "unifi_priv.h"
24 * ---------------------------------------------------------------------------
25 * wext_send_assoc_event
27 * Send wireless-extension events up to userland to announce
28 * successful association with an AP.
31 * priv Pointer to driver context.
32 * bssid MAC address of AP we associated with
33 * req_ie, req_ie_len IEs in the original request
34 * resp_ie, resp_ie_len IEs in the response
40 * This is sent on first successful association, and again if we
42 * ---------------------------------------------------------------------------
45 wext_send_assoc_event(unifi_priv_t
*priv
, unsigned char *bssid
,
46 unsigned char *req_ie
, int req_ie_len
,
47 unsigned char *resp_ie
, int resp_ie_len
,
48 unsigned char *scan_ie
, unsigned int scan_ie_len
)
51 union iwreq_data wrqu
;
53 if (req_ie_len
== 0) req_ie
= NULL
;
54 wrqu
.data
.length
= req_ie_len
;
56 wireless_send_event(priv
->netdev
[CSR_WIFI_INTERFACE_IN_USE
], IWEVASSOCREQIE
, &wrqu
, req_ie
);
58 if (resp_ie_len
== 0) resp_ie
= NULL
;
59 wrqu
.data
.length
= resp_ie_len
;
61 wireless_send_event(priv
->netdev
[CSR_WIFI_INTERFACE_IN_USE
], IWEVASSOCRESPIE
, &wrqu
, resp_ie
);
63 if (scan_ie_len
> 0) {
64 wrqu
.data
.length
= scan_ie_len
;
66 wireless_send_event(priv
->netdev
[CSR_WIFI_INTERFACE_IN_USE
], IWEVGENIE
, &wrqu
, scan_ie
);
69 memcpy(&wrqu
.ap_addr
.sa_data
, bssid
, ETH_ALEN
);
70 wireless_send_event(priv
->netdev
[CSR_WIFI_INTERFACE_IN_USE
], SIOCGIWAP
, &wrqu
, NULL
);
72 } /* wext_send_assoc_event() */
77 * ---------------------------------------------------------------------------
78 * wext_send_disassoc_event
80 * Send a wireless-extension event up to userland to announce
81 * that we disassociated from an AP.
84 * priv Pointer to driver context.
90 * The semantics of wpa_supplicant (the userland SME application) are
91 * that a SIOCGIWAP event with MAC address of all zero means
93 * ---------------------------------------------------------------------------
96 wext_send_disassoc_event(unifi_priv_t
*priv
)
99 union iwreq_data wrqu
;
101 memset(wrqu
.ap_addr
.sa_data
, 0, ETH_ALEN
);
102 wireless_send_event(priv
->netdev
[CSR_WIFI_INTERFACE_IN_USE
], SIOCGIWAP
, &wrqu
, NULL
);
104 } /* wext_send_disassoc_event() */
109 * ---------------------------------------------------------------------------
110 * wext_send_scan_results_event
112 * Send wireless-extension events up to userland to announce
113 * completion of a scan.
116 * priv Pointer to driver context.
122 * This doesn't actually report the results, they are retrieved
123 * using the SIOCGIWSCAN ioctl command.
124 * ---------------------------------------------------------------------------
127 wext_send_scan_results_event(unifi_priv_t
*priv
)
129 #if WIRELESS_EXT > 17
130 union iwreq_data wrqu
;
132 wrqu
.data
.length
= 0;
134 wireless_send_event(priv
->netdev
[CSR_WIFI_INTERFACE_IN_USE
], SIOCGIWSCAN
, &wrqu
, NULL
);
137 } /* wext_send_scan_results_event() */
142 * ---------------------------------------------------------------------------
143 * wext_send_michaelmicfailure_event
145 * Send wireless-extension events up to userland to announce
146 * completion of a scan.
149 * priv Pointer to driver context.
150 * count, macaddr, key_type, key_idx, tsc
151 * Parameters from report from UniFi.
155 * ---------------------------------------------------------------------------
157 #if WIRELESS_EXT >= 18
159 _send_michaelmicfailure_event(struct net_device
*dev
,
160 int count
, const unsigned char *macaddr
,
161 int key_type
, int key_idx
,
164 union iwreq_data wrqu
;
165 struct iw_michaelmicfailure mmf
;
167 memset(&mmf
, 0, sizeof(mmf
));
169 mmf
.flags
= key_idx
& IW_MICFAILURE_KEY_ID
;
170 if (key_type
== CSR_GROUP
) {
171 mmf
.flags
|= IW_MICFAILURE_GROUP
;
173 mmf
.flags
|= IW_MICFAILURE_PAIRWISE
;
175 mmf
.flags
|= ((count
<< 5) & IW_MICFAILURE_COUNT
);
177 mmf
.src_addr
.sa_family
= ARPHRD_ETHER
;
178 memcpy(mmf
.src_addr
.sa_data
, macaddr
, ETH_ALEN
);
180 memcpy(mmf
.tsc
, tsc
, IW_ENCODE_SEQ_MAX_SIZE
);
182 memset(&wrqu
, 0, sizeof(wrqu
));
183 wrqu
.data
.length
= sizeof(mmf
);
185 wireless_send_event(dev
, IWEVMICHAELMICFAILURE
, &wrqu
, (char *)&mmf
);
187 #elif WIRELESS_EXT >= 15
189 _send_michaelmicfailure_event(struct net_device
*dev
,
190 int count
, const unsigned char *macaddr
,
191 int key_type
, int key_idx
,
194 union iwreq_data wrqu
;
198 "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr=%pM)",
199 key_idx
, (key_type
== CSR_GROUP
) ? "broad" : "uni", macaddr
);
200 memset(&wrqu
, 0, sizeof(wrqu
));
201 wrqu
.data
.length
= strlen(buf
);
202 wireless_send_event(dev
, IWEVCUSTOM
, &wrqu
, buf
);
204 #else /* WIRELESS_EXT >= 15 */
206 _send_michaelmicfailure_event(struct net_device
*dev
,
207 int count
, const unsigned char *macaddr
,
208 int key_type
, int key_idx
,
211 /* Not supported before WEXT 15 */
213 #endif /* WIRELESS_EXT >= 15 */
217 wext_send_michaelmicfailure_event(unifi_priv_t
*priv
,
219 CsrWifiMacAddress address
,
220 CsrWifiSmeKeyType keyType
,
223 unsigned char tsc
[8] = {0};
225 if (interfaceTag
>= CSR_WIFI_NUM_INTERFACES
) {
226 unifi_error(priv
, "wext_send_michaelmicfailure_event bad interfaceTag\n");
230 _send_michaelmicfailure_event(priv
->netdev
[interfaceTag
],
236 } /* wext_send_michaelmicfailure_event() */
239 wext_send_pmkid_candidate_event(unifi_priv_t
*priv
, CsrWifiMacAddress bssid
, u8 preauth_allowed
, u16 interfaceTag
)
241 #if WIRELESS_EXT > 17
242 union iwreq_data wrqu
;
243 struct iw_pmkid_cand pmkid_cand
;
245 if (interfaceTag
>= CSR_WIFI_NUM_INTERFACES
) {
246 unifi_error(priv
, "wext_send_pmkid_candidate_event bad interfaceTag\n");
250 memset(&pmkid_cand
, 0, sizeof(pmkid_cand
));
252 if (preauth_allowed
) {
253 pmkid_cand
.flags
|= IW_PMKID_CAND_PREAUTH
;
255 pmkid_cand
.bssid
.sa_family
= ARPHRD_ETHER
;
256 memcpy(pmkid_cand
.bssid
.sa_data
, bssid
.a
, ETH_ALEN
);
257 /* Used as priority, smaller the number higher the priority, not really used in our case */
258 pmkid_cand
.index
= 1;
260 memset(&wrqu
, 0, sizeof(wrqu
));
261 wrqu
.data
.length
= sizeof(pmkid_cand
);
263 wireless_send_event(priv
->netdev
[interfaceTag
], IWEVPMKIDCAND
, &wrqu
, (char *)&pmkid_cand
);
265 } /* wext_send_pmkid_candidate_event() */
268 * Send a custom WEXT event to say we have completed initialisation
269 * and are now ready for WEXT ioctls. Used by Android wpa_supplicant.
272 wext_send_started_event(unifi_priv_t
*priv
)
274 #if WIRELESS_EXT > 17
275 union iwreq_data wrqu
;
276 char data
[] = "STARTED";
278 wrqu
.data
.length
= sizeof(data
);
280 wireless_send_event(priv
->netdev
[CSR_WIFI_INTERFACE_IN_USE
], IWEVCUSTOM
, &wrqu
, data
);
282 } /* wext_send_started_event() */