1 /* 2 * hostapd / Driver interaction with Atheros driver 3 * Copyright (c) 2004, Sam Leffler <sam (at) errno.com> 4 * Copyright (c) 2004, Video54 Technologies 5 * Copyright (c) 2005-2007, Jouni Malinen <j (at) w1.fi> 6 * Copyright (c) 2009, Atheros Communications 7 * 8 * This software may be distributed under the terms of the BSD license. 9 * See README for more details. 10 */ 11 12 #include "includes.h" 13 #include <net/if.h> 14 #include <sys/ioctl.h> 15 16 #include "common.h" 17 #include "eloop.h" 18 #include "common/ieee802_11_defs.h" 19 #include "l2_packet/l2_packet.h" 20 #include "p2p/p2p.h" 21 22 #include "common.h" 23 #ifndef _BYTE_ORDER 24 #ifdef WORDS_BIGENDIAN 25 #define _BYTE_ORDER _BIG_ENDIAN 26 #else 27 #define _BYTE_ORDER _LITTLE_ENDIAN 28 #endif 29 #endif /* _BYTE_ORDER */ 30 31 /* 32 * Note, the ATH_WPS_IE setting must match with the driver build.. If the 33 * driver does not include this, the IEEE80211_IOCTL_GETWPAIE ioctl will fail. 34 */ 35 #define ATH_WPS_IE 36 37 #include "ieee80211_external.h" 38 39 40 #ifdef CONFIG_WPS 41 #include <netpacket/packet.h> 42 #endif /* CONFIG_WPS */ 43 44 #ifndef ETH_P_80211_RAW 45 #define ETH_P_80211_RAW 0x0019 46 #endif 47 48 #include "linux_wext.h" 49 50 #include "driver.h" 51 #include "eloop.h" 52 #include "priv_netlink.h" 53 #include "l2_packet/l2_packet.h" 54 #include "common/ieee802_11_defs.h" 55 #include "netlink.h" 56 #include "linux_ioctl.h" 57 58 59 struct atheros_driver_data { 60 struct hostapd_data *hapd; /* back pointer */ 61 62 char iface[IFNAMSIZ + 1]; 63 int ifindex; 64 struct l2_packet_data *sock_xmit; /* raw packet xmit socket */ 65 struct l2_packet_data *sock_recv; /* raw packet recv socket */ 66 int ioctl_sock; /* socket for ioctl() use */ 67 struct netlink_data *netlink; 68 int we_version; 69 u8 acct_mac[ETH_ALEN]; 70 struct hostap_sta_driver_data acct_data; 71 72 struct l2_packet_data *sock_raw; /* raw 802.11 management frames */ 73 struct wpabuf *wpa_ie; 74 struct wpabuf *wps_beacon_ie; 75 struct wpabuf *wps_probe_resp_ie; 76 u8 own_addr[ETH_ALEN]; 77 }; 78 79 static int atheros_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, 80 int reason_code); 81 static int atheros_set_privacy(void *priv, int enabled); 82 83 static const char * athr_get_ioctl_name(int op) 84 { 85 switch (op) { 86 case IEEE80211_IOCTL_SETPARAM: 87 return "SETPARAM"; 88 case IEEE80211_IOCTL_GETPARAM: 89 return "GETPARAM"; 90 case IEEE80211_IOCTL_SETKEY: 91 return "SETKEY"; 92 case IEEE80211_IOCTL_SETWMMPARAMS: 93 return "SETWMMPARAMS"; 94 case IEEE80211_IOCTL_DELKEY: 95 return "DELKEY"; 96 case IEEE80211_IOCTL_GETWMMPARAMS: 97 return "GETWMMPARAMS"; 98 case IEEE80211_IOCTL_SETMLME: 99 return "SETMLME"; 100 case IEEE80211_IOCTL_GETCHANINFO: 101 return "GETCHANINFO"; 102 case IEEE80211_IOCTL_SETOPTIE: 103 return "SETOPTIE"; 104 case IEEE80211_IOCTL_GETOPTIE: 105 return "GETOPTIE"; 106 case IEEE80211_IOCTL_ADDMAC: 107 return "ADDMAC"; 108 case IEEE80211_IOCTL_DELMAC: 109 return "DELMAC"; 110 case IEEE80211_IOCTL_GETCHANLIST: 111 return "GETCHANLIST"; 112 case IEEE80211_IOCTL_SETCHANLIST: 113 return "SETCHANLIST"; 114 case IEEE80211_IOCTL_KICKMAC: 115 return "KICKMAC"; 116 case IEEE80211_IOCTL_CHANSWITCH: 117 return "CHANSWITCH"; 118 case IEEE80211_IOCTL_GETMODE: 119 return "GETMODE"; 120 case IEEE80211_IOCTL_SETMODE: 121 return "SETMODE"; 122 case IEEE80211_IOCTL_GET_APPIEBUF: 123 return "GET_APPIEBUF"; 124 case IEEE80211_IOCTL_SET_APPIEBUF: 125 return "SET_APPIEBUF"; 126 case IEEE80211_IOCTL_SET_ACPARAMS: 127 return "SET_ACPARAMS"; 128 case IEEE80211_IOCTL_FILTERFRAME: 129 return "FILTERFRAME"; 130 case IEEE80211_IOCTL_SET_RTPARAMS: 131 return "SET_RTPARAMS"; 132 case IEEE80211_IOCTL_SET_MEDENYENTRY: 133 return "SET_MEDENYENTRY"; 134 case IEEE80211_IOCTL_GET_MACADDR: 135 return "GET_MACADDR"; 136 case IEEE80211_IOCTL_SET_HBRPARAMS: 137 return "SET_HBRPARAMS"; 138 case IEEE80211_IOCTL_SET_RXTIMEOUT: 139 return "SET_RXTIMEOUT"; 140 case IEEE80211_IOCTL_STA_STATS: 141 return "STA_STATS"; 142 case IEEE80211_IOCTL_GETWPAIE: 143 return "GETWPAIE"; 144 default: 145 return "??"; 146 } 147 } 148 149 150 static const char * athr_get_param_name(int op) 151 { 152 switch (op) { 153 case IEEE80211_IOC_MCASTCIPHER: 154 return "MCASTCIPHER"; 155 case IEEE80211_PARAM_MCASTKEYLEN: 156 return "MCASTKEYLEN"; 157 case IEEE80211_PARAM_UCASTCIPHERS: 158 return "UCASTCIPHERS"; 159 case IEEE80211_PARAM_KEYMGTALGS: 160 return "KEYMGTALGS"; 161 case IEEE80211_PARAM_RSNCAPS: 162 return "RSNCAPS"; 163 case IEEE80211_PARAM_WPA: 164 return "WPA"; 165 case IEEE80211_PARAM_AUTHMODE: 166 return "AUTHMODE"; 167 case IEEE80211_PARAM_PRIVACY: 168 return "PRIVACY"; 169 case IEEE80211_PARAM_COUNTERMEASURES: 170 return "COUNTERMEASURES"; 171 default: 172 return "??"; 173 } 174 } 175 176 177 static int 178 set80211priv(struct atheros_driver_data *drv, int op, void *data, int len) 179 { 180 struct iwreq iwr; 181 int do_inline = len < IFNAMSIZ; 182 183 /* Certain ioctls must use the non-inlined method */ 184 if (op == IEEE80211_IOCTL_SET_APPIEBUF || 185 op == IEEE80211_IOCTL_FILTERFRAME) 186 do_inline = 0; 187 188 memset(&iwr, 0, sizeof(iwr)); 189 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 190 if (do_inline) { 191 /* 192 * Argument data fits inline; put it there. 193 */ 194 memcpy(iwr.u.name, data, len); 195 } else { 196 /* 197 * Argument data too big for inline transfer; setup a 198 * parameter block instead; the kernel will transfer 199 * the data for the driver. 200 */ 201 iwr.u.data.pointer = data; 202 iwr.u.data.length = len; 203 } 204 205 if (ioctl(drv->ioctl_sock, op, &iwr) < 0) { 206 wpa_printf(MSG_DEBUG, "atheros: %s: %s: ioctl op=0x%x " 207 "(%s) len=%d failed: %d (%s)", 208 __func__, drv->iface, op, 209 athr_get_ioctl_name(op), 210 len, errno, strerror(errno)); 211 return -1; 212 } 213 return 0; 214 } 215 216 static int 217 set80211param(struct atheros_driver_data *drv, int op, int arg) 218 { 219 struct iwreq iwr; 220 221 memset(&iwr, 0, sizeof(iwr)); 222 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 223 iwr.u.mode = op; 224 memcpy(iwr.u.name+sizeof(__u32), &arg, sizeof(arg)); 225 226 if (ioctl(drv->ioctl_sock, IEEE80211_IOCTL_SETPARAM, &iwr) < 0) { 227 perror("ioctl[IEEE80211_IOCTL_SETPARAM]"); 228 wpa_printf(MSG_DEBUG, "%s: %s: Failed to set parameter (op %d " 229 "(%s) arg %d)", __func__, drv->iface, op, 230 athr_get_param_name(op), arg); 231 return -1; 232 } 233 return 0; 234 } 235 236 #ifndef CONFIG_NO_STDOUT_DEBUG 237 static const char * 238 ether_sprintf(const u8 *addr) 239 { 240 static char buf[sizeof(MACSTR)]; 241 242 if (addr != NULL) 243 snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr)); 244 else 245 snprintf(buf, sizeof(buf), MACSTR, 0,0,0,0,0,0); 246 return buf; 247 } 248 #endif /* CONFIG_NO_STDOUT_DEBUG */ 249 250 /* 251 * Configure WPA parameters. 252 */ 253 static int 254 atheros_configure_wpa(struct atheros_driver_data *drv, 255 struct wpa_bss_params *params) 256 { 257 int v; 258 259 switch (params->wpa_group) { 260 case WPA_CIPHER_CCMP: 261 v = IEEE80211_CIPHER_AES_CCM; 262 break; 263 #ifdef ATH_GCM_SUPPORT 264 case WPA_CIPHER_CCMP_256: 265 v = IEEE80211_CIPHER_AES_CCM_256; 266 break; 267 case WPA_CIPHER_GCMP: 268 v = IEEE80211_CIPHER_AES_GCM; 269 break; 270 case WPA_CIPHER_GCMP_256: 271 v = IEEE80211_CIPHER_AES_GCM_256; 272 break; 273 #endif /* ATH_GCM_SUPPORT */ 274 case WPA_CIPHER_TKIP: 275 v = IEEE80211_CIPHER_TKIP; 276 break; 277 case WPA_CIPHER_WEP104: 278 v = IEEE80211_CIPHER_WEP; 279 break; 280 case WPA_CIPHER_WEP40: 281 v = IEEE80211_CIPHER_WEP; 282 break; 283 case WPA_CIPHER_NONE: 284 v = IEEE80211_CIPHER_NONE; 285 break; 286 default: 287 wpa_printf(MSG_ERROR, "Unknown group key cipher %u", 288 params->wpa_group); 289 return -1; 290 } 291 wpa_printf(MSG_DEBUG, "%s: group key cipher=%d", __func__, v); 292 if (set80211param(drv, IEEE80211_PARAM_MCASTCIPHER, v)) { 293 printf("Unable to set group key cipher to %u\n", v); 294 return -1; 295 } 296 if (v == IEEE80211_CIPHER_WEP) { 297 /* key length is done only for specific ciphers */ 298 v = (params->wpa_group == WPA_CIPHER_WEP104 ? 13 : 5); 299 if (set80211param(drv, IEEE80211_PARAM_MCASTKEYLEN, v)) { 300 printf("Unable to set group key length to %u\n", v); 301 return -1; 302 } 303 } 304 305 v = 0; 306 if (params->wpa_pairwise & WPA_CIPHER_CCMP) 307 v |= 1<<IEEE80211_CIPHER_AES_CCM; 308 #ifdef ATH_GCM_SUPPORT 309 if (params->wpa_pairwise & WPA_CIPHER_CCMP_256) 310 v |= 1<<IEEE80211_CIPHER_AES_CCM_256; 311 if (params->wpa_pairwise & WPA_CIPHER_GCMP) 312 v |= 1<<IEEE80211_CIPHER_AES_GCM; 313 if (params->wpa_pairwise & WPA_CIPHER_GCMP_256) 314 v |= 1<<IEEE80211_CIPHER_AES_GCM_256; 315 #endif /* ATH_GCM_SUPPORT */ 316 if (params->wpa_pairwise & WPA_CIPHER_TKIP) 317 v |= 1<<IEEE80211_CIPHER_TKIP; 318 if (params->wpa_pairwise & WPA_CIPHER_NONE) 319 v |= 1<<IEEE80211_CIPHER_NONE; 320 wpa_printf(MSG_DEBUG, "%s: pairwise key ciphers=0x%x", __func__, v); 321 if (set80211param(drv, IEEE80211_PARAM_UCASTCIPHERS, v)) { 322 printf("Unable to set pairwise key ciphers to 0x%x\n", v); 323 return -1; 324 } 325 326 wpa_printf(MSG_DEBUG, "%s: key management algorithms=0x%x", 327 __func__, params->wpa_key_mgmt); 328 if (set80211param(drv, IEEE80211_PARAM_KEYMGTALGS, 329 params->wpa_key_mgmt)) { 330 printf("Unable to set key management algorithms to 0x%x\n", 331 params->wpa_key_mgmt); 332 return -1; 333 } 334 335 v = 0; 336 if (params->rsn_preauth) 337 v |= BIT(0); 338 #ifdef CONFIG_IEEE80211W 339 if (params->ieee80211w != NO_MGMT_FRAME_PROTECTION) { 340 v |= BIT(7); 341 if (params->ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED) 342 v |= BIT(6); 343 } 344 #endif /* CONFIG_IEEE80211W */ 345 346 wpa_printf(MSG_DEBUG, "%s: rsn capabilities=0x%x", __func__, v); 347 if (set80211param(drv, IEEE80211_PARAM_RSNCAPS, v)) { 348 printf("Unable to set RSN capabilities to 0x%x\n", v); 349 return -1; 350 } 351 352 wpa_printf(MSG_DEBUG, "%s: enable WPA=0x%x", __func__, params->wpa); 353 if (set80211param(drv, IEEE80211_PARAM_WPA, params->wpa)) { 354 printf("Unable to set WPA to %u\n", params->wpa); 355 return -1; 356 } 357 return 0; 358 } 359 360 static int 361 atheros_set_ieee8021x(void *priv, struct wpa_bss_params *params) 362 { 363 struct atheros_driver_data *drv = priv; 364 365 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, params->enabled); 366 367 if (!params->enabled) { 368 /* XXX restore state */ 369 if (set80211param(priv, IEEE80211_PARAM_AUTHMODE, 370 IEEE80211_AUTH_AUTO) < 0) 371 return -1; 372 /* IEEE80211_AUTH_AUTO ends up enabling Privacy; clear that */ 373 return atheros_set_privacy(drv, 0); 374 } 375 if (!params->wpa && !params->ieee802_1x) { 376 wpa_printf(MSG_WARNING, "No 802.1X or WPA enabled!"); 377 return -1; 378 } 379 if (params->wpa && atheros_configure_wpa(drv, params) != 0) { 380 wpa_printf(MSG_WARNING, "Error configuring WPA state!"); 381 return -1; 382 } 383 if (set80211param(priv, IEEE80211_PARAM_AUTHMODE, 384 (params->wpa ? IEEE80211_AUTH_WPA : IEEE80211_AUTH_8021X))) { 385 wpa_printf(MSG_WARNING, "Error enabling WPA/802.1X!"); 386 return -1; 387 } 388 389 return 0; 390 } 391 392 static int 393 atheros_set_privacy(void *priv, int enabled) 394 { 395 struct atheros_driver_data *drv = priv; 396 397 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled); 398 399 return set80211param(drv, IEEE80211_PARAM_PRIVACY, enabled); 400 } 401 402 static int 403 atheros_set_sta_authorized(void *priv, const u8 *addr, int authorized) 404 { 405 struct atheros_driver_data *drv = priv; 406 struct ieee80211req_mlme mlme; 407 int ret; 408 409 wpa_printf(MSG_DEBUG, "%s: addr=%s authorized=%d", 410 __func__, ether_sprintf(addr), authorized); 411 412 if (authorized) 413 mlme.im_op = IEEE80211_MLME_AUTHORIZE; 414 else 415 mlme.im_op = IEEE80211_MLME_UNAUTHORIZE; 416 mlme.im_reason = 0; 417 memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); 418 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme)); 419 if (ret < 0) { 420 wpa_printf(MSG_DEBUG, "%s: Failed to %sauthorize STA " MACSTR, 421 __func__, authorized ? "" : "un", MAC2STR(addr)); 422 } 423 424 return ret; 425 } 426 427 static int 428 atheros_sta_set_flags(void *priv, const u8 *addr, 429 int total_flags, int flags_or, int flags_and) 430 { 431 /* For now, only support setting Authorized flag */ 432 if (flags_or & WPA_STA_AUTHORIZED) 433 return atheros_set_sta_authorized(priv, addr, 1); 434 if (!(flags_and & WPA_STA_AUTHORIZED)) 435 return atheros_set_sta_authorized(priv, addr, 0); 436 return 0; 437 } 438 439 static int 440 atheros_del_key(void *priv, const u8 *addr, int key_idx) 441 { 442 struct atheros_driver_data *drv = priv; 443 struct ieee80211req_del_key wk; 444 int ret; 445 446 wpa_printf(MSG_DEBUG, "%s: addr=%s key_idx=%d", 447 __func__, ether_sprintf(addr), key_idx); 448 449 memset(&wk, 0, sizeof(wk)); 450 if (addr != NULL) { 451 memcpy(wk.idk_macaddr, addr, IEEE80211_ADDR_LEN); 452 wk.idk_keyix = (u8) IEEE80211_KEYIX_NONE; 453 } else { 454 wk.idk_keyix = key_idx; 455 } 456 457 ret = set80211priv(drv, IEEE80211_IOCTL_DELKEY, &wk, sizeof(wk)); 458 if (ret < 0) { 459 wpa_printf(MSG_DEBUG, "%s: Failed to delete key (addr %s" 460 " key_idx %d)", __func__, ether_sprintf(addr), 461 key_idx); 462 } 463 464 return ret; 465 } 466 467 static int 468 atheros_set_key(const char *ifname, void *priv, enum wpa_alg alg, 469 const u8 *addr, int key_idx, int set_tx, const u8 *seq, 470 size_t seq_len, const u8 *key, size_t key_len) 471 { 472 struct atheros_driver_data *drv = priv; 473 struct ieee80211req_key wk; 474 u_int8_t cipher; 475 int ret; 476 477 if (alg == WPA_ALG_NONE) 478 return atheros_del_key(drv, addr, key_idx); 479 480 wpa_printf(MSG_DEBUG, "%s: alg=%d addr=%s key_idx=%d", 481 __func__, alg, ether_sprintf(addr), key_idx); 482 483 switch (alg) { 484 case WPA_ALG_WEP: 485 cipher = IEEE80211_CIPHER_WEP; 486 break; 487 case WPA_ALG_TKIP: 488 cipher = IEEE80211_CIPHER_TKIP; 489 break; 490 case WPA_ALG_CCMP: 491 cipher = IEEE80211_CIPHER_AES_CCM; 492 break; 493 #ifdef ATH_GCM_SUPPORT 494 case WPA_ALG_CCMP_256: 495 cipher = IEEE80211_CIPHER_AES_CCM_256; 496 break; 497 case WPA_ALG_GCMP: 498 cipher = IEEE80211_CIPHER_AES_GCM; 499 break; 500 case WPA_ALG_GCMP_256: 501 cipher = IEEE80211_CIPHER_AES_GCM_256; 502 break; 503 #endif /* ATH_GCM_SUPPORT */ 504 #ifdef CONFIG_IEEE80211W 505 case WPA_ALG_IGTK: 506 cipher = IEEE80211_CIPHER_AES_CMAC; 507 break; 508 #ifdef ATH_GCM_SUPPORT 509 case WPA_ALG_BIP_CMAC_256: 510 cipher = IEEE80211_CIPHER_AES_CMAC_256; 511 break; 512 case WPA_ALG_BIP_GMAC_128: 513 cipher = IEEE80211_CIPHER_AES_GMAC; 514 break; 515 case WPA_ALG_BIP_GMAC_256: 516 cipher = IEEE80211_CIPHER_AES_GMAC_256; 517 break; 518 #endif /* ATH_GCM_SUPPORT */ 519 #endif /* CONFIG_IEEE80211W */ 520 default: 521 printf("%s: unknown/unsupported algorithm %d\n", 522 __func__, alg); 523 return -1; 524 } 525 526 if (key_len > sizeof(wk.ik_keydata)) { 527 printf("%s: key length %lu too big\n", __func__, 528 (unsigned long) key_len); 529 return -3; 530 } 531 532 memset(&wk, 0, sizeof(wk)); 533 wk.ik_type = cipher; 534 wk.ik_flags = IEEE80211_KEY_RECV | IEEE80211_KEY_XMIT; 535 if (addr == NULL || is_broadcast_ether_addr(addr)) { 536 memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN); 537 wk.ik_keyix = key_idx; 538 if (set_tx) 539 wk.ik_flags |= IEEE80211_KEY_DEFAULT; 540 } else { 541 memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); 542 wk.ik_keyix = IEEE80211_KEYIX_NONE; 543 } 544 wk.ik_keylen = key_len; 545 memcpy(wk.ik_keydata, key, key_len); 546 547 ret = set80211priv(drv, IEEE80211_IOCTL_SETKEY, &wk, sizeof(wk)); 548 if (ret < 0) { 549 wpa_printf(MSG_DEBUG, "%s: Failed to set key (addr %s" 550 " key_idx %d alg %d key_len %lu set_tx %d)", 551 __func__, ether_sprintf(wk.ik_macaddr), key_idx, 552 alg, (unsigned long) key_len, set_tx); 553 } 554 555 return ret; 556 } 557 558 559 static int 560 atheros_get_seqnum(const char *ifname, void *priv, const u8 *addr, int idx, 561 u8 *seq) 562 { 563 struct atheros_driver_data *drv = priv; 564 struct ieee80211req_key wk; 565 566 wpa_printf(MSG_DEBUG, "%s: addr=%s idx=%d", 567 __func__, ether_sprintf(addr), idx); 568 569 memset(&wk, 0, sizeof(wk)); 570 if (addr == NULL) 571 memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN); 572 else 573 memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); 574 wk.ik_keyix = idx; 575 576 if (set80211priv(drv, IEEE80211_IOCTL_GETKEY, &wk, sizeof(wk))) { 577 wpa_printf(MSG_DEBUG, "%s: Failed to get encryption data " 578 "(addr " MACSTR " key_idx %d)", 579 __func__, MAC2STR(wk.ik_macaddr), idx); 580 return -1; 581 } 582 583 #ifdef WORDS_BIGENDIAN 584 { 585 /* 586 * wk.ik_keytsc is in host byte order (big endian), need to 587 * swap it to match with the byte order used in WPA. 588 */ 589 int i; 590 #ifndef WPA_KEY_RSC_LEN 591 #define WPA_KEY_RSC_LEN 8 592 #endif 593 u8 tmp[WPA_KEY_RSC_LEN]; 594 memcpy(tmp, &wk.ik_keytsc, sizeof(wk.ik_keytsc)); 595 for (i = 0; i < WPA_KEY_RSC_LEN; i++) { 596 seq[i] = tmp[WPA_KEY_RSC_LEN - i - 1]; 597 } 598 } 599 #else /* WORDS_BIGENDIAN */ 600 memcpy(seq, &wk.ik_keytsc, sizeof(wk.ik_keytsc)); 601 #endif /* WORDS_BIGENDIAN */ 602 return 0; 603 } 604 605 606 static int 607 atheros_flush(void *priv) 608 { 609 u8 allsta[IEEE80211_ADDR_LEN]; 610 memset(allsta, 0xff, IEEE80211_ADDR_LEN); 611 return atheros_sta_deauth(priv, NULL, allsta, 612 IEEE80211_REASON_AUTH_LEAVE); 613 } 614 615 616 static int 617 atheros_read_sta_driver_data(void *priv, struct hostap_sta_driver_data *data, 618 const u8 *addr) 619 { 620 struct atheros_driver_data *drv = priv; 621 struct ieee80211req_sta_stats stats; 622 623 memset(data, 0, sizeof(*data)); 624 625 /* 626 * Fetch statistics for station from the system. 627 */ 628 memset(&stats, 0, sizeof(stats)); 629 memcpy(stats.is_u.macaddr, addr, IEEE80211_ADDR_LEN); 630 if (set80211priv(drv, IEEE80211_IOCTL_STA_STATS, 631 &stats, sizeof(stats))) { 632 wpa_printf(MSG_DEBUG, "%s: Failed to fetch STA stats (addr " 633 MACSTR ")", __func__, MAC2STR(addr)); 634 if (memcmp(addr, drv->acct_mac, ETH_ALEN) == 0) { 635 memcpy(data, &drv->acct_data, sizeof(*data)); 636 return 0; 637 } 638 639 printf("Failed to get station stats information element.\n"); 640 return -1; 641 } 642 643 data->rx_packets = stats.is_stats.ns_rx_data; 644 data->rx_bytes = stats.is_stats.ns_rx_bytes; 645 data->tx_packets = stats.is_stats.ns_tx_data; 646 data->tx_bytes = stats.is_stats.ns_tx_bytes; 647 return 0; 648 } 649 650 651 static int 652 atheros_sta_clear_stats(void *priv, const u8 *addr) 653 { 654 struct atheros_driver_data *drv = priv; 655 struct ieee80211req_mlme mlme; 656 int ret; 657 658 wpa_printf(MSG_DEBUG, "%s: addr=%s", __func__, ether_sprintf(addr)); 659 660 mlme.im_op = IEEE80211_MLME_CLEAR_STATS; 661 memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); 662 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, 663 sizeof(mlme)); 664 if (ret < 0) { 665 wpa_printf(MSG_DEBUG, "%s: Failed to clear STA stats (addr " 666 MACSTR ")", __func__, MAC2STR(addr)); 667 } 668 669 return ret; 670 } 671 672 673 static int 674 atheros_set_opt_ie(void *priv, const u8 *ie, size_t ie_len) 675 { 676 struct atheros_driver_data *drv = priv; 677 u8 buf[512]; 678 struct ieee80211req_getset_appiebuf *app_ie; 679 680 wpa_printf(MSG_DEBUG, "%s buflen = %lu", __func__, 681 (unsigned long) ie_len); 682 wpa_hexdump(MSG_DEBUG, "atheros: set_generic_elem", ie, ie_len); 683 684 wpabuf_free(drv->wpa_ie); 685 drv->wpa_ie = wpabuf_alloc_copy(ie, ie_len); 686 687 app_ie = (struct ieee80211req_getset_appiebuf *) buf; 688 os_memcpy(&(app_ie->app_buf[0]), ie, ie_len); 689 app_ie->app_buflen = ie_len; 690 691 app_ie->app_frmtype = IEEE80211_APPIE_FRAME_BEACON; 692 693 /* append WPS IE for Beacon */ 694 if (drv->wps_beacon_ie != NULL) { 695 os_memcpy(&(app_ie->app_buf[ie_len]), 696 wpabuf_head(drv->wps_beacon_ie), 697 wpabuf_len(drv->wps_beacon_ie)); 698 app_ie->app_buflen = ie_len + wpabuf_len(drv->wps_beacon_ie); 699 } 700 wpa_hexdump(MSG_DEBUG, "atheros: SET_APPIEBUF(Beacon)", 701 app_ie->app_buf, app_ie->app_buflen); 702 set80211priv(drv, IEEE80211_IOCTL_SET_APPIEBUF, app_ie, 703 sizeof(struct ieee80211req_getset_appiebuf) + 704 app_ie->app_buflen); 705 706 /* append WPS IE for Probe Response */ 707 app_ie->app_frmtype = IEEE80211_APPIE_FRAME_PROBE_RESP; 708 if (drv->wps_probe_resp_ie != NULL) { 709 os_memcpy(&(app_ie->app_buf[ie_len]), 710 wpabuf_head(drv->wps_probe_resp_ie), 711 wpabuf_len(drv->wps_probe_resp_ie)); 712 app_ie->app_buflen = ie_len + 713 wpabuf_len(drv->wps_probe_resp_ie); 714 } else 715 app_ie->app_buflen = ie_len; 716 wpa_hexdump(MSG_DEBUG, "atheros: SET_APPIEBUF(ProbeResp)", 717 app_ie->app_buf, app_ie->app_buflen); 718 set80211priv(drv, IEEE80211_IOCTL_SET_APPIEBUF, app_ie, 719 sizeof(struct ieee80211req_getset_appiebuf) + 720 app_ie->app_buflen); 721 return 0; 722 } 723 724 static int 725 atheros_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, 726 int reason_code) 727 { 728 struct atheros_driver_data *drv = priv; 729 struct ieee80211req_mlme mlme; 730 int ret; 731 732 wpa_printf(MSG_DEBUG, "%s: addr=%s reason_code=%d", 733 __func__, ether_sprintf(addr), reason_code); 734 735 mlme.im_op = IEEE80211_MLME_DEAUTH; 736 mlme.im_reason = reason_code; 737 memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); 738 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme)); 739 if (ret < 0) { 740 wpa_printf(MSG_DEBUG, "%s: Failed to deauth STA (addr " MACSTR 741 " reason %d)", 742 __func__, MAC2STR(addr), reason_code); 743 } 744 745 return ret; 746 } 747 748 static int 749 atheros_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr, 750 int reason_code) 751 { 752 struct atheros_driver_data *drv = priv; 753 struct ieee80211req_mlme mlme; 754 int ret; 755 756 wpa_printf(MSG_DEBUG, "%s: addr=%s reason_code=%d", 757 __func__, ether_sprintf(addr), reason_code); 758 759 mlme.im_op = IEEE80211_MLME_DISASSOC; 760 mlme.im_reason = reason_code; 761 memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); 762 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme)); 763 if (ret < 0) { 764 wpa_printf(MSG_DEBUG, "%s: Failed to disassoc STA (addr " 765 MACSTR " reason %d)", 766 __func__, MAC2STR(addr), reason_code); 767 } 768 769 return ret; 770 } 771 772 #ifdef CONFIG_WPS 773 static void atheros_raw_recv_wps(void *ctx, const u8 *src_addr, const u8 *buf, 774 size_t len) 775 { 776 struct atheros_driver_data *drv = ctx; 777 const struct ieee80211_mgmt *mgmt; 778 u16 fc; 779 union wpa_event_data event; 780 781 /* Send Probe Request information to WPS processing */ 782 783 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req)) 784 return; 785 mgmt = (const struct ieee80211_mgmt *) buf; 786 787 fc = le_to_host16(mgmt->frame_control); 788 if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT || 789 WLAN_FC_GET_STYPE(fc) != WLAN_FC_STYPE_PROBE_REQ) 790 return; 791 792 os_memset(&event, 0, sizeof(event)); 793 event.rx_probe_req.sa = mgmt->sa; 794 event.rx_probe_req.da = mgmt->da; 795 event.rx_probe_req.bssid = mgmt->bssid; 796 event.rx_probe_req.ie = mgmt->u.probe_req.variable; 797 event.rx_probe_req.ie_len = 798 len - (IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req)); 799 wpa_supplicant_event(drv->hapd, EVENT_RX_PROBE_REQ, &event); 800 } 801 #endif /* CONFIG_WPS */ 802 803 #ifdef CONFIG_IEEE80211R 804 static void atheros_raw_recv_11r(void *ctx, const u8 *src_addr, const u8 *buf, 805 size_t len) 806 { 807 struct atheros_driver_data *drv = ctx; 808 union wpa_event_data event; 809 const struct ieee80211_mgmt *mgmt; 810 u16 fc; 811 u16 stype; 812 int ielen; 813 const u8 *iebuf; 814 815 /* Do 11R processing for ASSOC/AUTH/FT ACTION frames */ 816 if (len < IEEE80211_HDRLEN) 817 return; 818 mgmt = (const struct ieee80211_mgmt *) buf; 819 820 fc = le_to_host16(mgmt->frame_control); 821 822 if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT) 823 return; 824 stype = WLAN_FC_GET_STYPE(fc); 825 826 wpa_printf(MSG_DEBUG, "%s: subtype 0x%x len %d", __func__, stype, 827 (int) len); 828 829 if (os_memcmp(drv->own_addr, mgmt->bssid, ETH_ALEN) != 0) { 830 wpa_printf(MSG_DEBUG, "%s: BSSID does not match - ignore", 831 __func__); 832 return; 833 } 834 switch (stype) { 835 case WLAN_FC_STYPE_ASSOC_REQ: 836 if (len - IEEE80211_HDRLEN < sizeof(mgmt->u.assoc_req)) 837 break; 838 ielen = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.assoc_req)); 839 iebuf = mgmt->u.assoc_req.variable; 840 drv_event_assoc(drv->hapd, mgmt->sa, iebuf, ielen, 0); 841 break; 842 case WLAN_FC_STYPE_REASSOC_REQ: 843 if (len - IEEE80211_HDRLEN < sizeof(mgmt->u.reassoc_req)) 844 break; 845 ielen = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.reassoc_req)); 846 iebuf = mgmt->u.reassoc_req.variable; 847 drv_event_assoc(drv->hapd, mgmt->sa, iebuf, ielen, 1); 848 break; 849 case WLAN_FC_STYPE_ACTION: 850 os_memset(&event, 0, sizeof(event)); 851 event.rx_mgmt.frame = buf; 852 event.rx_mgmt.frame_len = len; 853 wpa_supplicant_event(drv->hapd, EVENT_RX_MGMT, &event); 854 break; 855 case WLAN_FC_STYPE_AUTH: 856 if (len - IEEE80211_HDRLEN < sizeof(mgmt->u.auth)) 857 break; 858 os_memset(&event, 0, sizeof(event)); 859 os_memcpy(event.auth.peer, mgmt->sa, ETH_ALEN); 860 os_memcpy(event.auth.bssid, mgmt->bssid, ETH_ALEN); 861 event.auth.auth_type = le_to_host16(mgmt->u.auth.auth_alg); 862 event.auth.status_code = 863 le_to_host16(mgmt->u.auth.status_code); 864 event.auth.auth_transaction = 865 le_to_host16(mgmt->u.auth.auth_transaction); 866 event.auth.ies = mgmt->u.auth.variable; 867 event.auth.ies_len = len - IEEE80211_HDRLEN - 868 sizeof(mgmt->u.auth); 869 wpa_supplicant_event(drv->hapd, EVENT_AUTH, &event); 870 break; 871 default: 872 break; 873 } 874 } 875 #endif /* CONFIG_IEEE80211R */ 876 877 #ifdef CONFIG_HS20 878 static void atheros_raw_recv_hs20(void *ctx, const u8 *src_addr, const u8 *buf, 879 size_t len) 880 { 881 struct atheros_driver_data *drv = ctx; 882 const struct ieee80211_mgmt *mgmt; 883 u16 fc; 884 union wpa_event_data event; 885 886 /* Send the Action frame for HS20 processing */ 887 888 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.action.category) + 889 sizeof(mgmt->u.action.u.public_action)) 890 return; 891 892 mgmt = (const struct ieee80211_mgmt *) buf; 893 894 fc = le_to_host16(mgmt->frame_control); 895 if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT || 896 WLAN_FC_GET_STYPE(fc) != WLAN_FC_STYPE_ACTION || 897 mgmt->u.action.category != WLAN_ACTION_PUBLIC) 898 return; 899 900 wpa_printf(MSG_DEBUG, "%s:Received Public Action frame", __func__); 901 902 os_memset(&event, 0, sizeof(event)); 903 event.rx_mgmt.frame = (const u8 *) mgmt; 904 event.rx_mgmt.frame_len = len; 905 wpa_supplicant_event(drv->hapd, EVENT_RX_MGMT, &event); 906 } 907 908 #endif /* CONFIG_HS20 */ 909 910 911 static int atheros_set_qos_map(void *ctx, const u8 *qos_map_set, 912 u8 qos_map_set_len) 913 { 914 #ifdef CONFIG_ATHEROS_QOS_MAP 915 struct atheros_driver_data *drv = ctx; 916 struct ieee80211req_athdbg req; 917 struct ieee80211_qos_map *qos_map = &req.data.qos_map; 918 struct iwreq iwr; 919 int i, up_start; 920 921 if (qos_map_set_len < 16 || qos_map_set_len > 58 || 922 qos_map_set_len & 1) { 923 wpa_printf(MSG_ERROR, "Invalid QoS Map"); 924 return -1; 925 } else { 926 memset(&req, 0, sizeof(struct ieee80211req_athdbg)); 927 req.cmd = IEEE80211_DBGREQ_SETQOSMAPCONF; 928 os_memset(&iwr, 0, sizeof(iwr)); 929 os_strlcpy(iwr.ifr_name, drv->iface, sizeof(iwr.ifr_name)); 930 iwr.u.data.pointer = (void *) &req; 931 iwr.u.data.length = sizeof(struct ieee80211req_athdbg); 932 } 933 934 qos_map->valid = 1; 935 qos_map->num_dscp_except = (qos_map_set_len - 16) / 2; 936 if (qos_map->num_dscp_except) { 937 for (i = 0; i < qos_map->num_dscp_except; i++) { 938 qos_map->dscp_exception[i].dscp = qos_map_set[i * 2]; 939 qos_map->dscp_exception[i].up = qos_map_set[i * 2 + 1]; 940 } 941 } 942 943 up_start = qos_map_set_len - 16; 944 for (i = 0; i < IEEE80211_MAX_QOS_UP_RANGE; i++) { 945 qos_map->up[i].low = qos_map_set[up_start + (i * 2)]; 946 qos_map->up[i].high = qos_map_set[up_start + (i * 2) + 1]; 947 } 948 949 if (ioctl(drv->ioctl_sock, IEEE80211_IOCTL_DBGREQ, &iwr) < 0) { 950 perror("ioctl[IEEE80211_IOCTL_DBGREQ]"); 951 wpa_printf(MSG_DEBUG, "%s: %s: Failed to set QoS Map", 952 __func__, drv->iface); 953 return -1; 954 } 955 #endif /* CONFIG_ATHEROS_QOS_MAP */ 956 957 return 0; 958 } 959 960 #if defined(CONFIG_WNM) && !defined(CONFIG_IEEE80211R) 961 static void atheros_raw_recv_11v(void *ctx, const u8 *src_addr, const u8 *buf, 962 size_t len) 963 { 964 struct atheros_driver_data *drv = ctx; 965 union wpa_event_data event; 966 const struct ieee80211_mgmt *mgmt; 967 u16 fc; 968 u16 stype; 969 970 /* Do 11R processing for WNM ACTION frames */ 971 if (len < IEEE80211_HDRLEN) 972 return; 973 mgmt = (const struct ieee80211_mgmt *) buf; 974 975 fc = le_to_host16(mgmt->frame_control); 976 977 if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT) 978 return; 979 stype = WLAN_FC_GET_STYPE(fc); 980 981 wpa_printf(MSG_DEBUG, "%s: subtype 0x%x len %d", __func__, stype, 982 (int) len); 983 984 if (os_memcmp(drv->own_addr, mgmt->bssid, ETH_ALEN) != 0) { 985 wpa_printf(MSG_DEBUG, "%s: BSSID does not match - ignore", 986 __func__); 987 return; 988 } 989 990 switch (stype) { 991 case WLAN_FC_STYPE_ACTION: 992 os_memset(&event, 0, sizeof(event)); 993 event.rx_mgmt.frame = buf; 994 event.rx_mgmt.frame_len = len; 995 wpa_supplicant_event(drv->hapd, EVENT_RX_MGMT, &event); 996 break; 997 default: 998 break; 999 } 1000 } 1001 #endif /* CONFIG_WNM */ 1002 1003 #if defined(CONFIG_WPS) || defined(CONFIG_IEEE80211R) || defined(CONFIG_WNM) 1004 static void atheros_raw_receive(void *ctx, const u8 *src_addr, const u8 *buf, 1005 size_t len) 1006 { 1007 #ifdef CONFIG_WPS 1008 atheros_raw_recv_wps(ctx, src_addr, buf, len); 1009 #endif /* CONFIG_WPS */ 1010 #ifdef CONFIG_IEEE80211R 1011 atheros_raw_recv_11r(ctx, src_addr, buf, len); 1012 #endif /* CONFIG_IEEE80211R */ 1013 #if defined(CONFIG_WNM) && !defined(CONFIG_IEEE80211R) 1014 atheros_raw_recv_11v(ctx, src_addr, buf, len); 1015 #endif /* CONFIG_WNM */ 1016 #ifdef CONFIG_HS20 1017 atheros_raw_recv_hs20(ctx, src_addr, buf, len); 1018 #endif /* CONFIG_HS20 */ 1019 } 1020 #endif /* CONFIG_WPS || CONFIG_IEEE80211R */ 1021 1022 static int atheros_receive_pkt(struct atheros_driver_data *drv) 1023 { 1024 int ret = 0; 1025 struct ieee80211req_set_filter filt; 1026 1027 wpa_printf(MSG_DEBUG, "%s Enter", __func__); 1028 filt.app_filterype = 0; 1029 #ifdef CONFIG_WPS 1030 filt.app_filterype |= IEEE80211_FILTER_TYPE_PROBE_REQ; 1031 #endif /* CONFIG_WPS */ 1032 #ifdef CONFIG_IEEE80211R 1033 filt.app_filterype |= (IEEE80211_FILTER_TYPE_ASSOC_REQ | 1034 IEEE80211_FILTER_TYPE_AUTH | 1035 IEEE80211_FILTER_TYPE_ACTION); 1036 #endif 1037 #ifdef CONFIG_WNM 1038 filt.app_filterype |= IEEE80211_FILTER_TYPE_ACTION; 1039 #endif /* CONFIG_WNM */ 1040 #ifdef CONFIG_HS20 1041 filt.app_filterype |= IEEE80211_FILTER_TYPE_ACTION; 1042 #endif /* CONFIG_HS20 */ 1043 if (filt.app_filterype) { 1044 ret = set80211priv(drv, IEEE80211_IOCTL_FILTERFRAME, &filt, 1045 sizeof(struct ieee80211req_set_filter)); 1046 if (ret) 1047 return ret; 1048 } 1049 1050 #if defined(CONFIG_WPS) || defined(CONFIG_IEEE80211R) 1051 drv->sock_raw = l2_packet_init(drv->iface, NULL, ETH_P_80211_RAW, 1052 atheros_raw_receive, drv, 1); 1053 if (drv->sock_raw == NULL) 1054 return -1; 1055 #endif /* CONFIG_WPS || CONFIG_IEEE80211R */ 1056 return ret; 1057 } 1058 1059 static int atheros_reset_appfilter(struct atheros_driver_data *drv) 1060 { 1061 struct ieee80211req_set_filter filt; 1062 filt.app_filterype = 0; 1063 return set80211priv(drv, IEEE80211_IOCTL_FILTERFRAME, &filt, 1064 sizeof(struct ieee80211req_set_filter)); 1065 } 1066 1067 #ifdef CONFIG_WPS 1068 static int 1069 atheros_set_wps_ie(void *priv, const u8 *ie, size_t len, u32 frametype) 1070 { 1071 struct atheros_driver_data *drv = priv; 1072 u8 buf[512]; 1073 struct ieee80211req_getset_appiebuf *beac_ie; 1074 1075 wpa_printf(MSG_DEBUG, "%s buflen = %lu frametype=%u", __func__, 1076 (unsigned long) len, frametype); 1077 wpa_hexdump(MSG_DEBUG, "atheros: IE", ie, len); 1078 1079 beac_ie = (struct ieee80211req_getset_appiebuf *) buf; 1080 beac_ie->app_frmtype = frametype; 1081 beac_ie->app_buflen = len; 1082 os_memcpy(&(beac_ie->app_buf[0]), ie, len); 1083 1084 /* append the WPA/RSN IE if it is set already */ 1085 if (((frametype == IEEE80211_APPIE_FRAME_BEACON) || 1086 (frametype == IEEE80211_APPIE_FRAME_PROBE_RESP)) && 1087 (drv->wpa_ie != NULL)) { 1088 wpa_hexdump_buf(MSG_DEBUG, "atheros: Append WPA/RSN IE", 1089 drv->wpa_ie); 1090 os_memcpy(&(beac_ie->app_buf[len]), wpabuf_head(drv->wpa_ie), 1091 wpabuf_len(drv->wpa_ie)); 1092 beac_ie->app_buflen += wpabuf_len(drv->wpa_ie); 1093 } 1094 1095 wpa_hexdump(MSG_DEBUG, "atheros: SET_APPIEBUF", 1096 beac_ie->app_buf, beac_ie->app_buflen); 1097 return set80211priv(drv, IEEE80211_IOCTL_SET_APPIEBUF, beac_ie, 1098 sizeof(struct ieee80211req_getset_appiebuf) + 1099 beac_ie->app_buflen); 1100 } 1101 1102 static int 1103 atheros_set_ap_wps_ie(void *priv, const struct wpabuf *beacon, 1104 const struct wpabuf *proberesp, 1105 const struct wpabuf *assocresp) 1106 { 1107 struct atheros_driver_data *drv = priv; 1108 1109 wpa_hexdump_buf(MSG_DEBUG, "atheros: set_ap_wps_ie - beacon", beacon); 1110 wpa_hexdump_buf(MSG_DEBUG, "atheros: set_ap_wps_ie - proberesp", 1111 proberesp); 1112 wpa_hexdump_buf(MSG_DEBUG, "atheros: set_ap_wps_ie - assocresp", 1113 assocresp); 1114 wpabuf_free(drv->wps_beacon_ie); 1115 drv->wps_beacon_ie = beacon ? wpabuf_dup(beacon) : NULL; 1116 wpabuf_free(drv->wps_probe_resp_ie); 1117 drv->wps_probe_resp_ie = proberesp ? wpabuf_dup(proberesp) : NULL; 1118 1119 atheros_set_wps_ie(priv, assocresp ? wpabuf_head(assocresp) : NULL, 1120 assocresp ? wpabuf_len(assocresp) : 0, 1121 IEEE80211_APPIE_FRAME_ASSOC_RESP); 1122 if (atheros_set_wps_ie(priv, beacon ? wpabuf_head(beacon) : NULL, 1123 beacon ? wpabuf_len(beacon) : 0, 1124 IEEE80211_APPIE_FRAME_BEACON)) 1125 return -1; 1126 return atheros_set_wps_ie(priv, 1127 proberesp ? wpabuf_head(proberesp) : NULL, 1128 proberesp ? wpabuf_len(proberesp): 0, 1129 IEEE80211_APPIE_FRAME_PROBE_RESP); 1130 } 1131 #else /* CONFIG_WPS */ 1132 #define atheros_set_ap_wps_ie NULL 1133 #endif /* CONFIG_WPS */ 1134 1135 #ifdef CONFIG_IEEE80211R 1136 static int 1137 atheros_sta_auth(void *priv, const u8 *own_addr, const u8 *addr, u16 seq, 1138 u16 status_code, const u8 *ie, size_t len) 1139 { 1140 struct atheros_driver_data *drv = priv; 1141 struct ieee80211req_mlme mlme; 1142 int ret; 1143 1144 wpa_printf(MSG_DEBUG, "%s: addr=%s status_code=%d", 1145 __func__, ether_sprintf(addr), status_code); 1146 1147 mlme.im_op = IEEE80211_MLME_AUTH; 1148 mlme.im_reason = status_code; 1149 mlme.im_seq = seq; 1150 os_memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); 1151 mlme.im_optie_len = len; 1152 if (len) { 1153 if (len < IEEE80211_MAX_OPT_IE) { 1154 os_memcpy(mlme.im_optie, ie, len); 1155 } else { 1156 wpa_printf(MSG_DEBUG, "%s: Not enough space to copy " 1157 "opt_ie STA (addr " MACSTR " reason %d, " 1158 "ie_len %d)", 1159 __func__, MAC2STR(addr), status_code, 1160 (int) len); 1161 return -1; 1162 } 1163 } 1164 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme)); 1165 if (ret < 0) { 1166 wpa_printf(MSG_DEBUG, "%s: Failed to auth STA (addr " MACSTR 1167 " reason %d)", 1168 __func__, MAC2STR(addr), status_code); 1169 } 1170 return ret; 1171 } 1172 1173 static int 1174 atheros_sta_assoc(void *priv, const u8 *own_addr, const u8 *addr, 1175 int reassoc, u16 status_code, const u8 *ie, size_t len) 1176 { 1177 struct atheros_driver_data *drv = priv; 1178 struct ieee80211req_mlme mlme; 1179 int ret; 1180 1181 wpa_printf(MSG_DEBUG, "%s: addr=%s status_code=%d reassoc %d", 1182 __func__, ether_sprintf(addr), status_code, reassoc); 1183 1184 if (reassoc) 1185 mlme.im_op = IEEE80211_MLME_REASSOC; 1186 else 1187 mlme.im_op = IEEE80211_MLME_ASSOC; 1188 mlme.im_reason = status_code; 1189 os_memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); 1190 mlme.im_optie_len = len; 1191 if (len) { 1192 if (len < IEEE80211_MAX_OPT_IE) { 1193 os_memcpy(mlme.im_optie, ie, len); 1194 } else { 1195 wpa_printf(MSG_DEBUG, "%s: Not enough space to copy " 1196 "opt_ie STA (addr " MACSTR " reason %d, " 1197 "ie_len %d)", 1198 __func__, MAC2STR(addr), status_code, 1199 (int) len); 1200 return -1; 1201 } 1202 } 1203 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme)); 1204 if (ret < 0) { 1205 wpa_printf(MSG_DEBUG, "%s: Failed to assoc STA (addr " MACSTR 1206 " reason %d)", 1207 __func__, MAC2STR(addr), status_code); 1208 } 1209 return ret; 1210 } 1211 #endif /* CONFIG_IEEE80211R */ 1212 1213 static void 1214 atheros_new_sta(struct atheros_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN]) 1215 { 1216 struct hostapd_data *hapd = drv->hapd; 1217 struct ieee80211req_wpaie ie; 1218 int ielen = 0; 1219 u8 *iebuf = NULL; 1220 1221 /* 1222 * Fetch negotiated WPA/RSN parameters from the system. 1223 */ 1224 memset(&ie, 0, sizeof(ie)); 1225 memcpy(ie.wpa_macaddr, addr, IEEE80211_ADDR_LEN); 1226 if (set80211priv(drv, IEEE80211_IOCTL_GETWPAIE, &ie, sizeof(ie))) { 1227 /* 1228 * See ATH_WPS_IE comment in the beginning of the file for a 1229 * possible cause for the failure.. 1230 */ 1231 wpa_printf(MSG_DEBUG, "%s: Failed to get WPA/RSN IE: %s", 1232 __func__, strerror(errno)); 1233 goto no_ie; 1234 } 1235 wpa_hexdump(MSG_MSGDUMP, "atheros req WPA IE", 1236 ie.wpa_ie, IEEE80211_MAX_OPT_IE); 1237 wpa_hexdump(MSG_MSGDUMP, "atheros req RSN IE", 1238 ie.rsn_ie, IEEE80211_MAX_OPT_IE); 1239 #ifdef ATH_WPS_IE 1240 wpa_hexdump(MSG_MSGDUMP, "atheros req WPS IE", 1241 ie.wps_ie, IEEE80211_MAX_OPT_IE); 1242 #endif /* ATH_WPS_IE */ 1243 iebuf = ie.wpa_ie; 1244 /* atheros seems to return some random data if WPA/RSN IE is not set. 1245 * Assume the IE was not included if the IE type is unknown. */ 1246 if (iebuf[0] != WLAN_EID_VENDOR_SPECIFIC) 1247 iebuf[1] = 0; 1248 if (iebuf[1] == 0 && ie.rsn_ie[1] > 0) { 1249 /* atheros-ng svn #1453 added rsn_ie. Use it, if wpa_ie was not 1250 * set. This is needed for WPA2. */ 1251 iebuf = ie.rsn_ie; 1252 if (iebuf[0] != WLAN_EID_RSN) 1253 iebuf[1] = 0; 1254 } 1255 1256 ielen = iebuf[1]; 1257 1258 #ifdef ATH_WPS_IE 1259 /* if WPS IE is present, preference is given to WPS */ 1260 if (ie.wps_ie && 1261 (ie.wps_ie[1] > 0 && (ie.wps_ie[0] == WLAN_EID_VENDOR_SPECIFIC))) { 1262 iebuf = ie.wps_ie; 1263 ielen = ie.wps_ie[1]; 1264 } 1265 #endif /* ATH_WPS_IE */ 1266 1267 if (ielen == 0) 1268 iebuf = NULL; 1269 else 1270 ielen += 2; 1271 1272 no_ie: 1273 drv_event_assoc(hapd, addr, iebuf, ielen, 0); 1274 1275 if (memcmp(addr, drv->acct_mac, ETH_ALEN) == 0) { 1276 /* Cached accounting data is not valid anymore. */ 1277 memset(drv->acct_mac, 0, ETH_ALEN); 1278 memset(&drv->acct_data, 0, sizeof(drv->acct_data)); 1279 } 1280 } 1281 1282 static void 1283 atheros_wireless_event_wireless_custom(struct atheros_driver_data *drv, 1284 char *custom, char *end) 1285 { 1286 wpa_printf(MSG_DEBUG, "Custom wireless event: '%s'", custom); 1287 1288 if (strncmp(custom, "MLME-MICHAELMICFAILURE.indication", 33) == 0) { 1289 char *pos; 1290 u8 addr[ETH_ALEN]; 1291 pos = strstr(custom, "addr="); 1292 if (pos == NULL) { 1293 wpa_printf(MSG_DEBUG, 1294 "MLME-MICHAELMICFAILURE.indication " 1295 "without sender address ignored"); 1296 return; 1297 } 1298 pos += 5; 1299 if (hwaddr_aton(pos, addr) == 0) { 1300 union wpa_event_data data; 1301 os_memset(&data, 0, sizeof(data)); 1302 data.michael_mic_failure.unicast = 1; 1303 data.michael_mic_failure.src = addr; 1304 wpa_supplicant_event(drv->hapd, 1305 EVENT_MICHAEL_MIC_FAILURE, &data); 1306 } else { 1307 wpa_printf(MSG_DEBUG, 1308 "MLME-MICHAELMICFAILURE.indication " 1309 "with invalid MAC address"); 1310 } 1311 } else if (strncmp(custom, "STA-TRAFFIC-STAT", 16) == 0) { 1312 char *key, *value; 1313 u32 val; 1314 key = custom; 1315 while ((key = strchr(key, '\n')) != NULL) { 1316 key++; 1317 value = strchr(key, '='); 1318 if (value == NULL) 1319 continue; 1320 *value++ = '\0'; 1321 val = strtoul(value, NULL, 10); 1322 if (strcmp(key, "mac") == 0) 1323 hwaddr_aton(value, drv->acct_mac); 1324 else if (strcmp(key, "rx_packets") == 0) 1325 drv->acct_data.rx_packets = val; 1326 else if (strcmp(key, "tx_packets") == 0) 1327 drv->acct_data.tx_packets = val; 1328 else if (strcmp(key, "rx_bytes") == 0) 1329 drv->acct_data.rx_bytes = val; 1330 else if (strcmp(key, "tx_bytes") == 0) 1331 drv->acct_data.tx_bytes = val; 1332 key = value; 1333 } 1334 #ifdef CONFIG_WPS 1335 } else if (strncmp(custom, "PUSH-BUTTON.indication", 22) == 0) { 1336 /* Some atheros kernels send push button as a wireless event */ 1337 /* PROBLEM! this event is received for ALL BSSs ... 1338 * so all are enabled for WPS... ugh. 1339 */ 1340 wpa_supplicant_event(drv->hapd, EVENT_WPS_BUTTON_PUSHED, NULL); 1341 #endif /* CONFIG_WPS */ 1342 #if defined(CONFIG_WPS) || defined(CONFIG_IEEE80211R) || defined(CONFIG_HS20) 1343 #define MGMT_FRAM_TAG_SIZE 30 /* hardcoded in driver */ 1344 } else if (strncmp(custom, "Manage.prob_req ", 16) == 0) { 1345 /* 1346 * Atheros driver uses a hack to pass Probe Request frames as a 1347 * binary data in the custom wireless event. The old way (using 1348 * packet sniffing) didn't work when bridging. 1349 * Format: "Manage.prob_req <frame len>" | zero padding | frame 1350 */ 1351 int len = atoi(custom + 16); 1352 if (len < 0 || custom + MGMT_FRAM_TAG_SIZE + len > end) { 1353 wpa_printf(MSG_DEBUG, "Invalid Manage.prob_req event " 1354 "length %d", len); 1355 return; 1356 } 1357 atheros_raw_receive(drv, NULL, 1358 (u8 *) custom + MGMT_FRAM_TAG_SIZE, len); 1359 } else if (strncmp(custom, "Manage.assoc_req ", 17) == 0) { 1360 /* Format: "Manage.assoc_req <frame len>" | zero padding | 1361 * frame */ 1362 int len = atoi(custom + 17); 1363 if (len < 0 || custom + MGMT_FRAM_TAG_SIZE + len > end) { 1364 wpa_printf(MSG_DEBUG, "Invalid Manage.prob_req/" 1365 "assoc_req/auth event length %d", len); 1366 return; 1367 } 1368 atheros_raw_receive(drv, NULL, 1369 (u8 *) custom + MGMT_FRAM_TAG_SIZE, len); 1370 } else if (strncmp(custom, "Manage.action ", 14) == 0) { 1371 /* Format: "Manage.assoc_req <frame len>" | zero padding | 1372 * frame */ 1373 int len = atoi(custom + 14); 1374 if (len < 0 || custom + MGMT_FRAM_TAG_SIZE + len > end) { 1375 wpa_printf(MSG_DEBUG, "Invalid Manage.prob_req/" 1376 "assoc_req/auth event length %d", len); 1377 return; 1378 } 1379 atheros_raw_receive(drv, NULL, 1380 (u8 *) custom + MGMT_FRAM_TAG_SIZE, len); 1381 } else if (strncmp(custom, "Manage.auth ", 12) == 0) { 1382 /* Format: "Manage.auth <frame len>" | zero padding | frame 1383 */ 1384 int len = atoi(custom + 12); 1385 if (len < 0 || custom + MGMT_FRAM_TAG_SIZE + len > end) { 1386 wpa_printf(MSG_DEBUG, "Invalid Manage.prob_req/" 1387 "assoc_req/auth event length %d", len); 1388 return; 1389 } 1390 atheros_raw_receive(drv, NULL, 1391 (u8 *) custom + MGMT_FRAM_TAG_SIZE, len); 1392 #endif /* CONFIG_WPS or CONFIG_IEEE80211R */ 1393 } 1394 } 1395 1396 /* 1397 * Handle size of data problem. WEXT only allows data of 256 bytes for custom 1398 * events, and p2p data can be much bigger. So the athr driver sends a small 1399 * event telling me to collect the big data with an ioctl. 1400 * On the first event, send all pending events to supplicant. 1401 */ 1402 static void fetch_pending_big_events(struct atheros_driver_data *drv) 1403 { 1404 union wpa_event_data event; 1405 const struct ieee80211_mgmt *mgmt; 1406 u8 tbuf[IW_PRIV_SIZE_MASK]; /* max size is 2047 bytes */ 1407 u16 fc, stype; 1408 struct iwreq iwr; 1409 size_t data_len; 1410 u32 freq, frame_type; 1411 1412 while (1) { 1413 os_memset(&iwr, 0, sizeof(iwr)); 1414 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 1415 1416 iwr.u.data.pointer = (void *) tbuf; 1417 iwr.u.data.length = sizeof(tbuf); 1418 iwr.u.data.flags = IEEE80211_IOC_P2P_FETCH_FRAME; 1419 1420 if (ioctl(drv->ioctl_sock, IEEE80211_IOCTL_P2P_BIG_PARAM, &iwr) 1421 < 0) { 1422 if (errno == ENOSPC) { 1423 wpa_printf(MSG_DEBUG, "%s:%d exit", 1424 __func__, __LINE__); 1425 return; 1426 } 1427 wpa_printf(MSG_DEBUG, "athr: %s: P2P_BIG_PARAM[" 1428 "P2P_FETCH_FRAME] failed: %s", 1429 __func__, strerror(errno)); 1430 return; 1431 } 1432 data_len = iwr.u.data.length; 1433 wpa_hexdump(MSG_DEBUG, "athr: P2P_FETCH_FRAME data", 1434 (u8 *) tbuf, data_len); 1435 if (data_len < sizeof(freq) + sizeof(frame_type) + 24) { 1436 wpa_printf(MSG_DEBUG, "athr: frame too short"); 1437 continue; 1438 } 1439 os_memcpy(&freq, tbuf, sizeof(freq)); 1440 os_memcpy(&frame_type, &tbuf[sizeof(freq)], 1441 sizeof(frame_type)); 1442 mgmt = (void *) &tbuf[sizeof(freq) + sizeof(frame_type)]; 1443 data_len -= sizeof(freq) + sizeof(frame_type); 1444 1445 if (frame_type == IEEE80211_EV_RX_MGMT) { 1446 fc = le_to_host16(mgmt->frame_control); 1447 stype = WLAN_FC_GET_STYPE(fc); 1448 1449 wpa_printf(MSG_DEBUG, "athr: EV_RX_MGMT stype=%u " 1450 "freq=%u len=%u", stype, freq, (int) data_len); 1451 1452 if (stype == WLAN_FC_STYPE_ACTION) { 1453 os_memset(&event, 0, sizeof(event)); 1454 event.rx_mgmt.frame = (const u8 *) mgmt; 1455 event.rx_mgmt.frame_len = data_len; 1456 wpa_supplicant_event(drv->hapd, EVENT_RX_MGMT, 1457 &event); 1458 continue; 1459 } 1460 } else { 1461 wpa_printf(MSG_DEBUG, "athr: %s unknown type %d", 1462 __func__, frame_type); 1463 continue; 1464 } 1465 } 1466 } 1467 1468 static void 1469 atheros_wireless_event_atheros_custom(struct atheros_driver_data *drv, 1470 int opcode, char *buf, int len) 1471 { 1472 switch (opcode) { 1473 case IEEE80211_EV_RX_MGMT: 1474 wpa_printf(MSG_DEBUG, "WEXT: EV_RX_MGMT"); 1475 fetch_pending_big_events(drv); 1476 break; 1477 default: 1478 break; 1479 } 1480 } 1481 1482 static void 1483 atheros_wireless_event_wireless(struct atheros_driver_data *drv, 1484 char *data, int len) 1485 { 1486 struct iw_event iwe_buf, *iwe = &iwe_buf; 1487 char *pos, *end, *custom, *buf; 1488 1489 pos = data; 1490 end = data + len; 1491 1492 while (pos + IW_EV_LCP_LEN <= end) { 1493 /* Event data may be unaligned, so make a local, aligned copy 1494 * before processing. */ 1495 memcpy(&iwe_buf, pos, IW_EV_LCP_LEN); 1496 wpa_printf(MSG_MSGDUMP, "Wireless event: cmd=0x%x len=%d", 1497 iwe->cmd, iwe->len); 1498 if (iwe->len <= IW_EV_LCP_LEN) 1499 return; 1500 1501 custom = pos + IW_EV_POINT_LEN; 1502 if (drv->we_version > 18 && 1503 (iwe->cmd == IWEVMICHAELMICFAILURE || 1504 iwe->cmd == IWEVASSOCREQIE || 1505 iwe->cmd == IWEVCUSTOM)) { 1506 /* WE-19 removed the pointer from struct iw_point */ 1507 char *dpos = (char *) &iwe_buf.u.data.length; 1508 int dlen = dpos - (char *) &iwe_buf; 1509 memcpy(dpos, pos + IW_EV_LCP_LEN, 1510 sizeof(struct iw_event) - dlen); 1511 } else { 1512 memcpy(&iwe_buf, pos, sizeof(struct iw_event)); 1513 custom += IW_EV_POINT_OFF; 1514 } 1515 1516 switch (iwe->cmd) { 1517 case IWEVEXPIRED: 1518 drv_event_disassoc(drv->hapd, 1519 (u8 *) iwe->u.addr.sa_data); 1520 break; 1521 case IWEVREGISTERED: 1522 atheros_new_sta(drv, (u8 *) iwe->u.addr.sa_data); 1523 break; 1524 case IWEVASSOCREQIE: 1525 /* Driver hack.. Use IWEVASSOCREQIE to bypass 1526 * IWEVCUSTOM size limitations. Need to handle this 1527 * just like IWEVCUSTOM. 1528 */ 1529 case IWEVCUSTOM: 1530 if (custom + iwe->u.data.length > end) 1531 return; 1532 buf = malloc(iwe->u.data.length + 1); 1533 if (buf == NULL) 1534 return; /* XXX */ 1535 memcpy(buf, custom, iwe->u.data.length); 1536 buf[iwe->u.data.length] = '\0'; 1537 1538 if (iwe->u.data.flags != 0) { 1539 atheros_wireless_event_atheros_custom( 1540 drv, (int) iwe->u.data.flags, 1541 buf, len); 1542 } else { 1543 atheros_wireless_event_wireless_custom( 1544 drv, buf, buf + iwe->u.data.length); 1545 } 1546 free(buf); 1547 break; 1548 } 1549 1550 pos += iwe->len; 1551 } 1552 } 1553 1554 1555 static void 1556 atheros_wireless_event_rtm_newlink(void *ctx, 1557 struct ifinfomsg *ifi, u8 *buf, size_t len) 1558 { 1559 struct atheros_driver_data *drv = ctx; 1560 int attrlen, rta_len; 1561 struct rtattr *attr; 1562 1563 if (ifi->ifi_index != drv->ifindex) 1564 return; 1565 1566 attrlen = len; 1567 attr = (struct rtattr *) buf; 1568 1569 rta_len = RTA_ALIGN(sizeof(struct rtattr)); 1570 while (RTA_OK(attr, attrlen)) { 1571 if (attr->rta_type == IFLA_WIRELESS) { 1572 atheros_wireless_event_wireless( 1573 drv, ((char *) attr) + rta_len, 1574 attr->rta_len - rta_len); 1575 } 1576 attr = RTA_NEXT(attr, attrlen); 1577 } 1578 } 1579 1580 1581 static int 1582 atheros_get_we_version(struct atheros_driver_data *drv) 1583 { 1584 struct iw_range *range; 1585 struct iwreq iwr; 1586 int minlen; 1587 size_t buflen; 1588 1589 drv->we_version = 0; 1590 1591 /* 1592 * Use larger buffer than struct iw_range in order to allow the 1593 * structure to grow in the future. 1594 */ 1595 buflen = sizeof(struct iw_range) + 500; 1596 range = os_zalloc(buflen); 1597 if (range == NULL) 1598 return -1; 1599 1600 memset(&iwr, 0, sizeof(iwr)); 1601 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 1602 iwr.u.data.pointer = (caddr_t) range; 1603 iwr.u.data.length = buflen; 1604 1605 minlen = ((char *) &range->enc_capa) - (char *) range + 1606 sizeof(range->enc_capa); 1607 1608 if (ioctl(drv->ioctl_sock, SIOCGIWRANGE, &iwr) < 0) { 1609 perror("ioctl[SIOCGIWRANGE]"); 1610 free(range); 1611 return -1; 1612 } else if (iwr.u.data.length >= minlen && 1613 range->we_version_compiled >= 18) { 1614 wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: WE(compiled)=%d " 1615 "WE(source)=%d enc_capa=0x%x", 1616 range->we_version_compiled, 1617 range->we_version_source, 1618 range->enc_capa); 1619 drv->we_version = range->we_version_compiled; 1620 } 1621 1622 os_free(range); 1623 return 0; 1624 } 1625 1626 1627 static int 1628 atheros_wireless_event_init(struct atheros_driver_data *drv) 1629 { 1630 struct netlink_config *cfg; 1631 1632 atheros_get_we_version(drv); 1633 1634 cfg = os_zalloc(sizeof(*cfg)); 1635 if (cfg == NULL) 1636 return -1; 1637 cfg->ctx = drv; 1638 cfg->newlink_cb = atheros_wireless_event_rtm_newlink; 1639 drv->netlink = netlink_init(cfg); 1640 if (drv->netlink == NULL) { 1641 os_free(cfg); 1642 return -1; 1643 } 1644 1645 return 0; 1646 } 1647 1648 1649 static int 1650 atheros_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t data_len, 1651 int encrypt, const u8 *own_addr, u32 flags) 1652 { 1653 struct atheros_driver_data *drv = priv; 1654 unsigned char buf[3000]; 1655 unsigned char *bp = buf; 1656 struct l2_ethhdr *eth; 1657 size_t len; 1658 int status; 1659 1660 /* 1661 * Prepend the Ethernet header. If the caller left us 1662 * space at the front we could just insert it but since 1663 * we don't know we copy to a local buffer. Given the frequency 1664 * and size of frames this probably doesn't matter. 1665 */ 1666 len = data_len + sizeof(struct l2_ethhdr); 1667 if (len > sizeof(buf)) { 1668 bp = malloc(len); 1669 if (bp == NULL) { 1670 printf("EAPOL frame discarded, cannot malloc temp " 1671 "buffer of size %lu!\n", (unsigned long) len); 1672 return -1; 1673 } 1674 } 1675 eth = (struct l2_ethhdr *) bp; 1676 memcpy(eth->h_dest, addr, ETH_ALEN); 1677 memcpy(eth->h_source, own_addr, ETH_ALEN); 1678 eth->h_proto = host_to_be16(ETH_P_EAPOL); 1679 memcpy(eth+1, data, data_len); 1680 1681 wpa_hexdump(MSG_MSGDUMP, "TX EAPOL", bp, len); 1682 1683 status = l2_packet_send(drv->sock_xmit, addr, ETH_P_EAPOL, bp, len); 1684 1685 if (bp != buf) 1686 free(bp); 1687 return status; 1688 } 1689 1690 static void 1691 handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len) 1692 { 1693 struct atheros_driver_data *drv = ctx; 1694 drv_event_eapol_rx(drv->hapd, src_addr, buf + sizeof(struct l2_ethhdr), 1695 len - sizeof(struct l2_ethhdr)); 1696 } 1697 1698 static void * 1699 atheros_init(struct hostapd_data *hapd, struct wpa_init_params *params) 1700 { 1701 struct atheros_driver_data *drv; 1702 struct ifreq ifr; 1703 struct iwreq iwr; 1704 char brname[IFNAMSIZ]; 1705 1706 drv = os_zalloc(sizeof(struct atheros_driver_data)); 1707 if (drv == NULL) { 1708 printf("Could not allocate memory for atheros driver data\n"); 1709 return NULL; 1710 } 1711 1712 drv->hapd = hapd; 1713 drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0); 1714 if (drv->ioctl_sock < 0) { 1715 perror("socket[PF_INET,SOCK_DGRAM]"); 1716 goto bad; 1717 } 1718 memcpy(drv->iface, params->ifname, sizeof(drv->iface)); 1719 1720 memset(&ifr, 0, sizeof(ifr)); 1721 os_strlcpy(ifr.ifr_name, drv->iface, sizeof(ifr.ifr_name)); 1722 if (ioctl(drv->ioctl_sock, SIOCGIFINDEX, &ifr) != 0) { 1723 perror("ioctl(SIOCGIFINDEX)"); 1724 goto bad; 1725 } 1726 drv->ifindex = ifr.ifr_ifindex; 1727 1728 drv->sock_xmit = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL, 1729 handle_read, drv, 1); 1730 if (drv->sock_xmit == NULL) 1731 goto bad; 1732 if (l2_packet_get_own_addr(drv->sock_xmit, params->own_addr)) 1733 goto bad; 1734 os_memcpy(drv->own_addr, params->own_addr, ETH_ALEN); 1735 if (params->bridge[0]) { 1736 wpa_printf(MSG_DEBUG, "Configure bridge %s for EAPOL traffic.", 1737 params->bridge[0]); 1738 drv->sock_recv = l2_packet_init(params->bridge[0], NULL, 1739 ETH_P_EAPOL, handle_read, drv, 1740 1); 1741 if (drv->sock_recv == NULL) 1742 goto bad; 1743 } else if (linux_br_get(brname, drv->iface) == 0) { 1744 wpa_printf(MSG_DEBUG, "Interface in bridge %s; configure for " 1745 "EAPOL receive", brname); 1746 drv->sock_recv = l2_packet_init(brname, NULL, ETH_P_EAPOL, 1747 handle_read, drv, 1); 1748 if (drv->sock_recv == NULL) 1749 goto bad; 1750 } else 1751 drv->sock_recv = drv->sock_xmit; 1752 1753 memset(&iwr, 0, sizeof(iwr)); 1754 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 1755 1756 iwr.u.mode = IW_MODE_MASTER; 1757 1758 if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0) { 1759 perror("ioctl[SIOCSIWMODE]"); 1760 printf("Could not set interface to master mode!\n"); 1761 goto bad; 1762 } 1763 1764 /* mark down during setup */ 1765 linux_set_iface_flags(drv->ioctl_sock, drv->iface, 0); 1766 atheros_set_privacy(drv, 0); /* default to no privacy */ 1767 1768 if (atheros_receive_pkt(drv)) 1769 goto bad; 1770 1771 if (atheros_wireless_event_init(drv)) 1772 goto bad; 1773 1774 return drv; 1775 bad: 1776 atheros_reset_appfilter(drv); 1777 if (drv->sock_raw) 1778 l2_packet_deinit(drv->sock_raw); 1779 if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit) 1780 l2_packet_deinit(drv->sock_recv); 1781 if (drv->sock_xmit != NULL) 1782 l2_packet_deinit(drv->sock_xmit); 1783 if (drv->ioctl_sock >= 0) 1784 close(drv->ioctl_sock); 1785 if (drv != NULL) 1786 free(drv); 1787 return NULL; 1788 } 1789 1790 1791 static void 1792 atheros_deinit(void *priv) 1793 { 1794 struct atheros_driver_data *drv = priv; 1795 1796 atheros_reset_appfilter(drv); 1797 netlink_deinit(drv->netlink); 1798 (void) linux_set_iface_flags(drv->ioctl_sock, drv->iface, 0); 1799 if (drv->ioctl_sock >= 0) 1800 close(drv->ioctl_sock); 1801 if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit) 1802 l2_packet_deinit(drv->sock_recv); 1803 if (drv->sock_xmit != NULL) 1804 l2_packet_deinit(drv->sock_xmit); 1805 if (drv->sock_raw) 1806 l2_packet_deinit(drv->sock_raw); 1807 wpabuf_free(drv->wpa_ie); 1808 wpabuf_free(drv->wps_beacon_ie); 1809 wpabuf_free(drv->wps_probe_resp_ie); 1810 free(drv); 1811 } 1812 1813 static int 1814 atheros_set_ssid(void *priv, const u8 *buf, int len) 1815 { 1816 struct atheros_driver_data *drv = priv; 1817 struct iwreq iwr; 1818 1819 memset(&iwr, 0, sizeof(iwr)); 1820 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 1821 iwr.u.essid.flags = 1; /* SSID active */ 1822 iwr.u.essid.pointer = (caddr_t) buf; 1823 iwr.u.essid.length = len + 1; 1824 1825 if (ioctl(drv->ioctl_sock, SIOCSIWESSID, &iwr) < 0) { 1826 perror("ioctl[SIOCSIWESSID]"); 1827 printf("len=%d\n", len); 1828 return -1; 1829 } 1830 return 0; 1831 } 1832 1833 static int 1834 atheros_get_ssid(void *priv, u8 *buf, int len) 1835 { 1836 struct atheros_driver_data *drv = priv; 1837 struct iwreq iwr; 1838 int ret = 0; 1839 1840 memset(&iwr, 0, sizeof(iwr)); 1841 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 1842 iwr.u.essid.pointer = (caddr_t) buf; 1843 iwr.u.essid.length = (len > IW_ESSID_MAX_SIZE) ? 1844 IW_ESSID_MAX_SIZE : len; 1845 1846 if (ioctl(drv->ioctl_sock, SIOCGIWESSID, &iwr) < 0) { 1847 perror("ioctl[SIOCGIWESSID]"); 1848 ret = -1; 1849 } else 1850 ret = iwr.u.essid.length; 1851 1852 return ret; 1853 } 1854 1855 static int 1856 atheros_set_countermeasures(void *priv, int enabled) 1857 { 1858 struct atheros_driver_data *drv = priv; 1859 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled); 1860 return set80211param(drv, IEEE80211_PARAM_COUNTERMEASURES, enabled); 1861 } 1862 1863 static int 1864 atheros_commit(void *priv) 1865 { 1866 struct atheros_driver_data *drv = priv; 1867 return linux_set_iface_flags(drv->ioctl_sock, drv->iface, 1); 1868 } 1869 1870 static int atheros_set_authmode(void *priv, int auth_algs) 1871 { 1872 int authmode; 1873 1874 if ((auth_algs & WPA_AUTH_ALG_OPEN) && 1875 (auth_algs & WPA_AUTH_ALG_SHARED)) 1876 authmode = IEEE80211_AUTH_AUTO; 1877 else if (auth_algs & WPA_AUTH_ALG_OPEN) 1878 authmode = IEEE80211_AUTH_OPEN; 1879 else if (auth_algs & WPA_AUTH_ALG_SHARED) 1880 authmode = IEEE80211_AUTH_SHARED; 1881 else 1882 return -1; 1883 1884 return set80211param(priv, IEEE80211_PARAM_AUTHMODE, authmode); 1885 } 1886 1887 static int atheros_set_ap(void *priv, struct wpa_driver_ap_params *params) 1888 { 1889 /* 1890 * TODO: Use this to replace set_authmode, set_privacy, set_ieee8021x, 1891 * set_generic_elem, and hapd_set_ssid. 1892 */ 1893 1894 wpa_printf(MSG_DEBUG, "atheros: set_ap - pairwise_ciphers=0x%x " 1895 "group_cipher=0x%x key_mgmt_suites=0x%x auth_algs=0x%x " 1896 "wpa_version=0x%x privacy=%d interworking=%d", 1897 params->pairwise_ciphers, params->group_cipher, 1898 params->key_mgmt_suites, params->auth_algs, 1899 params->wpa_version, params->privacy, params->interworking); 1900 wpa_hexdump_ascii(MSG_DEBUG, "atheros: SSID", 1901 params->ssid, params->ssid_len); 1902 if (params->hessid) 1903 wpa_printf(MSG_DEBUG, "atheros: HESSID " MACSTR, 1904 MAC2STR(params->hessid)); 1905 wpa_hexdump_buf(MSG_DEBUG, "atheros: beacon_ies", 1906 params->beacon_ies); 1907 wpa_hexdump_buf(MSG_DEBUG, "atheros: proberesp_ies", 1908 params->proberesp_ies); 1909 wpa_hexdump_buf(MSG_DEBUG, "atheros: assocresp_ies", 1910 params->assocresp_ies); 1911 1912 #if defined(CONFIG_HS20) && defined(IEEE80211_PARAM_OSEN) 1913 if (params->osen) { 1914 struct wpa_bss_params bss_params; 1915 1916 os_memset(&bss_params, 0, sizeof(struct wpa_bss_params)); 1917 bss_params.enabled = 1; 1918 bss_params.wpa = 2; 1919 bss_params.wpa_pairwise = WPA_CIPHER_CCMP; 1920 bss_params.wpa_group = WPA_CIPHER_CCMP; 1921 bss_params.ieee802_1x = 1; 1922 1923 if (atheros_set_privacy(priv, 1) || 1924 set80211param(priv, IEEE80211_PARAM_OSEN, 1)) 1925 return -1; 1926 1927 return atheros_set_ieee8021x(priv, &bss_params); 1928 } 1929 #endif /* CONFIG_HS20 && IEEE80211_PARAM_OSEN */ 1930 1931 return 0; 1932 } 1933 1934 1935 #ifdef CONFIG_IEEE80211R 1936 1937 static int atheros_send_mgmt(void *priv, const u8 *frm, size_t data_len, 1938 int noack) 1939 { 1940 struct atheros_driver_data *drv = priv; 1941 u8 buf[1510]; 1942 const struct ieee80211_mgmt *mgmt; 1943 struct ieee80211req_mgmtbuf *mgmt_frm; 1944 1945 mgmt = (const struct ieee80211_mgmt *) frm; 1946 wpa_printf(MSG_DEBUG, "%s frmlen = %lu " MACSTR, __func__, 1947 (unsigned long) data_len, MAC2STR(mgmt->da)); 1948 mgmt_frm = (struct ieee80211req_mgmtbuf *) buf; 1949 memcpy(mgmt_frm->macaddr, (u8 *)mgmt->da, IEEE80211_ADDR_LEN); 1950 mgmt_frm->buflen = data_len; 1951 if (&mgmt_frm->buf[0] + data_len > buf + sizeof(buf)) { 1952 wpa_printf(MSG_INFO, "atheros: Too long frame for " 1953 "atheros_send_mgmt (%u)", (unsigned int) data_len); 1954 return -1; 1955 } 1956 os_memcpy(&mgmt_frm->buf[0], frm, data_len); 1957 return set80211priv(drv, IEEE80211_IOCTL_SEND_MGMT, mgmt_frm, 1958 sizeof(struct ieee80211req_mgmtbuf) + data_len); 1959 } 1960 1961 1962 static int atheros_add_tspec(void *priv, const u8 *addr, u8 *tspec_ie, 1963 size_t tspec_ielen) 1964 { 1965 struct atheros_driver_data *drv = priv; 1966 int retv; 1967 struct ieee80211req_res req; 1968 struct ieee80211req_res_addts *addts = &req.u.addts; 1969 1970 wpa_printf(MSG_DEBUG, "%s", __func__); 1971 req.type = IEEE80211_RESREQ_ADDTS; 1972 os_memcpy(&req.macaddr[0], addr, IEEE80211_ADDR_LEN); 1973 os_memcpy(addts->tspecie, tspec_ie, tspec_ielen); 1974 retv = set80211priv(drv, IEEE80211_IOCTL_RES_REQ, &req, 1975 sizeof(struct ieee80211req_res)); 1976 if (retv < 0) { 1977 wpa_printf(MSG_DEBUG, "%s IEEE80211_IOCTL_RES_REQ FAILED " 1978 "retv = %d", __func__, retv); 1979 return -1; 1980 } 1981 os_memcpy(tspec_ie, addts->tspecie, tspec_ielen); 1982 return addts->status; 1983 } 1984 1985 1986 static int atheros_add_sta_node(void *priv, const u8 *addr, u16 auth_alg) 1987 { 1988 struct atheros_driver_data *drv = priv; 1989 struct ieee80211req_res req; 1990 struct ieee80211req_res_addnode *addnode = &req.u.addnode; 1991 1992 wpa_printf(MSG_DEBUG, "%s", __func__); 1993 req.type = IEEE80211_RESREQ_ADDNODE; 1994 os_memcpy(&req.macaddr[0], addr, IEEE80211_ADDR_LEN); 1995 addnode->auth_alg = auth_alg; 1996 return set80211priv(drv, IEEE80211_IOCTL_RES_REQ, &req, 1997 sizeof(struct ieee80211req_res)); 1998 } 1999 2000 #endif /* CONFIG_IEEE80211R */ 2001 2002 2003 /* Use only to set a big param, get will not work. */ 2004 static int 2005 set80211big(struct atheros_driver_data *drv, int op, const void *data, int len) 2006 { 2007 struct iwreq iwr; 2008 2009 os_memset(&iwr, 0, sizeof(iwr)); 2010 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 2011 2012 iwr.u.data.pointer = (void *) data; 2013 iwr.u.data.length = len; 2014 iwr.u.data.flags = op; 2015 wpa_printf(MSG_DEBUG, "%s: op=0x%x=%d (%s) len=0x%x", 2016 __func__, op, op, athr_get_param_name(op), len); 2017 2018 if (ioctl(drv->ioctl_sock, IEEE80211_IOCTL_P2P_BIG_PARAM, &iwr) < 0) { 2019 wpa_printf(MSG_DEBUG, "%s: op=0x%x (%s) subop=0x%x=%d " 2020 "value=0x%x,0x%x failed: %d (%s)", 2021 __func__, op, athr_get_ioctl_name(op), iwr.u.mode, 2022 iwr.u.mode, iwr.u.data.length, 2023 iwr.u.data.flags, errno, strerror(errno)); 2024 return -1; 2025 } 2026 return 0; 2027 } 2028 2029 2030 static int atheros_send_action(void *priv, unsigned int freq, 2031 unsigned int wait, 2032 const u8 *dst, const u8 *src, 2033 const u8 *bssid, 2034 const u8 *data, size_t data_len, int no_cck) 2035 { 2036 struct atheros_driver_data *drv = priv; 2037 struct ieee80211_p2p_send_action *act; 2038 int res; 2039 2040 act = os_zalloc(sizeof(*act) + data_len); 2041 if (act == NULL) 2042 return -1; 2043 act->freq = freq; 2044 os_memcpy(act->dst_addr, dst, ETH_ALEN); 2045 os_memcpy(act->src_addr, src, ETH_ALEN); 2046 os_memcpy(act->bssid, bssid, ETH_ALEN); 2047 os_memcpy(act + 1, data, data_len); 2048 wpa_printf(MSG_DEBUG, "%s: freq=%d, wait=%u, dst=" MACSTR ", src=" 2049 MACSTR ", bssid=" MACSTR, 2050 __func__, act->freq, wait, MAC2STR(act->dst_addr), 2051 MAC2STR(act->src_addr), MAC2STR(act->bssid)); 2052 wpa_hexdump(MSG_MSGDUMP, "athr: act", (u8 *) act, sizeof(*act)); 2053 wpa_hexdump(MSG_MSGDUMP, "athr: data", data, data_len); 2054 2055 res = set80211big(drv, IEEE80211_IOC_P2P_SEND_ACTION, 2056 act, sizeof(*act) + data_len); 2057 os_free(act); 2058 return res; 2059 } 2060 2061 2062 #if defined(CONFIG_WNM) && defined(IEEE80211_APPIE_FRAME_WNM) 2063 static int athr_wnm_tfs(struct atheros_driver_data *drv, const u8* peer, 2064 u8 *ie, u16 *len, enum wnm_oper oper) 2065 { 2066 #define IEEE80211_APPIE_MAX 1024 /* max appie buffer size */ 2067 u8 buf[IEEE80211_APPIE_MAX]; 2068 struct ieee80211req_getset_appiebuf *tfs_ie; 2069 u16 val; 2070 2071 wpa_printf(MSG_DEBUG, "atheros: ifname=%s, WNM TFS IE oper=%d " MACSTR, 2072 drv->iface, oper, MAC2STR(peer)); 2073 2074 switch (oper) { 2075 case WNM_SLEEP_TFS_REQ_IE_SET: 2076 if (*len > IEEE80211_APPIE_MAX - 2077 sizeof(struct ieee80211req_getset_appiebuf)) { 2078 wpa_printf(MSG_DEBUG, "TFS Req IE(s) too large"); 2079 return -1; 2080 } 2081 tfs_ie = (struct ieee80211req_getset_appiebuf *) buf; 2082 tfs_ie->app_frmtype = IEEE80211_APPIE_FRAME_WNM; 2083 tfs_ie->app_buflen = ETH_ALEN + 2 + 2 + *len; 2084 2085 /* Command header for driver */ 2086 os_memcpy(&(tfs_ie->app_buf[0]), peer, ETH_ALEN); 2087 val = oper; 2088 os_memcpy(&(tfs_ie->app_buf[0]) + ETH_ALEN, &val, 2); 2089 val = *len; 2090 os_memcpy(&(tfs_ie->app_buf[0]) + ETH_ALEN + 2, &val, 2); 2091 2092 /* copy the ie */ 2093 os_memcpy(&(tfs_ie->app_buf[0]) + ETH_ALEN + 2 + 2, ie, *len); 2094 2095 if (set80211priv(drv, IEEE80211_IOCTL_SET_APPIEBUF, tfs_ie, 2096 IEEE80211_APPIE_MAX)) { 2097 wpa_printf(MSG_DEBUG, "%s: Failed to set WNM TFS IE: " 2098 "%s", __func__, strerror(errno)); 2099 return -1; 2100 } 2101 break; 2102 case WNM_SLEEP_TFS_RESP_IE_ADD: 2103 tfs_ie = (struct ieee80211req_getset_appiebuf *) buf; 2104 tfs_ie->app_frmtype = IEEE80211_APPIE_FRAME_WNM; 2105 tfs_ie->app_buflen = IEEE80211_APPIE_MAX - 2106 sizeof(struct ieee80211req_getset_appiebuf); 2107 /* Command header for driver */ 2108 os_memcpy(&(tfs_ie->app_buf[0]), peer, ETH_ALEN); 2109 val = oper; 2110 os_memcpy(&(tfs_ie->app_buf[0]) + ETH_ALEN, &val, 2); 2111 val = 0; 2112 os_memcpy(&(tfs_ie->app_buf[0]) + ETH_ALEN + 2, &val, 2); 2113 2114 if (set80211priv(drv, IEEE80211_IOCTL_GET_APPIEBUF, tfs_ie, 2115 IEEE80211_APPIE_MAX)) { 2116 wpa_printf(MSG_DEBUG, "%s: Failed to get WNM TFS IE: " 2117 "%s", __func__, strerror(errno)); 2118 return -1; 2119 } 2120 2121 *len = tfs_ie->app_buflen; 2122 os_memcpy(ie, &(tfs_ie->app_buf[0]), *len); 2123 wpa_printf(MSG_DEBUG, "atheros: %c len=%d", tfs_ie->app_buf[0], 2124 *len); 2125 break; 2126 case WNM_SLEEP_TFS_RESP_IE_NONE: 2127 *len = 0; 2128 break; 2129 case WNM_SLEEP_TFS_IE_DEL: 2130 tfs_ie = (struct ieee80211req_getset_appiebuf *) buf; 2131 tfs_ie->app_frmtype = IEEE80211_APPIE_FRAME_WNM; 2132 tfs_ie->app_buflen = IEEE80211_APPIE_MAX - 2133 sizeof(struct ieee80211req_getset_appiebuf); 2134 /* Command header for driver */ 2135 os_memcpy(&(tfs_ie->app_buf[0]), peer, ETH_ALEN); 2136 val = oper; 2137 os_memcpy(&(tfs_ie->app_buf[0]) + ETH_ALEN, &val, 2); 2138 val = 0; 2139 os_memcpy(&(tfs_ie->app_buf[0]) + ETH_ALEN + 2, &val, 2); 2140 2141 if (set80211priv(drv, IEEE80211_IOCTL_SET_APPIEBUF, tfs_ie, 2142 IEEE80211_APPIE_MAX)) { 2143 wpa_printf(MSG_DEBUG, "%s: Failed to set WNM TFS IE: " 2144 "%s", __func__, strerror(errno)); 2145 return -1; 2146 } 2147 break; 2148 default: 2149 wpa_printf(MSG_DEBUG, "Unsupported TFS oper %d", oper); 2150 break; 2151 } 2152 2153 return 0; 2154 } 2155 2156 2157 static int atheros_wnm_sleep(struct atheros_driver_data *drv, 2158 const u8 *peer, enum wnm_oper oper) 2159 { 2160 u8 *data, *pos; 2161 size_t dlen; 2162 int ret; 2163 u16 val; 2164 2165 wpa_printf(MSG_DEBUG, "atheros: WNM-Sleep Oper %d, " MACSTR, 2166 oper, MAC2STR(peer)); 2167 2168 dlen = ETH_ALEN + 2 + 2; 2169 data = os_malloc(dlen); 2170 if (data == NULL) 2171 return -1; 2172 2173 /* Command header for driver */ 2174 pos = data; 2175 os_memcpy(pos, peer, ETH_ALEN); 2176 pos += ETH_ALEN; 2177 2178 val = oper; 2179 os_memcpy(pos, &val, 2); 2180 pos += 2; 2181 2182 val = 0; 2183 os_memcpy(pos, &val, 2); 2184 2185 ret = atheros_set_wps_ie(drv, data, dlen, IEEE80211_APPIE_FRAME_WNM); 2186 2187 os_free(data); 2188 2189 return ret; 2190 } 2191 2192 2193 static int atheros_wnm_oper(void *priv, enum wnm_oper oper, const u8 *peer, 2194 u8 *buf, u16 *buf_len) 2195 { 2196 struct atheros_driver_data *drv = priv; 2197 2198 switch (oper) { 2199 case WNM_SLEEP_ENTER_CONFIRM: 2200 case WNM_SLEEP_ENTER_FAIL: 2201 case WNM_SLEEP_EXIT_CONFIRM: 2202 case WNM_SLEEP_EXIT_FAIL: 2203 return atheros_wnm_sleep(drv, peer, oper); 2204 case WNM_SLEEP_TFS_REQ_IE_SET: 2205 case WNM_SLEEP_TFS_RESP_IE_ADD: 2206 case WNM_SLEEP_TFS_RESP_IE_NONE: 2207 case WNM_SLEEP_TFS_IE_DEL: 2208 return athr_wnm_tfs(drv, peer, buf, buf_len, oper); 2209 default: 2210 wpa_printf(MSG_DEBUG, "atheros: Unsupported WNM operation %d", 2211 oper); 2212 return -1; 2213 } 2214 } 2215 #endif /* CONFIG_WNM && IEEE80211_APPIE_FRAME_WNM */ 2216 2217 2218 const struct wpa_driver_ops wpa_driver_atheros_ops = { 2219 .name = "atheros", 2220 .hapd_init = atheros_init, 2221 .hapd_deinit = atheros_deinit, 2222 .set_ieee8021x = atheros_set_ieee8021x, 2223 .set_privacy = atheros_set_privacy, 2224 .set_key = atheros_set_key, 2225 .get_seqnum = atheros_get_seqnum, 2226 .flush = atheros_flush, 2227 .set_generic_elem = atheros_set_opt_ie, 2228 .sta_set_flags = atheros_sta_set_flags, 2229 .read_sta_data = atheros_read_sta_driver_data, 2230 .hapd_send_eapol = atheros_send_eapol, 2231 .sta_disassoc = atheros_sta_disassoc, 2232 .sta_deauth = atheros_sta_deauth, 2233 .hapd_set_ssid = atheros_set_ssid, 2234 .hapd_get_ssid = atheros_get_ssid, 2235 .set_countermeasures = atheros_set_countermeasures, 2236 .sta_clear_stats = atheros_sta_clear_stats, 2237 .commit = atheros_commit, 2238 .set_ap_wps_ie = atheros_set_ap_wps_ie, 2239 .set_authmode = atheros_set_authmode, 2240 .set_ap = atheros_set_ap, 2241 #ifdef CONFIG_IEEE80211R 2242 .sta_assoc = atheros_sta_assoc, 2243 .sta_auth = atheros_sta_auth, 2244 .send_mlme = atheros_send_mgmt, 2245 .add_tspec = atheros_add_tspec, 2246 .add_sta_node = atheros_add_sta_node, 2247 #endif /* CONFIG_IEEE80211R */ 2248 .send_action = atheros_send_action, 2249 #if defined(CONFIG_WNM) && defined(IEEE80211_APPIE_FRAME_WNM) 2250 .wnm_oper = atheros_wnm_oper, 2251 #endif /* CONFIG_WNM && IEEE80211_APPIE_FRAME_WNM */ 2252 .set_qos_map = atheros_set_qos_map, 2253 }; 2254