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