staging: ath6kl: Convert (status != A_OK) to (status)
[deliverable/linux.git] / drivers / staging / ath6kl / os / linux / wireless_ext.c
1 //------------------------------------------------------------------------------
2 // Copyright (c) 2004-2010 Atheros Communications Inc.
3 // All rights reserved.
4 //
5 //
6 //
7 // Permission to use, copy, modify, and/or distribute this software for any
8 // purpose with or without fee is hereby granted, provided that the above
9 // copyright notice and this permission notice appear in all copies.
10 //
11 // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 //
19 //
20 //
21 // Author(s): ="Atheros"
22 //------------------------------------------------------------------------------
23
24 #include "ar6000_drv.h"
25
26 #define IWE_STREAM_ADD_EVENT(p1, p2, p3, p4, p5) \
27 iwe_stream_add_event((p1), (p2), (p3), (p4), (p5))
28
29 #define IWE_STREAM_ADD_POINT(p1, p2, p3, p4, p5) \
30 iwe_stream_add_point((p1), (p2), (p3), (p4), (p5))
31
32 #define IWE_STREAM_ADD_VALUE(p1, p2, p3, p4, p5, p6) \
33 iwe_stream_add_value((p1), (p2), (p3), (p4), (p5), (p6))
34
35 static void ar6000_set_quality(struct iw_quality *iq, s8 rssi);
36 extern unsigned int wmitimeout;
37 extern A_WAITQUEUE_HEAD arEvent;
38
39 #if WIRELESS_EXT > 14
40 /*
41 * Encode a WPA or RSN information element as a custom
42 * element using the hostap format.
43 */
44 static u_int
45 encode_ie(void *buf, size_t bufsize,
46 const u_int8_t *ie, size_t ielen,
47 const char *leader, size_t leader_len)
48 {
49 u_int8_t *p;
50 int i;
51
52 if (bufsize < leader_len)
53 return 0;
54 p = buf;
55 memcpy(p, leader, leader_len);
56 bufsize -= leader_len;
57 p += leader_len;
58 for (i = 0; i < ielen && bufsize > 2; i++)
59 {
60 p += sprintf((char*)p, "%02x", ie[i]);
61 bufsize -= 2;
62 }
63 return (i == ielen ? p - (u_int8_t *)buf : 0);
64 }
65 #endif /* WIRELESS_EXT > 14 */
66
67 static u8 get_bss_phy_capability(bss_t *bss)
68 {
69 u8 capability = 0;
70 struct ieee80211_common_ie *cie = &bss->ni_cie;
71 #define CHAN_IS_11A(x) (!((x >= 2412) && (x <= 2484)))
72 if (CHAN_IS_11A(cie->ie_chan)) {
73 if (cie->ie_htcap) {
74 capability = WMI_11NA_CAPABILITY;
75 } else {
76 capability = WMI_11A_CAPABILITY;
77 }
78 } else if ((cie->ie_erp) || (cie->ie_xrates)) {
79 if (cie->ie_htcap) {
80 capability = WMI_11NG_CAPABILITY;
81 } else {
82 capability = WMI_11G_CAPABILITY;
83 }
84 }
85 return capability;
86 }
87
88 void
89 ar6000_scan_node(void *arg, bss_t *ni)
90 {
91 struct iw_event iwe;
92 #if WIRELESS_EXT > 14
93 char buf[256];
94 #endif
95 struct ar_giwscan_param *param;
96 char *current_ev;
97 char *end_buf;
98 struct ieee80211_common_ie *cie;
99 char *current_val;
100 s32 j;
101 u32 rate_len, data_len = 0;
102
103 param = (struct ar_giwscan_param *)arg;
104
105 current_ev = param->current_ev;
106 end_buf = param->end_buf;
107
108 cie = &ni->ni_cie;
109
110 if ((end_buf - current_ev) > IW_EV_ADDR_LEN)
111 {
112 A_MEMZERO(&iwe, sizeof(iwe));
113 iwe.cmd = SIOCGIWAP;
114 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
115 A_MEMCPY(iwe.u.ap_addr.sa_data, ni->ni_macaddr, 6);
116 current_ev = IWE_STREAM_ADD_EVENT(param->info, current_ev, end_buf,
117 &iwe, IW_EV_ADDR_LEN);
118 }
119 param->bytes_needed += IW_EV_ADDR_LEN;
120
121 data_len = cie->ie_ssid[1] + IW_EV_POINT_LEN;
122 if ((end_buf - current_ev) > data_len)
123 {
124 A_MEMZERO(&iwe, sizeof(iwe));
125 iwe.cmd = SIOCGIWESSID;
126 iwe.u.data.flags = 1;
127 iwe.u.data.length = cie->ie_ssid[1];
128 current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, end_buf,
129 &iwe, (char*)&cie->ie_ssid[2]);
130 }
131 param->bytes_needed += data_len;
132
133 if (cie->ie_capInfo & (IEEE80211_CAPINFO_ESS|IEEE80211_CAPINFO_IBSS)) {
134 if ((end_buf - current_ev) > IW_EV_UINT_LEN)
135 {
136 A_MEMZERO(&iwe, sizeof(iwe));
137 iwe.cmd = SIOCGIWMODE;
138 iwe.u.mode = cie->ie_capInfo & IEEE80211_CAPINFO_ESS ?
139 IW_MODE_MASTER : IW_MODE_ADHOC;
140 current_ev = IWE_STREAM_ADD_EVENT(param->info, current_ev, end_buf,
141 &iwe, IW_EV_UINT_LEN);
142 }
143 param->bytes_needed += IW_EV_UINT_LEN;
144 }
145
146 if ((end_buf - current_ev) > IW_EV_FREQ_LEN)
147 {
148 A_MEMZERO(&iwe, sizeof(iwe));
149 iwe.cmd = SIOCGIWFREQ;
150 iwe.u.freq.m = cie->ie_chan * 100000;
151 iwe.u.freq.e = 1;
152 current_ev = IWE_STREAM_ADD_EVENT(param->info, current_ev, end_buf,
153 &iwe, IW_EV_FREQ_LEN);
154 }
155 param->bytes_needed += IW_EV_FREQ_LEN;
156
157 if ((end_buf - current_ev) > IW_EV_QUAL_LEN)
158 {
159 A_MEMZERO(&iwe, sizeof(iwe));
160 iwe.cmd = IWEVQUAL;
161 ar6000_set_quality(&iwe.u.qual, ni->ni_snr);
162 current_ev = IWE_STREAM_ADD_EVENT(param->info, current_ev, end_buf,
163 &iwe, IW_EV_QUAL_LEN);
164 }
165 param->bytes_needed += IW_EV_QUAL_LEN;
166
167 if ((end_buf - current_ev) > IW_EV_POINT_LEN)
168 {
169 A_MEMZERO(&iwe, sizeof(iwe));
170 iwe.cmd = SIOCGIWENCODE;
171 if (cie->ie_capInfo & IEEE80211_CAPINFO_PRIVACY) {
172 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
173 } else {
174 iwe.u.data.flags = IW_ENCODE_DISABLED;
175 }
176 iwe.u.data.length = 0;
177 current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, end_buf,
178 &iwe, "");
179 }
180 param->bytes_needed += IW_EV_POINT_LEN;
181
182 /* supported bit rate */
183 A_MEMZERO(&iwe, sizeof(iwe));
184 iwe.cmd = SIOCGIWRATE;
185 iwe.u.bitrate.fixed = 0;
186 iwe.u.bitrate.disabled = 0;
187 iwe.u.bitrate.value = 0;
188 current_val = current_ev + IW_EV_LCP_LEN;
189 param->bytes_needed += IW_EV_LCP_LEN;
190
191 if (cie->ie_rates != NULL) {
192 rate_len = cie->ie_rates[1];
193 data_len = (rate_len * (IW_EV_PARAM_LEN - IW_EV_LCP_LEN));
194 if ((end_buf - current_ev) > data_len)
195 {
196 for (j = 0; j < rate_len; j++) {
197 unsigned char val;
198 val = cie->ie_rates[2 + j];
199 iwe.u.bitrate.value =
200 (val >= 0x80)? ((val - 0x80) * 500000): (val * 500000);
201 current_val = IWE_STREAM_ADD_VALUE(param->info, current_ev,
202 current_val, end_buf,
203 &iwe, IW_EV_PARAM_LEN);
204 }
205 }
206 param->bytes_needed += data_len;
207 }
208
209 if (cie->ie_xrates != NULL) {
210 rate_len = cie->ie_xrates[1];
211 data_len = (rate_len * (IW_EV_PARAM_LEN - IW_EV_LCP_LEN));
212 if ((end_buf - current_ev) > data_len)
213 {
214 for (j = 0; j < rate_len; j++) {
215 unsigned char val;
216 val = cie->ie_xrates[2 + j];
217 iwe.u.bitrate.value =
218 (val >= 0x80)? ((val - 0x80) * 500000): (val * 500000);
219 current_val = IWE_STREAM_ADD_VALUE(param->info, current_ev,
220 current_val, end_buf,
221 &iwe, IW_EV_PARAM_LEN);
222 }
223 }
224 param->bytes_needed += data_len;
225 }
226 /* remove fixed header if no rates were added */
227 if ((current_val - current_ev) > IW_EV_LCP_LEN)
228 current_ev = current_val;
229
230 #if WIRELESS_EXT >= 18
231 /* IE */
232 if (cie->ie_wpa != NULL) {
233 data_len = cie->ie_wpa[1] + 2 + IW_EV_POINT_LEN;
234 if ((end_buf - current_ev) > data_len)
235 {
236 A_MEMZERO(&iwe, sizeof(iwe));
237 iwe.cmd = IWEVGENIE;
238 iwe.u.data.length = cie->ie_wpa[1] + 2;
239 current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, end_buf,
240 &iwe, (char*)cie->ie_wpa);
241 }
242 param->bytes_needed += data_len;
243 }
244
245 if (cie->ie_rsn != NULL && cie->ie_rsn[0] == IEEE80211_ELEMID_RSN) {
246 data_len = cie->ie_rsn[1] + 2 + IW_EV_POINT_LEN;
247 if ((end_buf - current_ev) > data_len)
248 {
249 A_MEMZERO(&iwe, sizeof(iwe));
250 iwe.cmd = IWEVGENIE;
251 iwe.u.data.length = cie->ie_rsn[1] + 2;
252 current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, end_buf,
253 &iwe, (char*)cie->ie_rsn);
254 }
255 param->bytes_needed += data_len;
256 }
257
258 #endif /* WIRELESS_EXT >= 18 */
259
260 if ((end_buf - current_ev) > IW_EV_CHAR_LEN)
261 {
262 /* protocol */
263 A_MEMZERO(&iwe, sizeof(iwe));
264 iwe.cmd = SIOCGIWNAME;
265 switch (get_bss_phy_capability(ni)) {
266 case WMI_11A_CAPABILITY:
267 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11a");
268 break;
269 case WMI_11G_CAPABILITY:
270 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g");
271 break;
272 case WMI_11NA_CAPABILITY:
273 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11na");
274 break;
275 case WMI_11NG_CAPABILITY:
276 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11ng");
277 break;
278 default:
279 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b");
280 break;
281 }
282 current_ev = IWE_STREAM_ADD_EVENT(param->info, current_ev, end_buf,
283 &iwe, IW_EV_CHAR_LEN);
284 }
285 param->bytes_needed += IW_EV_CHAR_LEN;
286
287 #if WIRELESS_EXT > 14
288 A_MEMZERO(&iwe, sizeof(iwe));
289 iwe.cmd = IWEVCUSTOM;
290 iwe.u.data.length = snprintf(buf, sizeof(buf), "bcn_int=%d", cie->ie_beaconInt);
291 data_len = iwe.u.data.length + IW_EV_POINT_LEN;
292 if ((end_buf - current_ev) > data_len)
293 {
294 current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, end_buf,
295 &iwe, buf);
296 }
297 param->bytes_needed += data_len;
298
299 #if WIRELESS_EXT < 18
300 if (cie->ie_wpa != NULL) {
301 static const char wpa_leader[] = "wpa_ie=";
302 data_len = (sizeof(wpa_leader) - 1) + ((cie->ie_wpa[1]+2) * 2) + IW_EV_POINT_LEN;
303 if ((end_buf - current_ev) > data_len)
304 {
305 A_MEMZERO(&iwe, sizeof(iwe));
306 iwe.cmd = IWEVCUSTOM;
307 iwe.u.data.length = encode_ie(buf, sizeof(buf), cie->ie_wpa,
308 cie->ie_wpa[1]+2,
309 wpa_leader, sizeof(wpa_leader)-1);
310
311 if (iwe.u.data.length != 0) {
312 current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev,
313 end_buf, &iwe, buf);
314 }
315 }
316 param->bytes_needed += data_len;
317 }
318
319 if (cie->ie_rsn != NULL && cie->ie_rsn[0] == IEEE80211_ELEMID_RSN) {
320 static const char rsn_leader[] = "rsn_ie=";
321 data_len = (sizeof(rsn_leader) - 1) + ((cie->ie_rsn[1]+2) * 2) + IW_EV_POINT_LEN;
322 if ((end_buf - current_ev) > data_len)
323 {
324 A_MEMZERO(&iwe, sizeof(iwe));
325 iwe.cmd = IWEVCUSTOM;
326 iwe.u.data.length = encode_ie(buf, sizeof(buf), cie->ie_rsn,
327 cie->ie_rsn[1]+2,
328 rsn_leader, sizeof(rsn_leader)-1);
329
330 if (iwe.u.data.length != 0) {
331 current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev,
332 end_buf, &iwe, buf);
333 }
334 }
335 param->bytes_needed += data_len;
336 }
337 #endif /* WIRELESS_EXT < 18 */
338
339 if (cie->ie_wmm != NULL) {
340 static const char wmm_leader[] = "wmm_ie=";
341 data_len = (sizeof(wmm_leader) - 1) + ((cie->ie_wmm[1]+2) * 2) + IW_EV_POINT_LEN;
342 if ((end_buf - current_ev) > data_len)
343 {
344 A_MEMZERO(&iwe, sizeof(iwe));
345 iwe.cmd = IWEVCUSTOM;
346 iwe.u.data.length = encode_ie(buf, sizeof(buf), cie->ie_wmm,
347 cie->ie_wmm[1]+2,
348 wmm_leader, sizeof(wmm_leader)-1);
349 if (iwe.u.data.length != 0) {
350 current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev,
351 end_buf, &iwe, buf);
352 }
353 }
354 param->bytes_needed += data_len;
355 }
356
357 if (cie->ie_ath != NULL) {
358 static const char ath_leader[] = "ath_ie=";
359 data_len = (sizeof(ath_leader) - 1) + ((cie->ie_ath[1]+2) * 2) + IW_EV_POINT_LEN;
360 if ((end_buf - current_ev) > data_len)
361 {
362 A_MEMZERO(&iwe, sizeof(iwe));
363 iwe.cmd = IWEVCUSTOM;
364 iwe.u.data.length = encode_ie(buf, sizeof(buf), cie->ie_ath,
365 cie->ie_ath[1]+2,
366 ath_leader, sizeof(ath_leader)-1);
367 if (iwe.u.data.length != 0) {
368 current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev,
369 end_buf, &iwe, buf);
370 }
371 }
372 param->bytes_needed += data_len;
373 }
374
375 #ifdef WAPI_ENABLE
376 if (cie->ie_wapi != NULL) {
377 static const char wapi_leader[] = "wapi_ie=";
378 data_len = (sizeof(wapi_leader) - 1) + ((cie->ie_wapi[1] + 2) * 2) + IW_EV_POINT_LEN;
379 if ((end_buf - current_ev) > data_len) {
380 A_MEMZERO(&iwe, sizeof(iwe));
381 iwe.cmd = IWEVCUSTOM;
382 iwe.u.data.length = encode_ie(buf, sizeof(buf), cie->ie_wapi,
383 cie->ie_wapi[1] + 2,
384 wapi_leader, sizeof(wapi_leader) - 1);
385 if (iwe.u.data.length != 0) {
386 current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev,
387 end_buf, &iwe, buf);
388 }
389 }
390 param->bytes_needed += data_len;
391 }
392 #endif /* WAPI_ENABLE */
393
394 #endif /* WIRELESS_EXT > 14 */
395
396 #if WIRELESS_EXT >= 18
397 if (cie->ie_wsc != NULL) {
398 data_len = (cie->ie_wsc[1] + 2) + IW_EV_POINT_LEN;
399 if ((end_buf - current_ev) > data_len)
400 {
401 A_MEMZERO(&iwe, sizeof(iwe));
402 iwe.cmd = IWEVGENIE;
403 iwe.u.data.length = cie->ie_wsc[1] + 2;
404 current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, end_buf,
405 &iwe, (char*)cie->ie_wsc);
406 }
407 param->bytes_needed += data_len;
408 }
409 #endif /* WIRELESS_EXT >= 18 */
410
411 param->current_ev = current_ev;
412 }
413
414 int
415 ar6000_ioctl_giwscan(struct net_device *dev,
416 struct iw_request_info *info,
417 struct iw_point *data, char *extra)
418 {
419 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
420 struct ar_giwscan_param param;
421
422 if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
423 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
424 return -EOPNOTSUPP;
425 }
426
427 if (ar->arWlanState == WLAN_DISABLED) {
428 return -EIO;
429 }
430
431 if (ar->arWmiReady == false) {
432 return -EIO;
433 }
434
435 param.current_ev = extra;
436 param.end_buf = extra + data->length;
437 param.bytes_needed = 0;
438 param.info = info;
439
440 /* Translate data to WE format */
441 wmi_iterate_nodes(ar->arWmi, ar6000_scan_node, &param);
442
443 /* check if bytes needed is greater than bytes consumed */
444 if (param.bytes_needed > (param.current_ev - extra))
445 {
446 /* Request one byte more than needed, because when "data->length" equals bytes_needed,
447 it is not possible to add the last event data as all iwe_stream_add_xxxxx() functions
448 checks whether (cur_ptr + ev_len) < end_ptr, due to this one more retry would happen*/
449 data->length = param.bytes_needed + 1;
450
451 return -E2BIG;
452 }
453
454 return 0;
455 }
456
457 extern int reconnect_flag;
458 /* SIOCSIWESSID */
459 static int
460 ar6000_ioctl_siwessid(struct net_device *dev,
461 struct iw_request_info *info,
462 struct iw_point *data, char *ssid)
463 {
464 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
465 int status;
466 u8 arNetworkType;
467 u8 prevMode = ar->arNetworkType;
468
469 if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
470 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
471 return -EOPNOTSUPP;
472 }
473
474 if (ar->bIsDestroyProgress) {
475 return -EBUSY;
476 }
477
478 if (ar->arWlanState == WLAN_DISABLED) {
479 return -EIO;
480 }
481
482 if (ar->arWmiReady == false) {
483 return -EIO;
484 }
485
486 #if defined(WIRELESS_EXT)
487 if (WIRELESS_EXT >= 20) {
488 data->length += 1;
489 }
490 #endif
491
492 /*
493 * iwconfig passes a null terminated string with length including this
494 * so we need to account for this
495 */
496 if (data->flags && (!data->length || (data->length == 1) ||
497 ((data->length - 1) > sizeof(ar->arSsid))))
498 {
499 /*
500 * ssid is invalid
501 */
502 return -EINVAL;
503 }
504
505 if (ar->arNextMode == AP_NETWORK) {
506 /* SSID change for AP network - Will take effect on commit */
507 if(A_MEMCMP(ar->arSsid,ssid,32) != 0) {
508 ar->arSsidLen = data->length - 1;
509 A_MEMCPY(ar->arSsid, ssid, ar->arSsidLen);
510 ar->ap_profile_flag = 1; /* There is a change in profile */
511 }
512 return 0;
513 } else if(ar->arNetworkType == AP_NETWORK) {
514 u8 ctr;
515 struct sk_buff *skb;
516
517 /* We are switching from AP to STA | IBSS mode, cleanup the AP state */
518 for (ctr=0; ctr < AP_MAX_NUM_STA; ctr++) {
519 remove_sta(ar, ar->sta_list[ctr].mac, 0);
520 }
521 A_MUTEX_LOCK(&ar->mcastpsqLock);
522 while (!A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq)) {
523 skb = A_NETBUF_DEQUEUE(&ar->mcastpsq);
524 A_NETBUF_FREE(skb);
525 }
526 A_MUTEX_UNLOCK(&ar->mcastpsqLock);
527 }
528
529 /* Added for bug 25178, return an IOCTL error instead of target returning
530 Illegal parameter error when either the BSSID or channel is missing
531 and we cannot scan during connect.
532 */
533 if (data->flags) {
534 if (ar->arSkipScan == true &&
535 (ar->arChannelHint == 0 ||
536 (!ar->arReqBssid[0] && !ar->arReqBssid[1] && !ar->arReqBssid[2] &&
537 !ar->arReqBssid[3] && !ar->arReqBssid[4] && !ar->arReqBssid[5])))
538 {
539 return -EINVAL;
540 }
541 }
542
543 if (down_interruptible(&ar->arSem)) {
544 return -ERESTARTSYS;
545 }
546
547 if (ar->bIsDestroyProgress || ar->arWlanState == WLAN_DISABLED) {
548 up(&ar->arSem);
549 return -EBUSY;
550 }
551
552 if (ar->arTxPending[wmi_get_control_ep(ar->arWmi)]) {
553 /*
554 * sleep until the command queue drains
555 */
556 wait_event_interruptible_timeout(arEvent,
557 ar->arTxPending[wmi_get_control_ep(ar->arWmi)] == 0, wmitimeout * HZ);
558 if (signal_pending(current)) {
559 return -EINTR;
560 }
561 }
562
563 if (!data->flags) {
564 arNetworkType = ar->arNetworkType;
565 #ifdef ATH6K_CONFIG_CFG80211
566 if (ar->arConnected) {
567 #endif /* ATH6K_CONFIG_CFG80211 */
568 ar6000_init_profile_info(ar);
569 #ifdef ATH6K_CONFIG_CFG80211
570 }
571 #endif /* ATH6K_CONFIG_CFG80211 */
572 ar->arNetworkType = arNetworkType;
573 }
574
575 /* Update the arNetworkType */
576 ar->arNetworkType = ar->arNextMode;
577
578
579 if ((prevMode != AP_NETWORK) &&
580 ((ar->arSsidLen) || ((ar->arSsidLen == 0) && ar->arConnected) || (!data->flags)))
581 {
582 if ((!data->flags) ||
583 (A_MEMCMP(ar->arSsid, ssid, ar->arSsidLen) != 0) ||
584 (ar->arSsidLen != (data->length - 1)))
585 {
586 /*
587 * SSID set previously or essid off has been issued.
588 *
589 * Disconnect Command is issued in two cases after wmi is ready
590 * (1) ssid is different from the previous setting
591 * (2) essid off has been issued
592 *
593 */
594 if (ar->arWmiReady == true) {
595 reconnect_flag = 0;
596 status = wmi_setPmkid_cmd(ar->arWmi, ar->arBssid, NULL, 0);
597 status = wmi_disconnect_cmd(ar->arWmi);
598 A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
599 ar->arSsidLen = 0;
600 if (ar->arSkipScan == false) {
601 A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
602 }
603 if (!data->flags) {
604 up(&ar->arSem);
605 return 0;
606 }
607 } else {
608 up(&ar->arSem);
609 }
610 }
611 else
612 {
613 /*
614 * SSID is same, so we assume profile hasn't changed.
615 * If the interface is up and wmi is ready, we issue
616 * a reconnect cmd. Issue a reconnect only we are already
617 * connected.
618 */
619 if((ar->arConnected == true) && (ar->arWmiReady == true))
620 {
621 reconnect_flag = true;
622 status = wmi_reconnect_cmd(ar->arWmi,ar->arReqBssid,
623 ar->arChannelHint);
624 up(&ar->arSem);
625 if (status) {
626 return -EIO;
627 }
628 return 0;
629 }
630 else{
631 /*
632 * Dont return if connect is pending.
633 */
634 if(!(ar->arConnectPending)) {
635 up(&ar->arSem);
636 return 0;
637 }
638 }
639 }
640 }
641
642 ar->arSsidLen = data->length - 1;
643 A_MEMCPY(ar->arSsid, ssid, ar->arSsidLen);
644
645 if (ar6000_connect_to_ap(ar)!= A_OK) {
646 up(&ar->arSem);
647 return -EIO;
648 }else{
649 up(&ar->arSem);
650 }
651 return 0;
652 }
653
654 /* SIOCGIWESSID */
655 static int
656 ar6000_ioctl_giwessid(struct net_device *dev,
657 struct iw_request_info *info,
658 struct iw_point *data, char *essid)
659 {
660 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
661
662 if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
663 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
664 return -EOPNOTSUPP;
665 }
666
667 if (ar->arWlanState == WLAN_DISABLED) {
668 return -EIO;
669 }
670
671 if (!ar->arSsidLen) {
672 return -EINVAL;
673 }
674
675 data->flags = 1;
676 data->length = ar->arSsidLen;
677 A_MEMCPY(essid, ar->arSsid, ar->arSsidLen);
678
679 return 0;
680 }
681
682
683 void ar6000_install_static_wep_keys(AR_SOFTC_T *ar)
684 {
685 u8 index;
686 u8 keyUsage;
687
688 for (index = WMI_MIN_KEY_INDEX; index <= WMI_MAX_KEY_INDEX; index++) {
689 if (ar->arWepKeyList[index].arKeyLen) {
690 keyUsage = GROUP_USAGE;
691 if (index == ar->arDefTxKeyIndex) {
692 keyUsage |= TX_USAGE;
693 }
694 wmi_addKey_cmd(ar->arWmi,
695 index,
696 WEP_CRYPT,
697 keyUsage,
698 ar->arWepKeyList[index].arKeyLen,
699 NULL,
700 ar->arWepKeyList[index].arKey, KEY_OP_INIT_VAL, NULL,
701 NO_SYNC_WMIFLAG);
702 }
703 }
704 }
705
706 /*
707 * SIOCSIWRATE
708 */
709 int
710 ar6000_ioctl_siwrate(struct net_device *dev,
711 struct iw_request_info *info,
712 struct iw_param *rrq, char *extra)
713 {
714 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
715 u32 kbps;
716 s8 rate_idx;
717
718 if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
719 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
720 return -EOPNOTSUPP;
721 }
722
723 if (rrq->fixed) {
724 kbps = rrq->value / 1000; /* rrq->value is in bps */
725 } else {
726 kbps = -1; /* -1 indicates auto rate */
727 }
728 if(kbps != -1 && wmi_validate_bitrate(ar->arWmi, kbps, &rate_idx) != A_OK)
729 {
730 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BitRate is not Valid %d\n", kbps));
731 return -EINVAL;
732 }
733 ar->arBitRate = kbps;
734 if(ar->arWmiReady == true)
735 {
736 if (wmi_set_bitrate_cmd(ar->arWmi, kbps, -1, -1) != A_OK) {
737 return -EINVAL;
738 }
739 }
740 return 0;
741 }
742
743 /*
744 * SIOCGIWRATE
745 */
746 int
747 ar6000_ioctl_giwrate(struct net_device *dev,
748 struct iw_request_info *info,
749 struct iw_param *rrq, char *extra)
750 {
751 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
752 int ret = 0;
753
754 if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
755 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
756 return -EOPNOTSUPP;
757 }
758
759 if (ar->bIsDestroyProgress) {
760 return -EBUSY;
761 }
762
763 if (ar->arWlanState == WLAN_DISABLED) {
764 return -EIO;
765 }
766
767 if ((ar->arNextMode != AP_NETWORK && !ar->arConnected) || ar->arWmiReady == false) {
768 rrq->value = 1000 * 1000;
769 return 0;
770 }
771
772 if (down_interruptible(&ar->arSem)) {
773 return -ERESTARTSYS;
774 }
775
776 if (ar->bIsDestroyProgress || ar->arWlanState == WLAN_DISABLED) {
777 up(&ar->arSem);
778 return -EBUSY;
779 }
780
781 ar->arBitRate = 0xFFFF;
782 if (wmi_get_bitrate_cmd(ar->arWmi) != A_OK) {
783 up(&ar->arSem);
784 return -EIO;
785 }
786 wait_event_interruptible_timeout(arEvent, ar->arBitRate != 0xFFFF, wmitimeout * HZ);
787 if (signal_pending(current)) {
788 ret = -EINTR;
789 }
790 /* If the interface is down or wmi is not ready or the target is not
791 connected - return the value stored in the device structure */
792 if (!ret) {
793 if (ar->arBitRate == -1) {
794 rrq->fixed = true;
795 rrq->value = 0;
796 } else {
797 rrq->value = ar->arBitRate * 1000;
798 }
799 }
800
801 up(&ar->arSem);
802
803 return ret;
804 }
805
806 /*
807 * SIOCSIWTXPOW
808 */
809 static int
810 ar6000_ioctl_siwtxpow(struct net_device *dev,
811 struct iw_request_info *info,
812 struct iw_param *rrq, char *extra)
813 {
814 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
815 u8 dbM;
816
817 if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
818 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
819 return -EOPNOTSUPP;
820 }
821
822 if (ar->arWlanState == WLAN_DISABLED) {
823 return -EIO;
824 }
825
826 if (rrq->disabled) {
827 return -EOPNOTSUPP;
828 }
829
830 if (rrq->fixed) {
831 if (rrq->flags != IW_TXPOW_DBM) {
832 return -EOPNOTSUPP;
833 }
834 ar->arTxPwr= dbM = rrq->value;
835 ar->arTxPwrSet = true;
836 } else {
837 ar->arTxPwr = dbM = 0;
838 ar->arTxPwrSet = false;
839 }
840 if(ar->arWmiReady == true)
841 {
842 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("Set tx pwr cmd %d dbM\n", dbM));
843 wmi_set_txPwr_cmd(ar->arWmi, dbM);
844 }
845 return 0;
846 }
847
848 /*
849 * SIOCGIWTXPOW
850 */
851 int
852 ar6000_ioctl_giwtxpow(struct net_device *dev,
853 struct iw_request_info *info,
854 struct iw_param *rrq, char *extra)
855 {
856 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
857 int ret = 0;
858
859 if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
860 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
861 return -EOPNOTSUPP;
862 }
863
864 if (ar->bIsDestroyProgress) {
865 return -EBUSY;
866 }
867
868 if (ar->arWlanState == WLAN_DISABLED) {
869 return -EIO;
870 }
871
872 if (down_interruptible(&ar->arSem)) {
873 return -ERESTARTSYS;
874 }
875
876 if (ar->bIsDestroyProgress) {
877 up(&ar->arSem);
878 return -EBUSY;
879 }
880
881 if((ar->arWmiReady == true) && (ar->arConnected == true))
882 {
883 ar->arTxPwr = 0;
884
885 if (wmi_get_txPwr_cmd(ar->arWmi) != A_OK) {
886 up(&ar->arSem);
887 return -EIO;
888 }
889
890 wait_event_interruptible_timeout(arEvent, ar->arTxPwr != 0, wmitimeout * HZ);
891
892 if (signal_pending(current)) {
893 ret = -EINTR;
894 }
895 }
896 /* If the interace is down or wmi is not ready or target is not connected
897 then return value stored in the device structure */
898
899 if (!ret) {
900 if (ar->arTxPwrSet == true) {
901 rrq->fixed = true;
902 }
903 rrq->value = ar->arTxPwr;
904 rrq->flags = IW_TXPOW_DBM;
905 //
906 // IWLIST need this flag to get TxPower
907 //
908 rrq->disabled = 0;
909 }
910
911 up(&ar->arSem);
912
913 return ret;
914 }
915
916 /*
917 * SIOCSIWRETRY
918 * since iwconfig only provides us with one max retry value, we use it
919 * to apply to data frames of the BE traffic class.
920 */
921 static int
922 ar6000_ioctl_siwretry(struct net_device *dev,
923 struct iw_request_info *info,
924 struct iw_param *rrq, char *extra)
925 {
926 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
927
928 if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
929 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
930 return -EOPNOTSUPP;
931 }
932
933 if (ar->arWlanState == WLAN_DISABLED) {
934 return -EIO;
935 }
936
937 if (rrq->disabled) {
938 return -EOPNOTSUPP;
939 }
940
941 if ((rrq->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT) {
942 return -EOPNOTSUPP;
943 }
944
945 if ( !(rrq->value >= WMI_MIN_RETRIES) || !(rrq->value <= WMI_MAX_RETRIES)) {
946 return - EINVAL;
947 }
948 if(ar->arWmiReady == true)
949 {
950 if (wmi_set_retry_limits_cmd(ar->arWmi, DATA_FRAMETYPE, WMM_AC_BE,
951 rrq->value, 0) != A_OK){
952 return -EINVAL;
953 }
954 }
955 ar->arMaxRetries = rrq->value;
956 return 0;
957 }
958
959 /*
960 * SIOCGIWRETRY
961 */
962 static int
963 ar6000_ioctl_giwretry(struct net_device *dev,
964 struct iw_request_info *info,
965 struct iw_param *rrq, char *extra)
966 {
967 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
968
969 if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
970 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
971 return -EOPNOTSUPP;
972 }
973
974 if (ar->arWlanState == WLAN_DISABLED) {
975 return -EIO;
976 }
977
978 rrq->disabled = 0;
979 switch (rrq->flags & IW_RETRY_TYPE) {
980 case IW_RETRY_LIFETIME:
981 return -EOPNOTSUPP;
982 break;
983 case IW_RETRY_LIMIT:
984 rrq->flags = IW_RETRY_LIMIT;
985 switch (rrq->flags & IW_RETRY_MODIFIER) {
986 case IW_RETRY_MIN:
987 rrq->flags |= IW_RETRY_MIN;
988 rrq->value = WMI_MIN_RETRIES;
989 break;
990 case IW_RETRY_MAX:
991 rrq->flags |= IW_RETRY_MAX;
992 rrq->value = ar->arMaxRetries;
993 break;
994 }
995 break;
996 }
997 return 0;
998 }
999
1000 /*
1001 * SIOCSIWENCODE
1002 */
1003 static int
1004 ar6000_ioctl_siwencode(struct net_device *dev,
1005 struct iw_request_info *info,
1006 struct iw_point *erq, char *keybuf)
1007 {
1008 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1009 int index;
1010 s32 auth = 0;
1011
1012 if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
1013 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
1014 return -EOPNOTSUPP;
1015 }
1016
1017 if(ar->arNextMode != AP_NETWORK) {
1018 /*
1019 * Static WEP Keys should be configured before setting the SSID
1020 */
1021 if (ar->arSsid[0] && erq->length) {
1022 return -EIO;
1023 }
1024 }
1025
1026 if (ar->arWlanState == WLAN_DISABLED) {
1027 return -EIO;
1028 }
1029
1030 index = erq->flags & IW_ENCODE_INDEX;
1031
1032 if (index && (((index - 1) < WMI_MIN_KEY_INDEX) ||
1033 ((index - 1) > WMI_MAX_KEY_INDEX)))
1034 {
1035 return -EIO;
1036 }
1037
1038 if (erq->flags & IW_ENCODE_DISABLED) {
1039 /*
1040 * Encryption disabled
1041 */
1042 if (index) {
1043 /*
1044 * If key index was specified then clear the specified key
1045 */
1046 index--;
1047 A_MEMZERO(ar->arWepKeyList[index].arKey,
1048 sizeof(ar->arWepKeyList[index].arKey));
1049 ar->arWepKeyList[index].arKeyLen = 0;
1050 }
1051 ar->arDot11AuthMode = OPEN_AUTH;
1052 ar->arPairwiseCrypto = NONE_CRYPT;
1053 ar->arGroupCrypto = NONE_CRYPT;
1054 ar->arAuthMode = NONE_AUTH;
1055 } else {
1056 /*
1057 * Enabling WEP encryption
1058 */
1059 if (index) {
1060 index--; /* keyindex is off base 1 in iwconfig */
1061 }
1062
1063 if (erq->flags & IW_ENCODE_OPEN) {
1064 auth |= OPEN_AUTH;
1065 ar->arDefTxKeyIndex = index;
1066 }
1067 if (erq->flags & IW_ENCODE_RESTRICTED) {
1068 auth |= SHARED_AUTH;
1069 }
1070
1071 if (!auth) {
1072 auth = OPEN_AUTH;
1073 }
1074
1075 if (erq->length) {
1076 if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(erq->length)) {
1077 return -EIO;
1078 }
1079
1080 A_MEMZERO(ar->arWepKeyList[index].arKey,
1081 sizeof(ar->arWepKeyList[index].arKey));
1082 A_MEMCPY(ar->arWepKeyList[index].arKey, keybuf, erq->length);
1083 ar->arWepKeyList[index].arKeyLen = erq->length;
1084 ar->arDot11AuthMode = auth;
1085 } else {
1086 if (ar->arWepKeyList[index].arKeyLen == 0) {
1087 return -EIO;
1088 }
1089 ar->arDefTxKeyIndex = index;
1090
1091 if(ar->arSsidLen && ar->arWepKeyList[index].arKeyLen) {
1092 wmi_addKey_cmd(ar->arWmi,
1093 index,
1094 WEP_CRYPT,
1095 GROUP_USAGE | TX_USAGE,
1096 ar->arWepKeyList[index].arKeyLen,
1097 NULL,
1098 ar->arWepKeyList[index].arKey, KEY_OP_INIT_VAL, NULL,
1099 NO_SYNC_WMIFLAG);
1100 }
1101 }
1102
1103 ar->arPairwiseCrypto = WEP_CRYPT;
1104 ar->arGroupCrypto = WEP_CRYPT;
1105 ar->arAuthMode = NONE_AUTH;
1106 }
1107
1108 if(ar->arNextMode != AP_NETWORK) {
1109 /*
1110 * profile has changed. Erase ssid to signal change
1111 */
1112 A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
1113 ar->arSsidLen = 0;
1114 }
1115 ar->ap_profile_flag = 1; /* There is a change in profile */
1116 return 0;
1117 }
1118
1119 static int
1120 ar6000_ioctl_giwencode(struct net_device *dev,
1121 struct iw_request_info *info,
1122 struct iw_point *erq, char *key)
1123 {
1124 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1125 u8 keyIndex;
1126 struct ar_wep_key *wk;
1127
1128 if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
1129 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
1130 return -EOPNOTSUPP;
1131 }
1132
1133 if (ar->arWlanState == WLAN_DISABLED) {
1134 return -EIO;
1135 }
1136
1137 if (ar->arPairwiseCrypto == NONE_CRYPT) {
1138 erq->length = 0;
1139 erq->flags = IW_ENCODE_DISABLED;
1140 } else {
1141 if (ar->arPairwiseCrypto == WEP_CRYPT) {
1142 /* get the keyIndex */
1143 keyIndex = erq->flags & IW_ENCODE_INDEX;
1144 if (0 == keyIndex) {
1145 keyIndex = ar->arDefTxKeyIndex;
1146 } else if ((keyIndex - 1 < WMI_MIN_KEY_INDEX) ||
1147 (keyIndex - 1 > WMI_MAX_KEY_INDEX))
1148 {
1149 keyIndex = WMI_MIN_KEY_INDEX;
1150 } else {
1151 keyIndex--;
1152 }
1153 erq->flags = keyIndex + 1;
1154 erq->flags &= ~IW_ENCODE_DISABLED;
1155 wk = &ar->arWepKeyList[keyIndex];
1156 if (erq->length > wk->arKeyLen) {
1157 erq->length = wk->arKeyLen;
1158 }
1159 if (wk->arKeyLen) {
1160 A_MEMCPY(key, wk->arKey, erq->length);
1161 }
1162 } else {
1163 erq->flags &= ~IW_ENCODE_DISABLED;
1164 if (ar->user_saved_keys.keyOk) {
1165 erq->length = ar->user_saved_keys.ucast_ik.ik_keylen;
1166 if (erq->length) {
1167 A_MEMCPY(key, ar->user_saved_keys.ucast_ik.ik_keydata, erq->length);
1168 }
1169 } else {
1170 erq->length = 1; // not really printing any key but let iwconfig know enc is on
1171 }
1172 }
1173
1174 if (ar->arDot11AuthMode & OPEN_AUTH) {
1175 erq->flags |= IW_ENCODE_OPEN;
1176 }
1177 if (ar->arDot11AuthMode & SHARED_AUTH) {
1178 erq->flags |= IW_ENCODE_RESTRICTED;
1179 }
1180 }
1181
1182 return 0;
1183 }
1184
1185 #if WIRELESS_EXT >= 18
1186 /*
1187 * SIOCSIWGENIE
1188 */
1189 static int
1190 ar6000_ioctl_siwgenie(struct net_device *dev,
1191 struct iw_request_info *info,
1192 struct iw_point *erq, char *extra)
1193 {
1194 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1195
1196 #ifdef WAPI_ENABLE
1197 u8 *ie = erq->pointer;
1198 u8 ie_type = ie[0];
1199 u16 ie_length = erq->length;
1200 u8 wapi_ie[128];
1201 #endif
1202
1203 if (ar->arWmiReady == false) {
1204 return -EIO;
1205 }
1206 #ifdef WAPI_ENABLE
1207 if (ie_type == IEEE80211_ELEMID_WAPI) {
1208 if (ie_length > 0) {
1209 if (copy_from_user(wapi_ie, ie, ie_length)) {
1210 return -EIO;
1211 }
1212 }
1213 wmi_set_appie_cmd(ar->arWmi, WMI_FRAME_ASSOC_REQ, ie_length, wapi_ie);
1214 } else if (ie_length == 0) {
1215 wmi_set_appie_cmd(ar->arWmi, WMI_FRAME_ASSOC_REQ, ie_length, wapi_ie);
1216 }
1217 #endif
1218 return 0;
1219 }
1220
1221
1222 /*
1223 * SIOCGIWGENIE
1224 */
1225 static int
1226 ar6000_ioctl_giwgenie(struct net_device *dev,
1227 struct iw_request_info *info,
1228 struct iw_point *erq, char *extra)
1229 {
1230 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1231
1232 if (ar->arWmiReady == false) {
1233 return -EIO;
1234 }
1235 erq->length = 0;
1236 erq->flags = 0;
1237
1238 return 0;
1239 }
1240
1241 /*
1242 * SIOCSIWAUTH
1243 */
1244 static int
1245 ar6000_ioctl_siwauth(struct net_device *dev,
1246 struct iw_request_info *info,
1247 struct iw_param *data, char *extra)
1248 {
1249 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1250
1251 bool profChanged;
1252 u16 param;
1253 s32 ret;
1254 s32 value;
1255
1256 if (ar->arWmiReady == false) {
1257 return -EIO;
1258 }
1259
1260 if (ar->arWlanState == WLAN_DISABLED) {
1261 return -EIO;
1262 }
1263
1264 param = data->flags & IW_AUTH_INDEX;
1265 value = data->value;
1266 profChanged = true;
1267 ret = 0;
1268
1269 switch (param) {
1270 case IW_AUTH_WPA_VERSION:
1271 if (value & IW_AUTH_WPA_VERSION_DISABLED) {
1272 ar->arAuthMode = NONE_AUTH;
1273 } else if (value & IW_AUTH_WPA_VERSION_WPA) {
1274 ar->arAuthMode = WPA_AUTH;
1275 } else if (value & IW_AUTH_WPA_VERSION_WPA2) {
1276 ar->arAuthMode = WPA2_AUTH;
1277 } else {
1278 ret = -1;
1279 profChanged = false;
1280 }
1281 break;
1282 case IW_AUTH_CIPHER_PAIRWISE:
1283 if (value & IW_AUTH_CIPHER_NONE) {
1284 ar->arPairwiseCrypto = NONE_CRYPT;
1285 ar->arPairwiseCryptoLen = 0;
1286 } else if (value & IW_AUTH_CIPHER_WEP40) {
1287 ar->arPairwiseCrypto = WEP_CRYPT;
1288 ar->arPairwiseCryptoLen = 5;
1289 } else if (value & IW_AUTH_CIPHER_TKIP) {
1290 ar->arPairwiseCrypto = TKIP_CRYPT;
1291 ar->arPairwiseCryptoLen = 0;
1292 } else if (value & IW_AUTH_CIPHER_CCMP) {
1293 ar->arPairwiseCrypto = AES_CRYPT;
1294 ar->arPairwiseCryptoLen = 0;
1295 } else if (value & IW_AUTH_CIPHER_WEP104) {
1296 ar->arPairwiseCrypto = WEP_CRYPT;
1297 ar->arPairwiseCryptoLen = 13;
1298 } else {
1299 ret = -1;
1300 profChanged = false;
1301 }
1302 break;
1303 case IW_AUTH_CIPHER_GROUP:
1304 if (value & IW_AUTH_CIPHER_NONE) {
1305 ar->arGroupCrypto = NONE_CRYPT;
1306 ar->arGroupCryptoLen = 0;
1307 } else if (value & IW_AUTH_CIPHER_WEP40) {
1308 ar->arGroupCrypto = WEP_CRYPT;
1309 ar->arGroupCryptoLen = 5;
1310 } else if (value & IW_AUTH_CIPHER_TKIP) {
1311 ar->arGroupCrypto = TKIP_CRYPT;
1312 ar->arGroupCryptoLen = 0;
1313 } else if (value & IW_AUTH_CIPHER_CCMP) {
1314 ar->arGroupCrypto = AES_CRYPT;
1315 ar->arGroupCryptoLen = 0;
1316 } else if (value & IW_AUTH_CIPHER_WEP104) {
1317 ar->arGroupCrypto = WEP_CRYPT;
1318 ar->arGroupCryptoLen = 13;
1319 } else {
1320 ret = -1;
1321 profChanged = false;
1322 }
1323 break;
1324 case IW_AUTH_KEY_MGMT:
1325 if (value & IW_AUTH_KEY_MGMT_PSK) {
1326 if (WPA_AUTH == ar->arAuthMode) {
1327 ar->arAuthMode = WPA_PSK_AUTH;
1328 } else if (WPA2_AUTH == ar->arAuthMode) {
1329 ar->arAuthMode = WPA2_PSK_AUTH;
1330 } else {
1331 ret = -1;
1332 }
1333 } else if (!(value & IW_AUTH_KEY_MGMT_802_1X)) {
1334 ar->arAuthMode = NONE_AUTH;
1335 }
1336 break;
1337 case IW_AUTH_TKIP_COUNTERMEASURES:
1338 wmi_set_tkip_countermeasures_cmd(ar->arWmi, value);
1339 profChanged = false;
1340 break;
1341 case IW_AUTH_DROP_UNENCRYPTED:
1342 profChanged = false;
1343 break;
1344 case IW_AUTH_80211_AUTH_ALG:
1345 ar->arDot11AuthMode = 0;
1346 if (value & IW_AUTH_ALG_OPEN_SYSTEM) {
1347 ar->arDot11AuthMode |= OPEN_AUTH;
1348 }
1349 if (value & IW_AUTH_ALG_SHARED_KEY) {
1350 ar->arDot11AuthMode |= SHARED_AUTH;
1351 }
1352 if (value & IW_AUTH_ALG_LEAP) {
1353 ar->arDot11AuthMode = LEAP_AUTH;
1354 }
1355 if(ar->arDot11AuthMode == 0) {
1356 ret = -1;
1357 profChanged = false;
1358 }
1359 break;
1360 case IW_AUTH_WPA_ENABLED:
1361 if (!value) {
1362 ar->arAuthMode = NONE_AUTH;
1363 /* when the supplicant is stopped, it calls this
1364 * handler with value=0. The followings need to be
1365 * reset if the STA were to connect again
1366 * without security
1367 */
1368 ar->arDot11AuthMode = OPEN_AUTH;
1369 ar->arPairwiseCrypto = NONE_CRYPT;
1370 ar->arPairwiseCryptoLen = 0;
1371 ar->arGroupCrypto = NONE_CRYPT;
1372 ar->arGroupCryptoLen = 0;
1373 }
1374 break;
1375 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1376 profChanged = false;
1377 break;
1378 case IW_AUTH_ROAMING_CONTROL:
1379 profChanged = false;
1380 break;
1381 case IW_AUTH_PRIVACY_INVOKED:
1382 if (!value) {
1383 ar->arPairwiseCrypto = NONE_CRYPT;
1384 ar->arPairwiseCryptoLen = 0;
1385 ar->arGroupCrypto = NONE_CRYPT;
1386 ar->arGroupCryptoLen = 0;
1387 }
1388 break;
1389 #ifdef WAPI_ENABLE
1390 case IW_AUTH_WAPI_ENABLED:
1391 ar->arWapiEnable = value;
1392 break;
1393 #endif
1394 default:
1395 ret = -1;
1396 profChanged = false;
1397 break;
1398 }
1399
1400 if (profChanged == true) {
1401 /*
1402 * profile has changed. Erase ssid to signal change
1403 */
1404 A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
1405 ar->arSsidLen = 0;
1406 }
1407
1408 return ret;
1409 }
1410
1411
1412 /*
1413 * SIOCGIWAUTH
1414 */
1415 static int
1416 ar6000_ioctl_giwauth(struct net_device *dev,
1417 struct iw_request_info *info,
1418 struct iw_param *data, char *extra)
1419 {
1420 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1421 u16 param;
1422 s32 ret;
1423
1424 if (ar->arWmiReady == false) {
1425 return -EIO;
1426 }
1427
1428 if (ar->arWlanState == WLAN_DISABLED) {
1429 return -EIO;
1430 }
1431
1432 param = data->flags & IW_AUTH_INDEX;
1433 ret = 0;
1434 data->value = 0;
1435
1436
1437 switch (param) {
1438 case IW_AUTH_WPA_VERSION:
1439 if (ar->arAuthMode == NONE_AUTH) {
1440 data->value |= IW_AUTH_WPA_VERSION_DISABLED;
1441 } else if (ar->arAuthMode == WPA_AUTH) {
1442 data->value |= IW_AUTH_WPA_VERSION_WPA;
1443 } else if (ar->arAuthMode == WPA2_AUTH) {
1444 data->value |= IW_AUTH_WPA_VERSION_WPA2;
1445 } else {
1446 ret = -1;
1447 }
1448 break;
1449 case IW_AUTH_CIPHER_PAIRWISE:
1450 if (ar->arPairwiseCrypto == NONE_CRYPT) {
1451 data->value |= IW_AUTH_CIPHER_NONE;
1452 } else if (ar->arPairwiseCrypto == WEP_CRYPT) {
1453 if (ar->arPairwiseCryptoLen == 13) {
1454 data->value |= IW_AUTH_CIPHER_WEP104;
1455 } else {
1456 data->value |= IW_AUTH_CIPHER_WEP40;
1457 }
1458 } else if (ar->arPairwiseCrypto == TKIP_CRYPT) {
1459 data->value |= IW_AUTH_CIPHER_TKIP;
1460 } else if (ar->arPairwiseCrypto == AES_CRYPT) {
1461 data->value |= IW_AUTH_CIPHER_CCMP;
1462 } else {
1463 ret = -1;
1464 }
1465 break;
1466 case IW_AUTH_CIPHER_GROUP:
1467 if (ar->arGroupCrypto == NONE_CRYPT) {
1468 data->value |= IW_AUTH_CIPHER_NONE;
1469 } else if (ar->arGroupCrypto == WEP_CRYPT) {
1470 if (ar->arGroupCryptoLen == 13) {
1471 data->value |= IW_AUTH_CIPHER_WEP104;
1472 } else {
1473 data->value |= IW_AUTH_CIPHER_WEP40;
1474 }
1475 } else if (ar->arGroupCrypto == TKIP_CRYPT) {
1476 data->value |= IW_AUTH_CIPHER_TKIP;
1477 } else if (ar->arGroupCrypto == AES_CRYPT) {
1478 data->value |= IW_AUTH_CIPHER_CCMP;
1479 } else {
1480 ret = -1;
1481 }
1482 break;
1483 case IW_AUTH_KEY_MGMT:
1484 if ((ar->arAuthMode == WPA_PSK_AUTH) ||
1485 (ar->arAuthMode == WPA2_PSK_AUTH)) {
1486 data->value |= IW_AUTH_KEY_MGMT_PSK;
1487 } else if ((ar->arAuthMode == WPA_AUTH) ||
1488 (ar->arAuthMode == WPA2_AUTH)) {
1489 data->value |= IW_AUTH_KEY_MGMT_802_1X;
1490 }
1491 break;
1492 case IW_AUTH_TKIP_COUNTERMEASURES:
1493 // TODO. Save countermeassure enable/disable
1494 data->value = 0;
1495 break;
1496 case IW_AUTH_DROP_UNENCRYPTED:
1497 break;
1498 case IW_AUTH_80211_AUTH_ALG:
1499 if (ar->arDot11AuthMode == OPEN_AUTH) {
1500 data->value |= IW_AUTH_ALG_OPEN_SYSTEM;
1501 } else if (ar->arDot11AuthMode == SHARED_AUTH) {
1502 data->value |= IW_AUTH_ALG_SHARED_KEY;
1503 } else if (ar->arDot11AuthMode == LEAP_AUTH) {
1504 data->value |= IW_AUTH_ALG_LEAP;
1505 } else {
1506 ret = -1;
1507 }
1508 break;
1509 case IW_AUTH_WPA_ENABLED:
1510 if (ar->arAuthMode == NONE_AUTH) {
1511 data->value = 0;
1512 } else {
1513 data->value = 1;
1514 }
1515 break;
1516 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1517 break;
1518 case IW_AUTH_ROAMING_CONTROL:
1519 break;
1520 case IW_AUTH_PRIVACY_INVOKED:
1521 if (ar->arPairwiseCrypto == NONE_CRYPT) {
1522 data->value = 0;
1523 } else {
1524 data->value = 1;
1525 }
1526 break;
1527 #ifdef WAPI_ENABLE
1528 case IW_AUTH_WAPI_ENABLED:
1529 data->value = ar->arWapiEnable;
1530 break;
1531 #endif
1532 default:
1533 ret = -1;
1534 break;
1535 }
1536
1537 return 0;
1538 }
1539
1540 /*
1541 * SIOCSIWPMKSA
1542 */
1543 static int
1544 ar6000_ioctl_siwpmksa(struct net_device *dev,
1545 struct iw_request_info *info,
1546 struct iw_point *data, char *extra)
1547 {
1548 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1549 s32 ret;
1550 int status;
1551 struct iw_pmksa *pmksa;
1552
1553 pmksa = (struct iw_pmksa *)extra;
1554
1555 if (ar->arWmiReady == false) {
1556 return -EIO;
1557 }
1558
1559 ret = 0;
1560 status = A_OK;
1561
1562 switch (pmksa->cmd) {
1563 case IW_PMKSA_ADD:
1564 status = wmi_setPmkid_cmd(ar->arWmi, (u8 *)pmksa->bssid.sa_data, pmksa->pmkid, true);
1565 break;
1566 case IW_PMKSA_REMOVE:
1567 status = wmi_setPmkid_cmd(ar->arWmi, (u8 *)pmksa->bssid.sa_data, pmksa->pmkid, false);
1568 break;
1569 case IW_PMKSA_FLUSH:
1570 if (ar->arConnected == true) {
1571 status = wmi_setPmkid_cmd(ar->arWmi, ar->arBssid, NULL, 0);
1572 }
1573 break;
1574 default:
1575 ret=-1;
1576 break;
1577 }
1578 if (status) {
1579 ret = -1;
1580 }
1581
1582 return ret;
1583 }
1584
1585 #ifdef WAPI_ENABLE
1586
1587 #define PN_INIT 0x5c365c36
1588
1589 static int ar6000_set_wapi_key(struct net_device *dev,
1590 struct iw_request_info *info,
1591 struct iw_point *erq, char *extra)
1592 {
1593 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1594 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1595 KEY_USAGE keyUsage = 0;
1596 s32 keyLen;
1597 u8 *keyData;
1598 s32 index;
1599 u32 *PN;
1600 s32 i;
1601 int status;
1602 u8 wapiKeyRsc[16];
1603 CRYPTO_TYPE keyType = WAPI_CRYPT;
1604 const u8 broadcastMac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1605
1606 index = erq->flags & IW_ENCODE_INDEX;
1607 if (index && (((index - 1) < WMI_MIN_KEY_INDEX) ||
1608 ((index - 1) > WMI_MAX_KEY_INDEX))) {
1609 return -EIO;
1610 }
1611
1612 index--;
1613 if (index < 0 || index > 4) {
1614 return -EIO;
1615 }
1616 keyData = (u8 *)(ext + 1);
1617 keyLen = erq->length - sizeof(struct iw_encode_ext);
1618 A_MEMCPY(wapiKeyRsc, ext->tx_seq, sizeof(wapiKeyRsc));
1619
1620 if (A_MEMCMP(ext->addr.sa_data, broadcastMac, sizeof(broadcastMac)) == 0) {
1621 keyUsage |= GROUP_USAGE;
1622 PN = (u32 *)wapiKeyRsc;
1623 for (i = 0; i < 4; i++) {
1624 PN[i] = PN_INIT;
1625 }
1626 } else {
1627 keyUsage |= PAIRWISE_USAGE;
1628 }
1629 status = wmi_addKey_cmd(ar->arWmi,
1630 index,
1631 keyType,
1632 keyUsage,
1633 keyLen,
1634 wapiKeyRsc,
1635 keyData,
1636 KEY_OP_INIT_WAPIPN,
1637 NULL,
1638 SYNC_BEFORE_WMIFLAG);
1639 if (A_OK != status) {
1640 return -EIO;
1641 }
1642 return 0;
1643 }
1644
1645 #endif
1646
1647 /*
1648 * SIOCSIWENCODEEXT
1649 */
1650 static int
1651 ar6000_ioctl_siwencodeext(struct net_device *dev,
1652 struct iw_request_info *info,
1653 struct iw_point *erq, char *extra)
1654 {
1655 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1656 s32 index;
1657 struct iw_encode_ext *ext;
1658 KEY_USAGE keyUsage;
1659 s32 keyLen;
1660 u8 *keyData;
1661 u8 keyRsc[8];
1662 int status;
1663 CRYPTO_TYPE keyType;
1664 #ifdef USER_KEYS
1665 struct ieee80211req_key ik;
1666 #endif /* USER_KEYS */
1667
1668 if (ar->arWlanState == WLAN_DISABLED) {
1669 return -EIO;
1670 }
1671
1672 #ifdef USER_KEYS
1673 ar->user_saved_keys.keyOk = false;
1674 #endif /* USER_KEYS */
1675
1676 index = erq->flags & IW_ENCODE_INDEX;
1677
1678 if (index && (((index - 1) < WMI_MIN_KEY_INDEX) ||
1679 ((index - 1) > WMI_MAX_KEY_INDEX)))
1680 {
1681 return -EIO;
1682 }
1683
1684 ext = (struct iw_encode_ext *)extra;
1685 if (erq->flags & IW_ENCODE_DISABLED) {
1686 /*
1687 * Encryption disabled
1688 */
1689 if (index) {
1690 /*
1691 * If key index was specified then clear the specified key
1692 */
1693 index--;
1694 A_MEMZERO(ar->arWepKeyList[index].arKey,
1695 sizeof(ar->arWepKeyList[index].arKey));
1696 ar->arWepKeyList[index].arKeyLen = 0;
1697 }
1698 } else {
1699 /*
1700 * Enabling WEP encryption
1701 */
1702 if (index) {
1703 index--; /* keyindex is off base 1 in iwconfig */
1704 }
1705
1706 keyUsage = 0;
1707 keyLen = erq->length - sizeof(struct iw_encode_ext);
1708
1709 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
1710 keyUsage = TX_USAGE;
1711 ar->arDefTxKeyIndex = index;
1712 // Just setting the key index
1713 if (keyLen == 0) {
1714 return 0;
1715 }
1716 }
1717
1718 if (keyLen <= 0) {
1719 return -EIO;
1720 }
1721
1722 /* key follows iw_encode_ext */
1723 keyData = (u8 *)(ext + 1);
1724
1725 switch (ext->alg) {
1726 case IW_ENCODE_ALG_WEP:
1727 keyType = WEP_CRYPT;
1728 #ifdef USER_KEYS
1729 ik.ik_type = IEEE80211_CIPHER_WEP;
1730 #endif /* USER_KEYS */
1731 if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(keyLen)) {
1732 return -EIO;
1733 }
1734
1735 /* Check whether it is static wep. */
1736 if (!ar->arConnected) {
1737 A_MEMZERO(ar->arWepKeyList[index].arKey,
1738 sizeof(ar->arWepKeyList[index].arKey));
1739 A_MEMCPY(ar->arWepKeyList[index].arKey, keyData, keyLen);
1740 ar->arWepKeyList[index].arKeyLen = keyLen;
1741
1742 return 0;
1743 }
1744 break;
1745 case IW_ENCODE_ALG_TKIP:
1746 keyType = TKIP_CRYPT;
1747 #ifdef USER_KEYS
1748 ik.ik_type = IEEE80211_CIPHER_TKIP;
1749 #endif /* USER_KEYS */
1750 break;
1751 case IW_ENCODE_ALG_CCMP:
1752 keyType = AES_CRYPT;
1753 #ifdef USER_KEYS
1754 ik.ik_type = IEEE80211_CIPHER_AES_CCM;
1755 #endif /* USER_KEYS */
1756 break;
1757 #ifdef WAPI_ENABLE
1758 case IW_ENCODE_ALG_SM4:
1759 if (ar->arWapiEnable) {
1760 return ar6000_set_wapi_key(dev, info, erq, extra);
1761 } else {
1762 return -EIO;
1763 }
1764 #endif
1765 case IW_ENCODE_ALG_PMK:
1766 ar->arConnectCtrlFlags |= CONNECT_DO_WPA_OFFLOAD;
1767 return wmi_set_pmk_cmd(ar->arWmi, keyData);
1768 default:
1769 return -EIO;
1770 }
1771
1772
1773 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
1774 keyUsage |= GROUP_USAGE;
1775 } else {
1776 keyUsage |= PAIRWISE_USAGE;
1777 }
1778
1779 if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
1780 A_MEMCPY(keyRsc, ext->rx_seq, sizeof(keyRsc));
1781 } else {
1782 A_MEMZERO(keyRsc, sizeof(keyRsc));
1783 }
1784
1785 if (((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode)) &&
1786 (GROUP_USAGE & keyUsage))
1787 {
1788 A_UNTIMEOUT(&ar->disconnect_timer);
1789 }
1790
1791 status = wmi_addKey_cmd(ar->arWmi, index, keyType, keyUsage,
1792 keyLen, keyRsc,
1793 keyData, KEY_OP_INIT_VAL,
1794 (u8 *)ext->addr.sa_data,
1795 SYNC_BOTH_WMIFLAG);
1796 if (status) {
1797 return -EIO;
1798 }
1799
1800 #ifdef USER_KEYS
1801 ik.ik_keyix = index;
1802 ik.ik_keylen = keyLen;
1803 memcpy(ik.ik_keydata, keyData, keyLen);
1804 memcpy(&ik.ik_keyrsc, keyRsc, sizeof(keyRsc));
1805 memcpy(ik.ik_macaddr, ext->addr.sa_data, ETH_ALEN);
1806 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
1807 memcpy(&ar->user_saved_keys.bcast_ik, &ik,
1808 sizeof(struct ieee80211req_key));
1809 } else {
1810 memcpy(&ar->user_saved_keys.ucast_ik, &ik,
1811 sizeof(struct ieee80211req_key));
1812 }
1813 ar->user_saved_keys.keyOk = true;
1814 #endif /* USER_KEYS */
1815 }
1816
1817
1818 return 0;
1819 }
1820
1821 /*
1822 * SIOCGIWENCODEEXT
1823 */
1824 static int
1825 ar6000_ioctl_giwencodeext(struct net_device *dev,
1826 struct iw_request_info *info,
1827 struct iw_point *erq, char *extra)
1828 {
1829 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1830
1831 if (ar->arWlanState == WLAN_DISABLED) {
1832 return -EIO;
1833 }
1834
1835 if (ar->arPairwiseCrypto == NONE_CRYPT) {
1836 erq->length = 0;
1837 erq->flags = IW_ENCODE_DISABLED;
1838 } else {
1839 erq->length = 0;
1840 }
1841
1842 return 0;
1843 }
1844 #endif // WIRELESS_EXT >= 18
1845
1846 #if WIRELESS_EXT > 20
1847 static int ar6000_ioctl_siwpower(struct net_device *dev,
1848 struct iw_request_info *info,
1849 union iwreq_data *wrqu, char *extra)
1850 {
1851 #ifndef ATH6K_CONFIG_OTA_MODE
1852 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1853 WMI_POWER_MODE power_mode;
1854
1855 if (ar->arWmiReady == false) {
1856 return -EIO;
1857 }
1858
1859 if (ar->arWlanState == WLAN_DISABLED) {
1860 return -EIO;
1861 }
1862
1863 if (wrqu->power.disabled)
1864 power_mode = MAX_PERF_POWER;
1865 else
1866 power_mode = REC_POWER;
1867
1868 if (wmi_powermode_cmd(ar->arWmi, power_mode) < 0)
1869 return -EIO;
1870 #endif
1871 return 0;
1872 }
1873
1874 static int ar6000_ioctl_giwpower(struct net_device *dev,
1875 struct iw_request_info *info,
1876 union iwreq_data *wrqu, char *extra)
1877 {
1878 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1879 WMI_POWER_MODE power_mode;
1880
1881 if (ar->arWmiReady == false) {
1882 return -EIO;
1883 }
1884
1885 if (ar->arWlanState == WLAN_DISABLED) {
1886 return -EIO;
1887 }
1888
1889 power_mode = wmi_get_power_mode_cmd(ar->arWmi);
1890
1891 if (power_mode == MAX_PERF_POWER)
1892 wrqu->power.disabled = 1;
1893 else
1894 wrqu->power.disabled = 0;
1895
1896 return 0;
1897 }
1898 #endif // WIRELESS_EXT > 20
1899
1900 /*
1901 * SIOCGIWNAME
1902 */
1903 int
1904 ar6000_ioctl_giwname(struct net_device *dev,
1905 struct iw_request_info *info,
1906 char *name, char *extra)
1907 {
1908 u8 capability;
1909 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1910
1911 if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
1912 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
1913 return -EOPNOTSUPP;
1914 }
1915
1916 if (ar->arWlanState == WLAN_DISABLED) {
1917 return -EIO;
1918 }
1919
1920 capability = ar->arPhyCapability;
1921 if(ar->arNetworkType == INFRA_NETWORK && ar->arConnected) {
1922 bss_t *bss = wmi_find_node(ar->arWmi, ar->arBssid);
1923 if (bss) {
1924 capability = get_bss_phy_capability(bss);
1925 wmi_node_return(ar->arWmi, bss);
1926 }
1927 }
1928 switch (capability) {
1929 case (WMI_11A_CAPABILITY):
1930 strncpy(name, "AR6000 802.11a", IFNAMSIZ);
1931 break;
1932 case (WMI_11G_CAPABILITY):
1933 strncpy(name, "AR6000 802.11g", IFNAMSIZ);
1934 break;
1935 case (WMI_11AG_CAPABILITY):
1936 strncpy(name, "AR6000 802.11ag", IFNAMSIZ);
1937 break;
1938 case (WMI_11NA_CAPABILITY):
1939 strncpy(name, "AR6000 802.11na", IFNAMSIZ);
1940 break;
1941 case (WMI_11NG_CAPABILITY):
1942 strncpy(name, "AR6000 802.11ng", IFNAMSIZ);
1943 break;
1944 case (WMI_11NAG_CAPABILITY):
1945 strncpy(name, "AR6000 802.11nag", IFNAMSIZ);
1946 break;
1947 default:
1948 strncpy(name, "AR6000 802.11b", IFNAMSIZ);
1949 break;
1950 }
1951
1952 return 0;
1953 }
1954
1955 /*
1956 * SIOCSIWFREQ
1957 */
1958 int
1959 ar6000_ioctl_siwfreq(struct net_device *dev,
1960 struct iw_request_info *info,
1961 struct iw_freq *freq, char *extra)
1962 {
1963 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1964
1965 if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
1966 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
1967 return -EOPNOTSUPP;
1968 }
1969
1970 if (ar->arWlanState == WLAN_DISABLED) {
1971 return -EIO;
1972 }
1973
1974 /*
1975 * We support limiting the channels via wmiconfig.
1976 *
1977 * We use this command to configure the channel hint for the connect cmd
1978 * so it is possible the target will end up connecting to a different
1979 * channel.
1980 */
1981 if (freq->e > 1) {
1982 return -EINVAL;
1983 } else if (freq->e == 1) {
1984 ar->arChannelHint = freq->m / 100000;
1985 } else {
1986 if(freq->m) {
1987 ar->arChannelHint = wlan_ieee2freq(freq->m);
1988 } else {
1989 /* Auto Channel Selection */
1990 ar->arChannelHint = 0;
1991 }
1992 }
1993
1994 ar->ap_profile_flag = 1; /* There is a change in profile */
1995
1996 A_PRINTF("channel hint set to %d\n", ar->arChannelHint);
1997 return 0;
1998 }
1999
2000 /*
2001 * SIOCGIWFREQ
2002 */
2003 int
2004 ar6000_ioctl_giwfreq(struct net_device *dev,
2005 struct iw_request_info *info,
2006 struct iw_freq *freq, char *extra)
2007 {
2008 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
2009
2010 if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
2011 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
2012 return -EOPNOTSUPP;
2013 }
2014
2015 if (ar->arWlanState == WLAN_DISABLED) {
2016 return -EIO;
2017 }
2018
2019 if (ar->arNetworkType == AP_NETWORK) {
2020 if(ar->arChannelHint) {
2021 freq->m = ar->arChannelHint * 100000;
2022 } else if(ar->arACS) {
2023 freq->m = ar->arACS * 100000;
2024 } else {
2025 return -EINVAL;
2026 }
2027 } else {
2028 if (ar->arConnected != true) {
2029 return -EINVAL;
2030 } else {
2031 freq->m = ar->arBssChannel * 100000;
2032 }
2033 }
2034
2035 freq->e = 1;
2036
2037 return 0;
2038 }
2039
2040 /*
2041 * SIOCSIWMODE
2042 */
2043 int
2044 ar6000_ioctl_siwmode(struct net_device *dev,
2045 struct iw_request_info *info,
2046 __u32 *mode, char *extra)
2047 {
2048 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
2049
2050 if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
2051 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
2052 return -EOPNOTSUPP;
2053 }
2054
2055 if (ar->arWlanState == WLAN_DISABLED) {
2056 return -EIO;
2057 }
2058
2059 /*
2060 * clear SSID during mode switch in connected state
2061 */
2062 if(!(ar->arNetworkType == (((*mode) == IW_MODE_INFRA) ? INFRA_NETWORK : ADHOC_NETWORK)) && (ar->arConnected == true) ){
2063 A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
2064 ar->arSsidLen = 0;
2065 }
2066
2067 switch (*mode) {
2068 case IW_MODE_INFRA:
2069 ar->arNextMode = INFRA_NETWORK;
2070 break;
2071 case IW_MODE_ADHOC:
2072 ar->arNextMode = ADHOC_NETWORK;
2073 break;
2074 case IW_MODE_MASTER:
2075 ar->arNextMode = AP_NETWORK;
2076 break;
2077 default:
2078 return -EINVAL;
2079 }
2080
2081 /* clear all shared parameters between AP and STA|IBSS modes when we
2082 * switch between them. Switch between STA & IBSS modes does'nt clear
2083 * the shared profile. This is as per the original design for switching
2084 * between STA & IBSS.
2085 */
2086 if (ar->arNetworkType == AP_NETWORK || ar->arNextMode == AP_NETWORK) {
2087 ar->arDot11AuthMode = OPEN_AUTH;
2088 ar->arAuthMode = NONE_AUTH;
2089 ar->arPairwiseCrypto = NONE_CRYPT;
2090 ar->arPairwiseCryptoLen = 0;
2091 ar->arGroupCrypto = NONE_CRYPT;
2092 ar->arGroupCryptoLen = 0;
2093 ar->arChannelHint = 0;
2094 ar->arBssChannel = 0;
2095 A_MEMZERO(ar->arBssid, sizeof(ar->arBssid));
2096 A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
2097 ar->arSsidLen = 0;
2098 }
2099
2100 /* SSID has to be cleared to trigger a profile change while switching
2101 * between STA & IBSS modes having the same SSID
2102 */
2103 if (ar->arNetworkType != ar->arNextMode) {
2104 A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
2105 ar->arSsidLen = 0;
2106 }
2107
2108 return 0;
2109 }
2110
2111 /*
2112 * SIOCGIWMODE
2113 */
2114 int
2115 ar6000_ioctl_giwmode(struct net_device *dev,
2116 struct iw_request_info *info,
2117 __u32 *mode, char *extra)
2118 {
2119 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
2120
2121 if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
2122 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
2123 return -EOPNOTSUPP;
2124 }
2125
2126 if (ar->arWlanState == WLAN_DISABLED) {
2127 return -EIO;
2128 }
2129
2130 switch (ar->arNetworkType) {
2131 case INFRA_NETWORK:
2132 *mode = IW_MODE_INFRA;
2133 break;
2134 case ADHOC_NETWORK:
2135 *mode = IW_MODE_ADHOC;
2136 break;
2137 case AP_NETWORK:
2138 *mode = IW_MODE_MASTER;
2139 break;
2140 default:
2141 return -EIO;
2142 }
2143 return 0;
2144 }
2145
2146 /*
2147 * SIOCSIWSENS
2148 */
2149 int
2150 ar6000_ioctl_siwsens(struct net_device *dev,
2151 struct iw_request_info *info,
2152 struct iw_param *sens, char *extra)
2153 {
2154 return 0;
2155 }
2156
2157 /*
2158 * SIOCGIWSENS
2159 */
2160 int
2161 ar6000_ioctl_giwsens(struct net_device *dev,
2162 struct iw_request_info *info,
2163 struct iw_param *sens, char *extra)
2164 {
2165 sens->value = 0;
2166 sens->fixed = 1;
2167
2168 return 0;
2169 }
2170
2171 /*
2172 * SIOCGIWRANGE
2173 */
2174 int
2175 ar6000_ioctl_giwrange(struct net_device *dev,
2176 struct iw_request_info *info,
2177 struct iw_point *data, char *extra)
2178 {
2179 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
2180 struct iw_range *range = (struct iw_range *) extra;
2181 int i, ret = 0;
2182
2183 if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
2184 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
2185 return -EOPNOTSUPP;
2186 }
2187
2188 if (ar->bIsDestroyProgress) {
2189 return -EBUSY;
2190 }
2191
2192 if (ar->arWmiReady == false) {
2193 return -EIO;
2194 }
2195
2196 if (down_interruptible(&ar->arSem)) {
2197 return -ERESTARTSYS;
2198 }
2199
2200 if (ar->bIsDestroyProgress) {
2201 up(&ar->arSem);
2202 return -EBUSY;
2203 }
2204
2205 ar->arNumChannels = -1;
2206 A_MEMZERO(ar->arChannelList, sizeof (ar->arChannelList));
2207
2208 if (wmi_get_channelList_cmd(ar->arWmi) != A_OK) {
2209 up(&ar->arSem);
2210 return -EIO;
2211 }
2212
2213 wait_event_interruptible_timeout(arEvent, ar->arNumChannels != -1, wmitimeout * HZ);
2214
2215 if (signal_pending(current)) {
2216 up(&ar->arSem);
2217 return -EINTR;
2218 }
2219
2220 data->length = sizeof(struct iw_range);
2221 A_MEMZERO(range, sizeof(struct iw_range));
2222
2223 range->txpower_capa = 0;
2224
2225 range->min_pmp = 1 * 1024;
2226 range->max_pmp = 65535 * 1024;
2227 range->min_pmt = 1 * 1024;
2228 range->max_pmt = 1000 * 1024;
2229 range->pmp_flags = IW_POWER_PERIOD;
2230 range->pmt_flags = IW_POWER_TIMEOUT;
2231 range->pm_capa = 0;
2232
2233 range->we_version_compiled = WIRELESS_EXT;
2234 range->we_version_source = 13;
2235
2236 range->retry_capa = IW_RETRY_LIMIT;
2237 range->retry_flags = IW_RETRY_LIMIT;
2238 range->min_retry = 0;
2239 range->max_retry = 255;
2240
2241 range->num_frequency = range->num_channels = ar->arNumChannels;
2242 for (i = 0; i < ar->arNumChannels; i++) {
2243 range->freq[i].i = wlan_freq2ieee(ar->arChannelList[i]);
2244 range->freq[i].m = ar->arChannelList[i] * 100000;
2245 range->freq[i].e = 1;
2246 /*
2247 * Linux supports max of 32 channels, bail out once you
2248 * reach the max.
2249 */
2250 if (i == IW_MAX_FREQUENCIES) {
2251 break;
2252 }
2253 }
2254
2255 /* Max quality is max field value minus noise floor */
2256 range->max_qual.qual = 0xff - 161;
2257
2258 /*
2259 * In order to use dBm measurements, 'level' must be lower
2260 * than any possible measurement (see iw_print_stats() in
2261 * wireless tools). It's unclear how this is meant to be
2262 * done, but setting zero in these values forces dBm and
2263 * the actual numbers are not used.
2264 */
2265 range->max_qual.level = 0;
2266 range->max_qual.noise = 0;
2267
2268 range->sensitivity = 3;
2269
2270 range->max_encoding_tokens = 4;
2271 /* XXX query driver to find out supported key sizes */
2272 range->num_encoding_sizes = 3;
2273 range->encoding_size[0] = 5; /* 40-bit */
2274 range->encoding_size[1] = 13; /* 104-bit */
2275 range->encoding_size[2] = 16; /* 128-bit */
2276
2277 range->num_bitrates = 0;
2278
2279 /* estimated maximum TCP throughput values (bps) */
2280 range->throughput = 22000000;
2281
2282 range->min_rts = 0;
2283 range->max_rts = 2347;
2284 range->min_frag = 256;
2285 range->max_frag = 2346;
2286
2287 up(&ar->arSem);
2288
2289 return ret;
2290 }
2291
2292
2293 /*
2294 * SIOCSIWAP
2295 * This ioctl is used to set the desired bssid for the connect command.
2296 */
2297 int
2298 ar6000_ioctl_siwap(struct net_device *dev,
2299 struct iw_request_info *info,
2300 struct sockaddr *ap_addr, char *extra)
2301 {
2302 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
2303
2304 if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
2305 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
2306 return -EOPNOTSUPP;
2307 }
2308
2309 if (ar->arWlanState == WLAN_DISABLED) {
2310 return -EIO;
2311 }
2312
2313 if (ap_addr->sa_family != ARPHRD_ETHER) {
2314 return -EIO;
2315 }
2316
2317 if (A_MEMCMP(&ap_addr->sa_data, bcast_mac, AR6000_ETH_ADDR_LEN) == 0) {
2318 A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
2319 } else {
2320 A_MEMCPY(ar->arReqBssid, &ap_addr->sa_data, sizeof(ar->arReqBssid));
2321 }
2322
2323 return 0;
2324 }
2325
2326 /*
2327 * SIOCGIWAP
2328 */
2329 int
2330 ar6000_ioctl_giwap(struct net_device *dev,
2331 struct iw_request_info *info,
2332 struct sockaddr *ap_addr, char *extra)
2333 {
2334 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
2335
2336 if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
2337 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
2338 return -EOPNOTSUPP;
2339 }
2340
2341 if (ar->arWlanState == WLAN_DISABLED) {
2342 return -EIO;
2343 }
2344
2345 if (ar->arNetworkType == AP_NETWORK) {
2346 A_MEMCPY(&ap_addr->sa_data, dev->dev_addr, ATH_MAC_LEN);
2347 ap_addr->sa_family = ARPHRD_ETHER;
2348 return 0;
2349 }
2350
2351 if (ar->arConnected != true) {
2352 return -EINVAL;
2353 }
2354
2355 A_MEMCPY(&ap_addr->sa_data, ar->arBssid, sizeof(ar->arBssid));
2356 ap_addr->sa_family = ARPHRD_ETHER;
2357
2358 return 0;
2359 }
2360
2361 #if (WIRELESS_EXT >= 18)
2362 /*
2363 * SIOCSIWMLME
2364 */
2365 int
2366 ar6000_ioctl_siwmlme(struct net_device *dev,
2367 struct iw_request_info *info,
2368 struct iw_point *data, char *extra)
2369 {
2370 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
2371
2372 if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
2373 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
2374 return -EOPNOTSUPP;
2375 }
2376
2377 if (ar->bIsDestroyProgress) {
2378 return -EBUSY;
2379 }
2380
2381 if (ar->arWlanState == WLAN_DISABLED) {
2382 return -EIO;
2383 }
2384
2385 if (ar->arWmiReady == false) {
2386 return -EIO;
2387 }
2388
2389 if (down_interruptible(&ar->arSem)) {
2390 return -ERESTARTSYS;
2391 }
2392
2393 if (data->pointer && data->length == sizeof(struct iw_mlme)) {
2394
2395 u8 arNetworkType;
2396 struct iw_mlme mlme;
2397
2398 if (copy_from_user(&mlme, data->pointer, sizeof(struct iw_mlme)))
2399 return -EIO;
2400
2401 switch (mlme.cmd) {
2402
2403 case IW_MLME_DEAUTH:
2404 /* fall through */
2405 case IW_MLME_DISASSOC:
2406 if ((ar->arConnected != true) ||
2407 (memcmp(ar->arBssid, mlme.addr.sa_data, 6) != 0)) {
2408
2409 up(&ar->arSem);
2410 return -EINVAL;
2411 }
2412 wmi_setPmkid_cmd(ar->arWmi, ar->arBssid, NULL, 0);
2413 arNetworkType = ar->arNetworkType;
2414 ar6000_init_profile_info(ar);
2415 ar->arNetworkType = arNetworkType;
2416 reconnect_flag = 0;
2417 wmi_disconnect_cmd(ar->arWmi);
2418 A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
2419 ar->arSsidLen = 0;
2420 if (ar->arSkipScan == false) {
2421 A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
2422 }
2423 break;
2424
2425 case IW_MLME_AUTH:
2426 /* fall through */
2427 case IW_MLME_ASSOC:
2428 /* fall through */
2429 default:
2430 up(&ar->arSem);
2431 return -EOPNOTSUPP;
2432 }
2433 }
2434
2435 up(&ar->arSem);
2436 return 0;
2437 }
2438 #endif /* WIRELESS_EXT >= 18 */
2439
2440 /*
2441 * SIOCGIWAPLIST
2442 */
2443 int
2444 ar6000_ioctl_iwaplist(struct net_device *dev,
2445 struct iw_request_info *info,
2446 struct iw_point *data, char *extra)
2447 {
2448 return -EIO; /* for now */
2449 }
2450
2451 /*
2452 * SIOCSIWSCAN
2453 */
2454 int
2455 ar6000_ioctl_siwscan(struct net_device *dev,
2456 struct iw_request_info *info,
2457 struct iw_point *data, char *extra)
2458 {
2459 #define ACT_DWELLTIME_DEFAULT 105
2460 #define HOME_TXDRAIN_TIME 100
2461 #define SCAN_INT HOME_TXDRAIN_TIME + ACT_DWELLTIME_DEFAULT
2462 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
2463 int ret = 0;
2464
2465 if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
2466 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
2467 return -EOPNOTSUPP;
2468 }
2469
2470 if (ar->arWmiReady == false) {
2471 return -EIO;
2472 }
2473
2474 if (ar->arWlanState == WLAN_DISABLED) {
2475 return -EIO;
2476 }
2477
2478 /* If scan is issued in the middle of ongoing scan or connect,
2479 dont issue another one */
2480 if ( ar->scan_triggered > 0 ) {
2481 ++ar->scan_triggered;
2482 if (ar->scan_triggered < 5) {
2483 return 0;
2484 } else {
2485 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,("Scan request is triggered over 5 times. Not scan complete event\n"));
2486 }
2487 }
2488
2489 if (!ar->arUserBssFilter) {
2490 if (wmi_bssfilter_cmd(ar->arWmi, ALL_BSS_FILTER, 0) != A_OK) {
2491 return -EIO;
2492 }
2493 }
2494
2495 if (ar->arConnected) {
2496 if (wmi_get_stats_cmd(ar->arWmi) != A_OK) {
2497 return -EIO;
2498 }
2499 }
2500
2501 #ifdef ANDROID_ENV
2502 #if WIRELESS_EXT >= 18
2503 if (data->pointer && (data->length == sizeof(struct iw_scan_req)))
2504 {
2505 if ((data->flags & IW_SCAN_THIS_ESSID) == IW_SCAN_THIS_ESSID)
2506 {
2507 struct iw_scan_req req;
2508 if (copy_from_user(&req, data->pointer, sizeof(struct iw_scan_req)))
2509 return -EIO;
2510 if (wmi_probedSsid_cmd(ar->arWmi, 1, SPECIFIC_SSID_FLAG, req.essid_len, req.essid) != A_OK)
2511 return -EIO;
2512 ar->scanSpecificSsid = true;
2513 }
2514 else
2515 {
2516 if (ar->scanSpecificSsid) {
2517 if (wmi_probedSsid_cmd(ar->arWmi, 1, DISABLE_SSID_FLAG, 0, NULL) != A_OK)
2518 return -EIO;
2519 ar->scanSpecificSsid = false;
2520 }
2521 }
2522 }
2523 else
2524 {
2525 if (ar->scanSpecificSsid) {
2526 if (wmi_probedSsid_cmd(ar->arWmi, 1, DISABLE_SSID_FLAG, 0, NULL) != A_OK)
2527 return -EIO;
2528 ar->scanSpecificSsid = false;
2529 }
2530 }
2531 #endif
2532 #endif /* ANDROID_ENV */
2533
2534 if (wmi_startscan_cmd(ar->arWmi, WMI_LONG_SCAN, false, false, \
2535 0, 0, 0, NULL) != A_OK) {
2536 ret = -EIO;
2537 }
2538
2539 if (ret == 0) {
2540 ar->scan_triggered = 1;
2541 }
2542
2543 return ret;
2544 #undef ACT_DWELLTIME_DEFAULT
2545 #undef HOME_TXDRAIN_TIME
2546 #undef SCAN_INT
2547 }
2548
2549
2550 /*
2551 * Units are in db above the noise floor. That means the
2552 * rssi values reported in the tx/rx descriptors in the
2553 * driver are the SNR expressed in db.
2554 *
2555 * If you assume that the noise floor is -95, which is an
2556 * excellent assumption 99.5 % of the time, then you can
2557 * derive the absolute signal level (i.e. -95 + rssi).
2558 * There are some other slight factors to take into account
2559 * depending on whether the rssi measurement is from 11b,
2560 * 11g, or 11a. These differences are at most 2db and
2561 * can be documented.
2562 *
2563 * NB: various calculations are based on the orinoco/wavelan
2564 * drivers for compatibility
2565 */
2566 static void
2567 ar6000_set_quality(struct iw_quality *iq, s8 rssi)
2568 {
2569 if (rssi < 0) {
2570 iq->qual = 0;
2571 } else {
2572 iq->qual = rssi;
2573 }
2574
2575 /* NB: max is 94 because noise is hardcoded to 161 */
2576 if (iq->qual > 94)
2577 iq->qual = 94;
2578
2579 iq->noise = 161; /* -95dBm */
2580 iq->level = iq->noise + iq->qual;
2581 iq->updated = 7;
2582 }
2583
2584
2585 int
2586 ar6000_ioctl_siwcommit(struct net_device *dev,
2587 struct iw_request_info *info,
2588 struct iw_point *data, char *extra)
2589 {
2590 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
2591
2592 if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != A_OK) {
2593 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
2594 return -EOPNOTSUPP;
2595 }
2596
2597 if (ar->arWmiReady == false) {
2598 return -EIO;
2599 }
2600
2601 if (ar->arWlanState == WLAN_DISABLED) {
2602 return -EIO;
2603 }
2604
2605 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("AP: SSID %s freq %d authmode %d dot11 auth %d"\
2606 " PW crypto %d GRP crypto %d\n",
2607 ar->arSsid, ar->arChannelHint,
2608 ar->arAuthMode, ar->arDot11AuthMode,
2609 ar->arPairwiseCrypto, ar->arGroupCrypto));
2610
2611 ar6000_ap_mode_profile_commit(ar);
2612
2613 /* if there is a profile switch from STA|IBSS mode to AP mode,
2614 * update the host driver association state for the STA|IBSS mode.
2615 */
2616 if (ar->arNetworkType != AP_NETWORK && ar->arNextMode == AP_NETWORK) {
2617 ar->arConnectPending = false;
2618 ar->arConnected = false;
2619 /* Stop getting pkts from upper stack */
2620 netif_stop_queue(ar->arNetDev);
2621 A_MEMZERO(ar->arBssid, sizeof(ar->arBssid));
2622 ar->arBssChannel = 0;
2623 ar->arBeaconInterval = 0;
2624
2625 /* Flush the Tx queues */
2626 ar6000_TxDataCleanup(ar);
2627
2628 /* Start getting pkts from upper stack */
2629 netif_wake_queue(ar->arNetDev);
2630 }
2631
2632 return 0;
2633 }
2634
2635 #define W_PROTO(_x) wait_ ## _x
2636 #define WAIT_HANDLER_IMPL(_x, type) \
2637 int wait_ ## _x (struct net_device *dev, struct iw_request_info *info, type wrqu, char *extra) {\
2638 int ret; \
2639 dev_hold(dev); \
2640 rtnl_unlock(); \
2641 ret = _x(dev, info, wrqu, extra); \
2642 rtnl_lock(); \
2643 dev_put(dev); \
2644 return ret;\
2645 }
2646
2647 WAIT_HANDLER_IMPL(ar6000_ioctl_siwessid, struct iw_point *)
2648 WAIT_HANDLER_IMPL(ar6000_ioctl_giwrate, struct iw_param *)
2649 WAIT_HANDLER_IMPL(ar6000_ioctl_giwtxpow, struct iw_param *)
2650 WAIT_HANDLER_IMPL(ar6000_ioctl_giwrange, struct iw_point*)
2651
2652 /* Structures to export the Wireless Handlers */
2653 static const iw_handler ath_handlers[] = {
2654 (iw_handler) ar6000_ioctl_siwcommit, /* SIOCSIWCOMMIT */
2655 (iw_handler) ar6000_ioctl_giwname, /* SIOCGIWNAME */
2656 (iw_handler) NULL, /* SIOCSIWNWID */
2657 (iw_handler) NULL, /* SIOCGIWNWID */
2658 (iw_handler) ar6000_ioctl_siwfreq, /* SIOCSIWFREQ */
2659 (iw_handler) ar6000_ioctl_giwfreq, /* SIOCGIWFREQ */
2660 (iw_handler) ar6000_ioctl_siwmode, /* SIOCSIWMODE */
2661 (iw_handler) ar6000_ioctl_giwmode, /* SIOCGIWMODE */
2662 (iw_handler) ar6000_ioctl_siwsens, /* SIOCSIWSENS */
2663 (iw_handler) ar6000_ioctl_giwsens, /* SIOCGIWSENS */
2664 (iw_handler) NULL /* not _used */, /* SIOCSIWRANGE */
2665 (iw_handler) W_PROTO(ar6000_ioctl_giwrange),/* SIOCGIWRANGE */
2666 (iw_handler) NULL /* not used */, /* SIOCSIWPRIV */
2667 (iw_handler) NULL /* kernel code */, /* SIOCGIWPRIV */
2668 (iw_handler) NULL /* not used */, /* SIOCSIWSTATS */
2669 (iw_handler) NULL /* kernel code */, /* SIOCGIWSTATS */
2670 (iw_handler) NULL, /* SIOCSIWSPY */
2671 (iw_handler) NULL, /* SIOCGIWSPY */
2672 (iw_handler) NULL, /* SIOCSIWTHRSPY */
2673 (iw_handler) NULL, /* SIOCGIWTHRSPY */
2674 (iw_handler) ar6000_ioctl_siwap, /* SIOCSIWAP */
2675 (iw_handler) ar6000_ioctl_giwap, /* SIOCGIWAP */
2676 #if (WIRELESS_EXT >= 18)
2677 (iw_handler) ar6000_ioctl_siwmlme, /* SIOCSIWMLME */
2678 #else
2679 (iw_handler) NULL, /* -- hole -- */
2680 #endif /* WIRELESS_EXT >= 18 */
2681 (iw_handler) ar6000_ioctl_iwaplist, /* SIOCGIWAPLIST */
2682 (iw_handler) ar6000_ioctl_siwscan, /* SIOCSIWSCAN */
2683 (iw_handler) ar6000_ioctl_giwscan, /* SIOCGIWSCAN */
2684 (iw_handler) W_PROTO(ar6000_ioctl_siwessid),/* SIOCSIWESSID */
2685 (iw_handler) ar6000_ioctl_giwessid, /* SIOCGIWESSID */
2686 (iw_handler) NULL, /* SIOCSIWNICKN */
2687 (iw_handler) NULL, /* SIOCGIWNICKN */
2688 (iw_handler) NULL, /* -- hole -- */
2689 (iw_handler) NULL, /* -- hole -- */
2690 (iw_handler) ar6000_ioctl_siwrate, /* SIOCSIWRATE */
2691 (iw_handler) W_PROTO(ar6000_ioctl_giwrate), /* SIOCGIWRATE */
2692 (iw_handler) NULL, /* SIOCSIWRTS */
2693 (iw_handler) NULL, /* SIOCGIWRTS */
2694 (iw_handler) NULL, /* SIOCSIWFRAG */
2695 (iw_handler) NULL, /* SIOCGIWFRAG */
2696 (iw_handler) ar6000_ioctl_siwtxpow, /* SIOCSIWTXPOW */
2697 (iw_handler) W_PROTO(ar6000_ioctl_giwtxpow),/* SIOCGIWTXPOW */
2698 (iw_handler) ar6000_ioctl_siwretry, /* SIOCSIWRETRY */
2699 (iw_handler) ar6000_ioctl_giwretry, /* SIOCGIWRETRY */
2700 (iw_handler) ar6000_ioctl_siwencode, /* SIOCSIWENCODE */
2701 (iw_handler) ar6000_ioctl_giwencode, /* SIOCGIWENCODE */
2702 #if WIRELESS_EXT > 20
2703 (iw_handler) ar6000_ioctl_siwpower, /* SIOCSIWPOWER */
2704 (iw_handler) ar6000_ioctl_giwpower, /* SIOCGIWPOWER */
2705 #endif // WIRELESS_EXT > 20
2706 #if WIRELESS_EXT >= 18
2707 (iw_handler) NULL, /* -- hole -- */
2708 (iw_handler) NULL, /* -- hole -- */
2709 (iw_handler) ar6000_ioctl_siwgenie, /* SIOCSIWGENIE */
2710 (iw_handler) ar6000_ioctl_giwgenie, /* SIOCGIWGENIE */
2711 (iw_handler) ar6000_ioctl_siwauth, /* SIOCSIWAUTH */
2712 (iw_handler) ar6000_ioctl_giwauth, /* SIOCGIWAUTH */
2713 (iw_handler) ar6000_ioctl_siwencodeext, /* SIOCSIWENCODEEXT */
2714 (iw_handler) ar6000_ioctl_giwencodeext, /* SIOCGIWENCODEEXT */
2715 (iw_handler) ar6000_ioctl_siwpmksa, /* SIOCSIWPMKSA */
2716 #endif // WIRELESS_EXT >= 18
2717 };
2718
2719 struct iw_handler_def ath_iw_handler_def = {
2720 .standard = (iw_handler *)ath_handlers,
2721 .num_standard = ARRAY_SIZE(ath_handlers),
2722 .private = NULL,
2723 .num_private = 0,
2724 };
This page took 0.087011 seconds and 6 git commands to generate.