driver_atheros.c revision 04949598a23f501be6eec21697465fd46a28840a
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#ifndef _BYTE_ORDER 18#ifdef WORDS_BIGENDIAN 19#define _BYTE_ORDER _BIG_ENDIAN 20#else 21#define _BYTE_ORDER _LITTLE_ENDIAN 22#endif 23#endif /* _BYTE_ORDER */ 24 25/* 26 * Note, the ATH_WPS_IE setting must match with the driver build.. If the 27 * driver does not include this, the IEEE80211_IOCTL_GETWPAIE ioctl will fail. 28 */ 29#define ATH_WPS_IE 30 31#include "ieee80211_external.h" 32 33 34#ifdef CONFIG_WPS 35#include <netpacket/packet.h> 36#endif /* CONFIG_WPS */ 37 38#ifndef ETH_P_80211_RAW 39#define ETH_P_80211_RAW 0x0019 40#endif 41 42#include "linux_wext.h" 43 44#include "driver.h" 45#include "eloop.h" 46#include "priv_netlink.h" 47#include "l2_packet/l2_packet.h" 48#include "common/ieee802_11_defs.h" 49#include "netlink.h" 50#include "linux_ioctl.h" 51 52 53struct atheros_driver_data { 54 struct hostapd_data *hapd; /* back pointer */ 55 56 char iface[IFNAMSIZ + 1]; 57 int ifindex; 58 struct l2_packet_data *sock_xmit; /* raw packet xmit socket */ 59 struct l2_packet_data *sock_recv; /* raw packet recv socket */ 60 int ioctl_sock; /* socket for ioctl() use */ 61 struct netlink_data *netlink; 62 int we_version; 63 u8 acct_mac[ETH_ALEN]; 64 struct hostap_sta_driver_data acct_data; 65 66 struct l2_packet_data *sock_raw; /* raw 802.11 management frames */ 67 struct wpabuf *wpa_ie; 68 struct wpabuf *wps_beacon_ie; 69 struct wpabuf *wps_probe_resp_ie; 70 u8 own_addr[ETH_ALEN]; 71}; 72 73static int atheros_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, 74 int reason_code); 75static int atheros_set_privacy(void *priv, int enabled); 76 77static const char * athr_get_ioctl_name(int op) 78{ 79 switch (op) { 80 case IEEE80211_IOCTL_SETPARAM: 81 return "SETPARAM"; 82 case IEEE80211_IOCTL_GETPARAM: 83 return "GETPARAM"; 84 case IEEE80211_IOCTL_SETKEY: 85 return "SETKEY"; 86 case IEEE80211_IOCTL_SETWMMPARAMS: 87 return "SETWMMPARAMS"; 88 case IEEE80211_IOCTL_DELKEY: 89 return "DELKEY"; 90 case IEEE80211_IOCTL_GETWMMPARAMS: 91 return "GETWMMPARAMS"; 92 case IEEE80211_IOCTL_SETMLME: 93 return "SETMLME"; 94 case IEEE80211_IOCTL_GETCHANINFO: 95 return "GETCHANINFO"; 96 case IEEE80211_IOCTL_SETOPTIE: 97 return "SETOPTIE"; 98 case IEEE80211_IOCTL_GETOPTIE: 99 return "GETOPTIE"; 100 case IEEE80211_IOCTL_ADDMAC: 101 return "ADDMAC"; 102 case IEEE80211_IOCTL_DELMAC: 103 return "DELMAC"; 104 case IEEE80211_IOCTL_GETCHANLIST: 105 return "GETCHANLIST"; 106 case IEEE80211_IOCTL_SETCHANLIST: 107 return "SETCHANLIST"; 108 case IEEE80211_IOCTL_KICKMAC: 109 return "KICKMAC"; 110 case IEEE80211_IOCTL_CHANSWITCH: 111 return "CHANSWITCH"; 112 case IEEE80211_IOCTL_GETMODE: 113 return "GETMODE"; 114 case IEEE80211_IOCTL_SETMODE: 115 return "SETMODE"; 116 case IEEE80211_IOCTL_GET_APPIEBUF: 117 return "GET_APPIEBUF"; 118 case IEEE80211_IOCTL_SET_APPIEBUF: 119 return "SET_APPIEBUF"; 120 case IEEE80211_IOCTL_SET_ACPARAMS: 121 return "SET_ACPARAMS"; 122 case IEEE80211_IOCTL_FILTERFRAME: 123 return "FILTERFRAME"; 124 case IEEE80211_IOCTL_SET_RTPARAMS: 125 return "SET_RTPARAMS"; 126 case IEEE80211_IOCTL_SET_MEDENYENTRY: 127 return "SET_MEDENYENTRY"; 128 case IEEE80211_IOCTL_GET_MACADDR: 129 return "GET_MACADDR"; 130 case IEEE80211_IOCTL_SET_HBRPARAMS: 131 return "SET_HBRPARAMS"; 132 case IEEE80211_IOCTL_SET_RXTIMEOUT: 133 return "SET_RXTIMEOUT"; 134 case IEEE80211_IOCTL_STA_STATS: 135 return "STA_STATS"; 136 case IEEE80211_IOCTL_GETWPAIE: 137 return "GETWPAIE"; 138 default: 139 return "??"; 140 } 141} 142 143 144static const char * athr_get_param_name(int op) 145{ 146 switch (op) { 147 case IEEE80211_IOC_MCASTCIPHER: 148 return "MCASTCIPHER"; 149 case IEEE80211_PARAM_MCASTKEYLEN: 150 return "MCASTKEYLEN"; 151 case IEEE80211_PARAM_UCASTCIPHERS: 152 return "UCASTCIPHERS"; 153 case IEEE80211_PARAM_KEYMGTALGS: 154 return "KEYMGTALGS"; 155 case IEEE80211_PARAM_RSNCAPS: 156 return "RSNCAPS"; 157 case IEEE80211_PARAM_WPA: 158 return "WPA"; 159 case IEEE80211_PARAM_AUTHMODE: 160 return "AUTHMODE"; 161 case IEEE80211_PARAM_PRIVACY: 162 return "PRIVACY"; 163 case IEEE80211_PARAM_COUNTERMEASURES: 164 return "COUNTERMEASURES"; 165 default: 166 return "??"; 167 } 168} 169 170 171static int 172set80211priv(struct atheros_driver_data *drv, int op, void *data, int len) 173{ 174 struct iwreq iwr; 175 int do_inline = len < IFNAMSIZ; 176 177 /* Certain ioctls must use the non-inlined method */ 178 if (op == IEEE80211_IOCTL_SET_APPIEBUF || 179 op == IEEE80211_IOCTL_FILTERFRAME) 180 do_inline = 0; 181 182 memset(&iwr, 0, sizeof(iwr)); 183 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 184 if (do_inline) { 185 /* 186 * Argument data fits inline; put it there. 187 */ 188 memcpy(iwr.u.name, data, len); 189 } else { 190 /* 191 * Argument data too big for inline transfer; setup a 192 * parameter block instead; the kernel will transfer 193 * the data for the driver. 194 */ 195 iwr.u.data.pointer = data; 196 iwr.u.data.length = len; 197 } 198 199 if (ioctl(drv->ioctl_sock, op, &iwr) < 0) { 200 wpa_printf(MSG_DEBUG, "atheros: %s: %s: ioctl op=0x%x " 201 "(%s) len=%d failed: %d (%s)", 202 __func__, drv->iface, op, 203 athr_get_ioctl_name(op), 204 len, errno, strerror(errno)); 205 return -1; 206 } 207 return 0; 208} 209 210static int 211set80211param(struct atheros_driver_data *drv, int op, int arg) 212{ 213 struct iwreq iwr; 214 215 memset(&iwr, 0, sizeof(iwr)); 216 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 217 iwr.u.mode = op; 218 memcpy(iwr.u.name+sizeof(__u32), &arg, sizeof(arg)); 219 220 if (ioctl(drv->ioctl_sock, IEEE80211_IOCTL_SETPARAM, &iwr) < 0) { 221 perror("ioctl[IEEE80211_IOCTL_SETPARAM]"); 222 wpa_printf(MSG_DEBUG, "%s: %s: Failed to set parameter (op %d " 223 "(%s) arg %d)", __func__, drv->iface, op, 224 athr_get_param_name(op), arg); 225 return -1; 226 } 227 return 0; 228} 229 230#ifndef CONFIG_NO_STDOUT_DEBUG 231static const char * 232ether_sprintf(const u8 *addr) 233{ 234 static char buf[sizeof(MACSTR)]; 235 236 if (addr != NULL) 237 snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr)); 238 else 239 snprintf(buf, sizeof(buf), MACSTR, 0,0,0,0,0,0); 240 return buf; 241} 242#endif /* CONFIG_NO_STDOUT_DEBUG */ 243 244/* 245 * Configure WPA parameters. 246 */ 247static int 248atheros_configure_wpa(struct atheros_driver_data *drv, 249 struct wpa_bss_params *params) 250{ 251 int v; 252 253 switch (params->wpa_group) { 254 case WPA_CIPHER_CCMP: 255 v = IEEE80211_CIPHER_AES_CCM; 256 break; 257 case WPA_CIPHER_TKIP: 258 v = IEEE80211_CIPHER_TKIP; 259 break; 260 case WPA_CIPHER_WEP104: 261 v = IEEE80211_CIPHER_WEP; 262 break; 263 case WPA_CIPHER_WEP40: 264 v = IEEE80211_CIPHER_WEP; 265 break; 266 case WPA_CIPHER_NONE: 267 v = IEEE80211_CIPHER_NONE; 268 break; 269 default: 270 wpa_printf(MSG_ERROR, "Unknown group key cipher %u", 271 params->wpa_group); 272 return -1; 273 } 274 wpa_printf(MSG_DEBUG, "%s: group key cipher=%d", __func__, v); 275 if (set80211param(drv, IEEE80211_PARAM_MCASTCIPHER, v)) { 276 printf("Unable to set group key cipher to %u\n", v); 277 return -1; 278 } 279 if (v == IEEE80211_CIPHER_WEP) { 280 /* key length is done only for specific ciphers */ 281 v = (params->wpa_group == WPA_CIPHER_WEP104 ? 13 : 5); 282 if (set80211param(drv, IEEE80211_PARAM_MCASTKEYLEN, v)) { 283 printf("Unable to set group key length to %u\n", v); 284 return -1; 285 } 286 } 287 288 v = 0; 289 if (params->wpa_pairwise & WPA_CIPHER_CCMP) 290 v |= 1<<IEEE80211_CIPHER_AES_CCM; 291 if (params->wpa_pairwise & WPA_CIPHER_TKIP) 292 v |= 1<<IEEE80211_CIPHER_TKIP; 293 if (params->wpa_pairwise & WPA_CIPHER_NONE) 294 v |= 1<<IEEE80211_CIPHER_NONE; 295 wpa_printf(MSG_DEBUG, "%s: pairwise key ciphers=0x%x", __func__, v); 296 if (set80211param(drv, IEEE80211_PARAM_UCASTCIPHERS, v)) { 297 printf("Unable to set pairwise key ciphers to 0x%x\n", v); 298 return -1; 299 } 300 301 wpa_printf(MSG_DEBUG, "%s: key management algorithms=0x%x", 302 __func__, params->wpa_key_mgmt); 303 if (set80211param(drv, IEEE80211_PARAM_KEYMGTALGS, 304 params->wpa_key_mgmt)) { 305 printf("Unable to set key management algorithms to 0x%x\n", 306 params->wpa_key_mgmt); 307 return -1; 308 } 309 310 v = 0; 311 if (params->rsn_preauth) 312 v |= BIT(0); 313#ifdef CONFIG_IEEE80211W 314 if (params->ieee80211w != NO_MGMT_FRAME_PROTECTION) { 315 v |= BIT(7); 316 if (params->ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED) 317 v |= BIT(6); 318 } 319#endif /* CONFIG_IEEE80211W */ 320 321 wpa_printf(MSG_DEBUG, "%s: rsn capabilities=0x%x", 322 __func__, params->rsn_preauth); 323 if (set80211param(drv, IEEE80211_PARAM_RSNCAPS, v)) { 324 printf("Unable to set RSN capabilities to 0x%x\n", v); 325 return -1; 326 } 327 328 wpa_printf(MSG_DEBUG, "%s: enable WPA=0x%x", __func__, params->wpa); 329 if (set80211param(drv, IEEE80211_PARAM_WPA, params->wpa)) { 330 printf("Unable to set WPA to %u\n", params->wpa); 331 return -1; 332 } 333 return 0; 334} 335 336static int 337atheros_set_ieee8021x(void *priv, struct wpa_bss_params *params) 338{ 339 struct atheros_driver_data *drv = priv; 340 341 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, params->enabled); 342 343 if (!params->enabled) { 344 /* XXX restore state */ 345 if (set80211param(priv, IEEE80211_PARAM_AUTHMODE, 346 IEEE80211_AUTH_AUTO) < 0) 347 return -1; 348 /* IEEE80211_AUTH_AUTO ends up enabling Privacy; clear that */ 349 return atheros_set_privacy(drv, 0); 350 } 351 if (!params->wpa && !params->ieee802_1x) { 352 hostapd_logger(drv->hapd, NULL, HOSTAPD_MODULE_DRIVER, 353 HOSTAPD_LEVEL_WARNING, "No 802.1X or WPA enabled!"); 354 return -1; 355 } 356 if (params->wpa && atheros_configure_wpa(drv, params) != 0) { 357 hostapd_logger(drv->hapd, NULL, HOSTAPD_MODULE_DRIVER, 358 HOSTAPD_LEVEL_WARNING, "Error configuring WPA state!"); 359 return -1; 360 } 361 if (set80211param(priv, IEEE80211_PARAM_AUTHMODE, 362 (params->wpa ? IEEE80211_AUTH_WPA : IEEE80211_AUTH_8021X))) { 363 hostapd_logger(drv->hapd, NULL, HOSTAPD_MODULE_DRIVER, 364 HOSTAPD_LEVEL_WARNING, "Error enabling WPA/802.1X!"); 365 return -1; 366 } 367 368 return 0; 369} 370 371static int 372atheros_set_privacy(void *priv, int enabled) 373{ 374 struct atheros_driver_data *drv = priv; 375 376 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled); 377 378 return set80211param(drv, IEEE80211_PARAM_PRIVACY, enabled); 379} 380 381static int 382atheros_set_sta_authorized(void *priv, const u8 *addr, int authorized) 383{ 384 struct atheros_driver_data *drv = priv; 385 struct ieee80211req_mlme mlme; 386 int ret; 387 388 wpa_printf(MSG_DEBUG, "%s: addr=%s authorized=%d", 389 __func__, ether_sprintf(addr), authorized); 390 391 if (authorized) 392 mlme.im_op = IEEE80211_MLME_AUTHORIZE; 393 else 394 mlme.im_op = IEEE80211_MLME_UNAUTHORIZE; 395 mlme.im_reason = 0; 396 memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); 397 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme)); 398 if (ret < 0) { 399 wpa_printf(MSG_DEBUG, "%s: Failed to %sauthorize STA " MACSTR, 400 __func__, authorized ? "" : "un", MAC2STR(addr)); 401 } 402 403 return ret; 404} 405 406static int 407atheros_sta_set_flags(void *priv, const u8 *addr, 408 int total_flags, int flags_or, int flags_and) 409{ 410 /* For now, only support setting Authorized flag */ 411 if (flags_or & WPA_STA_AUTHORIZED) 412 return atheros_set_sta_authorized(priv, addr, 1); 413 if (!(flags_and & WPA_STA_AUTHORIZED)) 414 return atheros_set_sta_authorized(priv, addr, 0); 415 return 0; 416} 417 418static int 419atheros_del_key(void *priv, const u8 *addr, int key_idx) 420{ 421 struct atheros_driver_data *drv = priv; 422 struct ieee80211req_del_key wk; 423 int ret; 424 425 wpa_printf(MSG_DEBUG, "%s: addr=%s key_idx=%d", 426 __func__, ether_sprintf(addr), key_idx); 427 428 memset(&wk, 0, sizeof(wk)); 429 if (addr != NULL) { 430 memcpy(wk.idk_macaddr, addr, IEEE80211_ADDR_LEN); 431 wk.idk_keyix = (u8) IEEE80211_KEYIX_NONE; 432 } else { 433 wk.idk_keyix = key_idx; 434 } 435 436 ret = set80211priv(drv, IEEE80211_IOCTL_DELKEY, &wk, sizeof(wk)); 437 if (ret < 0) { 438 wpa_printf(MSG_DEBUG, "%s: Failed to delete key (addr %s" 439 " key_idx %d)", __func__, ether_sprintf(addr), 440 key_idx); 441 } 442 443 return ret; 444} 445 446static int 447atheros_set_key(const char *ifname, void *priv, enum wpa_alg alg, 448 const u8 *addr, int key_idx, int set_tx, const u8 *seq, 449 size_t seq_len, const u8 *key, size_t key_len) 450{ 451 struct atheros_driver_data *drv = priv; 452 struct ieee80211req_key wk; 453 u_int8_t cipher; 454 int ret; 455 456 if (alg == WPA_ALG_NONE) 457 return atheros_del_key(drv, addr, key_idx); 458 459 wpa_printf(MSG_DEBUG, "%s: alg=%d addr=%s key_idx=%d", 460 __func__, alg, ether_sprintf(addr), key_idx); 461 462 switch (alg) { 463 case WPA_ALG_WEP: 464 cipher = IEEE80211_CIPHER_WEP; 465 break; 466 case WPA_ALG_TKIP: 467 cipher = IEEE80211_CIPHER_TKIP; 468 break; 469 case WPA_ALG_CCMP: 470 cipher = IEEE80211_CIPHER_AES_CCM; 471 break; 472#ifdef CONFIG_IEEE80211W 473 case WPA_ALG_IGTK: 474 cipher = IEEE80211_CIPHER_AES_CMAC; 475 break; 476#endif /* CONFIG_IEEE80211W */ 477 default: 478 printf("%s: unknown/unsupported algorithm %d\n", 479 __func__, alg); 480 return -1; 481 } 482 483 if (key_len > sizeof(wk.ik_keydata)) { 484 printf("%s: key length %lu too big\n", __func__, 485 (unsigned long) key_len); 486 return -3; 487 } 488 489 memset(&wk, 0, sizeof(wk)); 490 wk.ik_type = cipher; 491 wk.ik_flags = IEEE80211_KEY_RECV | IEEE80211_KEY_XMIT; 492 if (addr == NULL || is_broadcast_ether_addr(addr)) { 493 memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN); 494 wk.ik_keyix = key_idx; 495 if (set_tx) 496 wk.ik_flags |= IEEE80211_KEY_DEFAULT; 497 } else { 498 memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); 499 wk.ik_keyix = IEEE80211_KEYIX_NONE; 500 } 501 wk.ik_keylen = key_len; 502 memcpy(wk.ik_keydata, key, key_len); 503 504 ret = set80211priv(drv, IEEE80211_IOCTL_SETKEY, &wk, sizeof(wk)); 505 if (ret < 0) { 506 wpa_printf(MSG_DEBUG, "%s: Failed to set key (addr %s" 507 " key_idx %d alg %d key_len %lu set_tx %d)", 508 __func__, ether_sprintf(wk.ik_macaddr), key_idx, 509 alg, (unsigned long) key_len, set_tx); 510 } 511 512 return ret; 513} 514 515 516static int 517atheros_get_seqnum(const char *ifname, void *priv, const u8 *addr, int idx, 518 u8 *seq) 519{ 520 struct atheros_driver_data *drv = priv; 521 struct ieee80211req_key wk; 522 523 wpa_printf(MSG_DEBUG, "%s: addr=%s idx=%d", 524 __func__, ether_sprintf(addr), idx); 525 526 memset(&wk, 0, sizeof(wk)); 527 if (addr == NULL) 528 memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN); 529 else 530 memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); 531 wk.ik_keyix = idx; 532 533 if (set80211priv(drv, IEEE80211_IOCTL_GETKEY, &wk, sizeof(wk))) { 534 wpa_printf(MSG_DEBUG, "%s: Failed to get encryption data " 535 "(addr " MACSTR " key_idx %d)", 536 __func__, MAC2STR(wk.ik_macaddr), idx); 537 return -1; 538 } 539 540#ifdef WORDS_BIGENDIAN 541 { 542 /* 543 * wk.ik_keytsc is in host byte order (big endian), need to 544 * swap it to match with the byte order used in WPA. 545 */ 546 int i; 547#ifndef WPA_KEY_RSC_LEN 548#define WPA_KEY_RSC_LEN 8 549#endif 550 u8 tmp[WPA_KEY_RSC_LEN]; 551 memcpy(tmp, &wk.ik_keytsc, sizeof(wk.ik_keytsc)); 552 for (i = 0; i < WPA_KEY_RSC_LEN; i++) { 553 seq[i] = tmp[WPA_KEY_RSC_LEN - i - 1]; 554 } 555 } 556#else /* WORDS_BIGENDIAN */ 557 memcpy(seq, &wk.ik_keytsc, sizeof(wk.ik_keytsc)); 558#endif /* WORDS_BIGENDIAN */ 559 return 0; 560} 561 562 563static int 564atheros_flush(void *priv) 565{ 566 u8 allsta[IEEE80211_ADDR_LEN]; 567 memset(allsta, 0xff, IEEE80211_ADDR_LEN); 568 return atheros_sta_deauth(priv, NULL, allsta, 569 IEEE80211_REASON_AUTH_LEAVE); 570} 571 572 573static int 574atheros_read_sta_driver_data(void *priv, struct hostap_sta_driver_data *data, 575 const u8 *addr) 576{ 577 struct atheros_driver_data *drv = priv; 578 struct ieee80211req_sta_stats stats; 579 580 memset(data, 0, sizeof(*data)); 581 582 /* 583 * Fetch statistics for station from the system. 584 */ 585 memset(&stats, 0, sizeof(stats)); 586 memcpy(stats.is_u.macaddr, addr, IEEE80211_ADDR_LEN); 587 if (set80211priv(drv, IEEE80211_IOCTL_STA_STATS, 588 &stats, sizeof(stats))) { 589 wpa_printf(MSG_DEBUG, "%s: Failed to fetch STA stats (addr " 590 MACSTR ")", __func__, MAC2STR(addr)); 591 if (memcmp(addr, drv->acct_mac, ETH_ALEN) == 0) { 592 memcpy(data, &drv->acct_data, sizeof(*data)); 593 return 0; 594 } 595 596 printf("Failed to get station stats information element.\n"); 597 return -1; 598 } 599 600 data->rx_packets = stats.is_stats.ns_rx_data; 601 data->rx_bytes = stats.is_stats.ns_rx_bytes; 602 data->tx_packets = stats.is_stats.ns_tx_data; 603 data->tx_bytes = stats.is_stats.ns_tx_bytes; 604 return 0; 605} 606 607 608static int 609atheros_sta_clear_stats(void *priv, const u8 *addr) 610{ 611 struct atheros_driver_data *drv = priv; 612 struct ieee80211req_mlme mlme; 613 int ret; 614 615 wpa_printf(MSG_DEBUG, "%s: addr=%s", __func__, ether_sprintf(addr)); 616 617 mlme.im_op = IEEE80211_MLME_CLEAR_STATS; 618 memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); 619 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, 620 sizeof(mlme)); 621 if (ret < 0) { 622 wpa_printf(MSG_DEBUG, "%s: Failed to clear STA stats (addr " 623 MACSTR ")", __func__, MAC2STR(addr)); 624 } 625 626 return ret; 627} 628 629 630static int 631atheros_set_opt_ie(void *priv, const u8 *ie, size_t ie_len) 632{ 633 struct atheros_driver_data *drv = priv; 634 u8 buf[512]; 635 struct ieee80211req_getset_appiebuf *app_ie; 636 637 wpa_printf(MSG_DEBUG, "%s buflen = %lu", __func__, 638 (unsigned long) ie_len); 639 wpa_hexdump(MSG_DEBUG, "atheros: set_generic_elem", ie, ie_len); 640 641 wpabuf_free(drv->wpa_ie); 642 drv->wpa_ie = wpabuf_alloc_copy(ie, ie_len); 643 644 app_ie = (struct ieee80211req_getset_appiebuf *) buf; 645 os_memcpy(&(app_ie->app_buf[0]), ie, ie_len); 646 app_ie->app_buflen = ie_len; 647 648 app_ie->app_frmtype = IEEE80211_APPIE_FRAME_BEACON; 649 650 /* append WPS IE for Beacon */ 651 if (drv->wps_beacon_ie != NULL) { 652 os_memcpy(&(app_ie->app_buf[ie_len]), 653 wpabuf_head(drv->wps_beacon_ie), 654 wpabuf_len(drv->wps_beacon_ie)); 655 app_ie->app_buflen = ie_len + wpabuf_len(drv->wps_beacon_ie); 656 } 657 wpa_hexdump(MSG_DEBUG, "atheros: SET_APPIEBUF(Beacon)", 658 app_ie->app_buf, app_ie->app_buflen); 659 set80211priv(drv, IEEE80211_IOCTL_SET_APPIEBUF, app_ie, 660 sizeof(struct ieee80211req_getset_appiebuf) + 661 app_ie->app_buflen); 662 663 /* append WPS IE for Probe Response */ 664 app_ie->app_frmtype = IEEE80211_APPIE_FRAME_PROBE_RESP; 665 if (drv->wps_probe_resp_ie != NULL) { 666 os_memcpy(&(app_ie->app_buf[ie_len]), 667 wpabuf_head(drv->wps_probe_resp_ie), 668 wpabuf_len(drv->wps_probe_resp_ie)); 669 app_ie->app_buflen = ie_len + 670 wpabuf_len(drv->wps_probe_resp_ie); 671 } else 672 app_ie->app_buflen = ie_len; 673 wpa_hexdump(MSG_DEBUG, "atheros: SET_APPIEBUF(ProbeResp)", 674 app_ie->app_buf, app_ie->app_buflen); 675 set80211priv(drv, IEEE80211_IOCTL_SET_APPIEBUF, app_ie, 676 sizeof(struct ieee80211req_getset_appiebuf) + 677 app_ie->app_buflen); 678 return 0; 679} 680 681static int 682atheros_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, 683 int reason_code) 684{ 685 struct atheros_driver_data *drv = priv; 686 struct ieee80211req_mlme mlme; 687 int ret; 688 689 wpa_printf(MSG_DEBUG, "%s: addr=%s reason_code=%d", 690 __func__, ether_sprintf(addr), reason_code); 691 692 mlme.im_op = IEEE80211_MLME_DEAUTH; 693 mlme.im_reason = reason_code; 694 memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); 695 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme)); 696 if (ret < 0) { 697 wpa_printf(MSG_DEBUG, "%s: Failed to deauth STA (addr " MACSTR 698 " reason %d)", 699 __func__, MAC2STR(addr), reason_code); 700 } 701 702 return ret; 703} 704 705static int 706atheros_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr, 707 int reason_code) 708{ 709 struct atheros_driver_data *drv = priv; 710 struct ieee80211req_mlme mlme; 711 int ret; 712 713 wpa_printf(MSG_DEBUG, "%s: addr=%s reason_code=%d", 714 __func__, ether_sprintf(addr), reason_code); 715 716 mlme.im_op = IEEE80211_MLME_DISASSOC; 717 mlme.im_reason = reason_code; 718 memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); 719 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme)); 720 if (ret < 0) { 721 wpa_printf(MSG_DEBUG, "%s: Failed to disassoc STA (addr " 722 MACSTR " reason %d)", 723 __func__, MAC2STR(addr), reason_code); 724 } 725 726 return ret; 727} 728 729#ifdef CONFIG_WPS 730static void atheros_raw_recv_wps(void *ctx, const u8 *src_addr, const u8 *buf, 731 size_t len) 732{ 733 struct atheros_driver_data *drv = ctx; 734 const struct ieee80211_mgmt *mgmt; 735 u16 fc; 736 union wpa_event_data event; 737 738 /* Send Probe Request information to WPS processing */ 739 740 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req)) 741 return; 742 mgmt = (const struct ieee80211_mgmt *) buf; 743 744 fc = le_to_host16(mgmt->frame_control); 745 if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT || 746 WLAN_FC_GET_STYPE(fc) != WLAN_FC_STYPE_PROBE_REQ) 747 return; 748 749 os_memset(&event, 0, sizeof(event)); 750 event.rx_probe_req.sa = mgmt->sa; 751 event.rx_probe_req.da = mgmt->da; 752 event.rx_probe_req.bssid = mgmt->bssid; 753 event.rx_probe_req.ie = mgmt->u.probe_req.variable; 754 event.rx_probe_req.ie_len = 755 len - (IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req)); 756 wpa_supplicant_event(drv->hapd, EVENT_RX_PROBE_REQ, &event); 757} 758#endif /* CONFIG_WPS */ 759 760#ifdef CONFIG_IEEE80211R 761static void atheros_raw_recv_11r(void *ctx, const u8 *src_addr, const u8 *buf, 762 size_t len) 763{ 764 struct atheros_driver_data *drv = ctx; 765 union wpa_event_data event; 766 const struct ieee80211_mgmt *mgmt; 767 u16 fc; 768 u16 stype; 769 int ielen; 770 const u8 *iebuf; 771 772 /* Do 11R processing for ASSOC/AUTH/FT ACTION frames */ 773 if (len < IEEE80211_HDRLEN) 774 return; 775 mgmt = (const struct ieee80211_mgmt *) buf; 776 777 fc = le_to_host16(mgmt->frame_control); 778 779 if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT) 780 return; 781 stype = WLAN_FC_GET_STYPE(fc); 782 783 wpa_printf(MSG_DEBUG, "%s: subtype 0x%x len %d", __func__, stype, 784 (int) len); 785 786 if (os_memcmp(drv->own_addr, mgmt->bssid, ETH_ALEN) != 0) { 787 wpa_printf(MSG_DEBUG, "%s: BSSID does not match - ignore", 788 __func__); 789 return; 790 } 791 switch (stype) { 792 case WLAN_FC_STYPE_ASSOC_REQ: 793 if (len - IEEE80211_HDRLEN < sizeof(mgmt->u.assoc_req)) 794 break; 795 ielen = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.assoc_req)); 796 iebuf = mgmt->u.assoc_req.variable; 797 drv_event_assoc(drv->hapd, mgmt->sa, iebuf, ielen, 0); 798 break; 799 case WLAN_FC_STYPE_REASSOC_REQ: 800 if (len - IEEE80211_HDRLEN < sizeof(mgmt->u.reassoc_req)) 801 break; 802 ielen = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.reassoc_req)); 803 iebuf = mgmt->u.reassoc_req.variable; 804 drv_event_assoc(drv->hapd, mgmt->sa, iebuf, ielen, 1); 805 break; 806 case WLAN_FC_STYPE_ACTION: 807 if (&mgmt->u.action.category > buf + len) 808 break; 809 os_memset(&event, 0, sizeof(event)); 810 event.rx_action.da = mgmt->da; 811 event.rx_action.sa = mgmt->sa; 812 event.rx_action.bssid = mgmt->bssid; 813 event.rx_action.category = mgmt->u.action.category; 814 event.rx_action.data = &mgmt->u.action.category; 815 event.rx_action.len = buf + len - event.rx_action.data; 816 wpa_supplicant_event(drv->hapd, EVENT_RX_ACTION, &event); 817 break; 818 case WLAN_FC_STYPE_AUTH: 819 if (len - IEEE80211_HDRLEN < sizeof(mgmt->u.auth)) 820 break; 821 os_memset(&event, 0, sizeof(event)); 822 os_memcpy(event.auth.peer, mgmt->sa, ETH_ALEN); 823 os_memcpy(event.auth.bssid, mgmt->bssid, ETH_ALEN); 824 event.auth.auth_type = le_to_host16(mgmt->u.auth.auth_alg); 825 event.auth.status_code = 826 le_to_host16(mgmt->u.auth.status_code); 827 event.auth.auth_transaction = 828 le_to_host16(mgmt->u.auth.auth_transaction); 829 event.auth.ies = mgmt->u.auth.variable; 830 event.auth.ies_len = len - IEEE80211_HDRLEN - 831 sizeof(mgmt->u.auth); 832 wpa_supplicant_event(drv->hapd, EVENT_AUTH, &event); 833 break; 834 default: 835 break; 836 } 837} 838#endif /* CONFIG_IEEE80211R */ 839 840#if defined(CONFIG_WPS) || defined(CONFIG_IEEE80211R) 841static void atheros_raw_receive(void *ctx, const u8 *src_addr, const u8 *buf, 842 size_t len) 843{ 844#ifdef CONFIG_WPS 845 atheros_raw_recv_wps(ctx, src_addr, buf, len); 846#endif /* CONFIG_WPS */ 847#ifdef CONFIG_IEEE80211R 848 atheros_raw_recv_11r(ctx, src_addr, buf, len); 849#endif /* CONFIG_IEEE80211R */ 850} 851#endif /* CONFIG_WPS || CONFIG_IEEE80211R */ 852 853static int atheros_receive_pkt(struct atheros_driver_data *drv) 854{ 855 int ret = 0; 856 struct ieee80211req_set_filter filt; 857 858 wpa_printf(MSG_DEBUG, "%s Enter", __func__); 859 filt.app_filterype = 0; 860#ifdef CONFIG_WPS 861 filt.app_filterype |= IEEE80211_FILTER_TYPE_PROBE_REQ; 862#endif /* CONFIG_WPS */ 863#ifdef CONFIG_IEEE80211R 864 filt.app_filterype |= (IEEE80211_FILTER_TYPE_ASSOC_REQ | 865 IEEE80211_FILTER_TYPE_AUTH); 866#endif 867 if (filt.app_filterype) { 868 ret = set80211priv(drv, IEEE80211_IOCTL_FILTERFRAME, &filt, 869 sizeof(struct ieee80211req_set_filter)); 870 if (ret) 871 return ret; 872 } 873 874#if defined(CONFIG_WPS) || defined(CONFIG_IEEE80211R) 875 drv->sock_raw = l2_packet_init(drv->iface, NULL, ETH_P_80211_RAW, 876 atheros_raw_receive, drv, 1); 877 if (drv->sock_raw == NULL) 878 return -1; 879#endif /* CONFIG_WPS || CONFIG_IEEE80211R */ 880 if (l2_packet_get_own_addr(drv->sock_xmit, drv->own_addr)) 881 return -1; 882 return ret; 883} 884 885static int atheros_reset_appfilter(struct atheros_driver_data *drv) 886{ 887 struct ieee80211req_set_filter filt; 888 filt.app_filterype = 0; 889 return set80211priv(drv, IEEE80211_IOCTL_FILTERFRAME, &filt, 890 sizeof(struct ieee80211req_set_filter)); 891} 892 893#ifdef CONFIG_WPS 894static int 895atheros_set_wps_ie(void *priv, const u8 *ie, size_t len, u32 frametype) 896{ 897 struct atheros_driver_data *drv = priv; 898 u8 buf[512]; 899 struct ieee80211req_getset_appiebuf *beac_ie; 900 901 wpa_printf(MSG_DEBUG, "%s buflen = %lu frametype=%u", __func__, 902 (unsigned long) len, frametype); 903 wpa_hexdump(MSG_DEBUG, "atheros: IE", ie, len); 904 905 beac_ie = (struct ieee80211req_getset_appiebuf *) buf; 906 beac_ie->app_frmtype = frametype; 907 beac_ie->app_buflen = len; 908 os_memcpy(&(beac_ie->app_buf[0]), ie, len); 909 910 /* append the WPA/RSN IE if it is set already */ 911 if (((frametype == IEEE80211_APPIE_FRAME_BEACON) || 912 (frametype == IEEE80211_APPIE_FRAME_PROBE_RESP)) && 913 (drv->wpa_ie != NULL)) { 914 wpa_hexdump_buf(MSG_DEBUG, "atheros: Append WPA/RSN IE", 915 drv->wpa_ie); 916 os_memcpy(&(beac_ie->app_buf[len]), wpabuf_head(drv->wpa_ie), 917 wpabuf_len(drv->wpa_ie)); 918 beac_ie->app_buflen += wpabuf_len(drv->wpa_ie); 919 } 920 921 wpa_hexdump(MSG_DEBUG, "atheros: SET_APPIEBUF", 922 beac_ie->app_buf, beac_ie->app_buflen); 923 return set80211priv(drv, IEEE80211_IOCTL_SET_APPIEBUF, beac_ie, 924 sizeof(struct ieee80211req_getset_appiebuf) + 925 beac_ie->app_buflen); 926} 927 928static int 929atheros_set_ap_wps_ie(void *priv, const struct wpabuf *beacon, 930 const struct wpabuf *proberesp, 931 const struct wpabuf *assocresp) 932{ 933 struct atheros_driver_data *drv = priv; 934 935 wpa_hexdump_buf(MSG_DEBUG, "atheros: set_ap_wps_ie - beacon", beacon); 936 wpa_hexdump_buf(MSG_DEBUG, "atheros: set_ap_wps_ie - proberesp", 937 proberesp); 938 wpa_hexdump_buf(MSG_DEBUG, "atheros: set_ap_wps_ie - assocresp", 939 assocresp); 940 wpabuf_free(drv->wps_beacon_ie); 941 drv->wps_beacon_ie = beacon ? wpabuf_dup(beacon) : NULL; 942 wpabuf_free(drv->wps_probe_resp_ie); 943 drv->wps_probe_resp_ie = proberesp ? wpabuf_dup(proberesp) : NULL; 944 945 atheros_set_wps_ie(priv, assocresp ? wpabuf_head(assocresp) : NULL, 946 assocresp ? wpabuf_len(assocresp) : 0, 947 IEEE80211_APPIE_FRAME_ASSOC_RESP); 948 if (atheros_set_wps_ie(priv, beacon ? wpabuf_head(beacon) : NULL, 949 beacon ? wpabuf_len(beacon) : 0, 950 IEEE80211_APPIE_FRAME_BEACON)) 951 return -1; 952 return atheros_set_wps_ie(priv, 953 proberesp ? wpabuf_head(proberesp) : NULL, 954 proberesp ? wpabuf_len(proberesp): 0, 955 IEEE80211_APPIE_FRAME_PROBE_RESP); 956} 957#else /* CONFIG_WPS */ 958#define atheros_set_ap_wps_ie NULL 959#endif /* CONFIG_WPS */ 960 961#ifdef CONFIG_IEEE80211R 962static int 963atheros_sta_auth(void *priv, const u8 *own_addr, const u8 *addr, u16 seq, 964 u16 status_code, const u8 *ie, size_t len) 965{ 966 struct atheros_driver_data *drv = priv; 967 struct ieee80211req_mlme mlme; 968 int ret; 969 970 wpa_printf(MSG_DEBUG, "%s: addr=%s status_code=%d", 971 __func__, ether_sprintf(addr), status_code); 972 973 mlme.im_op = IEEE80211_MLME_AUTH; 974 mlme.im_reason = status_code; 975 mlme.im_seq = seq; 976 os_memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); 977 mlme.im_optie_len = len; 978 if (len) { 979 if (len < IEEE80211_MAX_OPT_IE) { 980 os_memcpy(mlme.im_optie, ie, len); 981 } else { 982 wpa_printf(MSG_DEBUG, "%s: Not enough space to copy " 983 "opt_ie STA (addr " MACSTR " reason %d, " 984 "ie_len %d)", 985 __func__, MAC2STR(addr), status_code, 986 (int) len); 987 return -1; 988 } 989 } 990 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme)); 991 if (ret < 0) { 992 wpa_printf(MSG_DEBUG, "%s: Failed to auth STA (addr " MACSTR 993 " reason %d)", 994 __func__, MAC2STR(addr), status_code); 995 } 996 return ret; 997} 998 999static int 1000atheros_sta_assoc(void *priv, const u8 *own_addr, const u8 *addr, 1001 int reassoc, u16 status_code, const u8 *ie, size_t len) 1002{ 1003 struct atheros_driver_data *drv = priv; 1004 struct ieee80211req_mlme mlme; 1005 int ret; 1006 1007 wpa_printf(MSG_DEBUG, "%s: addr=%s status_code=%d reassoc %d", 1008 __func__, ether_sprintf(addr), status_code, reassoc); 1009 1010 if (reassoc) 1011 mlme.im_op = IEEE80211_MLME_REASSOC; 1012 else 1013 mlme.im_op = IEEE80211_MLME_ASSOC; 1014 mlme.im_reason = status_code; 1015 os_memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); 1016 mlme.im_optie_len = len; 1017 if (len) { 1018 if (len < IEEE80211_MAX_OPT_IE) { 1019 os_memcpy(mlme.im_optie, ie, len); 1020 } else { 1021 wpa_printf(MSG_DEBUG, "%s: Not enough space to copy " 1022 "opt_ie STA (addr " MACSTR " reason %d, " 1023 "ie_len %d)", 1024 __func__, MAC2STR(addr), status_code, 1025 (int) len); 1026 return -1; 1027 } 1028 } 1029 ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme)); 1030 if (ret < 0) { 1031 wpa_printf(MSG_DEBUG, "%s: Failed to assoc STA (addr " MACSTR 1032 " reason %d)", 1033 __func__, MAC2STR(addr), status_code); 1034 } 1035 return ret; 1036} 1037#endif /* CONFIG_IEEE80211R */ 1038 1039static void 1040atheros_new_sta(struct atheros_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN]) 1041{ 1042 struct hostapd_data *hapd = drv->hapd; 1043 struct ieee80211req_wpaie ie; 1044 int ielen = 0; 1045 u8 *iebuf = NULL; 1046 1047 /* 1048 * Fetch negotiated WPA/RSN parameters from the system. 1049 */ 1050 memset(&ie, 0, sizeof(ie)); 1051 memcpy(ie.wpa_macaddr, addr, IEEE80211_ADDR_LEN); 1052 if (set80211priv(drv, IEEE80211_IOCTL_GETWPAIE, &ie, sizeof(ie))) { 1053 /* 1054 * See ATH_WPS_IE comment in the beginning of the file for a 1055 * possible cause for the failure.. 1056 */ 1057 wpa_printf(MSG_DEBUG, "%s: Failed to get WPA/RSN IE: %s", 1058 __func__, strerror(errno)); 1059 goto no_ie; 1060 } 1061 wpa_hexdump(MSG_MSGDUMP, "atheros req WPA IE", 1062 ie.wpa_ie, IEEE80211_MAX_OPT_IE); 1063 wpa_hexdump(MSG_MSGDUMP, "atheros req RSN IE", 1064 ie.rsn_ie, IEEE80211_MAX_OPT_IE); 1065#ifdef ATH_WPS_IE 1066 wpa_hexdump(MSG_MSGDUMP, "atheros req WPS IE", 1067 ie.wps_ie, IEEE80211_MAX_OPT_IE); 1068#endif /* ATH_WPS_IE */ 1069 iebuf = ie.wpa_ie; 1070 /* atheros seems to return some random data if WPA/RSN IE is not set. 1071 * Assume the IE was not included if the IE type is unknown. */ 1072 if (iebuf[0] != WLAN_EID_VENDOR_SPECIFIC) 1073 iebuf[1] = 0; 1074 if (iebuf[1] == 0 && ie.rsn_ie[1] > 0) { 1075 /* atheros-ng svn #1453 added rsn_ie. Use it, if wpa_ie was not 1076 * set. This is needed for WPA2. */ 1077 iebuf = ie.rsn_ie; 1078 if (iebuf[0] != WLAN_EID_RSN) 1079 iebuf[1] = 0; 1080 } 1081 1082 ielen = iebuf[1]; 1083 1084#ifdef ATH_WPS_IE 1085 /* if WPS IE is present, preference is given to WPS */ 1086 if (ie.wps_ie && 1087 (ie.wps_ie[1] > 0 && (ie.wps_ie[0] == WLAN_EID_VENDOR_SPECIFIC))) { 1088 iebuf = ie.wps_ie; 1089 ielen = ie.wps_ie[1]; 1090 } 1091#endif /* ATH_WPS_IE */ 1092 1093 if (ielen == 0) 1094 iebuf = NULL; 1095 else 1096 ielen += 2; 1097 1098no_ie: 1099 drv_event_assoc(hapd, addr, iebuf, ielen, 0); 1100 1101 if (memcmp(addr, drv->acct_mac, ETH_ALEN) == 0) { 1102 /* Cached accounting data is not valid anymore. */ 1103 memset(drv->acct_mac, 0, ETH_ALEN); 1104 memset(&drv->acct_data, 0, sizeof(drv->acct_data)); 1105 } 1106} 1107 1108static void 1109atheros_wireless_event_wireless_custom(struct atheros_driver_data *drv, 1110 char *custom, char *end) 1111{ 1112 wpa_printf(MSG_DEBUG, "Custom wireless event: '%s'", custom); 1113 1114 if (strncmp(custom, "MLME-MICHAELMICFAILURE.indication", 33) == 0) { 1115 char *pos; 1116 u8 addr[ETH_ALEN]; 1117 pos = strstr(custom, "addr="); 1118 if (pos == NULL) { 1119 wpa_printf(MSG_DEBUG, 1120 "MLME-MICHAELMICFAILURE.indication " 1121 "without sender address ignored"); 1122 return; 1123 } 1124 pos += 5; 1125 if (hwaddr_aton(pos, addr) == 0) { 1126 union wpa_event_data data; 1127 os_memset(&data, 0, sizeof(data)); 1128 data.michael_mic_failure.unicast = 1; 1129 data.michael_mic_failure.src = addr; 1130 wpa_supplicant_event(drv->hapd, 1131 EVENT_MICHAEL_MIC_FAILURE, &data); 1132 } else { 1133 wpa_printf(MSG_DEBUG, 1134 "MLME-MICHAELMICFAILURE.indication " 1135 "with invalid MAC address"); 1136 } 1137 } else if (strncmp(custom, "STA-TRAFFIC-STAT", 16) == 0) { 1138 char *key, *value; 1139 u32 val; 1140 key = custom; 1141 while ((key = strchr(key, '\n')) != NULL) { 1142 key++; 1143 value = strchr(key, '='); 1144 if (value == NULL) 1145 continue; 1146 *value++ = '\0'; 1147 val = strtoul(value, NULL, 10); 1148 if (strcmp(key, "mac") == 0) 1149 hwaddr_aton(value, drv->acct_mac); 1150 else if (strcmp(key, "rx_packets") == 0) 1151 drv->acct_data.rx_packets = val; 1152 else if (strcmp(key, "tx_packets") == 0) 1153 drv->acct_data.tx_packets = val; 1154 else if (strcmp(key, "rx_bytes") == 0) 1155 drv->acct_data.rx_bytes = val; 1156 else if (strcmp(key, "tx_bytes") == 0) 1157 drv->acct_data.tx_bytes = val; 1158 key = value; 1159 } 1160#ifdef CONFIG_WPS 1161 } else if (strncmp(custom, "PUSH-BUTTON.indication", 22) == 0) { 1162 /* Some atheros kernels send push button as a wireless event */ 1163 /* PROBLEM! this event is received for ALL BSSs ... 1164 * so all are enabled for WPS... ugh. 1165 */ 1166 wpa_supplicant_event(drv->hapd, EVENT_WPS_BUTTON_PUSHED, NULL); 1167#endif /* CONFIG_WPS */ 1168#if defined(CONFIG_WPS) || defined(CONFIG_IEEE80211R) 1169#define WPS_FRAM_TAG_SIZE 30 /* hardcoded in driver */ 1170 } else if (strncmp(custom, "Manage.prob_req ", 16) == 0) { 1171 /* 1172 * Atheros driver uses a hack to pass Probe Request frames as a 1173 * binary data in the custom wireless event. The old way (using 1174 * packet sniffing) didn't work when bridging. 1175 * Format: "Manage.prob_req <frame len>" | zero padding | frame 1176 */ 1177 int len = atoi(custom + 16); 1178 if (len < 0 || custom + WPS_FRAM_TAG_SIZE + len > end) { 1179 wpa_printf(MSG_DEBUG, "Invalid Manage.prob_req event " 1180 "length %d", len); 1181 return; 1182 } 1183 atheros_raw_receive(drv, NULL, 1184 (u8 *) custom + WPS_FRAM_TAG_SIZE, len); 1185 } else if (strncmp(custom, "Manage.assoc_req ", 17) == 0) { 1186 /* Format: "Manage.assoc_req <frame len>" | zero padding | 1187 * frame */ 1188 int len = atoi(custom + 17); 1189 if (len < 0 || custom + WPS_FRAM_TAG_SIZE + len > end) { 1190 wpa_printf(MSG_DEBUG, "Invalid Manage.prob_req/" 1191 "assoc_req/auth event length %d", len); 1192 return; 1193 } 1194 atheros_raw_receive(drv, NULL, 1195 (u8 *) custom + WPS_FRAM_TAG_SIZE, len); 1196 } else if (strncmp(custom, "Manage.action ", 14) == 0) { 1197 /* Format: "Manage.assoc_req <frame len>" | zero padding | 1198 * frame */ 1199 int len = atoi(custom + 14); 1200 if (len < 0 || custom + WPS_FRAM_TAG_SIZE + len > end) { 1201 wpa_printf(MSG_DEBUG, "Invalid Manage.prob_req/" 1202 "assoc_req/auth event length %d", len); 1203 return; 1204 } 1205 atheros_raw_receive(drv, NULL, 1206 (u8 *) custom + WPS_FRAM_TAG_SIZE, len); 1207 } else if (strncmp(custom, "Manage.auth ", 12) == 0) { 1208 /* Format: "Manage.auth <frame len>" | zero padding | frame 1209 */ 1210 int len = atoi(custom + 12); 1211 if (len < 0 || custom + WPS_FRAM_TAG_SIZE + len > end) { 1212 wpa_printf(MSG_DEBUG, "Invalid Manage.prob_req/" 1213 "assoc_req/auth event length %d", len); 1214 return; 1215 } 1216 atheros_raw_receive(drv, NULL, 1217 (u8 *) custom + WPS_FRAM_TAG_SIZE, len); 1218#endif /* CONFIG_WPS or CONFIG_IEEE80211R */ 1219 } 1220} 1221 1222static void 1223atheros_wireless_event_wireless(struct atheros_driver_data *drv, 1224 char *data, int len) 1225{ 1226 struct iw_event iwe_buf, *iwe = &iwe_buf; 1227 char *pos, *end, *custom, *buf; 1228 1229 pos = data; 1230 end = data + len; 1231 1232 while (pos + IW_EV_LCP_LEN <= end) { 1233 /* Event data may be unaligned, so make a local, aligned copy 1234 * before processing. */ 1235 memcpy(&iwe_buf, pos, IW_EV_LCP_LEN); 1236 wpa_printf(MSG_MSGDUMP, "Wireless event: cmd=0x%x len=%d", 1237 iwe->cmd, iwe->len); 1238 if (iwe->len <= IW_EV_LCP_LEN) 1239 return; 1240 1241 custom = pos + IW_EV_POINT_LEN; 1242 if (drv->we_version > 18 && 1243 (iwe->cmd == IWEVMICHAELMICFAILURE || 1244 iwe->cmd == IWEVASSOCREQIE || 1245 iwe->cmd == IWEVCUSTOM)) { 1246 /* WE-19 removed the pointer from struct iw_point */ 1247 char *dpos = (char *) &iwe_buf.u.data.length; 1248 int dlen = dpos - (char *) &iwe_buf; 1249 memcpy(dpos, pos + IW_EV_LCP_LEN, 1250 sizeof(struct iw_event) - dlen); 1251 } else { 1252 memcpy(&iwe_buf, pos, sizeof(struct iw_event)); 1253 custom += IW_EV_POINT_OFF; 1254 } 1255 1256 switch (iwe->cmd) { 1257 case IWEVEXPIRED: 1258 drv_event_disassoc(drv->hapd, 1259 (u8 *) iwe->u.addr.sa_data); 1260 break; 1261 case IWEVREGISTERED: 1262 atheros_new_sta(drv, (u8 *) iwe->u.addr.sa_data); 1263 break; 1264 case IWEVASSOCREQIE: 1265 /* Driver hack.. Use IWEVASSOCREQIE to bypass 1266 * IWEVCUSTOM size limitations. Need to handle this 1267 * just like IWEVCUSTOM. 1268 */ 1269 case IWEVCUSTOM: 1270 if (custom + iwe->u.data.length > end) 1271 return; 1272 buf = malloc(iwe->u.data.length + 1); 1273 if (buf == NULL) 1274 return; /* XXX */ 1275 memcpy(buf, custom, iwe->u.data.length); 1276 buf[iwe->u.data.length] = '\0'; 1277 atheros_wireless_event_wireless_custom( 1278 drv, buf, buf + iwe->u.data.length); 1279 free(buf); 1280 break; 1281 } 1282 1283 pos += iwe->len; 1284 } 1285} 1286 1287 1288static void 1289atheros_wireless_event_rtm_newlink(void *ctx, 1290 struct ifinfomsg *ifi, u8 *buf, size_t len) 1291{ 1292 struct atheros_driver_data *drv = ctx; 1293 int attrlen, rta_len; 1294 struct rtattr *attr; 1295 1296 if (ifi->ifi_index != drv->ifindex) 1297 return; 1298 1299 attrlen = len; 1300 attr = (struct rtattr *) buf; 1301 1302 rta_len = RTA_ALIGN(sizeof(struct rtattr)); 1303 while (RTA_OK(attr, attrlen)) { 1304 if (attr->rta_type == IFLA_WIRELESS) { 1305 atheros_wireless_event_wireless( 1306 drv, ((char *) attr) + rta_len, 1307 attr->rta_len - rta_len); 1308 } 1309 attr = RTA_NEXT(attr, attrlen); 1310 } 1311} 1312 1313 1314static int 1315atheros_get_we_version(struct atheros_driver_data *drv) 1316{ 1317 struct iw_range *range; 1318 struct iwreq iwr; 1319 int minlen; 1320 size_t buflen; 1321 1322 drv->we_version = 0; 1323 1324 /* 1325 * Use larger buffer than struct iw_range in order to allow the 1326 * structure to grow in the future. 1327 */ 1328 buflen = sizeof(struct iw_range) + 500; 1329 range = os_zalloc(buflen); 1330 if (range == NULL) 1331 return -1; 1332 1333 memset(&iwr, 0, sizeof(iwr)); 1334 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 1335 iwr.u.data.pointer = (caddr_t) range; 1336 iwr.u.data.length = buflen; 1337 1338 minlen = ((char *) &range->enc_capa) - (char *) range + 1339 sizeof(range->enc_capa); 1340 1341 if (ioctl(drv->ioctl_sock, SIOCGIWRANGE, &iwr) < 0) { 1342 perror("ioctl[SIOCGIWRANGE]"); 1343 free(range); 1344 return -1; 1345 } else if (iwr.u.data.length >= minlen && 1346 range->we_version_compiled >= 18) { 1347 wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: WE(compiled)=%d " 1348 "WE(source)=%d enc_capa=0x%x", 1349 range->we_version_compiled, 1350 range->we_version_source, 1351 range->enc_capa); 1352 drv->we_version = range->we_version_compiled; 1353 } 1354 1355 os_free(range); 1356 return 0; 1357} 1358 1359 1360static int 1361atheros_wireless_event_init(struct atheros_driver_data *drv) 1362{ 1363 struct netlink_config *cfg; 1364 1365 atheros_get_we_version(drv); 1366 1367 cfg = os_zalloc(sizeof(*cfg)); 1368 if (cfg == NULL) 1369 return -1; 1370 cfg->ctx = drv; 1371 cfg->newlink_cb = atheros_wireless_event_rtm_newlink; 1372 drv->netlink = netlink_init(cfg); 1373 if (drv->netlink == NULL) { 1374 os_free(cfg); 1375 return -1; 1376 } 1377 1378 return 0; 1379} 1380 1381 1382static int 1383atheros_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t data_len, 1384 int encrypt, const u8 *own_addr, u32 flags) 1385{ 1386 struct atheros_driver_data *drv = priv; 1387 unsigned char buf[3000]; 1388 unsigned char *bp = buf; 1389 struct l2_ethhdr *eth; 1390 size_t len; 1391 int status; 1392 1393 /* 1394 * Prepend the Ethernet header. If the caller left us 1395 * space at the front we could just insert it but since 1396 * we don't know we copy to a local buffer. Given the frequency 1397 * and size of frames this probably doesn't matter. 1398 */ 1399 len = data_len + sizeof(struct l2_ethhdr); 1400 if (len > sizeof(buf)) { 1401 bp = malloc(len); 1402 if (bp == NULL) { 1403 printf("EAPOL frame discarded, cannot malloc temp " 1404 "buffer of size %lu!\n", (unsigned long) len); 1405 return -1; 1406 } 1407 } 1408 eth = (struct l2_ethhdr *) bp; 1409 memcpy(eth->h_dest, addr, ETH_ALEN); 1410 memcpy(eth->h_source, own_addr, ETH_ALEN); 1411 eth->h_proto = host_to_be16(ETH_P_EAPOL); 1412 memcpy(eth+1, data, data_len); 1413 1414 wpa_hexdump(MSG_MSGDUMP, "TX EAPOL", bp, len); 1415 1416 status = l2_packet_send(drv->sock_xmit, addr, ETH_P_EAPOL, bp, len); 1417 1418 if (bp != buf) 1419 free(bp); 1420 return status; 1421} 1422 1423static void 1424handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len) 1425{ 1426 struct atheros_driver_data *drv = ctx; 1427 drv_event_eapol_rx(drv->hapd, src_addr, buf + sizeof(struct l2_ethhdr), 1428 len - sizeof(struct l2_ethhdr)); 1429} 1430 1431static void * 1432atheros_init(struct hostapd_data *hapd, struct wpa_init_params *params) 1433{ 1434 struct atheros_driver_data *drv; 1435 struct ifreq ifr; 1436 struct iwreq iwr; 1437 char brname[IFNAMSIZ]; 1438 1439 drv = os_zalloc(sizeof(struct atheros_driver_data)); 1440 if (drv == NULL) { 1441 printf("Could not allocate memory for atheros driver data\n"); 1442 return NULL; 1443 } 1444 1445 drv->hapd = hapd; 1446 drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0); 1447 if (drv->ioctl_sock < 0) { 1448 perror("socket[PF_INET,SOCK_DGRAM]"); 1449 goto bad; 1450 } 1451 memcpy(drv->iface, params->ifname, sizeof(drv->iface)); 1452 1453 memset(&ifr, 0, sizeof(ifr)); 1454 os_strlcpy(ifr.ifr_name, drv->iface, sizeof(ifr.ifr_name)); 1455 if (ioctl(drv->ioctl_sock, SIOCGIFINDEX, &ifr) != 0) { 1456 perror("ioctl(SIOCGIFINDEX)"); 1457 goto bad; 1458 } 1459 drv->ifindex = ifr.ifr_ifindex; 1460 1461 drv->sock_xmit = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL, 1462 handle_read, drv, 1); 1463 if (drv->sock_xmit == NULL) 1464 goto bad; 1465 if (l2_packet_get_own_addr(drv->sock_xmit, params->own_addr)) 1466 goto bad; 1467 if (params->bridge[0]) { 1468 wpa_printf(MSG_DEBUG, "Configure bridge %s for EAPOL traffic.", 1469 params->bridge[0]); 1470 drv->sock_recv = l2_packet_init(params->bridge[0], NULL, 1471 ETH_P_EAPOL, handle_read, drv, 1472 1); 1473 if (drv->sock_recv == NULL) 1474 goto bad; 1475 } else if (linux_br_get(brname, drv->iface) == 0) { 1476 wpa_printf(MSG_DEBUG, "Interface in bridge %s; configure for " 1477 "EAPOL receive", brname); 1478 drv->sock_recv = l2_packet_init(brname, NULL, ETH_P_EAPOL, 1479 handle_read, drv, 1); 1480 if (drv->sock_recv == NULL) 1481 goto bad; 1482 } else 1483 drv->sock_recv = drv->sock_xmit; 1484 1485 memset(&iwr, 0, sizeof(iwr)); 1486 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 1487 1488 iwr.u.mode = IW_MODE_MASTER; 1489 1490 if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0) { 1491 perror("ioctl[SIOCSIWMODE]"); 1492 printf("Could not set interface to master mode!\n"); 1493 goto bad; 1494 } 1495 1496 /* mark down during setup */ 1497 linux_set_iface_flags(drv->ioctl_sock, drv->iface, 0); 1498 atheros_set_privacy(drv, 0); /* default to no privacy */ 1499 1500 atheros_receive_pkt(drv); 1501 1502 if (atheros_wireless_event_init(drv)) 1503 goto bad; 1504 1505 return drv; 1506bad: 1507 if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit) 1508 l2_packet_deinit(drv->sock_recv); 1509 if (drv->sock_xmit != NULL) 1510 l2_packet_deinit(drv->sock_xmit); 1511 if (drv->ioctl_sock >= 0) 1512 close(drv->ioctl_sock); 1513 if (drv != NULL) 1514 free(drv); 1515 return NULL; 1516} 1517 1518 1519static void 1520atheros_deinit(void *priv) 1521{ 1522 struct atheros_driver_data *drv = priv; 1523 1524 atheros_reset_appfilter(drv); 1525 netlink_deinit(drv->netlink); 1526 (void) linux_set_iface_flags(drv->ioctl_sock, drv->iface, 0); 1527 if (drv->ioctl_sock >= 0) 1528 close(drv->ioctl_sock); 1529 if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit) 1530 l2_packet_deinit(drv->sock_recv); 1531 if (drv->sock_xmit != NULL) 1532 l2_packet_deinit(drv->sock_xmit); 1533 if (drv->sock_raw) 1534 l2_packet_deinit(drv->sock_raw); 1535 wpabuf_free(drv->wpa_ie); 1536 wpabuf_free(drv->wps_beacon_ie); 1537 wpabuf_free(drv->wps_probe_resp_ie); 1538 free(drv); 1539} 1540 1541static int 1542atheros_set_ssid(void *priv, const u8 *buf, int len) 1543{ 1544 struct atheros_driver_data *drv = priv; 1545 struct iwreq iwr; 1546 1547 memset(&iwr, 0, sizeof(iwr)); 1548 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 1549 iwr.u.essid.flags = 1; /* SSID active */ 1550 iwr.u.essid.pointer = (caddr_t) buf; 1551 iwr.u.essid.length = len + 1; 1552 1553 if (ioctl(drv->ioctl_sock, SIOCSIWESSID, &iwr) < 0) { 1554 perror("ioctl[SIOCSIWESSID]"); 1555 printf("len=%d\n", len); 1556 return -1; 1557 } 1558 return 0; 1559} 1560 1561static int 1562atheros_get_ssid(void *priv, u8 *buf, int len) 1563{ 1564 struct atheros_driver_data *drv = priv; 1565 struct iwreq iwr; 1566 int ret = 0; 1567 1568 memset(&iwr, 0, sizeof(iwr)); 1569 os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); 1570 iwr.u.essid.pointer = (caddr_t) buf; 1571 iwr.u.essid.length = (len > IW_ESSID_MAX_SIZE) ? 1572 IW_ESSID_MAX_SIZE : len; 1573 1574 if (ioctl(drv->ioctl_sock, SIOCGIWESSID, &iwr) < 0) { 1575 perror("ioctl[SIOCGIWESSID]"); 1576 ret = -1; 1577 } else 1578 ret = iwr.u.essid.length; 1579 1580 return ret; 1581} 1582 1583static int 1584atheros_set_countermeasures(void *priv, int enabled) 1585{ 1586 struct atheros_driver_data *drv = priv; 1587 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled); 1588 return set80211param(drv, IEEE80211_PARAM_COUNTERMEASURES, enabled); 1589} 1590 1591static int 1592atheros_commit(void *priv) 1593{ 1594 struct atheros_driver_data *drv = priv; 1595 return linux_set_iface_flags(drv->ioctl_sock, drv->iface, 1); 1596} 1597 1598static int atheros_set_authmode(void *priv, int auth_algs) 1599{ 1600 int authmode; 1601 1602 if ((auth_algs & WPA_AUTH_ALG_OPEN) && 1603 (auth_algs & WPA_AUTH_ALG_SHARED)) 1604 authmode = IEEE80211_AUTH_AUTO; 1605 else if (auth_algs & WPA_AUTH_ALG_OPEN) 1606 authmode = IEEE80211_AUTH_OPEN; 1607 else if (auth_algs & WPA_AUTH_ALG_SHARED) 1608 authmode = IEEE80211_AUTH_SHARED; 1609 else 1610 return -1; 1611 1612 return set80211param(priv, IEEE80211_PARAM_AUTHMODE, authmode); 1613} 1614 1615static int atheros_set_ap(void *priv, struct wpa_driver_ap_params *params) 1616{ 1617 /* 1618 * TODO: Use this to replace set_authmode, set_privacy, set_ieee8021x, 1619 * set_generic_elem, and hapd_set_ssid. 1620 */ 1621 1622 wpa_printf(MSG_DEBUG, "atheros: set_ap - pairwise_ciphers=0x%x " 1623 "group_cipher=0x%x key_mgmt_suites=0x%x auth_algs=0x%x " 1624 "wpa_version=0x%x privacy=%d interworking=%d", 1625 params->pairwise_ciphers, params->group_cipher, 1626 params->key_mgmt_suites, params->auth_algs, 1627 params->wpa_version, params->privacy, params->interworking); 1628 wpa_hexdump_ascii(MSG_DEBUG, "atheros: SSID", 1629 params->ssid, params->ssid_len); 1630 if (params->hessid) 1631 wpa_printf(MSG_DEBUG, "atheros: HESSID " MACSTR, 1632 MAC2STR(params->hessid)); 1633 wpa_hexdump_buf(MSG_DEBUG, "atheros: beacon_ies", 1634 params->beacon_ies); 1635 wpa_hexdump_buf(MSG_DEBUG, "atheros: proberesp_ies", 1636 params->proberesp_ies); 1637 wpa_hexdump_buf(MSG_DEBUG, "atheros: assocresp_ies", 1638 params->assocresp_ies); 1639 1640 return 0; 1641} 1642 1643 1644#ifdef CONFIG_IEEE80211R 1645 1646static int atheros_send_mgmt(void *priv, const u8 *frm, size_t data_len, 1647 int noack) 1648{ 1649 struct atheros_driver_data *drv = priv; 1650 u8 buf[1510]; 1651 const struct ieee80211_mgmt *mgmt; 1652 struct ieee80211req_mgmtbuf *mgmt_frm; 1653 1654 mgmt = (const struct ieee80211_mgmt *) frm; 1655 wpa_printf(MSG_DEBUG, "%s frmlen = %lu " MACSTR, __func__, 1656 (unsigned long) data_len, MAC2STR(mgmt->da)); 1657 mgmt_frm = (struct ieee80211req_mgmtbuf *) buf; 1658 memcpy(mgmt_frm->macaddr, (u8 *)mgmt->da, IEEE80211_ADDR_LEN); 1659 mgmt_frm->buflen = data_len; 1660 if (&mgmt_frm->buf[0] + data_len > buf + sizeof(buf)) { 1661 wpa_printf(MSG_INFO, "atheros: Too long frame for " 1662 "atheros_send_mgmt (%u)", (unsigned int) data_len); 1663 return -1; 1664 } 1665 os_memcpy(&mgmt_frm->buf[0], frm, data_len); 1666 return set80211priv(drv, IEEE80211_IOCTL_SEND_MGMT, mgmt_frm, 1667 sizeof(struct ieee80211req_mgmtbuf) + data_len); 1668} 1669 1670 1671static int atheros_add_tspec(void *priv, const u8 *addr, u8 *tspec_ie, 1672 size_t tspec_ielen) 1673{ 1674 struct atheros_driver_data *drv = priv; 1675 int retv; 1676 struct ieee80211req_res req; 1677 struct ieee80211req_res_addts *addts = &req.u.addts; 1678 1679 wpa_printf(MSG_DEBUG, "%s", __func__); 1680 req.type = IEEE80211_RESREQ_ADDTS; 1681 os_memcpy(&req.macaddr[0], addr, IEEE80211_ADDR_LEN); 1682 os_memcpy(addts->tspecie, tspec_ie, tspec_ielen); 1683 retv = set80211priv(drv, IEEE80211_IOCTL_RES_REQ, &req, 1684 sizeof(struct ieee80211req_res)); 1685 if (retv < 0) { 1686 wpa_printf(MSG_DEBUG, "%s IEEE80211_IOCTL_RES_REQ FAILED " 1687 "retv = %d", __func__, retv); 1688 return -1; 1689 } 1690 os_memcpy(tspec_ie, addts->tspecie, tspec_ielen); 1691 return addts->status; 1692} 1693 1694 1695static int atheros_add_sta_node(void *priv, const u8 *addr, u16 auth_alg) 1696{ 1697 struct atheros_driver_data *drv = priv; 1698 struct ieee80211req_res req; 1699 struct ieee80211req_res_addnode *addnode = &req.u.addnode; 1700 1701 wpa_printf(MSG_DEBUG, "%s", __func__); 1702 req.type = IEEE80211_RESREQ_ADDNODE; 1703 os_memcpy(&req.macaddr[0], addr, IEEE80211_ADDR_LEN); 1704 addnode->auth_alg = auth_alg; 1705 return set80211priv(drv, IEEE80211_IOCTL_RES_REQ, &req, 1706 sizeof(struct ieee80211req_res)); 1707} 1708 1709#endif /* CONFIG_IEEE80211R */ 1710 1711 1712const struct wpa_driver_ops wpa_driver_atheros_ops = { 1713 .name = "atheros", 1714 .hapd_init = atheros_init, 1715 .hapd_deinit = atheros_deinit, 1716 .set_ieee8021x = atheros_set_ieee8021x, 1717 .set_privacy = atheros_set_privacy, 1718 .set_key = atheros_set_key, 1719 .get_seqnum = atheros_get_seqnum, 1720 .flush = atheros_flush, 1721 .set_generic_elem = atheros_set_opt_ie, 1722 .sta_set_flags = atheros_sta_set_flags, 1723 .read_sta_data = atheros_read_sta_driver_data, 1724 .hapd_send_eapol = atheros_send_eapol, 1725 .sta_disassoc = atheros_sta_disassoc, 1726 .sta_deauth = atheros_sta_deauth, 1727 .hapd_set_ssid = atheros_set_ssid, 1728 .hapd_get_ssid = atheros_get_ssid, 1729 .set_countermeasures = atheros_set_countermeasures, 1730 .sta_clear_stats = atheros_sta_clear_stats, 1731 .commit = atheros_commit, 1732 .set_ap_wps_ie = atheros_set_ap_wps_ie, 1733 .set_authmode = atheros_set_authmode, 1734 .set_ap = atheros_set_ap, 1735#ifdef CONFIG_IEEE80211R 1736 .sta_assoc = atheros_sta_assoc, 1737 .sta_auth = atheros_sta_auth, 1738 .send_mlme = atheros_send_mgmt, 1739 .add_tspec = atheros_add_tspec, 1740 .add_sta_node = atheros_add_sta_node, 1741#endif /* CONFIG_IEEE80211R */ 1742}; 1743