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