1526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* 2526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * WPA Supplicant - driver interaction with old Broadcom wl.o driver 3526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Copyright (c) 2004, Nikki Chumkov <nikki@gattaca.ru> 4526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Copyright (c) 2004, Jouni Malinen <j@w1.fi> 5526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 6526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This program is free software; you can redistribute it and/or modify 7526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * it under the terms of the GNU General Public License version 2 as 8526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * published by the Free Software Foundation. 9526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 10526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Alternatively, this software may be distributed under the terms of BSD 11526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * license. 12526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 13526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * See README and COPYING for more details. 14526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 15526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Please note that the newer Broadcom driver ("hybrid Linux driver") supports 16526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Linux wireless extensions and does not need (or even work) with this old 17526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * driver wrapper. Use driver_wext.c with that driver. 18526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 19526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 20526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "includes.h" 21526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 22526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include <sys/ioctl.h> 23526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 24526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "common.h" 25526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 26526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#if 0 27526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include <netpacket/packet.h> 28526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include <net/ethernet.h> /* the L2 protocols */ 29526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#else 30526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include <linux/if_packet.h> 31526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include <linux/if_ether.h> /* The L2 protocols */ 32526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif 33526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include <net/if.h> 34526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include <typedefs.h> 35526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 36526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* wlioctl.h is a Broadcom header file and it is available, e.g., from Linksys 37526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * WRT54G GPL tarball. */ 38526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include <wlioctl.h> 39526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 40526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "driver.h" 41526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "eloop.h" 42526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 43526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct wpa_driver_broadcom_data { 44526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void *ctx; 45526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int ioctl_sock; 46526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int event_sock; 47526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char ifname[IFNAMSIZ + 1]; 48526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}; 49526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 50526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 51526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifndef WLC_DEAUTHENTICATE 52526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define WLC_DEAUTHENTICATE 143 53526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif 54526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifndef WLC_DEAUTHENTICATE_WITH_REASON 55526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define WLC_DEAUTHENTICATE_WITH_REASON 201 56526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif 57526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifndef WLC_SET_TKIP_COUNTERMEASURES 58526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define WLC_SET_TKIP_COUNTERMEASURES 202 59526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif 60526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 61526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#if !defined(PSK_ENABLED) /* NEW driver interface */ 62526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define WL_VERSION 360130 63526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* wireless authentication bit vector */ 64526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define WPA_ENABLED 1 65526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define PSK_ENABLED 2 66526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 67526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define WAUTH_WPA_ENABLED(wauth) ((wauth) & WPA_ENABLED) 68526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define WAUTH_PSK_ENABLED(wauth) ((wauth) & PSK_ENABLED) 69526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define WAUTH_ENABLED(wauth) ((wauth) & (WPA_ENABLED | PSK_ENABLED)) 70526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 71526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define WSEC_PRIMARY_KEY WL_PRIMARY_KEY 72526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 73526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidttypedef wl_wsec_key_t wsec_key_t; 74526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif 75526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 76526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidttypedef struct { 77526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt uint32 val; 78526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct ether_addr ea; 79526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt uint16 res; 80526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} wlc_deauth_t; 81526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 82526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 83526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void wpa_driver_broadcom_scan_timeout(void *eloop_ctx, 84526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void *timeout_ctx); 85526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 86526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int broadcom_ioctl(struct wpa_driver_broadcom_data *drv, int cmd, 87526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void *buf, int len) 88526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 89526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct ifreq ifr; 90526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wl_ioctl_t ioc; 91526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int ret = 0; 92526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 93526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_MSGDUMP, "BROADCOM: wlioctl(%s,%d,len=%d,val=%p)", 94526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt drv->ifname, cmd, len, buf); 95526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* wpa_hexdump(MSG_MSGDUMP, "BROADCOM: wlioctl buf", buf, len); */ 96526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 97526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ioc.cmd = cmd; 98526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ioc.buf = buf; 99526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ioc.len = len; 100526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_strlcpy(ifr.ifr_name, drv->ifname, IFNAMSIZ); 101526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ifr.ifr_data = (caddr_t) &ioc; 102526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if ((ret = ioctl(drv->ioctl_sock, SIOCDEVPRIVATE, &ifr)) < 0) { 103526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (cmd != WLC_GET_MAGIC) 104526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt perror(ifr.ifr_name); 105526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_MSGDUMP, "BROADCOM: wlioctl cmd=%d res=%d", 106526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt cmd, ret); 107526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 108526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 109526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return ret; 110526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 111526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 112526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int wpa_driver_broadcom_get_bssid(void *priv, u8 *bssid) 113526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 114526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_driver_broadcom_data *drv = priv; 115526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (broadcom_ioctl(drv, WLC_GET_BSSID, bssid, ETH_ALEN) == 0) 116526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 117526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 118526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memset(bssid, 0, ETH_ALEN); 119526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 120526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 121526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 122526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int wpa_driver_broadcom_get_ssid(void *priv, u8 *ssid) 123526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 124526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_driver_broadcom_data *drv = priv; 125526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wlc_ssid_t s; 126526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 127526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (broadcom_ioctl(drv, WLC_GET_SSID, &s, sizeof(s)) == -1) 128526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 129526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 130526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(ssid, s.SSID, s.SSID_len); 131526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return s.SSID_len; 132526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 133526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 134526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int wpa_driver_broadcom_set_wpa(void *priv, int enable) 135526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 136526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_driver_broadcom_data *drv = priv; 137526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt unsigned int wauth, wsec; 138526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct ether_addr ea; 139526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 140526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memset(&ea, enable ? 0xff : 0, sizeof(ea)); 141526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (broadcom_ioctl(drv, WLC_GET_WPA_AUTH, &wauth, sizeof(wauth)) == 142526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt -1 || 143526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt broadcom_ioctl(drv, WLC_GET_WSEC, &wsec, sizeof(wsec)) == -1) 144526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 145526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 146526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (enable) { 147526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wauth = PSK_ENABLED; 148526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wsec = TKIP_ENABLED; 149526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else { 150526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wauth = 255; 151526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wsec &= ~(TKIP_ENABLED | AES_ENABLED); 152526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 153526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 154526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (broadcom_ioctl(drv, WLC_SET_WPA_AUTH, &wauth, sizeof(wauth)) == 155526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt -1 || 156526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt broadcom_ioctl(drv, WLC_SET_WSEC, &wsec, sizeof(wsec)) == -1) 157526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 158526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 159526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* FIX: magic number / error handling? */ 160526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt broadcom_ioctl(drv, 122, &ea, sizeof(ea)); 161526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 162526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 163526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 164526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 165526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int wpa_driver_broadcom_set_key(void *priv, wpa_alg alg, 166526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const u8 *addr, int key_idx, int set_tx, 167526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const u8 *seq, size_t seq_len, 168526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const u8 *key, size_t key_len) 169526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 170526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_driver_broadcom_data *drv = priv; 171526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int ret; 172526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wsec_key_t wkt; 173526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 174526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memset(&wkt, 0, sizeof wkt); 175526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_MSGDUMP, "BROADCOM: SET %sKEY[%d] alg=%d", 176526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt set_tx ? "PRIMARY " : "", key_idx, alg); 177526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (key && key_len > 0) 178526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_hexdump_key(MSG_MSGDUMP, "BROADCOM: key", key, key_len); 179526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 180526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt switch (alg) { 181526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case WPA_ALG_NONE: 182526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wkt.algo = CRYPTO_ALGO_OFF; 183526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 184526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case WPA_ALG_WEP: 185526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wkt.algo = CRYPTO_ALGO_WEP128; /* CRYPTO_ALGO_WEP1? */ 186526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 187526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case WPA_ALG_TKIP: 188526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wkt.algo = 0; /* CRYPTO_ALGO_TKIP? */ 189526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 190526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case WPA_ALG_CCMP: 191526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wkt.algo = 0; /* CRYPTO_ALGO_AES_CCM; 192526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * AES_OCB_MSDU, AES_OCB_MPDU? */ 193526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 194526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt default: 195526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wkt.algo = CRYPTO_ALGO_NALG; 196526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 197526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 198526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 199526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (seq && seq_len > 0) 200526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "BROADCOM: SEQ", seq, seq_len); 201526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 202526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (addr) 203526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "BROADCOM: addr", addr, ETH_ALEN); 204526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 205526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wkt.index = key_idx; 206526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wkt.len = key_len; 207526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (key && key_len > 0) { 208526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(wkt.data, key, key_len); 209526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (key_len == 32) { 210526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* hack hack hack XXX */ 211526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(&wkt.data[16], &key[24], 8); 212526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(&wkt.data[24], &key[16], 8); 213526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 214526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 215526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* wkt.algo = CRYPTO_ALGO_...; */ 216526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wkt.flags = set_tx ? 0 : WSEC_PRIMARY_KEY; 217526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (addr && set_tx) 218526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(&wkt.ea, addr, sizeof(wkt.ea)); 219526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = broadcom_ioctl(drv, WLC_SET_KEY, &wkt, sizeof(wkt)); 220526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (addr && set_tx) { 221526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* FIX: magic number / error handling? */ 222526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt broadcom_ioctl(drv, 121, &wkt.ea, sizeof(wkt.ea)); 223526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 224526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return ret; 225526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 226526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 227526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 228526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void wpa_driver_broadcom_event_receive(int sock, void *ctx, 229526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void *sock_ctx) 230526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 231526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char buf[8192]; 232526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int left; 233526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wl_wpa_header_t *wwh; 234526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt union wpa_event_data data; 235526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 236526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if ((left = recv(sock, buf, sizeof buf, 0)) < 0) 237526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 238526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 239526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_hexdump(MSG_DEBUG, "RECEIVE EVENT", (u8 *) buf, left); 240526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 241526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if ((size_t) left < sizeof(wl_wpa_header_t)) 242526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 243526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 244526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wwh = (wl_wpa_header_t *) buf; 245526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 246526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (wwh->snap.type != WL_WPA_ETHER_TYPE) 247526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 248526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (os_memcmp(&wwh->snap, wl_wpa_snap_template, 6) != 0) 249526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 250526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 251526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memset(&data, 0, sizeof(data)); 252526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 253526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt switch (wwh->type) { 254526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case WLC_ASSOC_MSG: 255526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt left -= WL_WPA_HEADER_LEN; 256526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "BROADCOM: ASSOC MESSAGE (left: %d)", 257526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt left); 258526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (left > 0) { 259526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data.assoc_info.resp_ies = os_malloc(left); 260526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data.assoc_info.resp_ies == NULL) 261526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 262526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(data.assoc_info.resp_ies, 263526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt buf + WL_WPA_HEADER_LEN, left); 264526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data.assoc_info.resp_ies_len = left; 265526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "BROADCOM: copying %d bytes " 266526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "into resp_ies", 267526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data.assoc_info.resp_ies, left); 268526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 269526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* data.assoc_info.req_ies = NULL; */ 270526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* data.assoc_info.req_ies_len = 0; */ 271526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 272526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_supplicant_event(ctx, EVENT_ASSOCINFO, &data); 273526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_supplicant_event(ctx, EVENT_ASSOC, NULL); 274526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 275526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case WLC_DISASSOC_MSG: 276526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "BROADCOM: DISASSOC MESSAGE"); 277526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_supplicant_event(ctx, EVENT_DISASSOC, NULL); 278526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 279526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case WLC_PTK_MIC_MSG: 280526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "BROADCOM: PTK MIC MSG MESSAGE"); 281526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data.michael_mic_failure.unicast = 1; 282526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_supplicant_event(ctx, EVENT_MICHAEL_MIC_FAILURE, &data); 283526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 284526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case WLC_GTK_MIC_MSG: 285526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "BROADCOM: GTK MIC MSG MESSAGE"); 286526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data.michael_mic_failure.unicast = 0; 287526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_supplicant_event(ctx, EVENT_MICHAEL_MIC_FAILURE, &data); 288526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 289526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt default: 290526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "BROADCOM: UNKNOWN MESSAGE (%d)", 291526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wwh->type); 292526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 293526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 294526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(data.assoc_info.resp_ies); 295526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 296526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 297526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void * wpa_driver_broadcom_init(void *ctx, const char *ifname) 298526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 299526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int s; 300526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct sockaddr_ll ll; 301526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_driver_broadcom_data *drv; 302526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct ifreq ifr; 303526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 304526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* open socket to kernel */ 305526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 306526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt perror("socket"); 307526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 308526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 309526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* do it */ 310526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); 311526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) { 312526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt perror(ifr.ifr_name); 313526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 314526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 315526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 316526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 317526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt drv = os_zalloc(sizeof(*drv)); 318526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (drv == NULL) 319526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 320526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt drv->ctx = ctx; 321526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname)); 322526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt drv->ioctl_sock = s; 323526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 324526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt s = socket(PF_PACKET, SOCK_RAW, ntohs(ETH_P_802_2)); 325526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (s < 0) { 326526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt perror("socket(PF_PACKET, SOCK_RAW, ntohs(ETH_P_802_2))"); 327526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt close(drv->ioctl_sock); 328526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(drv); 329526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 330526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 331526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 332526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memset(&ll, 0, sizeof(ll)); 333526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ll.sll_family = AF_PACKET; 334526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ll.sll_protocol = ntohs(ETH_P_802_2); 335526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ll.sll_ifindex = ifr.ifr_ifindex; 336526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ll.sll_hatype = 0; 337526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ll.sll_pkttype = PACKET_HOST; 338526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ll.sll_halen = 0; 339526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 340526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (bind(s, (struct sockaddr *) &ll, sizeof(ll)) < 0) { 341526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt perror("bind(netlink)"); 342526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt close(s); 343526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt close(drv->ioctl_sock); 344526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(drv); 345526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 346526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 347526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 348526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop_register_read_sock(s, wpa_driver_broadcom_event_receive, ctx, 349526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt NULL); 350526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt drv->event_sock = s; 351526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 352526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return drv; 353526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 354526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 355526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void wpa_driver_broadcom_deinit(void *priv) 356526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 357526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_driver_broadcom_data *drv = priv; 358526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop_cancel_timeout(wpa_driver_broadcom_scan_timeout, drv, drv->ctx); 359526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop_unregister_read_sock(drv->event_sock); 360526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt close(drv->event_sock); 361526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt close(drv->ioctl_sock); 362526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(drv); 363526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 364526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 365526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int wpa_driver_broadcom_set_countermeasures(void *priv, 366526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int enabled) 367526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 368526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#if 0 369526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_driver_broadcom_data *drv = priv; 370526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* FIX: ? */ 371526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return broadcom_ioctl(drv, WLC_SET_TKIP_COUNTERMEASURES, &enabled, 372526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sizeof(enabled)); 373526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#else 374526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 375526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif 376526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 377526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 378526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int wpa_driver_broadcom_set_drop_unencrypted(void *priv, int enabled) 379526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 380526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_driver_broadcom_data *drv = priv; 381526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* SET_EAP_RESTRICT, SET_WEP_RESTRICT */ 382526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int restrict = (enabled ? 1 : 0); 383526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 384526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (broadcom_ioctl(drv, WLC_SET_WEP_RESTRICT, 385526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &restrict, sizeof(restrict)) < 0 || 386526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt broadcom_ioctl(drv, WLC_SET_EAP_RESTRICT, 387526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &restrict, sizeof(restrict)) < 0) 388526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 389526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 390526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 391526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 392526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 393526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void wpa_driver_broadcom_scan_timeout(void *eloop_ctx, 394526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void *timeout_ctx) 395526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 396526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "Scan timeout - try to get results"); 397526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL); 398526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 399526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 400526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int wpa_driver_broadcom_scan(void *priv, const u8 *ssid, 401526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t ssid_len) 402526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 403526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_driver_broadcom_data *drv = priv; 404526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wlc_ssid_t wst = { 0, "" }; 405526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 406526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ssid && ssid_len > 0 && ssid_len <= sizeof(wst.SSID)) { 407526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wst.SSID_len = ssid_len; 408526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(wst.SSID, ssid, ssid_len); 409526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 410526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 411526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (broadcom_ioctl(drv, WLC_SCAN, &wst, sizeof(wst)) < 0) 412526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 413526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 414526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop_cancel_timeout(wpa_driver_broadcom_scan_timeout, drv, drv->ctx); 415526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop_register_timeout(3, 0, wpa_driver_broadcom_scan_timeout, drv, 416526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt drv->ctx); 417526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 418526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 419526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 420526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 421526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic const int frequency_list[] = { 422526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 2412, 2417, 2422, 2427, 2432, 2437, 2442, 423526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 2447, 2452, 2457, 2462, 2467, 2472, 2484 424526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}; 425526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 426526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct bss_ie_hdr { 427526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 elem_id; 428526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 len; 429526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 oui[3]; 430526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* u8 oui_type; */ 431526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* u16 version; */ 432526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} __attribute__ ((packed)); 433526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 434526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int 435526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtwpa_driver_broadcom_get_scan_results(void *priv, 436526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_scan_result *results, 437526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t max_size) 438526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 439526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_driver_broadcom_data *drv = priv; 440526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char *buf; 441526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wl_scan_results_t *wsr; 442526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wl_bss_info_t *wbi; 443526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t ap_num; 444526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 445526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt buf = os_malloc(WLC_IOCTL_MAXLEN); 446526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (buf == NULL) 447526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 448526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 449526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wsr = (wl_scan_results_t *) buf; 450526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 451526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wsr->buflen = WLC_IOCTL_MAXLEN - sizeof(wsr); 452526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wsr->version = 107; 453526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wsr->count = 0; 454526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 455526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (broadcom_ioctl(drv, WLC_SCAN_RESULTS, buf, WLC_IOCTL_MAXLEN) < 0) { 456526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(buf); 457526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 458526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 459526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 460526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memset(results, 0, max_size * sizeof(struct wpa_scan_result)); 461526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 462526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (ap_num = 0, wbi = wsr->bss_info; ap_num < wsr->count; ++ap_num) { 463526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int left; 464526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct bss_ie_hdr *ie; 465526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 466526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(results[ap_num].bssid, &wbi->BSSID, ETH_ALEN); 467526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(results[ap_num].ssid, wbi->SSID, wbi->SSID_len); 468526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt results[ap_num].ssid_len = wbi->SSID_len; 469526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt results[ap_num].freq = frequency_list[wbi->channel - 1]; 470526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* get ie's */ 471526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "BROADCOM: AP IEs", 472526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (u8 *) wbi + sizeof(*wbi), wbi->ie_length); 473526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ie = (struct bss_ie_hdr *) ((u8 *) wbi + sizeof(*wbi)); 474526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (left = wbi->ie_length; left > 0; 475526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt left -= (ie->len + 2), ie = (struct bss_ie_hdr *) 476526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ((u8 *) ie + 2 + ie->len)) { 477526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_MSGDUMP, "BROADCOM: IE: id:%x, len:%d", 478526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ie->elem_id, ie->len); 479526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ie->len >= 3) 480526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_MSGDUMP, 481526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "BROADCOM: oui:%02x%02x%02x", 482526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ie->oui[0], ie->oui[1], ie->oui[2]); 483526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ie->elem_id != 0xdd || 484526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ie->len < 6 || 485526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcmp(ie->oui, WPA_OUI, 3) != 0) 486526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt continue; 487526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(results[ap_num].wpa_ie, ie, ie->len + 2); 488526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt results[ap_num].wpa_ie_len = ie->len + 2; 489526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 490526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 491526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 492526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wbi = (wl_bss_info_t *) ((u8 *) wbi + wbi->length); 493526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 494526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 495526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_MSGDUMP, "Received %d bytes of scan results (%lu " 496526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "BSSes)", 497526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wsr->buflen, (unsigned long) ap_num); 498526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 499526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(buf); 500526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return ap_num; 501526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 502526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 503526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int wpa_driver_broadcom_deauthenticate(void *priv, const u8 *addr, 504526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int reason_code) 505526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 506526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_driver_broadcom_data *drv = priv; 507526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wlc_deauth_t wdt; 508526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wdt.val = reason_code; 509526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(&wdt.ea, addr, sizeof wdt.ea); 510526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wdt.res = 0x7fff; 511526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return broadcom_ioctl(drv, WLC_DEAUTHENTICATE_WITH_REASON, &wdt, 512526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sizeof(wdt)); 513526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 514526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 515526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int wpa_driver_broadcom_disassociate(void *priv, const u8 *addr, 516526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int reason_code) 517526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 518526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_driver_broadcom_data *drv = priv; 519526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return broadcom_ioctl(drv, WLC_DISASSOC, 0, 0); 520526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 521526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 522526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int 523526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtwpa_driver_broadcom_associate(void *priv, 524526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_driver_associate_params *params) 525526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 526526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_driver_broadcom_data *drv = priv; 527526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wlc_ssid_t s; 528526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int infra = 1; 529526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int auth = 0; 530526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int wsec = 4; 531526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int dummy; 532526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int wpa_auth; 533526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 534526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt s.SSID_len = params->ssid_len; 535526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(s.SSID, params->ssid, params->ssid_len); 536526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 537526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt switch (params->pairwise_suite) { 538526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case CIPHER_WEP40: 539526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case CIPHER_WEP104: 540526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wsec = 1; 541526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 542526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 543526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case CIPHER_TKIP: 544526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wsec = 2; 545526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 546526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 547526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case CIPHER_CCMP: 548526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wsec = 4; 549526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 550526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 551526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt default: 552526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wsec = 0; 553526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 554526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 555526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 556526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt switch (params->key_mgmt_suite) { 557526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case KEY_MGMT_802_1X: 558526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_auth = 1; 559526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 560526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 561526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case KEY_MGMT_PSK: 562526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_auth = 2; 563526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 564526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 565526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt default: 566526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_auth = 255; 567526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 568526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 569526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 570526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* printf("broadcom_associate: %u %u %u\n", pairwise_suite, 571526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * group_suite, key_mgmt_suite); 572526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * broadcom_ioctl(ifname, WLC_GET_WSEC, &wsec, sizeof(wsec)); 573526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * wl join uses wlc_sec_wep here, not wlc_set_wsec */ 574526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 575526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (broadcom_ioctl(drv, WLC_SET_WSEC, &wsec, sizeof(wsec)) < 0 || 576526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt broadcom_ioctl(drv, WLC_SET_WPA_AUTH, &wpa_auth, 577526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sizeof(wpa_auth)) < 0 || 578526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt broadcom_ioctl(drv, WLC_GET_WEP, &dummy, sizeof(dummy)) < 0 || 579526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt broadcom_ioctl(drv, WLC_SET_INFRA, &infra, sizeof(infra)) < 0 || 580526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt broadcom_ioctl(drv, WLC_SET_AUTH, &auth, sizeof(auth)) < 0 || 581526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt broadcom_ioctl(drv, WLC_SET_WEP, &wsec, sizeof(wsec)) < 0 || 582526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt broadcom_ioctl(drv, WLC_SET_SSID, &s, sizeof(s)) < 0) 583526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 584526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 585526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 586526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 587526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 588526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtconst struct wpa_driver_ops wpa_driver_broadcom_ops = { 589526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt .name = "broadcom", 590526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt .desc = "Broadcom wl.o driver", 591526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt .get_bssid = wpa_driver_broadcom_get_bssid, 592526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt .get_ssid = wpa_driver_broadcom_get_ssid, 593526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt .set_wpa = wpa_driver_broadcom_set_wpa, 594526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt .set_key = wpa_driver_broadcom_set_key, 595526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt .init = wpa_driver_broadcom_init, 596526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt .deinit = wpa_driver_broadcom_deinit, 597526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt .set_countermeasures = wpa_driver_broadcom_set_countermeasures, 598526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt .set_drop_unencrypted = wpa_driver_broadcom_set_drop_unencrypted, 599526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt .scan = wpa_driver_broadcom_scan, 600526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt .get_scan_results = wpa_driver_broadcom_get_scan_results, 601526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt .deauthenticate = wpa_driver_broadcom_deauthenticate, 602526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt .disassociate = wpa_driver_broadcom_disassociate, 603526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt .associate = wpa_driver_broadcom_associate, 604526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}; 605