summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/bcmdhd/wl_cfg80211.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/bcmdhd/wl_cfg80211.c')
-rw-r--r--drivers/net/wireless/bcmdhd/wl_cfg80211.c854
1 files changed, 556 insertions, 298 deletions
diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.c b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
index 2242a7adc0c..20bbb208291 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfg80211.c
+++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
@@ -1,9 +1,9 @@
/*
* Linux cfg80211 driver
*
- * Copyright (C) 1999-2011, Broadcom Corporation
+ * Copyright (C) 1999-2012, Broadcom Corporation
*
- * Unless you and Broadcom execute a separate written software license
+ * Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
* under the terms of the GNU General Public License version 2 (the "GPL"),
* available at http://www.broadcom.com/licenses/GPLv2.php, with the
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: wl_cfg80211.c,v 1.1.4.1.2.14 2011/02/09 01:40:07 Exp $
+ * $Id: wl_cfg80211.c 310409 2012-01-24 18:47:09Z $
*/
#include <typedefs.h>
@@ -60,8 +60,41 @@
#include <wl_cfg80211.h>
#include <wl_cfgp2p.h>
+#ifdef BCMWAPI_WPI
+/* these items should evetually go into wireless.h of the linux system headfile dir */
+#ifndef IW_ENCODE_ALG_SM4
+#define IW_ENCODE_ALG_SM4 0x20
+#endif
+
+#ifndef IW_AUTH_WAPI_ENABLED
+#define IW_AUTH_WAPI_ENABLED 0x20
+#endif
+
+#ifndef IW_AUTH_WAPI_VERSION_1
+#define IW_AUTH_WAPI_VERSION_1 0x00000008
+#endif
+
+#ifndef IW_AUTH_CIPHER_SMS4
+#define IW_AUTH_CIPHER_SMS4 0x00000020
+#endif
+
+#ifndef IW_AUTH_KEY_MGMT_WAPI_PSK
+#define IW_AUTH_KEY_MGMT_WAPI_PSK 4
+#endif
+
+#ifndef IW_AUTH_KEY_MGMT_WAPI_CERT
+#define IW_AUTH_KEY_MGMT_WAPI_CERT 8
+#endif
+#endif /* BCMWAPI_WPI */
+
+#ifdef BCMWAPI_WPI
+#define IW_WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED | SMS4_ENABLED))
+#else /* BCMWAPI_WPI */
+#define IW_WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED))
+#endif /* BCMWAPI_WPI */
+
+
static struct device *cfg80211_parent_dev = NULL;
-static int vsdb_supported = 0;
struct wl_priv *wlcfg_drv_priv = NULL;
u32 wl_dbg_level = WL_DBG_ERR;
@@ -69,17 +102,19 @@ u32 wl_dbg_level = WL_DBG_ERR;
#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
#define MAX_WAIT_TIME 1500
-#define WL_SCAN_ACTIVE_TIME 40
-#define WL_SCAN_PASSIVE_TIME 130
+#define WL_SCAN_ACTIVE_TIME 40 /* ms : Embedded default Active setting from DHD Driver */
+#define WL_SCAN_PASSIVE_TIME 130 /* ms: Embedded default Passive setting from DHD Driver */
+
+#define WL_CHANSPEC_CTL_SB_NONE WL_CHANSPEC_CTL_SB_LLL
+
#define DNGL_FUNC(func, parameters) func parameters;
#define COEX_DHCP
-
/* Set this to 1 to use a seperate interface (p2p0)
* for p2p operations.
*/
-#define ENABLE_P2P_INTERFACE 1
+#define ENABLE_P2P_INTERFACE 0
/* This is to override regulatory domains defined in cfg80211 module (reg.c)
* By default world regulatory domain defined in reg.c puts the flags NL80211_RRF_PASSIVE_SCAN
@@ -220,8 +255,6 @@ static s32 wl_enq_event(struct wl_priv *wl, struct net_device *ndev, u32 type,
const wl_event_msg_t *msg, void *data);
static void wl_put_event(struct wl_event_q *e);
static void wl_wakeup_event(struct wl_priv *wl);
-static s32 wl_notify_connect_status_ap(struct wl_priv *wl, struct net_device *ndev,
- const wl_event_msg_t *e, void *data);
static s32 wl_notify_connect_status(struct wl_priv *wl,
struct net_device *ndev,
const wl_event_msg_t *e, void *data);
@@ -236,14 +269,16 @@ static s32 wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
const wl_event_msg_t *e, void *data);
static s32 wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
const wl_event_msg_t *e, void *data);
-static s32 wl_notify_pfn_status(struct wl_priv *wl, struct net_device *ndev,
- const wl_event_msg_t *e, void *data);
/*
* register/deregister parent device
*/
static void wl_cfg80211_clear_parent_dev(void);
/*
+ * ioctl utilites
+ */
+
+/*
* cfg80211 set_wiphy_params utilities
*/
static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold);
@@ -271,6 +306,10 @@ static s32 wl_set_key_mgmt(struct net_device *dev,
struct cfg80211_connect_params *sme);
static s32 wl_set_set_sharedkey(struct net_device *dev,
struct cfg80211_connect_params *sme);
+#ifdef BCMWAPI_WPI
+static s32 wl_set_set_wapi_ie(struct net_device *dev,
+ struct cfg80211_connect_params *sme);
+#endif
static s32 wl_get_assoc_ies(struct wl_priv *wl, struct net_device *ndev);
static void wl_ch_to_chanspec(int ch,
struct wl_join_params *join_params, size_t *join_params_size);
@@ -285,7 +324,7 @@ static s32 wl_cp_ie(struct wl_priv *wl, u8 *dst, u16 dst_size);
static u32 wl_get_ielen(struct wl_priv *wl);
-static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *dev);
+static struct wireless_dev *wl_alloc_wdev(struct device *dev);
static void wl_free_wdev(struct wl_priv *wl);
static s32 wl_inform_bss(struct wl_priv *wl);
@@ -376,18 +415,19 @@ int dhd_monitor_init(void *dhd_pub);
int dhd_monitor_uninit(void);
int dhd_start_xmit(struct sk_buff *skb, struct net_device *net);
-#define CHECK_SYS_UP(wlpriv) \
+
+#define CHECK_SYS_UP(wlpriv) \
do { \
- struct net_device *ndev = wl_to_prmry_ndev(wlpriv); \
+ struct net_device *ndev = wl_to_prmry_ndev(wlpriv); \
if (unlikely(!wl_get_drv_status(wlpriv, READY, ndev))) { \
- WL_INFO(("device is not ready\n")); \
- return -EIO; \
+ WL_INFO(("device is not ready\n")); \
+ return -EIO; \
} \
} while (0)
-#define IS_WPA_AKM(akm) ((akm) == RSN_AKM_NONE || \
- (akm) == RSN_AKM_UNSPECIFIED || \
+#define IS_WPA_AKM(akm) ((akm) == RSN_AKM_NONE || \
+ (akm) == RSN_AKM_UNSPECIFIED || \
(akm) == RSN_AKM_PSK)
@@ -539,8 +579,134 @@ static const u32 __wl_cipher_suites[] = {
WLAN_CIPHER_SUITE_TKIP,
WLAN_CIPHER_SUITE_CCMP,
WLAN_CIPHER_SUITE_AES_CMAC,
+#ifdef BCMWAPI_WPI
+ WLAN_CIPHER_SUITE_SMS4
+#endif
};
+/* IOCtl version read from targeted driver */
+static int ioctl_version;
+
+/* Return a new chanspec given a legacy chanspec
+ * Returns INVCHANSPEC on error
+ */
+static chanspec_t
+wl_chspec_from_legacy(chanspec_t legacy_chspec)
+{
+ chanspec_t chspec;
+
+ /* get the channel number */
+ chspec = LCHSPEC_CHANNEL(legacy_chspec);
+
+ /* convert the band */
+ if (LCHSPEC_IS2G(legacy_chspec)) {
+ chspec |= WL_CHANSPEC_BAND_2G;
+ } else {
+ chspec |= WL_CHANSPEC_BAND_5G;
+ }
+
+ /* convert the bw and sideband */
+ if (LCHSPEC_IS20(legacy_chspec)) {
+ chspec |= WL_CHANSPEC_BW_20;
+ } else {
+ chspec |= WL_CHANSPEC_BW_40;
+ if (LCHSPEC_CTL_SB(legacy_chspec) == WL_LCHANSPEC_CTL_SB_LOWER) {
+ chspec |= WL_CHANSPEC_CTL_SB_L;
+ } else {
+ chspec |= WL_CHANSPEC_CTL_SB_U;
+ }
+ }
+
+ if (wf_chspec_malformed(chspec)) {
+ WL_ERR(("wl_chspec_from_legacy: output chanspec (0x%04X) malformed\n",
+ chspec));
+ return INVCHANSPEC;
+ }
+
+ return chspec;
+}
+
+/* Return a legacy chanspec given a new chanspec
+ * Returns INVCHANSPEC on error
+ */
+static chanspec_t
+wl_chspec_to_legacy(chanspec_t chspec)
+{
+ chanspec_t lchspec;
+
+ if (wf_chspec_malformed(chspec)) {
+ WL_ERR(("wl_chspec_to_legacy: input chanspec (0x%04X) malformed\n",
+ chspec));
+ return INVCHANSPEC;
+ }
+
+ /* get the channel number */
+ lchspec = CHSPEC_CHANNEL(chspec);
+
+ /* convert the band */
+ if (CHSPEC_IS2G(chspec)) {
+ lchspec |= WL_LCHANSPEC_BAND_2G;
+ } else {
+ lchspec |= WL_LCHANSPEC_BAND_5G;
+ }
+
+ /* convert the bw and sideband */
+ if (CHSPEC_IS20(chspec)) {
+ lchspec |= WL_LCHANSPEC_BW_20;
+ lchspec |= WL_LCHANSPEC_CTL_SB_NONE;
+ } else if (CHSPEC_IS40(chspec)) {
+ lchspec |= WL_LCHANSPEC_BW_40;
+ if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_L) {
+ lchspec |= WL_LCHANSPEC_CTL_SB_LOWER;
+ } else {
+ lchspec |= WL_LCHANSPEC_CTL_SB_UPPER;
+ }
+ } else {
+ /* cannot express the bandwidth */
+ char chanbuf[CHANSPEC_STR_LEN];
+ WL_ERR((
+ "wl_chspec_to_legacy: unable to convert chanspec %s (0x%04X) "
+ "to pre-11ac format\n",
+ wf_chspec_ntoa(chspec, chanbuf), chspec));
+ return INVCHANSPEC;
+ }
+
+ return lchspec;
+}
+
+/* given a chanspec value, do the endian and chanspec version conversion to
+ * a chanspec_t value
+ * Returns INVCHANSPEC on error
+ */
+static chanspec_t
+wl_chspec_host_to_driver(chanspec_t chanspec)
+{
+ if (ioctl_version == 1) {
+ chanspec = wl_chspec_to_legacy(chanspec);
+ if (chanspec == INVCHANSPEC) {
+ return chanspec;
+ }
+ }
+ chanspec = htodchanspec(chanspec);
+
+ return chanspec;
+}
+
+/* given a chanspec value from the driver, do the endian and chanspec version conversion to
+ * a chanspec_t value
+ * Returns INVCHANSPEC on error
+ */
+static chanspec_t
+wl_chspec_driver_to_host(chanspec_t chanspec)
+{
+ chanspec = dtohchanspec(chanspec);
+ if (ioctl_version == 1) {
+ chanspec = wl_chspec_from_legacy(chanspec);
+ }
+
+ return chanspec;
+}
+
/* There isn't a lot of sense in it, but you can transmit anything you like */
static const struct ieee80211_txrx_stypes
wl_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
@@ -691,47 +857,43 @@ wl_validate_wps_ie(char *wps_ie, bool *pbc)
static chanspec_t wl_cfg80211_get_shared_freq(struct wiphy *wiphy)
{
- if (vsdb_supported) {
+ chanspec_t chspec;
+ int err = 0;
+ struct wl_priv *wl = wiphy_priv(wiphy);
+ struct net_device *dev = wl_to_prmry_ndev(wl);
+ struct ether_addr bssid;
+ struct wl_bss_info *bss = NULL;
+
+ if ((err = wldev_ioctl(dev, WLC_GET_BSSID, &bssid, sizeof(bssid), false))) {
+ /* STA interface is not associated. So start the new interface on a temp
+ * channel . Later proper channel will be applied by the above framework
+ * via set_channel (cfg80211 API).
+ */
+ WL_DBG(("Not associated. Return a temp channel. \n"));
return wf_chspec_aton(WL_P2P_TEMP_CHAN);
}
- else {
- chanspec_t chspec;
- int err = 0;
- struct wl_priv *wl = wiphy_priv(wiphy);
- struct net_device *dev = wl_to_prmry_ndev(wl);
- struct ether_addr bssid;
- struct wl_bss_info *bss = NULL;
- if ((err = wldev_ioctl(dev, WLC_GET_BSSID, &bssid, sizeof(bssid), false))) {
- /* STA interface is not associated. So start the new interface on a temp
- * channel . Later proper channel will be applied by the above framework
- * via set_channel (cfg80211 API).
- */
- WL_DBG(("Not associated. Return a temp channel. \n"));
- return wf_chspec_aton(WL_P2P_TEMP_CHAN);
- }
- *(u32 *) wl->extra_buf = htod32(WL_EXTRA_BUF_MAX);
- if ((err = wldev_ioctl(dev, WLC_GET_BSS_INFO, wl->extra_buf,
- sizeof(WL_EXTRA_BUF_MAX), false))) {
- WL_ERR(("Failed to get associated bss info, use temp channel \n"));
- chspec = wf_chspec_aton(WL_P2P_TEMP_CHAN);
- }
- else {
- bss = (struct wl_bss_info *) (wl->extra_buf + 4);
- chspec = bss->chanspec;
- WL_DBG(("Valid BSS Found. chanspec:%d \n", bss->chanspec));
- }
- return chspec;
+ *(u32 *) wl->extra_buf = htod32(WL_EXTRA_BUF_MAX);
+ if ((err = wldev_ioctl(dev, WLC_GET_BSS_INFO, wl->extra_buf,
+ sizeof(WL_EXTRA_BUF_MAX), false))) {
+ WL_ERR(("Failed to get associated bss info, use temp channel \n"));
+ chspec = wf_chspec_aton(WL_P2P_TEMP_CHAN);
+ }
+ else {
+ bss = (struct wl_bss_info *) (wl->extra_buf + 4);
+ chspec = bss->chanspec;
+ WL_DBG(("Valid BSS Found. chanspec:%d \n", bss->chanspec));
}
+
+ return chspec;
}
static struct net_device* wl_cfg80211_add_monitor_if(char *name)
{
- int ret = 0;
struct net_device* ndev = NULL;
- ret = dhd_add_monitor(name, &ndev);
+ dhd_add_monitor(name, &ndev);
WL_INFO(("wl_cfg80211_add_monitor_if net device returned: 0x%p\n", ndev));
return ndev;
}
@@ -752,7 +914,7 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name,
int (*net_attach)(void *dhdp, int ifidx);
bool rollback_lock = false;
- /* Use primary I/F for sending cmds down to firmware */
+ /* Use primary I/F for to send commands down */
_ndev = wl_to_prmry_ndev(wl);
WL_DBG(("if name: %s, type: %d\n", name, type));
@@ -859,7 +1021,7 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name,
}
vwdev->wiphy = wl->wdev->wiphy;
WL_INFO((" virtual interface(%s) is created memalloc done \n",
- wl->p2p->vir_ifname));
+ wl->p2p->vir_ifname));
vwdev->iftype = type;
_ndev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION);
_ndev->ieee80211_ptr = vwdev;
@@ -909,8 +1071,8 @@ wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, struct net_device *dev)
WL_DBG(("Enter\n"));
if (wl->p2p_net == dev) {
- /* Since there is no ifidx corresponding to p2p0, cmds to
- * firmware should be routed through primary I/F
+ /* Since there is no ifidx corresponding to p2p0,
+ * all commands should be routed through primary I/F
*/
dev = wl_to_prmry_ndev(wl);
}
@@ -924,6 +1086,7 @@ wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, struct net_device *dev)
wldev_iovar_setint(dev, "mpc", 1);
wl_set_p2p_status(wl, IF_DELETING);
ret = wl_cfgp2p_ifdel(wl, &p2p_mac);
+#if defined(DONGLEHOST)
/* Firmware could not delete the interface so we will not get WLC_E_IF
* event for cleaning the dhd virtual nw interace
* So lets do it here. Failures from fw will ensure the application to do
@@ -937,6 +1100,7 @@ wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, struct net_device *dev)
"HANG Notification sent to %s\n", ret, ndev->name));
wl_cfg80211_hang(ndev, WLAN_REASON_UNSPECIFIED);
}
+#endif /* defined(DONGLEHOST) */
/* Wait for any pending scan req to get aborted from the sysioc context */
timeout = wait_event_interruptible_timeout(wl->netif_change_event,
@@ -960,8 +1124,6 @@ wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev,
{
s32 ap = 0;
s32 infra = 0;
- s32 err = BCME_OK;
- s32 timeout = -1;
s32 wlif_type;
s32 mode = 0;
chanspec_t chspec;
@@ -1011,8 +1173,8 @@ wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev,
ndev->name, ap, infra, type));
wl_set_p2p_status(wl, IF_CHANGING);
wl_clr_p2p_status(wl, IF_CHANGED);
- err = wl_cfgp2p_ifchange(wl, &wl->p2p->int_addr, htod32(wlif_type), chspec);
- timeout = wait_event_interruptible_timeout(wl->netif_change_event,
+ wl_cfgp2p_ifchange(wl, &wl->p2p->int_addr, htod32(wlif_type), chspec);
+ wait_event_interruptible_timeout(wl->netif_change_event,
(wl_get_p2p_status(wl, IF_CHANGED) == true),
msecs_to_jiffies(MAX_WAIT_TIME));
wl_set_mode_by_netdev(wl, ndev, mode);
@@ -1037,18 +1199,16 @@ wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev,
}
s32
-wl_cfg80211_notify_ifadd(struct net_device *ndev, s32 idx, s32 bssidx,
- void* _net_attach)
+wl_cfg80211_notify_ifadd(struct net_device *ndev, s32 idx, s32 bssidx, void* _net_attach)
{
struct wl_priv *wl = wlcfg_drv_priv;
s32 ret = BCME_OK;
- WL_DBG(("Enter"));
if (!ndev) {
WL_ERR(("net is NULL\n"));
return 0;
}
if (wl->p2p_supported && wl_get_p2p_status(wl, IF_ADD)) {
- WL_DBG(("IF_ADD event called from dongle, old interface name: %s,"
+ WL_DBG(("IF_ADD event received, old interface name: %s,"
"new name: %s\n", ndev->name, wl->p2p->vir_ifname));
/* Assign the net device to CONNECT BSSCFG */
strncpy(ndev->name, wl->p2p->vir_ifname, IFNAMSIZ - 1);
@@ -1071,7 +1231,6 @@ wl_cfg80211_notify_ifdel(struct net_device *ndev)
struct wl_priv *wl = wlcfg_drv_priv;
bool rollback_lock = false;
s32 index = 0;
-
if (!ndev || !ndev->name) {
WL_ERR(("net is NULL\n"));
return 0;
@@ -1092,7 +1251,7 @@ wl_cfg80211_notify_ifdel(struct net_device *ndev)
if (rollback_lock)
rtnl_unlock();
}
- WL_ERR(("IF_DEL event called from dongle, net %x, vif name: %s\n",
+ WL_ERR(("IF_DEL event received, net %x, vif name: %s\n",
(unsigned int)ndev, wl->p2p->vir_ifname));
memset(wl->p2p->vir_ifname, '\0', IFNAMSIZ);
@@ -1146,8 +1305,8 @@ wl_cfg80211_notify_ifchange(void)
static void wl_scan_prep(struct wl_scan_params *params, struct cfg80211_scan_request *request)
{
- u32 n_ssids;
- u32 n_channels;
+ u32 n_ssids = request->n_ssids;
+ u32 n_channels = request->n_channels;
u16 channel;
chanspec_t chanspec;
s32 i, offset;
@@ -1176,13 +1335,6 @@ static void wl_scan_prep(struct wl_scan_params *params, struct cfg80211_scan_req
params->passive_time = htod32(params->passive_time);
params->home_time = htod32(params->home_time);
- /* if request is null just exit so it will be all channel broadcast scan */
- if (!request)
- return;
-
- n_ssids = request->n_ssids;
- n_channels = request->n_channels;
-
/* Copy channel array if applicable */
WL_SCAN(("### List of channelspecs to scan ###\n"));
if (n_channels > 0) {
@@ -1268,10 +1420,12 @@ wl_run_iscan(struct wl_iscan_ctrl *iscan, struct cfg80211_scan_request *request,
}
params = (struct wl_iscan_params *)kzalloc(params_size, GFP_KERNEL);
if (!params) {
- return -ENOMEM;
+ err = -ENOMEM;
+ goto done;
}
- wl_scan_prep(&params->params, request);
+ if (request != NULL)
+ wl_scan_prep(&params->params, request);
params->version = htod32(ISCAN_REQ_VERSION);
params->action = htod16(action);
@@ -1291,8 +1445,8 @@ wl_run_iscan(struct wl_iscan_ctrl *iscan, struct cfg80211_scan_request *request,
WL_ERR(("error (%d)\n", err));
}
}
-done:
kfree(params);
+done:
return err;
}
@@ -1319,7 +1473,6 @@ static s32 wl_do_iscan(struct wl_priv *wl, struct cfg80211_scan_request *request
return err;
}
-
static s32
wl_get_valid_channels(struct net_device *ndev, u8 *valid_chan_list, s32 size)
{
@@ -1338,7 +1491,6 @@ wl_get_valid_channels(struct net_device *ndev, u8 *valid_chan_list, s32 size)
return err;
}
-
static s32
wl_run_escan(struct wl_priv *wl, struct net_device *ndev,
struct cfg80211_scan_request *request, uint16 action)
@@ -1385,13 +1537,13 @@ wl_run_escan(struct wl_priv *wl, struct net_device *ndev,
goto exit;
}
- wl_scan_prep(&params->params, request);
+ if (request != NULL)
+ wl_scan_prep(&params->params, request);
params->version = htod32(ESCAN_REQ_VERSION);
params->action = htod16(action);
params->sync_id = htod16(0x1234);
if (params_size + sizeof("escan") >= WLC_IOCTL_MEDLEN) {
WL_ERR(("ioctl buffer length not sufficient\n"));
- kfree(params);
err = -ENOMEM;
goto exit;
}
@@ -1508,7 +1660,7 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
wpa_ie_fixed_t *wps_ie;
s32 passive_scan;
bool iscan_req;
- bool escan_req;
+ bool escan_req = false;
bool p2p_ssid;
s32 err = 0;
s32 i;
@@ -1746,7 +1898,6 @@ static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
s32 err = 0;
CHECK_SYS_UP(wl);
- WL_DBG(("Enter\n"));
if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
(wl->conf->rts_threshold != wiphy->rts_threshold)) {
wl->conf->rts_threshold = wiphy->rts_threshold;
@@ -1776,6 +1927,7 @@ static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
return err;
}
}
+
return err;
}
@@ -1886,6 +2038,13 @@ wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme)
if (is_wps_conn(sme))
val = WPA_AUTH_DISABLED;
+#ifdef BCMWAPI_WPI
+ if (sme->crypto.wpa_versions & NL80211_WAPI_VERSION_1) {
+ WL_DBG((" * wl_set_wpa_version, set wpa_auth"
+ " to WPA_AUTH_WAPI 0x400"));
+ val = WAPI_AUTH_PSK | WAPI_AUTH_UNSPECIFIED;
+ }
+#endif
WL_DBG(("setting wpa_auth to 0x%0x\n", val));
err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", val, bssidx);
if (unlikely(err)) {
@@ -1897,6 +2056,30 @@ wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme)
return err;
}
+#ifdef BCMWAPI_WPI
+static s32
+wl_set_set_wapi_ie(struct net_device *dev, struct cfg80211_connect_params *sme)
+{
+ struct wl_priv *wl = wlcfg_drv_priv;
+ s32 err = 0;
+ s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
+
+ WL_DBG((" %s \n", __FUNCTION__));
+
+ if (sme->crypto.wpa_versions & NL80211_WAPI_VERSION_1) {
+ err = wldev_iovar_setbuf_bsscfg(dev, "wapiie", sme->ie,
+ sme->ie_len, wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync);
+
+ if (unlikely(err)) {
+ WL_ERR(("===> set_wapi_ie Error (%d)\n", err));
+ return err;
+ }
+ } else
+ WL_DBG((" * skip \n"));
+ return err;
+}
+#endif /* BCMWAPI_WPI */
+
static s32
wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme)
{
@@ -1944,6 +2127,9 @@ wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme)
s32 pval = 0;
s32 gval = 0;
s32 err = 0;
+#ifdef BCMWAPI_WPI
+ s32 val = 0;
+#endif
s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
if (sme->crypto.n_ciphers_pairwise) {
@@ -1961,6 +2147,12 @@ wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme)
case WLAN_CIPHER_SUITE_AES_CMAC:
pval = AES_ENABLED;
break;
+#ifdef BCMWAPI_WPI
+ case WLAN_CIPHER_SUITE_SMS4:
+ val = SMS4_ENABLED;
+ pval = SMS4_ENABLED;
+ break;
+#endif
default:
WL_ERR(("invalid cipher pairwise (%d)\n",
sme->crypto.ciphers_pairwise[0]));
@@ -1982,6 +2174,12 @@ wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme)
case WLAN_CIPHER_SUITE_AES_CMAC:
gval = AES_ENABLED;
break;
+#ifdef BCMWAPI_WPI
+ case WLAN_CIPHER_SUITE_SMS4:
+ val = SMS4_ENABLED;
+ gval = SMS4_ENABLED;
+ break;
+#endif
default:
WL_ERR(("invalid cipher group (%d)\n",
sme->crypto.cipher_group));
@@ -1994,9 +2192,18 @@ wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme)
if (is_wps_conn(sme)) {
err = wldev_iovar_setint_bsscfg(dev, "wsec", 4, bssidx);
} else {
- WL_DBG((" NO, is_wps_conn, Set pval | gval to WSEC"));
- err = wldev_iovar_setint_bsscfg(dev, "wsec",
+#ifdef BCMWAPI_WPI
+ if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_SMS4) {
+ WL_DBG((" NO, is_wps_conn, WAPI set to SMS4_ENABLED"));
+ err = wldev_iovar_setint_bsscfg(dev, "wsec", val, bssidx);
+ } else {
+#endif
+ WL_DBG((" NO, is_wps_conn, Set pval | gval to WSEC"));
+ err = wldev_iovar_setint_bsscfg(dev, "wsec",
pval | gval, bssidx);
+#ifdef BCMWAPI_WPI
+ }
+#endif
}
if (unlikely(err)) {
WL_ERR(("error (%d)\n", err));
@@ -2052,6 +2259,22 @@ wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme)
return -EINVAL;
}
}
+#ifdef BCMWAPI_WPI
+ else if (val & (WAPI_AUTH_PSK | WAPI_AUTH_UNSPECIFIED)) {
+ switch (sme->crypto.akm_suites[0]) {
+ case WLAN_AKM_SUITE_WAPI_CERT:
+ val = WAPI_AUTH_UNSPECIFIED;
+ break;
+ case WLAN_AKM_SUITE_WAPI_PSK:
+ val = WAPI_AUTH_PSK;
+ break;
+ default:
+ WL_ERR(("invalid cipher group (%d)\n",
+ sme->crypto.cipher_group));
+ return -EINVAL;
+ }
+ }
+#endif
WL_DBG(("setting wpa_auth to %d\n", val));
err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", val, bssidx);
@@ -2083,9 +2306,17 @@ wl_set_set_sharedkey(struct net_device *dev,
WL_DBG(("wpa_versions 0x%x cipher_pairwise 0x%x\n",
sec->wpa_versions, sec->cipher_pairwise));
if (!(sec->wpa_versions & (NL80211_WPA_VERSION_1 |
+#ifdef BCMWAPI_WPI
+ NL80211_WPA_VERSION_2 | NL80211_WAPI_VERSION_1)) &&
+#else
NL80211_WPA_VERSION_2)) &&
+#endif
(sec->cipher_pairwise & (WLAN_CIPHER_SUITE_WEP40 |
+#ifdef BCMWAPI_WPI
+ WLAN_CIPHER_SUITE_WEP104 | WLAN_CIPHER_SUITE_SMS4)))
+#else
WLAN_CIPHER_SUITE_WEP104)))
+#endif
{
memset(&key, 0, sizeof(key));
key.len = (u32) sme->key_len;
@@ -2103,6 +2334,11 @@ wl_set_set_sharedkey(struct net_device *dev,
case WLAN_CIPHER_SUITE_WEP104:
key.algo = CRYPTO_ALGO_WEP128;
break;
+#ifdef BCMWAPI_WPI
+ case WLAN_CIPHER_SUITE_SMS4:
+ key.algo = CRYPTO_ALGO_SMS4;
+ break;
+#endif
default:
WL_ERR(("Invalid algorithm (%d)\n",
sme->crypto.ciphers_pairwise[0]));
@@ -2152,7 +2388,6 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
u32 chan_cnt = 0;
u8 wpsie[IE_MAX_LEN];
struct ether_addr bssid;
-
WL_DBG(("In\n"));
CHECK_SYS_UP(wl);
@@ -2240,18 +2475,37 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
chan->center_freq));
} else
wl->channel = 0;
+#ifdef BCMWAPI_WPI
+ WL_DBG(("1. enable wapi auth\n"));
+ if (sme->crypto.wpa_versions & NL80211_WAPI_VERSION_1) {
+ WL_DBG(("2. set wapi ie \n"));
+ err = wl_set_set_wapi_ie(dev, sme);
+ if (unlikely(err))
+ return err;
+ } else
+ WL_DBG(("2. Not wapi ie \n"));
+#endif
WL_DBG(("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len));
+ WL_DBG(("3. set wapi version \n"));
err = wl_set_wpa_version(dev, sme);
if (unlikely(err)) {
WL_ERR(("Invalid wpa_version\n"));
return err;
}
-
- err = wl_set_auth_type(dev, sme);
- if (unlikely(err)) {
- WL_ERR(("Invalid auth type\n"));
- return err;
+#ifdef BCMWAPI_WPI
+ if (sme->crypto.wpa_versions & NL80211_WAPI_VERSION_1)
+ WL_DBG(("4. WAPI Dont Set wl_set_auth_type\n"));
+ else {
+ WL_DBG(("4. wl_set_auth_type\n"));
+#endif
+ err = wl_set_auth_type(dev, sme);
+ if (unlikely(err)) {
+ WL_ERR(("Invalid auth type\n"));
+ return err;
+ }
+#ifdef BCMWAPI_WPI
}
+#endif
err = wl_set_set_cipher(dev, sme);
if (unlikely(err)) {
@@ -2313,7 +2567,7 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
ext_join_params->assoc.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK;
ext_join_params->assoc.chanspec_list[0] |= chspec;
ext_join_params->assoc.chanspec_list[0] =
- htodchanspec(ext_join_params->assoc.chanspec_list[0]);
+ wl_chspec_host_to_driver(ext_join_params->assoc.chanspec_list[0]);
}
ext_join_params->assoc.chanspec_num = htod32(ext_join_params->assoc.chanspec_num);
if (ext_join_params->ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
@@ -2576,6 +2830,12 @@ wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
key.algo = CRYPTO_ALGO_AES_CCM;
WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n"));
break;
+#ifdef BCMWAPI_WPI
+ case WLAN_CIPHER_SUITE_SMS4:
+ key.algo = CRYPTO_ALGO_SMS4;
+ WL_DBG(("WLAN_CIPHER_SUITE_SMS4\n"));
+ break;
+#endif
default:
WL_ERR(("Invalid cipher (0x%x)\n", params->cipher));
return -EINVAL;
@@ -2660,6 +2920,13 @@ wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
val = AES_ENABLED;
WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n"));
break;
+#ifdef BCMWAPI_WPI
+ case WLAN_CIPHER_SUITE_SMS4:
+ key.algo = CRYPTO_ALGO_SMS4;
+ WL_DBG(("WLAN_CIPHER_SUITE_SMS4\n"));
+ val = SMS4_ENABLED;
+ break;
+#endif /* BCMWAPI_WPI */
default:
WL_ERR(("Invalid cipher (0x%x)\n", params->cipher));
return -EINVAL;
@@ -2773,6 +3040,12 @@ wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n"));
break;
+#ifdef BCMWAPI_WPI
+ case WLAN_CIPHER_SUITE_SMS4:
+ key.algo = CRYPTO_ALGO_SMS4;
+ WL_DBG(("WLAN_CIPHER_SUITE_SMS4\n"));
+ break;
+#endif
default:
WL_ERR(("Invalid algo (0x%x)\n", wsec));
return -EINVAL;
@@ -2804,7 +3077,6 @@ wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
s8 eabuf[ETHER_ADDR_STR_LEN];
#endif
dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
-
CHECK_SYS_UP(wl);
if (wl_get_mode_by_netdev(wl, dev) == WL_MODE_AP) {
err = wldev_iovar_getbuf(dev, "sta_info", (struct ether_addr *)mac,
@@ -2831,42 +3103,41 @@ wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
sta->idle * 1000));
#endif
} else if (wl_get_mode_by_netdev(wl, dev) == WL_MODE_BSS) {
- u8 *curmacp = wl_read_prof(wl, dev, WL_PROF_BSSID);
- if (!wl_get_drv_status(wl, CONNECTED, dev) ||
- (dhd_is_associated(dhd, NULL) == FALSE)) {
- WL_ERR(("NOT assoc\n"));
- err = -ENODEV;
- goto get_station_err;
- }
- if (memcmp(mac, curmacp, ETHER_ADDR_LEN)) {
- WL_ERR(("Wrong Mac address: "MACSTR" != "MACSTR"\n",
- MAC2STR(mac), MAC2STR(curmacp)));
- }
-
- /* Report the current tx rate */
- err = wldev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate), false);
- if (err) {
- WL_ERR(("Could not get rate (%d)\n", err));
- } else {
- rate = dtoh32(rate);
- sinfo->filled |= STATION_INFO_TX_BITRATE;
- sinfo->txrate.legacy = rate * 5;
- WL_DBG(("Rate %d Mbps\n", (rate / 2)));
- }
+ u8 *curmacp = wl_read_prof(wl, dev, WL_PROF_BSSID);
+ if (!wl_get_drv_status(wl, CONNECTED, dev) ||
+ (dhd_is_associated(dhd, NULL) == FALSE)) {
+ WL_ERR(("NOT assoc\n"));
+ err = -ENODEV;
+ goto get_station_err;
+ }
+ if (memcmp(mac, curmacp, ETHER_ADDR_LEN)) {
+ WL_ERR(("Wrong Mac address: "MACSTR" != "MACSTR"\n",
+ MAC2STR(mac), MAC2STR(curmacp)));
+ }
- memset(&scb_val, 0, sizeof(scb_val));
- scb_val.val = 0;
- err = wldev_ioctl(dev, WLC_GET_RSSI, &scb_val,
- sizeof(scb_val_t), false);
- if (err) {
- WL_ERR(("Could not get rssi (%d)\n", err));
- goto get_station_err;
- }
+ /* Report the current tx rate */
+ err = wldev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate), false);
+ if (err) {
+ WL_ERR(("Could not get rate (%d)\n", err));
+ } else {
+ rate = dtoh32(rate);
+ sinfo->filled |= STATION_INFO_TX_BITRATE;
+ sinfo->txrate.legacy = rate * 5;
+ WL_DBG(("Rate %d Mbps\n", (rate / 2)));
+ }
- rssi = dtoh32(scb_val.val);
- sinfo->filled |= STATION_INFO_SIGNAL;
- sinfo->signal = rssi;
- WL_DBG(("RSSI %d dBm\n", rssi));
+ memset(&scb_val, 0, sizeof(scb_val));
+ scb_val.val = 0;
+ err = wldev_ioctl(dev, WLC_GET_RSSI, &scb_val,
+ sizeof(scb_val_t), false);
+ if (err) {
+ WL_ERR(("Could not get rssi (%d)\n", err));
+ goto get_station_err;
+ }
+ rssi = dtoh32(scb_val.val);
+ sinfo->filled |= STATION_INFO_SIGNAL;
+ sinfo->signal = rssi;
+ WL_DBG(("RSSI %d dBm\n", rssi));
get_station_err:
if (err) {
@@ -2968,7 +3239,6 @@ static s32 wl_cfg80211_suspend(struct wiphy *wiphy)
struct net_info *iter, *next;
struct net_device *ndev = wl_to_prmry_ndev(wl);
unsigned long flags;
-
if (unlikely(!wl_get_drv_status(wl, READY, ndev))) {
WL_INFO(("device is not ready : status (%d)\n",
(int)wl->status));
@@ -3009,8 +3279,8 @@ wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list,
return -EINVAL;
}
/* pmk list is supported only for STA interface i.e. primary interface
- * Refer code wlc_bsscfg.c->wlc_bsscfg_sta_init
- */
+ * Refer code wlc_bsscfg.c->wlc_bsscfg_sta_init
+ */
if (primary_dev != dev) {
WL_INFO(("Not supporting Flushing pmklist on virtual"
" interfaces than primary interface\n"));
@@ -3156,7 +3426,7 @@ wl_cfg80211_scan_alloc_params(int channel, int nprobes, int *out_params_size)
params->active_time = htod32(-1);
params->passive_time = htod32(-1);
params->home_time = htod32(10);
- params->channel_list[0] = htodchanspec(channel);
+ params->channel_list[0] = wl_chspec_host_to_driver(channel);
/* Our scan params have 1 channel and 0 ssids */
params->channel_num = htod32((0 << WL_SCAN_PARAMS_NSSID_SHIFT) |
@@ -3165,7 +3435,6 @@ wl_cfg80211_scan_alloc_params(int channel, int nprobes, int *out_params_size)
*out_params_size = params_size; /* rtn size to the caller */
return params;
}
-
s32
wl_cfg80211_scan_abort(struct wl_priv *wl, struct net_device *ndev)
{
@@ -3200,7 +3469,6 @@ wl_cfg80211_scan_abort(struct wl_priv *wl, struct net_device *ndev)
kfree(params);
return err;
}
-
static s32
wl_cfg80211_remain_on_channel(struct wiphy *wiphy, struct net_device *dev,
struct ieee80211_channel * channel,
@@ -3266,7 +3534,6 @@ wl_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, struct net_device *dev
WL_DBG((" enter ) netdev_ifidx: %d \n", dev->ifindex));
return err;
}
-
static s32
wl_cfg80211_send_pending_tx_act_frm(struct wl_priv *wl)
{
@@ -3359,14 +3626,18 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *ndev,
struct ieee80211_channel *channel, bool offchan,
enum nl80211_channel_type channel_type,
bool channel_type_valid, unsigned int wait,
- const u8* buf, size_t len, bool no_cck,
- bool dont_wait_for_ack, u64 *cookie)
+ const u8* buf, size_t len,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
+ bool no_cck, bool dont_wait_for_ack,
+#endif
+ u64 *cookie)
{
wl_action_frame_t *action_frame;
wl_af_params_t *af_params;
wifi_p2p_ie_t *p2p_ie;
wpa_ie_fixed_t *wps_ie;
scb_val_t scb_val;
+ wifi_wfd_ie_t *wfd_ie;
const struct ieee80211_mgmt *mgmt;
struct wl_priv *wl = wiphy_priv(wiphy);
struct net_device *dev = NULL;
@@ -3374,6 +3645,7 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *ndev,
s32 bssidx = 0;
u32 p2pie_len = 0;
u32 wpsie_len = 0;
+ u32 wfdie_len = 0;
u32 id;
u32 retry = 0;
bool ack = false;
@@ -3422,6 +3694,11 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *ndev,
/* Total length of P2P Information Element */
p2pie_len = p2p_ie->len + sizeof(p2p_ie->len) + sizeof(p2p_ie->id);
}
+ if ((wfd_ie = wl_cfgp2p_find_wfdie((u8 *)(buf + ie_offset), ie_len))
+ != NULL) {
+ /* Total length of WFD Information Element */
+ wfdie_len = wfd_ie->len + sizeof(wfd_ie->len) + sizeof(wfd_ie->id);
+ }
if ((wps_ie = wl_cfgp2p_find_wpsie((u8 *)(buf + ie_offset), ie_len))
!= NULL) {
/* Order of Vendor IE is 1) WPS IE +
@@ -3433,7 +3710,7 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *ndev,
sizeof(wps_ie->tag);
wl_cfgp2p_set_management_ie(wl, dev, bssidx,
VNDR_IE_PRBRSP_FLAG,
- (u8 *)wps_ie, wpsie_len + p2pie_len);
+ (u8 *)wps_ie, wpsie_len + p2pie_len + wfdie_len);
}
cfg80211_mgmt_tx_status(ndev, *cookie, buf, len, true, GFP_KERNEL);
goto exit;
@@ -3685,6 +3962,11 @@ wl_validate_wpa2ie(struct net_device *dev, bcm_tlv_t *wpa2ie, s32 bssidx)
case WPA_CIPHER_AES_CCM:
gval = AES_ENABLED;
break;
+#ifdef BCMWAPI_WPI
+ case WAPI_CIPHER_SMS4:
+ gval = SMS4_ENABLED;
+ break;
+#endif
default:
WL_ERR(("No Security Info\n"));
break;
@@ -3708,6 +3990,11 @@ wl_validate_wpa2ie(struct net_device *dev, bcm_tlv_t *wpa2ie, s32 bssidx)
case WPA_CIPHER_AES_CCM:
pval = AES_ENABLED;
break;
+#ifdef BCMWAPI_WPI
+ case WAPI_CIPHER_SMS4:
+ pval = SMS4_ENABLED;
+ break;
+#endif
default:
WL_ERR(("No Security Info\n"));
}
@@ -3911,11 +4198,13 @@ wl_cfg80211_add_set_beacon(struct wiphy *wiphy, struct net_device *dev,
wpa_ie_fixed_t *wpa_ie;
bcm_tlv_t *wpa2_ie;
wifi_p2p_ie_t *p2p_ie;
+ wifi_wfd_ie_t *wfd_ie;
bool is_bssup = false;
bool update_bss = false;
bool pbc = false;
u16 wpsie_len = 0;
u16 p2pie_len = 0;
+ u32 wfdie_len = 0;
u8 beacon_ie[IE_MAX_LEN];
s32 ie_offset = 0;
s32 bssidx = 0;
@@ -3973,10 +4262,25 @@ wl_cfg80211_add_set_beacon(struct wiphy *wiphy, struct net_device *dev,
} else {
WL_ERR(("No P2PIE in beacon \n"));
}
+
+ /* find the WFD IEs */
+ if ((wfd_ie = wl_cfgp2p_find_wfdie((u8 *)info->tail, info->tail_len)) != NULL) {
+ /* Total length of P2P Information Element */
+ wfdie_len = wfd_ie->len + sizeof(wfd_ie->len) + sizeof(wfd_ie->id);
+ if ((wpsie_len + p2pie_len + wfdie_len) < IE_MAX_LEN) {
+ memcpy(&beacon_ie[wpsie_len + p2pie_len], wfd_ie, wfdie_len);
+ } else {
+ WL_ERR(("Found WFD IE but there is no space, (%d)(%d)(%d)\n",
+ wpsie_len, p2pie_len, wfdie_len));
+ wfdie_len = 0;
+ }
+ } else {
+ WL_ERR(("No WFDIE in beacon \n"));
+ }
/* add WLC_E_PROBREQ_MSG event to respose probe_request from STA */
wl_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, pbc);
wl_cfgp2p_set_management_ie(wl, dev, bssidx, VNDR_IE_BEACON_FLAG,
- beacon_ie, wpsie_len + p2pie_len);
+ beacon_ie, wpsie_len + p2pie_len + wfdie_len);
/* find the RSN_IE */
if ((wpa2_ie = bcm_parse_tlvs((u8 *)info->tail, info->tail_len,
@@ -4081,7 +4385,7 @@ wl_cfg80211_add_set_beacon(struct wiphy *wiphy, struct net_device *dev,
memcpy(beacon_ie, wps_ie, wpsie_len);
wl_cfgp2p_set_management_ie(wl, dev, bssidx, VNDR_IE_BEACON_FLAG,
beacon_ie, wpsie_len);
- wl->ap_info->wps_ie = kmemdup(wps_ie, wpsie_len, GFP_KERNEL);
+ wl->ap_info->wps_ie = kmemdup(wps_ie, wpsie_len, GFP_KERNEL);
/* add WLC_E_PROBREQ_MSG event to respose probe_request from STA */
wl_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, pbc);
} else {
@@ -4134,12 +4438,12 @@ wl_cfg80211_add_set_beacon(struct wiphy *wiphy, struct net_device *dev,
memcmp(wl->ap_info->wps_ie, wps_ie, wpsie_len)) {
WL_DBG((" WPS IE is changed\n"));
kfree(wl->ap_info->wps_ie);
- wl->ap_info->wps_ie = kmemdup(wps_ie, wpsie_len, GFP_KERNEL);
+ wl->ap_info->wps_ie = kmemdup(wps_ie, wpsie_len, GFP_KERNEL);
/* add WLC_E_PROBREQ_MSG event to respose probe_request from STA */
wl_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, pbc);
} else if (wl->ap_info->wps_ie == NULL) {
WL_DBG((" WPS IE is added\n"));
- wl->ap_info->wps_ie = kmemdup(wps_ie, wpsie_len, GFP_KERNEL);
+ wl->ap_info->wps_ie = kmemdup(wps_ie, wpsie_len, GFP_KERNEL);
/* add WLC_E_PROBREQ_MSG event to respose probe_request from STA */
wl_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, pbc);
}
@@ -4277,17 +4581,23 @@ s32 wl_mode_to_nl80211_iftype(s32 mode)
return err;
}
-static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev)
+static struct wireless_dev *wl_alloc_wdev(struct device *dev)
{
+ struct wireless_dev *wdev;
s32 err = 0;
+ wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
+ if (unlikely(!wdev)) {
+ WL_ERR(("Could not allocate wireless device\n"));
+ return ERR_PTR(-ENOMEM);
+ }
wdev->wiphy =
wiphy_new(&wl_cfg80211_ops, sizeof(struct wl_priv));
if (unlikely(!wdev->wiphy)) {
WL_ERR(("Couldn not allocate wiphy device\n"));
err = -ENOMEM;
- return err;
+ goto wiphy_new_out;
}
- set_wiphy_dev(wdev->wiphy, sdiofunc_dev);
+ set_wiphy_dev(wdev->wiphy, dev);
wdev->wiphy->max_scan_ie_len = WL_SCAN_IE_LEN_MAX;
/* Report how many SSIDs Driver can support per Scan request */
wdev->wiphy->max_scan_ssids = WL_SCAN_PARAMS_SSID_MAX;
@@ -4314,9 +4624,7 @@ static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev
WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS |
#endif
WIPHY_FLAG_4ADDR_STATION;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
- wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
-#endif
+
WL_DBG(("Registering custom regulatory)\n"));
wdev->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
wiphy_apply_custom_regulatory(wdev->wiphy, &brcm_regdom);
@@ -4324,9 +4632,17 @@ static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev
err = wiphy_register(wdev->wiphy);
if (unlikely(err < 0)) {
WL_ERR(("Couldn not register wiphy device (%d)\n", err));
- wiphy_free(wdev->wiphy);
+ goto wiphy_register_out;
}
- return err;
+ return wdev;
+
+wiphy_register_out:
+ wiphy_free(wdev->wiphy);
+
+wiphy_new_out:
+ kfree(wdev);
+
+ return ERR_PTR(err);
}
static void wl_free_wdev(struct wl_priv *wl)
@@ -4421,6 +4737,7 @@ static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
u.beacon.variable) + wl_get_ielen(wl);
#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
freq = ieee80211_channel_to_frequency(notif_bss_info->channel);
+ (void)band->band;
#else
freq = ieee80211_channel_to_frequency(notif_bss_info->channel, band->band);
#endif
@@ -4433,7 +4750,6 @@ static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
notif_bss_info->frame_len));
signal = notif_bss_info->rssi * 100;
-
#if defined(WLP2P) && ENABLE_P2P_INTERFACE
if (wl->p2p_net && wl->scan_request &&
wl->scan_request->dev == wl->p2p_net) {
@@ -4516,136 +4832,91 @@ static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e)
return false;
}
-/* The mainline kernel >= 3.2.0 has support for indicating new/del station
- * to AP/P2P GO via events. If this change is backported to kernel for which
- * this driver is being built, set CFG80211_STA_EVENT_AVAILABLE to 1. You
- * should use this new/del sta event mechanism for BRCM supplicant from BRANCH
- * HOSTAP_BRANCH_0_15 (ver >= 15_1).
- */
-#define CFG80211_STA_EVENT_AVAILABLE 0
static s32
-wl_notify_connect_status_ap(struct wl_priv *wl, struct net_device *ndev,
+wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
const wl_event_msg_t *e, void *data)
{
+ bool act;
+ bool isfree = false;
s32 err = 0;
+ s32 freq;
+ s32 channel;
+ u8 body[200];
u32 event = ntoh32(e->event_type);
u32 reason = ntoh32(e->reason);
u32 len = ntoh32(e->datalen);
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)) && !CFG80211_STA_EVENT_AVAILABLE
- bool isfree = false;
+ u16 fc = 0;
u8 *mgmt_frame;
u8 bsscfgidx = e->bsscfgidx;
- s32 freq;
- s32 channel;
- u8 body[200];
- u16 fc = 0;
struct ieee80211_supported_band *band;
struct ether_addr da;
struct ether_addr bssid;
struct wiphy *wiphy = wl_to_wiphy(wl);
channel_info_t ci;
-#else
- struct station_info sinfo;
-#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)) && !CFG80211_STA_EVENT_AVAILABLE */
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)) && !CFG80211_STA_EVENT_AVAILABLE
memset(body, 0, sizeof(body));
memset(&bssid, 0, ETHER_ADDR_LEN);
WL_DBG(("Enter \n"));
if (wl_get_mode_by_netdev(wl, ndev) == WL_INVALID)
return WL_INVALID;
- memcpy(body, data, len);
- wldev_iovar_getbuf_bsscfg(ndev, "cur_etheraddr",
- NULL, 0, wl->ioctl_buf, WLC_IOCTL_MAXLEN, bsscfgidx, &wl->ioctl_buf_sync);
- memcpy(da.octet, wl->ioctl_buf, ETHER_ADDR_LEN);
- err = wldev_ioctl(ndev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false);
- switch (event) {
- case WLC_E_ASSOC_IND:
- fc = FC_ASSOC_REQ;
- break;
- case WLC_E_REASSOC_IND:
- fc = FC_REASSOC_REQ;
- break;
- case WLC_E_DISASSOC_IND:
- fc = FC_DISASSOC;
- break;
- case WLC_E_DEAUTH_IND:
- fc = FC_DISASSOC;
- break;
- case WLC_E_DEAUTH:
- fc = FC_DISASSOC;
- break;
- default:
- fc = 0;
- goto exit;
- }
- if ((err = wldev_ioctl(ndev, WLC_GET_CHANNEL, &ci, sizeof(ci), false)))
- return err;
+ if (wl_get_mode_by_netdev(wl, ndev) == WL_MODE_AP) {
+ memcpy(body, data, len);
+ wldev_iovar_getbuf_bsscfg(ndev, "cur_etheraddr",
+ NULL, 0, wl->ioctl_buf, WLC_IOCTL_MAXLEN, bsscfgidx, &wl->ioctl_buf_sync);
+ memcpy(da.octet, wl->ioctl_buf, ETHER_ADDR_LEN);
+ err = wldev_ioctl(ndev, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, false);
+ switch (event) {
+ case WLC_E_ASSOC_IND:
+ fc = FC_ASSOC_REQ;
+ break;
+ case WLC_E_REASSOC_IND:
+ fc = FC_REASSOC_REQ;
+ break;
+ case WLC_E_DISASSOC_IND:
+ fc = FC_DISASSOC;
+ break;
+ case WLC_E_DEAUTH_IND:
+ fc = FC_DISASSOC;
+ break;
+ case WLC_E_DEAUTH:
+ fc = FC_DISASSOC;
+ break;
+ default:
+ fc = 0;
+ goto exit;
+ }
+ if ((err = wldev_ioctl(ndev, WLC_GET_CHANNEL, &ci, sizeof(ci), false)))
+ return err;
- channel = dtoh32(ci.hw_channel);
- if (channel <= CH_MAX_2G_CHANNEL)
- band = wiphy->bands[IEEE80211_BAND_2GHZ];
- else
- band = wiphy->bands[IEEE80211_BAND_5GHZ];
+ channel = dtoh32(ci.hw_channel);
+ if (channel <= CH_MAX_2G_CHANNEL)
+ band = wiphy->bands[IEEE80211_BAND_2GHZ];
+ else
+ band = wiphy->bands[IEEE80211_BAND_5GHZ];
#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
- freq = ieee80211_channel_to_frequency(channel);
+ freq = ieee80211_channel_to_frequency(channel);
+ (void)band->band;
#else
- freq = ieee80211_channel_to_frequency(channel, band->band);
+ freq = ieee80211_channel_to_frequency(channel, band->band);
#endif
- err = wl_frame_get_mgmt(fc, &da, &e->addr, &bssid,
+ err = wl_frame_get_mgmt(fc, &da, &e->addr, &bssid,
&mgmt_frame, &len, body);
- if (err < 0)
- goto exit;
- isfree = true;
-
- if (event == WLC_E_ASSOC_IND && reason == DOT11_SC_SUCCESS) {
- cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC);
- } else if (event == WLC_E_DISASSOC_IND) {
- cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC);
- } else if ((event == WLC_E_DEAUTH_IND) || (event == WLC_E_DEAUTH)) {
- cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC);
- }
+ if (err < 0)
+ goto exit;
+ isfree = true;
-exit:
- if (isfree)
- kfree(mgmt_frame);
- return err;
-#else /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0) && !CFG80211_STA_EVENT_AVAILABLE */
- sinfo.filled = 0;
- if (((event == WLC_E_ASSOC_IND) || (event == WLC_E_REASSOC_IND)) &&
- reason == DOT11_SC_SUCCESS) {
- sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
- if (!data) {
- WL_ERR(("No IEs present in ASSOC/REASSOC_IND"));
- return -EINVAL;
+ if (event == WLC_E_ASSOC_IND && reason == DOT11_SC_SUCCESS) {
+ cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC);
+ } else if (event == WLC_E_DISASSOC_IND) {
+ cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC);
+ } else if ((event == WLC_E_DEAUTH_IND) || (event == WLC_E_DEAUTH)) {
+ cfg80211_rx_mgmt(ndev, freq, mgmt_frame, len, GFP_ATOMIC);
}
- sinfo.assoc_req_ies = data;
- sinfo.assoc_req_ies_len = len;
- cfg80211_new_sta(ndev, e->addr.octet, &sinfo, GFP_ATOMIC);
- } else if (event == WLC_E_DISASSOC_IND) {
- cfg80211_del_sta(ndev, e->addr.octet, GFP_ATOMIC);
- } else if ((event == WLC_E_DEAUTH_IND) || (event == WLC_E_DEAUTH)) {
- cfg80211_del_sta(ndev, e->addr.octet, GFP_ATOMIC);
- }
-#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0) && !CFG80211_STA_EVENT_AVAILABLE */
- return err;
-}
-static s32
-wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
- const wl_event_msg_t *e, void *data)
-{
- bool act;
- s32 err = 0;
- u32 event = ntoh32(e->event_type);
-
- if (wl_get_mode_by_netdev(wl, ndev) == WL_MODE_AP) {
- wl_notify_connect_status_ap(wl, ndev, e, data);
} else {
WL_DBG(("wl_notify_connect_status : event %d status : %d \n",
ntoh32(e->event_type), ntoh32(e->status)));
@@ -4717,6 +4988,9 @@ wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
printk("%s nothing\n", __FUNCTION__);
}
}
+exit:
+ if (isfree)
+ kfree(mgmt_frame);
return err;
}
@@ -4834,7 +5108,7 @@ static void wl_ch_to_chanspec(int ch, struct wl_join_params *join_params,
join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK;
join_params->params.chanspec_list[0] |= chanspec;
join_params->params.chanspec_list[0] =
- htodchanspec(join_params->params.chanspec_list[0]);
+ wl_chspec_host_to_driver(join_params->params.chanspec_list[0]);
join_params->params.chanspec_num =
htod32(join_params->params.chanspec_num);
@@ -4858,6 +5132,7 @@ static s32 wl_update_bss_info(struct wl_priv *wl, struct net_device *ndev)
u8 *curbssid;
s32 err = 0;
struct wiphy *wiphy;
+
wiphy = wl_to_wiphy(wl);
if (wl_is_ibssmode(wl, ndev))
@@ -5010,19 +5285,6 @@ wl_notify_mic_status(struct wl_priv *wl, struct net_device *ndev,
}
static s32
-wl_notify_pfn_status(struct wl_priv *wl, struct net_device *ndev,
- const wl_event_msg_t *e, void *data)
-{
- WL_ERR((" PNO Event\n"));
-
- mutex_lock(&wl->usr_sync);
- /* TODO: Use cfg80211_sched_scan_results(wiphy); */
- cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL);
- mutex_unlock(&wl->usr_sync);
- return 0;
-}
-
-static s32
wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev,
const wl_event_msg_t *e, void *data)
{
@@ -5161,6 +5423,7 @@ wl_notify_rx_mgmt_frame(struct wl_priv *wl, struct net_device *ndev,
#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
freq = ieee80211_channel_to_frequency(channel);
+ (void)band->band;
#else
freq = ieee80211_channel_to_frequency(channel, band->band);
#endif
@@ -5258,7 +5521,7 @@ static void wl_init_event_handler(struct wl_priv *wl)
wl->evt_handler[WLC_E_P2P_DISC_LISTEN_COMPLETE] = wl_cfgp2p_listen_complete;
wl->evt_handler[WLC_E_ACTION_FRAME_COMPLETE] = wl_cfgp2p_action_tx_complete;
wl->evt_handler[WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE] = wl_cfgp2p_action_tx_complete;
- wl->evt_handler[WLC_E_PFN_NET_FOUND] = wl_notify_pfn_status;
+
}
static s32 wl_init_priv_mem(struct wl_priv *wl)
@@ -5565,7 +5828,6 @@ static void wl_scan_timeout(unsigned long data)
wl_notify_iscan_complete(wl_to_iscan(wl), true);
}
}
-
static void wl_iscan_timer(unsigned long data)
{
struct wl_iscan_ctrl *iscan = (struct wl_iscan_ctrl *)data;
@@ -5629,7 +5891,6 @@ wl_cfg80211_netdev_notifier_call(struct notifier_block * nb,
static struct notifier_block wl_cfg80211_netdev_notifier = {
.notifier_call = wl_cfg80211_netdev_notifier_call,
};
-
static void wl_notify_escan_complete(struct wl_priv *wl,
struct net_device *ndev,
bool aborted)
@@ -5713,7 +5974,8 @@ static s32 wl_escan_handler(struct wl_priv *wl,
p2p_dev_addr = wl_cfgp2p_retreive_p2p_dev_addr(bi, bi_length);
if (p2p_dev_addr && !memcmp(p2p_dev_addr,
wl->afx_hdl->pending_tx_dst_addr.octet, ETHER_ADDR_LEN)) {
- s32 channel = CHSPEC_CHANNEL(dtohchanspec(bi->chanspec));
+ s32 channel = CHSPEC_CHANNEL(
+ wl_chspec_driver_to_host(bi->chanspec));
WL_DBG(("ACTION FRAME SCAN : Peer found, channel : %d\n", channel));
wl_clr_p2p_status(wl, SCANNING);
wl->afx_hdl->peer_chan = channel;
@@ -5951,11 +6213,9 @@ s32 wl_cfg80211_attach_post(struct net_device *ndev)
if (wl && !wl_get_drv_status(wl, READY, ndev)) {
if (wl->wdev &&
wl_cfgp2p_supported(wl, ndev)) {
-#if !ENABLE_P2P_INTERFACE
wl->wdev->wiphy->interface_modes |=
(BIT(NL80211_IFTYPE_P2P_CLIENT)|
BIT(NL80211_IFTYPE_P2P_GO));
-#endif
if ((err = wl_cfgp2p_init_priv(wl)) != 0)
goto fail;
@@ -5996,17 +6256,10 @@ s32 wl_cfg80211_attach(struct net_device *ndev, void *data)
}
WL_DBG(("func %p\n", wl_cfg80211_get_parent_dev()));
dev = wl_cfg80211_get_parent_dev();
-
- wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
- if (unlikely(!wdev)) {
- WL_ERR(("Could not allocate wireless device\n"));
- return -ENOMEM;
- }
- err = wl_setup_wiphy(wdev, dev);
- if (unlikely(err)) {
- kfree(wdev);
+ wdev = wl_alloc_wdev(dev);
+ if (IS_ERR(wdev))
return -ENOMEM;
- }
+
wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS);
wl = (struct wl_priv *)wiphy_priv(wdev->wiphy);
wl->wdev = wdev;
@@ -6061,6 +6314,7 @@ void wl_cfg80211_detach(void *para)
{
struct wl_priv *wl;
+ (void)para;
wl = wlcfg_drv_priv;
WL_TRACE(("In\n"));
@@ -6136,9 +6390,7 @@ static s32 wl_event_handler(void *data)
tsk_ctl_t *tsk = (tsk_ctl_t *)data;
wl = (struct wl_priv *)tsk->parent;
-
- DAEMONIZE("wl_event_handler");
-
+ DAEMONIZE("dhd_cfg80211_event");
complete(&tsk->completed);
while (down_interruptible (&tsk->sema) == 0) {
@@ -6184,6 +6436,11 @@ wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t * e, void *data)
WL_DBG(("event_type (%d):" "WLC_E_" "%s\n", event_type, estr));
#endif /* (WL_DBG_LEVEL > 0) */
+ if (event_type == WLC_E_PFN_NET_FOUND)
+ WL_ERR((" PNOEVENT: PNO_NET_FOUND\n"));
+ else if (event_type == WLC_E_PFN_NET_LOST)
+ WL_ERR((" PNOEVENT: PNO_NET_LOST\n"));
+
if (likely(!wl_enq_event(wl, ndev, event_type, e, data)))
wl_wakeup_event(wl);
}
@@ -6443,15 +6700,33 @@ s32 wl_cfg80211_up(void *para)
{
struct wl_priv *wl;
s32 err = 0;
+ int val = 0;
+ (void)para;
WL_TRACE(("In\n"));
wl = wlcfg_drv_priv;
+
+ if ((err = wldev_ioctl(wl_to_prmry_ndev(wl), WLC_GET_VERSION, &val,
+ sizeof(int), false) < 0)) {
+ WL_ERR(("WLC_GET_VERSION failed, err=%d\n", err));
+ return err;
+ }
+ val = dtoh32(val);
+ if (val != WLC_IOCTL_VERSION && val != 1) {
+ WL_ERR(("Version mismatch, please upgrade. Got %d, expected %d or 1\n",
+ val, WLC_IOCTL_VERSION));
+ return BCME_VERSION;
+ }
+ ioctl_version = val;
+ WL_ERR(("WLC_GET_VERSION=%d\n", ioctl_version));
+
mutex_lock(&wl->usr_sync);
wl_cfg80211_attach_post(wl_to_prmry_ndev(wl));
err = __wl_cfg80211_up(wl);
if (err)
WL_ERR(("__wl_cfg80211_up failed\n"));
mutex_unlock(&wl->usr_sync);
+
return err;
}
@@ -6474,6 +6749,7 @@ s32 wl_cfg80211_down(void *para)
struct wl_priv *wl;
s32 err = 0;
+ (void)para;
WL_TRACE(("In\n"));
wl = wlcfg_drv_priv;
mutex_lock(&wl->usr_sync);
@@ -6688,7 +6964,6 @@ s32 wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pd
struct wl_priv *wl = wlcfg_drv_priv;
struct ether_addr p2pif_addr;
struct ether_addr primary_mac;
-
if (!wl->p2p)
return -1;
if (!p2p_is_on(wl)) {
@@ -6699,6 +6974,7 @@ s32 wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pd
wl->p2p->dev_addr.octet, ETHER_ADDR_LEN);
}
+
return 0;
}
s32 wl_cfg80211_set_p2p_noa(struct net_device *net, char* buf, int len)
@@ -6837,21 +7113,3 @@ static void get_primary_mac(struct wl_priv *wl, struct ether_addr *mac)
0, wl->ioctl_buf, WLC_IOCTL_MAXLEN, 0, &wl->ioctl_buf_sync);
memcpy(mac->octet, wl->ioctl_buf, ETHER_ADDR_LEN);
}
-
-int wl_cfg80211_do_driver_init(struct net_device *net)
-{
- struct wl_priv *wl = *(struct wl_priv **)netdev_priv(net);
-
- if (!wl || !wl->wdev)
- return -EINVAL;
-
- if (dhd_do_driver_init(wl->wdev->netdev) < 0)
- return -1;
-
- return 0;
-}
-
-void wl_cfg80211_enable_trace(int level)
-{
- wl_dbg_level |= WL_DBG_DBG;
-}