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