summaryrefslogtreecommitdiff
path: root/drivers/net/wireless
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/bcmdhd/Makefile2
-rw-r--r--drivers/net/wireless/bcmdhd/bcmevent.c7
-rw-r--r--drivers/net/wireless/bcmdhd/bcmsdh_linux.c9
-rw-r--r--drivers/net/wireless/bcmdhd/dhd.h8
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_bus.h5
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_cdc.c60
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_common.c102
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_linux.c50
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_linux_mon.c4
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_sdio.c22
-rw-r--r--drivers/net/wireless/bcmdhd/include/bcmutils.h2
-rw-r--r--drivers/net/wireless/bcmdhd/include/epivers.h8
-rw-r--r--drivers/net/wireless/bcmdhd/include/proto/bcmevent.h3
-rw-r--r--drivers/net/wireless/bcmdhd/include/sdio.h5
-rw-r--r--drivers/net/wireless/bcmdhd/include/wlioctl.h6
-rw-r--r--drivers/net/wireless/bcmdhd/wl_android.c2
-rw-r--r--drivers/net/wireless/bcmdhd/wl_cfg80211.c805
-rw-r--r--drivers/net/wireless/bcmdhd/wl_cfg80211.h35
-rw-r--r--drivers/net/wireless/bcmdhd/wl_cfgp2p.c23
-rw-r--r--drivers/net/wireless/bcmdhd/wl_cfgp2p.h1
-rw-r--r--drivers/net/wireless/bcmdhd/wl_iw.c100
21 files changed, 694 insertions, 565 deletions
diff --git a/drivers/net/wireless/bcmdhd/Makefile b/drivers/net/wireless/bcmdhd/Makefile
index 56500b7220c..e82c9856f00 100644
--- a/drivers/net/wireless/bcmdhd/Makefile
+++ b/drivers/net/wireless/bcmdhd/Makefile
@@ -1,5 +1,5 @@
# bcmdhd
-DHDCFLAGS = -Wall -Wstrict-prototypes -Werror -Dlinux -DBCMDRIVER \
+DHDCFLAGS = -Wall -Wstrict-prototypes -Dlinux -DBCMDRIVER \
-DBCMDONGLEHOST -DUNRELEASEDCHIP -DBCMDMA32 -DWLBTAMP -DBCMFILEIMAGE \
-DDHDTHREAD -DDHD_GPL -DDHD_SCHED -DDHD_DEBUG -DSDTEST -DBDC -DTOE \
-DDHD_BCMEVENTS -DSHOW_EVENTS -DDONGLEOVERLAYS -DBCMDBG \
diff --git a/drivers/net/wireless/bcmdhd/bcmevent.c b/drivers/net/wireless/bcmdhd/bcmevent.c
index 3cee7c214e3..24581ddd353 100644
--- a/drivers/net/wireless/bcmdhd/bcmevent.c
+++ b/drivers/net/wireless/bcmdhd/bcmevent.c
@@ -29,7 +29,7 @@
#include <proto/bcmeth.h>
#include <proto/bcmevent.h>
-#if WLC_E_LAST != 84
+#if WLC_E_LAST != 85
#error "You need to add an entry to bcmevent_names[] for the new event"
#endif
@@ -115,7 +115,10 @@ const bcmevent_name_t bcmevent_names[] = {
{ WLC_E_CSA_COMPLETE_IND, "WLC_E_CSA_COMPLETE_IND" },
{ WLC_E_EXCESS_PM_WAKE_EVENT, "EXCESS_PM_WAKE_EVENT" },
{ WLC_E_PFN_SCAN_NONE, "PFN_SCAN_NONE" },
- { WLC_E_PFN_SCAN_ALLGONE, "PFN_SCAN_ALLGONE" }
+ { WLC_E_PFN_SCAN_ALLGONE, "PFN_SCAN_ALLGONE" },
+#ifdef SOFTAP
+ { WLC_E_GTK_PLUMBED, "GTK_PLUMBED" }
+#endif
};
diff --git a/drivers/net/wireless/bcmdhd/bcmsdh_linux.c b/drivers/net/wireless/bcmdhd/bcmsdh_linux.c
index 6fa47378cfe..a4dc6ff4042 100644
--- a/drivers/net/wireless/bcmdhd/bcmsdh_linux.c
+++ b/drivers/net/wireless/bcmdhd/bcmsdh_linux.c
@@ -48,15 +48,6 @@ extern void dhdsdio_isr(void * args);
#include <dngl_stats.h>
#include <dhd.h>
#endif /* defined(OOB_INTR_ONLY) */
-#if defined(CONFIG_MACH_SANDGATE2G) || defined(CONFIG_MACH_LOGICPD_PXA270)
-#if !defined(BCMPLATFORM_BUS)
-#define BCMPLATFORM_BUS
-#endif /* !defined(BCMPLATFORM_BUS) */
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19))
-#include <linux/platform_device.h>
-#endif /* KERNEL_VERSION(2, 6, 19) */
-#endif /* CONFIG_MACH_SANDGATE2G || CONFIG_MACH_LOGICPD_PXA270 */
/**
* SDIO Host Controller info
diff --git a/drivers/net/wireless/bcmdhd/dhd.h b/drivers/net/wireless/bcmdhd/dhd.h
index ea8f67ce8b4..281e047af85 100644
--- a/drivers/net/wireless/bcmdhd/dhd.h
+++ b/drivers/net/wireless/bcmdhd/dhd.h
@@ -71,6 +71,12 @@ enum dhd_bus_state {
DHD_BUS_DATA /* Ready for frame transfers */
};
+/* Firmware requested operation mode */
+#define STA_MASK 0x0001
+#define HOSTAPD_MASK 0x0002
+#define WFD_MASK 0x0004
+#define SOFTAP_FW_MASK 0x0008
+
enum dhd_bus_wake_state {
WAKE_LOCK_OFF,
WAKE_LOCK_PRIV,
@@ -173,6 +179,7 @@ typedef struct dhd_pub {
wl_country_t dhd_cspec; /* Current Locale info */
char eventmask[WL_EVENTING_MASK_LEN];
+ int op_mode; /* STA, HostAPD, WFD, SoftAP */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_HAS_WAKELOCK)
struct wake_lock wakelock[WAKE_LOCK_MAX];
@@ -423,6 +430,7 @@ extern void dhd_timeout_start(dhd_timeout_t *tmo, uint usec);
extern int dhd_timeout_expired(dhd_timeout_t *tmo);
extern int dhd_ifname2idx(struct dhd_info *dhd, char *name);
+extern int dhd_net2idx(struct dhd_info *dhd, struct net_device *net);
extern struct net_device * dhd_idx2net(struct dhd_pub *dhd_pub, int ifidx);
extern int wl_host_event(dhd_pub_t *dhd_pub, int *idx, void *pktdata,
wl_event_msg_t *, void **data_ptr);
diff --git a/drivers/net/wireless/bcmdhd/dhd_bus.h b/drivers/net/wireless/bcmdhd/dhd_bus.h
index 294322026e9..bccb8b6603f 100644
--- a/drivers/net/wireless/bcmdhd/dhd_bus.h
+++ b/drivers/net/wireless/bcmdhd/dhd_bus.h
@@ -48,6 +48,11 @@ extern void dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex);
/* Initialize bus module: prepare for communication w/dongle */
extern int dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex);
+/* Get the Bus Idle Time */
+extern void dhd_bus_getidletime(dhd_pub_t *dhdp, int *idletime);
+
+/* Set the Bus Idle Time*/
+extern void dhd_bus_setidletime(dhd_pub_t *dhdp, int idle_time);
/* Send a data frame to the dongle. Callee disposes of txp. */
extern int dhd_bus_txdata(struct dhd_bus *bus, void *txp);
diff --git a/drivers/net/wireless/bcmdhd/dhd_cdc.c b/drivers/net/wireless/bcmdhd/dhd_cdc.c
index 91c461f7bbe..0f9893a1537 100644
--- a/drivers/net/wireless/bcmdhd/dhd_cdc.c
+++ b/drivers/net/wireless/bcmdhd/dhd_cdc.c
@@ -916,7 +916,10 @@ _dhd_wlfc_send_signalonly_packet(athost_wl_status_info_t* ctx, wlfc_mac_descript
#ifdef PROP_TXSTATUS_DEBUG
ctx->stats.signal_only_pkts_sent++;
#endif
- dhd_bus_txdata(((dhd_pub_t *)ctx->dhdp)->bus, p);
+ rc = dhd_bus_txdata(((dhd_pub_t *)ctx->dhdp)->bus, p);
+ if (rc != BCME_OK) {
+ PKTFREE(ctx->osh, p, TRUE);
+ }
}
else {
DHD_ERROR(("%s: couldn't allocate new %d-byte packet\n",
@@ -1920,7 +1923,6 @@ dhd_wlfc_init(dhd_pub_t *dhd)
WLFC_FLAGS_CREDIT_STATUS_SIGNALS |
WLFC_FLAGS_HOST_PROPTXSTATUS_ACTIVE : 0;
- dhd->wlfc_state = NULL;
/*
try to enable/disable signaling by sending "tlv" iovar. if that fails,
@@ -2237,49 +2239,6 @@ dhd_prot_dstats(dhd_pub_t *dhd)
return;
}
-int dhd_set_suspend(int value, dhd_pub_t *dhd)
-{
- int power_mode = PM_MAX;
- wl_pkt_filter_enable_t enable_parm;
- char iovbuf[32];
- int bcn_li_dtim = 3;
-
-#define htod32(i) i
-
- if (dhd && dhd->up) {
- if (value) {
- dhd_wl_ioctl_cmd(dhd, WLC_SET_PM,
- (char *)&power_mode, sizeof(power_mode), TRUE, 0);
- /* Enable packet filter, only allow unicast packet to send up */
- enable_parm.id = htod32(100);
- enable_parm.enable = htod32(1);
- bcm_mkiovar("pkt_filter_enable", (char *)&enable_parm,
- sizeof(wl_pkt_filter_enable_t), iovbuf, sizeof(iovbuf));
- dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
- /* set bcn_li_dtim */
- bcm_mkiovar("bcn_li_dtim", (char *)&bcn_li_dtim,
- 4, iovbuf, sizeof(iovbuf));
- dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
- } else {
- power_mode = PM_FAST;
- dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)&power_mode,
- sizeof(power_mode), TRUE, 0);
- /* disable pkt filter */
- enable_parm.id = htod32(100);
- enable_parm.enable = htod32(0);
- bcm_mkiovar("pkt_filter_enable", (char *)&enable_parm,
- sizeof(wl_pkt_filter_enable_t), iovbuf, sizeof(iovbuf));
- dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
- /* set bcn_li_dtim */
- bcn_li_dtim = 0;
- bcm_mkiovar("bcn_li_dtim", (char *)&bcn_li_dtim,
- 4, iovbuf, sizeof(iovbuf));
- dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
- }
- }
-
- return 0;
-}
int
dhd_prot_init(dhd_pub_t *dhd)
@@ -2297,16 +2256,17 @@ dhd_prot_init(dhd_pub_t *dhd)
goto done;
+#ifdef PROP_TXSTATUS
+ ret = dhd_wlfc_init(dhd);
+#endif
+
+#ifndef WL_CFG80211
ret = dhd_preinit_ioctls(dhd);
+#endif /* WL_CFG80211 */
/* Always assumes wl for now */
dhd->iswl = TRUE;
-#ifdef PROP_TXSTATUS
- ret = dhd_wlfc_init(dhd);
-#endif
- goto done;
-
done:
return ret;
}
diff --git a/drivers/net/wireless/bcmdhd/dhd_common.c b/drivers/net/wireless/bcmdhd/dhd_common.c
index c50f05325f6..f6bb8e5bb56 100644
--- a/drivers/net/wireless/bcmdhd/dhd_common.c
+++ b/drivers/net/wireless/bcmdhd/dhd_common.c
@@ -70,6 +70,7 @@ char nv_path[MOD_PARAM_PATHLEN];
#ifdef SOFTAP
char fw_path2[MOD_PARAM_PATHLEN];
+extern bool softap_enabled;
#endif
/* Last connection success/failure status */
@@ -1533,8 +1534,10 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
uint32 dongle_align = DHD_SDALIGN;
uint32 glom = 0;
uint bcn_timeout = 4;
+ uint retry_max = 3;
+#if defined(ARP_OFFLOAD_SUPPORT)
int arpoe = 1;
- int arp_ol = 0xf;
+#endif
int scan_assoc_time = 40;
int scan_unassoc_time = 40;
const char *str;
@@ -1551,14 +1554,17 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
#if defined(SOFTAP)
uint dtim = 1;
#endif
-#ifdef AP
+#if (defined(AP) && !defined(WLP2P)) || (!defined(AP) && defined(WL_CFG80211))
uint32 mpc = 0; /* Turn MPC off for AP/APSTA mode */
+#endif /* AP */
+#if defined(AP) || defined(WLP2P)
uint32 apsta = 1; /* Enable APSTA mode */
-#endif
+#endif /* defined(AP) || defined(WLP2P) */
#ifdef GET_CUSTOM_MAC_ENABLE
struct ether_addr ea_addr;
#endif /* GET_CUSTOM_MAC_ENABLE */
+ dhd->op_mode = 0;
#ifdef GET_CUSTOM_MAC_ENABLE
ret = dhd_custom_get_mac_address(ea_addr.octet);
if (!ret) {
@@ -1586,7 +1592,7 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
#endif /* GET_CUSTOM_MAC_ENABLE */
#ifdef SET_RANDOM_MAC_SOFTAP
- if (strstr(fw_path, "apsta") != NULL) {
+ if (strstr(fw_path, "_apsta") != NULL) {
uint rand_mac;
srandom32((uint)jiffies);
@@ -1607,9 +1613,52 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
}
#endif /* SET_RANDOM_MAC_SOFTAP */
- DHD_ERROR(("Firmware up: Broadcom Dongle Host Driver mac=%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
- dhd->mac.octet[0], dhd->mac.octet[1], dhd->mac.octet[2],
- dhd->mac.octet[3], dhd->mac.octet[4], dhd->mac.octet[5]));
+ DHD_TRACE(("Firmware = %s\n", fw_path));
+#if !defined(AP) && defined(WLP2P)
+ /* Check if firmware with WFD support used */
+ if (strstr(fw_path, "_p2p") != NULL) {
+ bcm_mkiovar("apsta", (char *)&apsta, 4, iovbuf, sizeof(iovbuf));
+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR,
+ iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) {
+ DHD_ERROR(("%s APSTA for WFD failed ret= %d\n", __FUNCTION__, ret));
+ } else {
+ dhd->op_mode |= WFD_MASK;
+#if defined(ARP_OFFLOAD_SUPPORT)
+ arpoe = 0;
+#endif /* (ARP_OFFLOAD_SUPPORT) */
+ dhd_pkt_filter_enable = FALSE;
+ }
+ }
+#endif /* !defined(AP) && defined(WLP2P) */
+
+#if !defined(AP) && defined(WL_CFG80211)
+ /* Check if firmware with HostAPD support used */
+ if (strstr(fw_path, "_apsta") != NULL) {
+ /* Turn off MPC in AP mode */
+ bcm_mkiovar("mpc", (char *)&mpc, 4, iovbuf, sizeof(iovbuf));
+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
+ sizeof(iovbuf), TRUE, 0)) < 0) {
+ DHD_ERROR(("%s mpc for HostAPD failed %d\n", __FUNCTION__, ret));
+ } else {
+ dhd->op_mode |= HOSTAPD_MASK;
+#if defined(ARP_OFFLOAD_SUPPORT)
+ arpoe = 0;
+#endif /* (ARP_OFFLOAD_SUPPORT) */
+ dhd_pkt_filter_enable = FALSE;
+ }
+ }
+#endif /* !defined(AP) && defined(WL_CFG80211) */
+
+ if ((dhd->op_mode != WFD_MASK) && (dhd->op_mode != HOSTAPD_MASK)) {
+ /* STA only operation mode */
+ dhd->op_mode |= STA_MASK;
+ dhd_pkt_filter_enable = TRUE;
+ }
+ DHD_ERROR(("Firmware up: op_mode=%d, "
+ "Broadcom Dongle Host Driver mac=%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
+ dhd->op_mode,
+ dhd->mac.octet[0], dhd->mac.octet[1], dhd->mac.octet[2],
+ dhd->mac.octet[3], dhd->mac.octet[4], dhd->mac.octet[5]));
/* Set Country code */
if (dhd->dhd_cspec.ccode[0] != 0) {
@@ -1649,15 +1698,16 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
/* Setup timeout if Beacons are lost and roam is off to report link down */
bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf, sizeof(iovbuf));
dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
-#ifdef AP
+ /* Setup assoc_retry_max count to reconnect target AP in dongle */
+ bcm_mkiovar("assoc_retry_max", (char *)&retry_max, 4, iovbuf, sizeof(iovbuf));
+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+#if defined(AP) && !defined(WLP2P)
/* Turn off MPC in AP mode */
bcm_mkiovar("mpc", (char *)&mpc, 4, iovbuf, sizeof(iovbuf));
dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
-
- /* Enable APSTA mode */
bcm_mkiovar("apsta", (char *)&apsta, 4, iovbuf, sizeof(iovbuf));
dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
-#endif
+#endif /* defined(AP) && !defined(WLP2P) */
#if defined(SOFTAP)
if (ap_fw_loaded == TRUE) {
dhd_wl_ioctl_cmd(dhd, WLC_SET_DTIMPRD, (char *)&dtim, sizeof(dtim), TRUE, 0);
@@ -1720,12 +1770,6 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
dhd_wl_ioctl_cmd(dhd, WLC_SET_SCAN_UNASSOC_TIME, (char *)&scan_unassoc_time,
sizeof(scan_unassoc_time), TRUE, 0);
- /* Set ARP offload */
- bcm_mkiovar("arpoe", (char *)&arpoe, 4, iovbuf, sizeof(iovbuf));
- dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
- bcm_mkiovar("arp_ol", (char *)&arp_ol, 4, iovbuf, sizeof(iovbuf));
- dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
-
/* add a default packet filter pattern */
str = "pkt_filter_add";
str_len = strlen(str);
@@ -1779,9 +1823,9 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
#ifdef ARP_OFFLOAD_SUPPORT
/* Set and enable ARP offload feature for STA only */
- if (dhd_arp_enable && !ap_fw_loaded) {
+ if (arpoe && !ap_fw_loaded) {
dhd_arp_offload_set(dhd, dhd_arp_mode);
- dhd_arp_offload_enable(dhd, dhd_arp_enable);
+ dhd_arp_offload_enable(dhd, arpoe);
} else {
dhd_arp_offload_set(dhd, 0);
dhd_arp_offload_enable(dhd, FALSE);
@@ -2061,6 +2105,17 @@ exit:
return bcn_li_dtim;
}
+/* Check if HostAPD or WFD mode setup */
+bool dhd_check_ap_wfd_mode_set(dhd_pub_t *dhd)
+{
+#ifdef WL_CFG80211
+ if (((dhd->op_mode & HOSTAPD_MASK) == HOSTAPD_MASK) ||
+ ((dhd->op_mode & WFD_MASK) == WFD_MASK))
+ return TRUE;
+ else
+#endif /* WL_CFG80211 */
+ return FALSE;
+}
#ifdef PNO_SUPPORT
int
@@ -2105,6 +2160,8 @@ dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled)
return ret;
}
+ if (dhd_check_ap_wfd_mode_set(dhd) == TRUE)
+ return (ret);
memset(iovbuf, 0, sizeof(iovbuf));
/* Check if disassoc to enable pno */
if ((pfn_enabled) &&
@@ -2152,6 +2209,8 @@ dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid, ushort scan_fr,
DHD_ERROR(("%s error exit\n", __FUNCTION__));
err = -1;
}
+ if (dhd_check_ap_wfd_mode_set(dhd) == TRUE)
+ return (err);
/* Check for broadcast ssid */
for (k = 0; k < nssid; k++) {
@@ -2268,7 +2327,10 @@ int dhd_keep_alive_onoff(dhd_pub_t *dhd)
int str_len;
int res = -1;
- DHD_ERROR(("%s Enter\n", __FUNCTION__));
+ if (dhd_check_ap_wfd_mode_set(dhd) == TRUE)
+ return (res);
+
+ DHD_TRACE(("%s execution\n", __FUNCTION__));
str = "mkeep_alive";
str_len = strlen(str);
diff --git a/drivers/net/wireless/bcmdhd/dhd_linux.c b/drivers/net/wireless/bcmdhd/dhd_linux.c
index 5d35f78cf2a..03ba34a2c82 100644
--- a/drivers/net/wireless/bcmdhd/dhd_linux.c
+++ b/drivers/net/wireless/bcmdhd/dhd_linux.c
@@ -443,11 +443,9 @@ static void dhd_htsf_addrxts(dhd_pub_t *dhdp, void *pktbuf);
static void dhd_dump_htsfhisto(histo_t *his, char *s);
#endif /* WLMEDIA_HTSF */
-extern s32 wl_cfg80211_ifdel_ops(struct net_device *net);
-
/* Monitor interface */
-extern int dhd_monitor_init(void *dhd_pub);
-extern int dhd_monitor_uninit(void);
+int dhd_monitor_init(void *dhd_pub);
+int dhd_monitor_uninit(void);
#if defined(CONFIG_WIRELESS_EXT)
@@ -673,7 +671,7 @@ dhd_timeout_expired(dhd_timeout_t *tmo)
return 0;
}
-static int
+int
dhd_net2idx(dhd_info_t *dhd, struct net_device *net)
{
int i = 0;
@@ -971,7 +969,8 @@ dhd_op_if(dhd_if_t *ifp)
memcpy(netdev_priv(ifp->net), &dhd, sizeof(dhd));
#ifdef WL_CFG80211
if (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211)
- if (!wl_cfg80211_notify_ifadd(ifp->net, ifp->idx, dhd_net_attach)) {
+ if (!wl_cfg80211_notify_ifadd(ifp->net, ifp->idx, ifp->bssidx,
+ dhd_net_attach)) {
ifp->state = 0;
return;
}
@@ -1023,10 +1022,10 @@ dhd_op_if(dhd_if_t *ifp)
free_netdev(ifp->net);
}
dhd->iflist[ifp->idx] = NULL;
- MFREE(dhd->pub.osh, ifp, sizeof(*ifp));
#ifdef WL_CFG80211
- if (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211)
+ if (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211) {
wl_cfg80211_notify_ifdel(ifp->net);
+ }
#endif
#ifdef SOFTAP
flags = dhd_os_spin_lock(&dhd->pub);
@@ -1034,6 +1033,7 @@ dhd_op_if(dhd_if_t *ifp)
ap_net_dev = NULL; /* NULL SOFTAP global wl0.1 as well */
dhd_os_spin_unlock(&dhd->pub, flags);
#endif /* SOFTAP */
+ MFREE(dhd->pub.osh, ifp, sizeof(*ifp));
}
}
@@ -1385,7 +1385,7 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan)
struct sk_buff *skb;
uchar *eth;
uint len;
- void *data, *pnext, *save_pktbuf;
+ void *data, *pnext = NULL, *save_pktbuf;
int i;
dhd_if_t *ifp;
wl_event_msg_t event;
@@ -1398,6 +1398,16 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan)
struct ether_header *eh;
struct dot11_llc_snap_header *lsh;
+ ifp = dhd->iflist[ifidx];
+
+ /* Dropping packets before registering net device to avoid kernel panic */
+ if (!ifp->net || ifp->net->reg_state != NETREG_REGISTERED) {
+ DHD_ERROR(("%s: net device is NOT registered yet. drop packet\n",
+ __FUNCTION__));
+ PKTFREE(dhdp->osh, pktbuf, TRUE);
+ continue;
+ }
+
pnext = PKTNEXT(dhdp->osh, pktbuf);
PKTSETNEXT(wl->sh.osh, pktbuf, NULL);
@@ -1487,14 +1497,6 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan)
dhdp->dstats.rx_bytes += skb->len;
dhdp->rx_packets++; /* Local count */
- /* Dropping packets before registering net device to avoid kernel panic */
- if (!ifp->net || ifp->net->reg_state != NETREG_REGISTERED) {
- DHD_ERROR(("%s: net device is NOT registered yet. drop [%s] packet\n",
- __FUNCTION__, (ntoh16(skb->protocol) == ETHER_TYPE_BRCM) ? "event" : "data"));
- PKTFREE(dhdp->osh, pktbuf, TRUE);
- continue;
- }
-
if (in_interrupt()) {
netif_rx(skb);
} else {
@@ -2355,6 +2357,7 @@ dhd_add_if(dhd_info_t *dhd, int ifidx, void *handle, char *name,
if (handle == NULL) {
ifp->state = WLC_E_IF_ADD;
ifp->idx = ifidx;
+ ifp->bssidx = bssidx;
ASSERT(&dhd->thr_sysioc_ctl.thr_pid >= 0);
up(&dhd->thr_sysioc_ctl.sema);
} else
@@ -3057,6 +3060,7 @@ void dhd_detach(dhd_pub_t *dhdp)
{
dhd_info_t *dhd;
unsigned long flags;
+ int timer_valid = FALSE;
if (!dhdp)
return;
@@ -3118,17 +3122,23 @@ void dhd_detach(dhd_pub_t *dhdp)
if (ifp->net->netdev_ops == &dhd_ops_pri)
#endif
{
- unregister_netdev(ifp->net);
+ if (ifp->net) {
+ unregister_netdev(ifp->net);
+ free_netdev(ifp->net);
+ ifp->net = NULL;
+ }
MFREE(dhd->pub.osh, ifp, sizeof(*ifp));
-
+ dhd->iflist[0] = NULL;
}
}
/* Clear the watchdog timer */
flags = dhd_os_spin_lock(&dhd->pub);
+ timer_valid = dhd->wd_timer_valid;
dhd->wd_timer_valid = FALSE;
dhd_os_spin_unlock(&dhd->pub, flags);
- del_timer_sync(&dhd->timer);
+ if (timer_valid)
+ del_timer_sync(&dhd->timer);
if (dhd->dhd_state & DHD_ATTACH_STATE_THREADS_CREATED) {
#ifdef DHDTHREAD
diff --git a/drivers/net/wireless/bcmdhd/dhd_linux_mon.c b/drivers/net/wireless/bcmdhd/dhd_linux_mon.c
index 6c1ff4d8ad4..dd9c71f75be 100644
--- a/drivers/net/wireless/bcmdhd/dhd_linux_mon.c
+++ b/drivers/net/wireless/bcmdhd/dhd_linux_mon.c
@@ -106,8 +106,10 @@ static struct net_device* lookup_real_netdev(char *name)
for (i = 0; i < DHD_MAX_IFS; i++) {
ndev = dhd_idx2net(g_monitor.dhd_pub, i);
if (ndev && strstr(name, ndev->name)) {
- if (strlen(ndev->name) > last_name_len)
+ if (strlen(ndev->name) > last_name_len) {
ndev_found = ndev;
+ last_name_len = strlen(ndev->name);
+ }
}
}
diff --git a/drivers/net/wireless/bcmdhd/dhd_sdio.c b/drivers/net/wireless/bcmdhd/dhd_sdio.c
index db763ab8c3d..6d89f6b984a 100644
--- a/drivers/net/wireless/bcmdhd/dhd_sdio.c
+++ b/drivers/net/wireless/bcmdhd/dhd_sdio.c
@@ -52,6 +52,7 @@
#include <sbsdio.h>
#include <sbsdpcmdev.h>
#include <bcmsdpcm.h>
+#include <bcmsdbus.h>
#include <proto/ethernet.h>
#include <proto/802.1d.h>
@@ -76,11 +77,7 @@
#define TXRETRIES 2 /* # of retries for tx frames */
-#if defined(CONFIG_MACH_SANDGATE2G)
-#define DHD_RXBOUND 250 /* Default for max rx frames in one scheduling */
-#else
#define DHD_RXBOUND 50 /* Default for max rx frames in one scheduling */
-#endif /* defined(CONFIG_MACH_SANDGATE2G) */
#define DHD_TXBOUND 20 /* Default for max tx frames in one scheduling */
@@ -360,7 +357,7 @@ static const uint retry_limit = 2;
static bool forcealign;
/* Flag to indicate if we should download firmware on driver load */
-uint dhd_download_fw_on_driverload = TRUE;
+uint dhd_download_fw_on_driverload = FALSE;
#define ALIGNMENT 4
@@ -1026,7 +1023,9 @@ dhdsdio_txpkt(dhd_bus_t *bus, void *pkt, uint chan, bool free_pkt)
htol32_ua_store(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader));
#ifdef DHD_DEBUG
- tx_packets[PKTPRIO(pkt)]++;
+ if (PKTPRIO(pkt) < ARRAYSIZE(tx_packets)) {
+ tx_packets[PKTPRIO(pkt)]++;
+ }
if (DHD_BYTES_ON() &&
(((DHD_CTL_ON() && (chan == SDPCM_CONTROL_CHANNEL)) ||
(DHD_DATA_ON() && (chan != SDPCM_CONTROL_CHANNEL))))) {
@@ -1843,6 +1842,8 @@ dhdsdio_readshared(dhd_bus_t *bus, sdpcm_shared_t *sh)
sh->console_addr = ltoh32(sh->console_addr);
sh->msgtrace_addr = ltoh32(sh->msgtrace_addr);
+ if ((sh->flags & SDPCM_SHARED_VERSION_MASK) == 3 && SDPCM_SHARED_VERSION == 1)
+ return BCME_OK;
if ((sh->flags & SDPCM_SHARED_VERSION_MASK) != SDPCM_SHARED_VERSION) {
DHD_ERROR(("%s: sdpcm_shared version %d in dhd "
"is different than sdpcm_shared version %d in dongle\n",
@@ -6219,10 +6220,13 @@ dhd_bus_devreset(dhd_pub_t *dhdp, uint8 flag)
dhd_os_sdunlock(dhdp);
} else {
- bcmerror = BCME_NOTDOWN;
- DHD_ERROR(("%s: Set DEVRESET=FALSE invoked when device is on\n",
+ DHD_INFO(("%s called when dongle is not in reset\n",
__FUNCTION__));
- bcmerror = BCME_SDIO_ERROR;
+ DHD_INFO(("Will call dhd_bus_start instead\n"));
+ sdioh_start(NULL, 1);
+ if ((bcmerror = dhd_bus_start(dhdp)) != 0)
+ DHD_ERROR(("%s: dhd_bus_start fail with %d\n",
+ __FUNCTION__, bcmerror));
}
}
return bcmerror;
diff --git a/drivers/net/wireless/bcmdhd/include/bcmutils.h b/drivers/net/wireless/bcmdhd/include/bcmutils.h
index f7f23009fdd..530036f0ba7 100644
--- a/drivers/net/wireless/bcmdhd/include/bcmutils.h
+++ b/drivers/net/wireless/bcmdhd/include/bcmutils.h
@@ -140,7 +140,9 @@ typedef bool (*ifpkt_cb_t)(void*, int);
#define SHARED_POOL ((struct pktpool *)NULL)
#endif
+#ifndef PKTPOOL_LEN_MAX
#define PKTPOOL_LEN_MAX 40
+#endif
#define PKTPOOL_CB_MAX 3
struct pktpool;
diff --git a/drivers/net/wireless/bcmdhd/include/epivers.h b/drivers/net/wireless/bcmdhd/include/epivers.h
index 5c63a391321..f474dfa482a 100644
--- a/drivers/net/wireless/bcmdhd/include/epivers.h
+++ b/drivers/net/wireless/bcmdhd/include/epivers.h
@@ -33,17 +33,17 @@
#define EPI_RC_NUMBER 125
-#define EPI_INCREMENTAL_NUMBER 52
+#define EPI_INCREMENTAL_NUMBER 69
#define EPI_BUILD_NUMBER 0
-#define EPI_VERSION 5, 90, 125, 52
+#define EPI_VERSION 5, 90, 125, 69
-#define EPI_VERSION_NUM 0x055a7d34
+#define EPI_VERSION_NUM 0x055a7d45
#define EPI_VERSION_DEV 5.90.125
-#define EPI_VERSION_STR "5.90.125.52"
+#define EPI_VERSION_STR "5.90.125.69"
#endif
diff --git a/drivers/net/wireless/bcmdhd/include/proto/bcmevent.h b/drivers/net/wireless/bcmdhd/include/proto/bcmevent.h
index 7f51faa0d3d..30ec848c40a 100644
--- a/drivers/net/wireless/bcmdhd/include/proto/bcmevent.h
+++ b/drivers/net/wireless/bcmdhd/include/proto/bcmevent.h
@@ -181,7 +181,8 @@ typedef BWL_PRE_PACKED_STRUCT struct bcm_event {
#define WLC_E_EXCESS_PM_WAKE_EVENT 81
#define WLC_E_PFN_SCAN_NONE 82
#define WLC_E_PFN_SCAN_ALLGONE 83
-#define WLC_E_LAST 84
+#define WLC_E_GTK_PLUMBED 84
+#define WLC_E_LAST 85
typedef struct {
diff --git a/drivers/net/wireless/bcmdhd/include/sdio.h b/drivers/net/wireless/bcmdhd/include/sdio.h
index 7e94e7df13c..ca932266a1b 100644
--- a/drivers/net/wireless/bcmdhd/include/sdio.h
+++ b/drivers/net/wireless/bcmdhd/include/sdio.h
@@ -376,6 +376,7 @@ typedef volatile struct {
#define SDIOH_CMD_5 5
#define SDIOH_CMD_7 7
#define SDIOH_CMD_11 11
+#define SDIOH_CMD_14 14
#define SDIOH_CMD_15 15
#define SDIOH_CMD_19 19
#define SDIOH_CMD_52 52
@@ -411,6 +412,10 @@ typedef volatile struct {
#define CMD7_RCA_M BITFIELD_MASK(16)
#define CMD7_RCA_S 16
+#define CMD14_RCA_M BITFIELD_MASK(16)
+#define CMD14_RCA_S 16
+#define CMD14_SLEEP_M BITFIELD_MASK(1)
+#define CMD14_SLEEP_S 15
#define CMD_15_RCA_M BITFIELD_MASK(16)
#define CMD_15_RCA_S 16
diff --git a/drivers/net/wireless/bcmdhd/include/wlioctl.h b/drivers/net/wireless/bcmdhd/include/wlioctl.h
index a441eabc076..1059de147ef 100644
--- a/drivers/net/wireless/bcmdhd/include/wlioctl.h
+++ b/drivers/net/wireless/bcmdhd/include/wlioctl.h
@@ -190,6 +190,7 @@ typedef struct wlc_ssid {
#define WL_SCANFLAGS_RESERVED 0x02
#define WL_SCANFLAGS_PROHIBITED 0x04
+#define WL_SCAN_PARAMS_SSID_MAX 10
typedef struct wl_scan_params {
wlc_ssid_t ssid;
struct ether_addr bssid;
@@ -554,6 +555,7 @@ typedef enum sup_auth_status {
#define CRYPTO_ALGO_AES_OCB_MSDU 5
#define CRYPTO_ALGO_AES_OCB_MPDU 6
#define CRYPTO_ALGO_NALG 7
+#define CRYPTO_ALGO_PMK 12
#define WSEC_GEN_MIC_ERROR 0x0001
#define WSEC_GEN_REPLAY 0x0002
@@ -615,6 +617,9 @@ typedef struct {
#define WPA2_AUTH_PSK 0x0080
#define BRCM_AUTH_PSK 0x0100
#define BRCM_AUTH_DPT 0x0200
+#define WPA2_AUTH_MFP 0x1000
+#define WPA2_AUTH_TPK 0x2000
+#define WPA2_AUTH_FT 0x4000
#define MAXPMKID 16
@@ -1498,6 +1503,7 @@ typedef struct wl_sampledata {
#define WL_JOIN_PREF_WPA 2
#define WL_JOIN_PREF_BAND 3
#define WL_JOIN_PREF_RSSI_DELTA 4
+#define WL_JOIN_PREF_TRANS_PREF 5
#define WLJP_BAND_ASSOC_PREF 255
diff --git a/drivers/net/wireless/bcmdhd/wl_android.c b/drivers/net/wireless/bcmdhd/wl_android.c
index e054d7b3886..d6471d99106 100644
--- a/drivers/net/wireless/bcmdhd/wl_android.c
+++ b/drivers/net/wireless/bcmdhd/wl_android.c
@@ -338,10 +338,10 @@ int wl_android_wifi_off(struct net_device *dev)
dhd_net_if_lock(dev);
if (g_wifi_on) {
dhd_dev_reset(dev, 1);
- dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF);
sdioh_stop(NULL);
/* clean up dtim_skip setting */
net_os_set_dtim_skip(dev, TRUE);
+ dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF);
g_wifi_on = 0;
}
dhd_net_if_unlock(dev);
diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.c b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
index 366ce2224ab..09529136787 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfg80211.c
+++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
@@ -2,13 +2,13 @@
* Linux cfg80211 driver
*
* Copyright (C) 1999-2011, Broadcom Corporation
- *
+ *
* 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
* following added to such license:
- *
+ *
* As a special exception, the copyright holders of this software give you
* permission to link this software with independent modules, and to copy and
* distribute the resulting executable under terms of your choice, provided that
@@ -74,7 +74,7 @@
#include <wl_cfgp2p.h>
static struct sdio_func *cfg80211_sdio_func;
-static struct wl_dev *wl_cfg80211_dev;
+static struct wl_priv *wlcfg_drv_priv;
u32 wl_dbg_level = WL_DBG_ERR;
@@ -83,7 +83,7 @@ u32 wl_dbg_level = WL_DBG_ERR;
#define WL_TRACE(a) printk("%s ", __FUNCTION__); printk a
#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 3000
+#define MAX_WAIT_TIME 1500
static s8 ioctlbuf[WLC_IOCTL_MAXLEN];
#if defined(DHD_P2P_DEV_ADDR_FROM_SYSFS) && defined(CONFIG_SYSCTL)
@@ -148,13 +148,10 @@ static const struct ieee80211_regdomain brcm_regdom = {
NL80211_RRF_PASSIVE_SCAN |
NL80211_RRF_NO_IBSS |
NL80211_RRF_NO_OFDM),
- /* IEEE 802.11a, channel 36..48 */
- REG_RULE(5180-10, 5240+10, 40, 6, 20, 0),
-
- /* NB: 5260 MHz - 5700 MHz requies DFS */
-
- /* IEEE 802.11a, channel 149..165 */
- REG_RULE(5745-10, 5825+10, 40, 6, 20, 0), }
+ /* IEEE 802.11a, channel 36..64 */
+ REG_RULE(5150-10, 5350+10, 40, 6, 20, 0),
+ /* IEEE 802.11a, channel 100..165 */
+ REG_RULE(5470-10, 5850+10, 40, 6, 20, 0), }
};
@@ -339,8 +336,7 @@ static u32 wl_get_ielen(struct wl_priv *wl);
static s32 wl_mode_to_nl80211_iftype(s32 mode);
-static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface,
- struct device *dev);
+static struct wireless_dev *wl_alloc_wdev(struct device *sdiofunc_dev);
static void wl_free_wdev(struct wl_priv *wl);
static s32 wl_inform_bss(struct wl_priv *wl);
@@ -365,12 +361,6 @@ static void wl_deinit_priv_mem(struct wl_priv *wl);
static void wl_delay(u32 ms);
/*
- * store/restore cfg80211 instance data
- */
-static void wl_set_drvdata(struct wl_dev *dev, void *data);
-static void *wl_get_drvdata(struct wl_dev *dev);
-
-/*
* ibss mode utilities
*/
static bool wl_is_ibssmode(struct wl_priv *wl, struct net_device *ndev);
@@ -423,9 +413,9 @@ static void wl_iscan_timer(unsigned long data);
static void wl_term_iscan(struct wl_priv *wl);
static s32 wl_init_scan(struct wl_priv *wl);
static s32 wl_iscan_thread(void *data);
-static s32 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid,
+static s32 wl_run_iscan(struct wl_iscan_ctrl *iscan, struct cfg80211_scan_request *request,
u16 action);
-static s32 wl_do_iscan(struct wl_priv *wl);
+static s32 wl_do_iscan(struct wl_priv *wl, struct cfg80211_scan_request *request);
static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan);
static s32 wl_invoke_iscan(struct wl_priv *wl);
static s32 wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status,
@@ -474,23 +464,11 @@ 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 WL_PRIV_GET() \
- ({ \
- struct wl_iface *ci = NULL; \
- if (unlikely(!(wl_cfg80211_dev && \
- (ci = wl_get_drvdata(wl_cfg80211_dev))))) { \
- WL_ERR(("wl_cfg80211_dev is unavailable\n")); \
- BUG(); \
- } \
- ci_to_wl(ci); \
-})
-
-#define CHECK_SYS_UP() \
+#define CHECK_SYS_UP(wlpriv) \
do { \
- struct wl_priv *wl = WL_PRIV_GET(); \
- if (unlikely(!wl_get_drv_status(wl, READY))) { \
+ if (unlikely(!wl_get_drv_status(wlpriv, READY))) { \
WL_INFO(("device is not ready : status (%d)\n", \
- (int)wl->status)); \
+ (int)wlpriv->status)); \
return -EIO; \
} \
} while (0)
@@ -609,70 +587,7 @@ static struct ieee80211_channel __wl_5ghz_a_channels[] = {
CHAN5G(132, 0), CHAN5G(136, 0),
CHAN5G(140, 0), CHAN5G(149, 0),
CHAN5G(153, 0), CHAN5G(157, 0),
- CHAN5G(161, 0), CHAN5G(165, 0),
- CHAN5G(184, 0), CHAN5G(188, 0),
- CHAN5G(192, 0), CHAN5G(196, 0),
- CHAN5G(200, 0), CHAN5G(204, 0),
- CHAN5G(208, 0), CHAN5G(212, 0),
- CHAN5G(216, 0)
-};
-
-static struct ieee80211_channel __wl_5ghz_n_channels[] = {
- CHAN5G(32, 0), CHAN5G(34, 0),
- CHAN5G(36, 0), CHAN5G(38, 0),
- CHAN5G(40, 0), CHAN5G(42, 0),
- CHAN5G(44, 0), CHAN5G(46, 0),
- CHAN5G(48, 0), CHAN5G(50, 0),
- CHAN5G(52, 0), CHAN5G(54, 0),
- CHAN5G(56, 0), CHAN5G(58, 0),
- CHAN5G(60, 0), CHAN5G(62, 0),
- CHAN5G(64, 0), CHAN5G(66, 0),
- CHAN5G(68, 0), CHAN5G(70, 0),
- CHAN5G(72, 0), CHAN5G(74, 0),
- CHAN5G(76, 0), CHAN5G(78, 0),
- CHAN5G(80, 0), CHAN5G(82, 0),
- CHAN5G(84, 0), CHAN5G(86, 0),
- CHAN5G(88, 0), CHAN5G(90, 0),
- CHAN5G(92, 0), CHAN5G(94, 0),
- CHAN5G(96, 0), CHAN5G(98, 0),
- CHAN5G(100, 0), CHAN5G(102, 0),
- CHAN5G(104, 0), CHAN5G(106, 0),
- CHAN5G(108, 0), CHAN5G(110, 0),
- CHAN5G(112, 0), CHAN5G(114, 0),
- CHAN5G(116, 0), CHAN5G(118, 0),
- CHAN5G(120, 0), CHAN5G(122, 0),
- CHAN5G(124, 0), CHAN5G(126, 0),
- CHAN5G(128, 0), CHAN5G(130, 0),
- CHAN5G(132, 0), CHAN5G(134, 0),
- CHAN5G(136, 0), CHAN5G(138, 0),
- CHAN5G(140, 0), CHAN5G(142, 0),
- CHAN5G(144, 0), CHAN5G(145, 0),
- CHAN5G(146, 0), CHAN5G(147, 0),
- CHAN5G(148, 0), CHAN5G(149, 0),
- CHAN5G(150, 0), CHAN5G(151, 0),
- CHAN5G(152, 0), CHAN5G(153, 0),
- CHAN5G(154, 0), CHAN5G(155, 0),
- CHAN5G(156, 0), CHAN5G(157, 0),
- CHAN5G(158, 0), CHAN5G(159, 0),
- CHAN5G(160, 0), CHAN5G(161, 0),
- CHAN5G(162, 0), CHAN5G(163, 0),
- CHAN5G(164, 0), CHAN5G(165, 0),
- CHAN5G(166, 0), CHAN5G(168, 0),
- CHAN5G(170, 0), CHAN5G(172, 0),
- CHAN5G(174, 0), CHAN5G(176, 0),
- CHAN5G(178, 0), CHAN5G(180, 0),
- CHAN5G(182, 0), CHAN5G(184, 0),
- CHAN5G(186, 0), CHAN5G(188, 0),
- CHAN5G(190, 0), CHAN5G(192, 0),
- CHAN5G(194, 0), CHAN5G(196, 0),
- CHAN5G(198, 0), CHAN5G(200, 0),
- CHAN5G(202, 0), CHAN5G(204, 0),
- CHAN5G(206, 0), CHAN5G(208, 0),
- CHAN5G(210, 0), CHAN5G(212, 0),
- CHAN5G(214, 0), CHAN5G(216, 0),
- CHAN5G(218, 0), CHAN5G(220, 0),
- CHAN5G(222, 0), CHAN5G(224, 0),
- CHAN5G(226, 0), CHAN5G(228, 0)
+ CHAN5G(161, 0), CHAN5G(165, 0)
};
static struct ieee80211_supported_band __wl_band_2ghz = {
@@ -691,14 +606,6 @@ static struct ieee80211_supported_band __wl_band_5ghz_a = {
.n_bitrates = wl_a_rates_size
};
-static struct ieee80211_supported_band __wl_band_5ghz_n = {
- .band = IEEE80211_BAND_5GHZ,
- .channels = __wl_5ghz_n_channels,
- .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
- .bitrates = wl_a_rates,
- .n_bitrates = wl_a_rates_size
-};
-
static const u32 __wl_cipher_suites[] = {
WLAN_CIPHER_SUITE_WEP40,
WLAN_CIPHER_SUITE_WEP104,
@@ -876,11 +783,10 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name,
s32 index = 0;
s32 mode = 0;
chanspec_t chspec;
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wiphy_priv(wiphy);
struct net_device *_ndev;
dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
int (*net_attach)(dhd_pub_t *dhdp, int ifidx);
-
WL_DBG(("if name: %s, type: %d\n", name, type));
switch (type) {
case NL80211_IFTYPE_ADHOC:
@@ -968,7 +874,8 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name,
return ERR_PTR(-ENOMEM);
}
vwdev->wiphy = wl->wdev->wiphy;
- WL_INFO((" virtual interface(%s) is created \n", wl->p2p->vir_ifname));
+ WL_INFO((" virtual interface(%s) is created memalloc done \n",
+ wl->p2p->vir_ifname));
index = alloc_idx_vwdev(wl);
wl->vwdev[index] = vwdev;
vwdev->iftype =
@@ -981,12 +888,11 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name,
wl_set_drv_status(wl, READY);
wl->p2p->vif_created = true;
set_mode_by_netdev(wl, _ndev, mode);
- wl = wdev_to_wl(vwdev);
net_attach = wl_to_p2p_bss_private(wl, P2PAPI_BSSCFG_CONNECTION);
rtnl_unlock();
if (net_attach && !net_attach(dhd, _ndev->ifindex))
WL_DBG((" virtual interface(%s) is "
- "created\n", wl->p2p->vir_ifname));
+ "created net attach done\n", wl->p2p->vir_ifname));
else {
rtnl_lock();
goto fail;
@@ -1010,10 +916,10 @@ static s32
wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, struct net_device *dev)
{
struct ether_addr p2p_mac;
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wiphy_priv(wiphy);
s32 timeout = -1;
s32 ret = 0;
-
+ WL_DBG(("Enter\n"));
if (wl->p2p_supported) {
memcpy(p2p_mac.octet, wl->p2p->int_addr.octet, ETHER_ADDR_LEN);
if (wl->p2p->vif_created) {
@@ -1021,8 +927,17 @@ wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, struct net_device *dev)
wl_cfg80211_scan_abort(wl, dev);
}
- wl_cfgp2p_ifdel(wl, &p2p_mac);
+ ret = wl_cfgp2p_ifdel(wl, &p2p_mac);
wl_set_p2p_status(wl, IF_DELETING);
+ if (ret) {
+ /* 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 ifconfig <inter> down and up sequnce, which will reload the fw
+ * however we should cleanup the linux network virtual interfaces
+ */
+ dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
+ WL_ERR(("Firmware returned an error from p2p_ifdel, try to remove linux virtual network interface dev->name %s\n", dev->name));
+ dhd_del_if(dhd->info, dhd_net2idx(dhd->info, dev));
+ }
/* Wait for any pending scan req to get aborted from the sysioc context */
timeout = wait_event_interruptible_timeout(wl->dongle_event_wait,
@@ -1052,7 +967,7 @@ wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev,
s32 wlif_type;
s32 mode = 0;
chanspec_t chspec;
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wiphy_priv(wiphy);
WL_DBG(("Enter \n"));
switch (type) {
case NL80211_IFTYPE_MONITOR:
@@ -1118,10 +1033,10 @@ wl_cfg80211_change_virtual_iface(struct wiphy *wiphy, struct net_device *ndev,
}
s32
-wl_cfg80211_notify_ifadd(struct net_device *net, s32 idx,
+wl_cfg80211_notify_ifadd(struct net_device *net, s32 idx, s32 bssidx,
int (*_net_attach)(dhd_pub_t *dhdp, int ifidx))
{
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wlcfg_drv_priv;
s32 ret = BCME_OK;
if (!net) {
WL_ERR(("net is NULL\n"));
@@ -1133,11 +1048,11 @@ int (*_net_attach)(dhd_pub_t *dhdp, int ifidx))
/* Assign the net device to CONNECT BSSCFG */
strncpy(net->name, wl->p2p->vir_ifname, IFNAMSIZ - 1);
wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION) = net;
- wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_CONNECTION) =
- P2PAPI_BSSCFG_CONNECTION;
+ wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_CONNECTION) = bssidx;
wl_to_p2p_bss_private(wl, P2PAPI_BSSCFG_CONNECTION) = _net_attach;
- wl_clr_p2p_status(wl, IF_ADD);
net->ifindex = idx;
+ wl_clr_p2p_status(wl, IF_ADD);
+
wake_up_interruptible(&wl->dongle_event_wait);
}
return ret;
@@ -1146,7 +1061,7 @@ int (*_net_attach)(dhd_pub_t *dhdp, int ifidx))
s32
wl_cfg80211_ifdel_ops(struct net_device *net)
{
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wlcfg_drv_priv;
if (!net || !net->name) {
WL_DBG(("net is NULL\n"));
@@ -1172,14 +1087,14 @@ wl_cfg80211_ifdel_ops(struct net_device *net)
s32
wl_cfg80211_notify_ifdel(struct net_device *net)
{
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wlcfg_drv_priv;
if (wl->p2p->vif_created) {
s32 index = 0;
- WL_DBG(("IF_DEL event called from dongle, _net name: %s, vif name: %s\n",
- net->name, wl->p2p->vir_ifname));
+ WL_DBG(("IF_DEL event called from dongle, net %x, vif name: %s\n",
+ (unsigned int)net, wl->p2p->vir_ifname));
memset(wl->p2p->vir_ifname, '\0', IFNAMSIZ);
index = wl_cfgp2p_find_idx(wl, net);
@@ -1208,7 +1123,7 @@ s32
wl_cfg80211_is_progress_ifadd(void)
{
s32 is_progress = 0;
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wlcfg_drv_priv;
if (wl_get_p2p_status(wl, IF_ADD))
is_progress = 1;
return is_progress;
@@ -1218,7 +1133,7 @@ s32
wl_cfg80211_is_progress_ifchange(void)
{
s32 is_progress = 0;
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wlcfg_drv_priv;
if (wl_get_p2p_status(wl, IF_CHANGING))
is_progress = 1;
return is_progress;
@@ -1228,7 +1143,7 @@ wl_cfg80211_is_progress_ifchange(void)
s32
wl_cfg80211_notify_ifchange(void)
{
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wlcfg_drv_priv;
if (wl_get_p2p_status(wl, IF_CHANGING)) {
wl_set_p2p_status(wl, IF_CHANGED);
wake_up_interruptible(&wl->dongle_event_wait);
@@ -1236,8 +1151,16 @@ wl_cfg80211_notify_ifchange(void)
return 0;
}
-static void wl_iscan_prep(struct wl_scan_params *params, struct wlc_ssid *ssid)
+static void wl_scan_prep(struct wl_scan_params *params, struct cfg80211_scan_request *request)
{
+ u32 n_ssids = request->n_ssids;
+ u32 n_channels = request->n_channels;
+ u16 channel;
+ chanspec_t chanspec;
+ s32 i, offset;
+ char *ptr;
+ wlc_ssid_t ssid;
+
memcpy(&params->bssid, &ether_bcast, ETHER_ADDR_LEN);
params->bss_type = DOT11_BSSTYPE_ANY;
params->scan_type = 0;
@@ -1246,63 +1169,142 @@ static void wl_iscan_prep(struct wl_scan_params *params, struct wlc_ssid *ssid)
params->passive_time = -1;
params->home_time = -1;
params->channel_num = 0;
+ memset(&params->ssid, 0, sizeof(wlc_ssid_t));
+
+ WL_SCAN(("Preparing Scan request\n"));
+ WL_SCAN(("nprobes=%d\n", params->nprobes));
+ WL_SCAN(("active_time=%d\n", params->active_time));
+ WL_SCAN(("passive_time=%d\n", params->passive_time));
+ WL_SCAN(("home_time=%d\n", params->home_time));
+ WL_SCAN(("scan_type=%d\n", params->scan_type));
params->nprobes = htod32(params->nprobes);
params->active_time = htod32(params->active_time);
params->passive_time = htod32(params->passive_time);
params->home_time = htod32(params->home_time);
- if (ssid && ssid->SSID_len)
- memcpy(&params->ssid, ssid, sizeof(wlc_ssid_t));
+ /* Copy channel array if applicable */
+ WL_SCAN(("### List of channelspecs to scan ###\n"));
+ if (n_channels > 0) {
+ for (i = 0; i < n_channels; i++) {
+ chanspec = 0;
+ channel = ieee80211_frequency_to_channel(request->channels[i]->center_freq);
+ if (request->channels[i]->band == IEEE80211_BAND_2GHZ)
+ chanspec |= WL_CHANSPEC_BAND_2G;
+ else
+ chanspec |= WL_CHANSPEC_BAND_5G;
+
+ if (request->channels[i]->flags & IEEE80211_CHAN_NO_HT40) {
+ chanspec |= WL_CHANSPEC_BW_20;
+ chanspec |= WL_CHANSPEC_CTL_SB_NONE;
+ } else {
+ chanspec |= WL_CHANSPEC_BW_40;
+ if (request->channels[i]->flags & IEEE80211_CHAN_NO_HT40PLUS)
+ chanspec |= WL_CHANSPEC_CTL_SB_LOWER;
+ else
+ chanspec |= WL_CHANSPEC_CTL_SB_UPPER;
+ }
+
+ params->channel_list[i] = channel;
+ params->channel_list[i] &= WL_CHANSPEC_CHAN_MASK;
+ params->channel_list[i] |= chanspec;
+ WL_SCAN(("Chan : %d, Channel spec: %x \n",
+ channel, params->channel_list[i]));
+ params->channel_list[i] = htod16(params->channel_list[i]);
+ }
+ } else {
+ WL_SCAN(("Scanning all channels\n"));
+ }
+
+ /* Copy ssid array if applicable */
+ WL_SCAN(("### List of SSIDs to scan ###\n"));
+ if (n_ssids > 0) {
+ offset = offsetof(wl_scan_params_t, channel_list) + n_channels * sizeof(u16);
+ offset = roundup(offset, sizeof(u32));
+ ptr = (char*)params + offset;
+ for (i = 0; i < n_ssids; i++) {
+ memset(&ssid, 0, sizeof(wlc_ssid_t));
+ ssid.SSID_len = request->ssids[i].ssid_len;
+ memcpy(ssid.SSID, request->ssids[i].ssid, ssid.SSID_len);
+ if (!ssid.SSID_len)
+ WL_SCAN(("%d: Broadcast scan\n", i));
+ else
+ WL_SCAN(("%d: scan for %s size =%d\n", i,
+ ssid.SSID, ssid.SSID_len));
+ memcpy(ptr, &ssid, sizeof(wlc_ssid_t));
+ ptr += sizeof(wlc_ssid_t);
+ }
+ } else {
+ WL_SCAN(("Broadcast scan\n"));
+ }
+ /* Adding mask to channel numbers */
+ params->channel_num =
+ htod32((n_ssids << WL_SCAN_PARAMS_NSSID_SHIFT) |
+ (n_channels & WL_SCAN_PARAMS_COUNT_MASK));
}
static s32
-wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid, u16 action)
+wl_run_iscan(struct wl_iscan_ctrl *iscan, struct cfg80211_scan_request *request, u16 action)
{
+ u32 n_channels;
+ u32 n_ssids;
s32 params_size =
- (WL_SCAN_PARAMS_FIXED_SIZE + offsetof(wl_iscan_params_t, params));
+ (WL_SCAN_PARAMS_FIXED_SIZE + offsetof(wl_iscan_params_t, params));
struct wl_iscan_params *params;
s32 err = 0;
- if (ssid && ssid->SSID_len)
- params_size += sizeof(struct wlc_ssid);
+ if (request != NULL) {
+ n_channels = request->n_channels;
+ n_ssids = request->n_ssids;
+ /* Allocate space for populating ssids in wl_iscan_params struct */
+ if (n_channels % 2)
+ /* If n_channels is odd, add a padd of u16 */
+ params_size += sizeof(u16) * (n_channels + 1);
+ else
+ params_size += sizeof(u16) * n_channels;
+
+ /* Allocate space for populating ssids in wl_iscan_params struct */
+ params_size += sizeof(struct wlc_ssid) * n_ssids;
+ }
params = (struct wl_iscan_params *)kzalloc(params_size, GFP_KERNEL);
- if (unlikely(!params))
- return -ENOMEM;
- memset(params, 0, params_size);
- BUG_ON(unlikely(params_size >= WLC_IOCTL_SMLEN));
+ if (!params) {
+ err = -ENOMEM;
+ goto done;
+ }
- wl_iscan_prep(&params->params, ssid);
+ if (request != NULL)
+ wl_scan_prep(&params->params, request);
params->version = htod32(ISCAN_REQ_VERSION);
params->action = htod16(action);
params->scan_duration = htod16(0);
- /* params_size += offsetof(wl_iscan_params_t, params); */
+ if (params_size + sizeof("iscan") >= WLC_IOCTL_MEDLEN) {
+ WL_ERR(("ioctl buffer length is not sufficient\n"));
+ err = -ENOMEM;
+ goto done;
+ }
err = wldev_iovar_setbuf(iscan->dev, "iscan", params, params_size,
- iscan->ioctl_buf, WLC_IOCTL_SMLEN);
+ iscan->ioctl_buf, WLC_IOCTL_MEDLEN);
if (unlikely(err)) {
if (err == -EBUSY) {
- WL_INFO(("system busy : iscan canceled\n"));
+ WL_INFO(("system busy : iscan canceled\n"));
} else {
WL_ERR(("error (%d)\n", err));
}
}
kfree(params);
+done:
return err;
}
-static s32 wl_do_iscan(struct wl_priv *wl)
+static s32 wl_do_iscan(struct wl_priv *wl, struct cfg80211_scan_request *request)
{
struct wl_iscan_ctrl *iscan = wl_to_iscan(wl);
struct net_device *ndev = wl_to_prmry_ndev(wl);
- struct wlc_ssid ssid;
s32 passive_scan;
s32 err = 0;
- /* Broadcast scan by default */
- memset(&ssid, 0, sizeof(ssid));
-
iscan->state = WL_ISCAN_STATE_SCANING;
passive_scan = wl->active_scan ? 0 : 1;
@@ -1313,7 +1315,7 @@ static s32 wl_do_iscan(struct wl_priv *wl)
return err;
}
wl->iscan_kickstart = true;
- wl_run_iscan(iscan, &ssid, WL_SCAN_ACTION_START);
+ wl_run_iscan(iscan, request, WL_SCAN_ACTION_START);
mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
iscan->timer_on = 1;
@@ -1321,9 +1323,12 @@ static s32 wl_do_iscan(struct wl_priv *wl)
}
static s32
-wl_run_escan(struct wl_priv *wl, struct net_device *ndev, wlc_ssid_t *ssid, uint16 action)
+wl_run_escan(struct wl_priv *wl, struct net_device *ndev,
+ struct cfg80211_scan_request *request, uint16 action)
{
s32 err = BCME_OK;
+ u32 n_channels;
+ u32 n_ssids;
s32 params_size = (WL_SCAN_PARAMS_FIXED_SIZE + OFFSETOF(wl_escan_params_t, params));
wl_escan_params_t *params;
struct cfg80211_scan_request *scan_request = wl->scan_request;
@@ -1337,31 +1342,37 @@ wl_run_escan(struct wl_priv *wl, struct net_device *ndev, wlc_ssid_t *ssid, uint
if (!wl->p2p_supported || ((ndev == wl_to_prmry_ndev(wl)) &&
!p2p_scan(wl))) {
/* LEGACY SCAN TRIGGER */
- WL_DBG(("LEGACY SCAN START\n"));
- if (ssid && ssid->SSID_len) {
- params_size += sizeof(wlc_ssid_t);
+ WL_SCAN((" LEGACY E-SCAN START\n"));
+
+ if (request != NULL) {
+ n_channels = request->n_channels;
+ n_ssids = request->n_ssids;
+ /* Allocate space for populating ssids in wl_iscan_params struct */
+ if (n_channels % 2)
+ /* If n_channels is odd, add a padd of u16 */
+ params_size += sizeof(u16) * (n_channels + 1);
+ else
+ params_size += sizeof(u16) * n_channels;
+
+ /* Allocate space for populating ssids in wl_iscan_params struct */
+ params_size += sizeof(struct wlc_ssid) * n_ssids;
}
- params = (wl_escan_params_t *) kmalloc(params_size, GFP_KERNEL);
-
- if (params == NULL)
- return -ENOMEM;
-
- memset(params, 0, params_size);
- memcpy(&params->params.bssid, &ether_bcast, ETHER_ADDR_LEN);
- params->params.bss_type = DOT11_BSSTYPE_ANY;
- params->params.scan_type = 0;
- params->params.nprobes = htod32(-1);
- params->params.active_time = htod32(-1);
- params->params.passive_time = htod32(-1);
- params->params.home_time = htod32(-1);
- params->params.channel_num = 0;
- if (ssid && ssid->SSID_len) {
- memcpy(params->params.ssid.SSID, ssid->SSID, ssid->SSID_len);
- params->params.ssid.SSID_len = htod32(ssid->SSID_len);
+ params = (wl_escan_params_t *) kzalloc(params_size, GFP_KERNEL);
+ if (params == NULL) {
+ err = -ENOMEM;
+ goto exit;
}
+
+ 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"));
+ err = -ENOMEM;
+ goto exit;
+ }
wldev_iovar_setbuf(ndev, "escan", params, params_size,
wl->escan_ioctl_buf, WLC_IOCTL_MEDLEN);
kfree(params);
@@ -1370,7 +1381,7 @@ wl_run_escan(struct wl_priv *wl, struct net_device *ndev, wlc_ssid_t *ssid, uint
/* P2P SCAN TRIGGER */
if (scan_request && scan_request->n_channels) {
num_chans = scan_request->n_channels;
- WL_INFO((" chann number : %d\n", num_chans));
+ WL_SCAN((" chann number : %d\n", num_chans));
default_chan_list = kzalloc(num_chans * sizeof(*default_chan_list),
GFP_KERNEL);
if (default_chan_list == NULL) {
@@ -1407,12 +1418,13 @@ exit:
static s32
-wl_do_escan(struct wl_priv *wl, struct wiphy *wiphy, struct net_device *ndev, wlc_ssid_t *ssid)
+wl_do_escan(struct wl_priv *wl, struct wiphy *wiphy, struct net_device *ndev,
+ struct cfg80211_scan_request *request)
{
s32 err = BCME_OK;
s32 passive_scan;
wl_scan_results_t *results;
- WL_DBG(("Enter \n"));
+ WL_SCAN(("Enter \n"));
wl->escan_info.wiphy = wiphy;
wl->escan_info.escan_state = WL_ESCAN_STATE_SCANING;
@@ -1428,7 +1440,7 @@ wl_do_escan(struct wl_priv *wl, struct wiphy *wiphy, struct net_device *ndev, wl
results->count = 0;
results->buflen = WL_SCAN_RESULTS_FIXED_SIZE;
- wl_run_escan(wl, ndev, ssid, WL_SCAN_ACTION_START);
+ wl_run_escan(wl, ndev, request, WL_SCAN_ACTION_START);
return err;
}
@@ -1437,15 +1449,16 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
struct cfg80211_scan_request *request,
struct cfg80211_ssid *this_ssid)
{
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wiphy_priv(wiphy);
struct cfg80211_ssid *ssids;
struct wl_scan_req *sr = wl_to_sr(wl);
- wlc_ssid_t ssid_info;
s32 passive_scan;
bool iscan_req;
bool escan_req;
bool spec_scan;
+ bool p2p_ssid;
s32 err = 0;
+ s32 i;
if (unlikely(wl_get_drv_status(wl, SCANNING))) {
WL_ERR(("Scanning already : status (%d)\n", (int)wl->status));
@@ -1456,6 +1469,10 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
(int)wl->status));
return -EAGAIN;
}
+ if (request->n_ssids > WL_SCAN_PARAMS_SSID_MAX) {
+ WL_ERR(("n_ssids > WL_SCAN_PARAMS_SSID_MAX\n"));
+ return -EOPNOTSUPP;
+ }
WL_DBG(("wiphy (%p)\n", wiphy));
@@ -1463,11 +1480,18 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
spec_scan = false;
if (request) { /* scan bss */
ssids = request->ssids;
- if (wl->iscan_on && (!ssids || !ssids->ssid_len)) {
+ if (wl->iscan_on && (!ssids || !ssids->ssid_len || request->n_ssids != 1)) {
iscan_req = true;
} else if (wl->escan_on) {
escan_req = true;
- if (ssids->ssid_len && IS_P2P_SSID(ssids->ssid)) {
+ p2p_ssid = false;
+ for (i = 0; i < request->n_ssids; i++) {
+ if (ssids[i].ssid_len && IS_P2P_SSID(ssids[i].ssid)) {
+ p2p_ssid = true;
+ break;
+ }
+ }
+ if (p2p_ssid) {
if (wl->p2p_supported) {
/* p2p scan trigger */
if (p2p_on(wl) == false) {
@@ -1477,7 +1501,6 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
}
p2p_scan(wl) = true;
}
-
} else {
/* legacy scan trigger
* So, we have to disable p2p discovery if p2p discovery is on
@@ -1510,17 +1533,12 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
wl->scan_request = request;
wl_set_drv_status(wl, SCANNING);
if (iscan_req) {
- err = wl_do_iscan(wl);
+ err = wl_do_iscan(wl, request);
if (likely(!err))
return err;
else
goto scan_out;
} else if (escan_req) {
- WL_DBG(("ssid \"%s\", ssid_len (%d)\n",
- ssids->ssid, ssids->ssid_len));
-
- memcpy(ssid_info.SSID, ssids->ssid, ssids->ssid_len);
- ssid_info.SSID_len = ssids->ssid_len;
if (wl->p2p_supported) {
if (p2p_on(wl) && p2p_scan(wl)) {
@@ -1532,7 +1550,7 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
}
}
}
- err = wl_do_escan(wl, wiphy, ndev, &ssid_info);
+ err = wl_do_escan(wl, wiphy, ndev, request);
if (likely(!err))
return err;
else
@@ -1546,18 +1564,18 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
if (sr->ssid.SSID_len) {
memcpy(sr->ssid.SSID, ssids->ssid, sr->ssid.SSID_len);
sr->ssid.SSID_len = htod32(sr->ssid.SSID_len);
- WL_DBG(("Specific scan ssid=\"%s\" len=%d\n",
+ WL_SCAN(("Specific scan ssid=\"%s\" len=%d\n",
sr->ssid.SSID, sr->ssid.SSID_len));
spec_scan = true;
} else {
- WL_DBG(("Broadcast scan\n"));
+ WL_SCAN(("Broadcast scan\n"));
}
- WL_DBG(("sr->ssid.SSID_len (%d)\n", sr->ssid.SSID_len));
+ WL_SCAN(("sr->ssid.SSID_len (%d)\n", sr->ssid.SSID_len));
passive_scan = wl->active_scan ? 0 : 1;
err = wldev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
&passive_scan, sizeof(passive_scan), false);
if (unlikely(err)) {
- WL_ERR(("WLC_SET_PASSIVE_SCAN error (%d)\n", err));
+ WL_SCAN(("WLC_SET_PASSIVE_SCAN error (%d)\n", err));
goto scan_out;
}
err = wldev_ioctl(ndev, WLC_SCAN, &sr->ssid,
@@ -1586,9 +1604,10 @@ wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
struct cfg80211_scan_request *request)
{
s32 err = 0;
+ struct wl_priv *wl = wiphy_priv(wiphy);
WL_DBG(("Enter \n"));
- CHECK_SYS_UP();
+ CHECK_SYS_UP(wl);
err = __wl_cfg80211_scan(wiphy, ndev, request, NULL);
if (unlikely(err)) {
WL_ERR(("scan error (%d)\n", err));
@@ -1679,11 +1698,11 @@ static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l)
static s32 wl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
{
- struct wl_priv *wl = wiphy_to_wl(wiphy);
+ struct wl_priv *wl = (struct wl_priv *)wiphy_priv(wiphy);
struct net_device *ndev = wl_to_prmry_ndev(wl);
s32 err = 0;
- CHECK_SYS_UP();
+ CHECK_SYS_UP(wl);
if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
(wl->conf->rts_threshold != wiphy->rts_threshold)) {
wl->conf->rts_threshold = wiphy->rts_threshold;
@@ -1721,7 +1740,7 @@ static s32
wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_ibss_params *params)
{
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wiphy_priv(wiphy);
struct cfg80211_bss *bss;
struct ieee80211_channel *chan;
struct wl_join_params join_params;
@@ -1730,7 +1749,7 @@ wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
s32 err = 0;
WL_TRACE(("In\n"));
- CHECK_SYS_UP();
+ CHECK_SYS_UP(wl);
if (params->bssid) {
WL_ERR(("Invalid bssid\n"));
return -EOPNOTSUPP;
@@ -1791,10 +1810,10 @@ wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
{
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wiphy_priv(wiphy);
s32 err = 0;
- CHECK_SYS_UP();
+ CHECK_SYS_UP(wl);
wl_link_down(wl);
return err;
@@ -1803,7 +1822,7 @@ static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
static s32
wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme)
{
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wlcfg_drv_priv;
struct wl_security *sec;
s32 val = 0;
s32 err = 0;
@@ -1833,7 +1852,7 @@ wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme)
static s32
wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme)
{
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wlcfg_drv_priv;
struct wl_security *sec;
s32 val = 0;
s32 err = 0;
@@ -1872,7 +1891,7 @@ wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme)
static s32
wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme)
{
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wlcfg_drv_priv;
struct wl_security *sec;
s32 pval = 0;
s32 gval = 0;
@@ -1944,7 +1963,7 @@ wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme)
static s32
wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme)
{
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wlcfg_drv_priv;
struct wl_security *sec;
s32 val = 0;
s32 err = 0;
@@ -2002,7 +2021,7 @@ static s32
wl_set_set_sharedkey(struct net_device *dev,
struct cfg80211_connect_params *sme)
{
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wlcfg_drv_priv;
struct wl_security *sec;
struct wl_wsec_key key;
s32 val;
@@ -2068,14 +2087,17 @@ static s32
wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_connect_params *sme)
{
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wiphy_priv(wiphy);
struct ieee80211_channel *chan = sme->channel;
struct wl_join_params join_params;
size_t join_params_size;
s32 err = 0;
-
+ wpa_ie_fixed_t *wpa_ie;
+ bcm_tlv_t *wpa2_ie;
+ u8* wpaie = 0;
+ u32 wpaie_len = 0;
WL_DBG(("In\n"));
- CHECK_SYS_UP();
+ CHECK_SYS_UP(wl);
/*
* Cancel ongoing scan to sync up with sme state machine of cfg80211.
@@ -2107,8 +2129,28 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
VNDR_IE_ASSOCREQ_FLAG, sme->ie, sme->ie_len);
}
- } else {
- WL_INFO(("No P2PIE in beacon \n"));
+ } else if (dev == wl_to_prmry_ndev(wl)) {
+ /* find the RSN_IE */
+ if ((wpa2_ie = bcm_parse_tlvs((u8 *)sme->ie, sme->ie_len,
+ DOT11_MNG_RSN_ID)) != NULL) {
+ WL_DBG((" WPA2 IE is found\n"));
+ }
+ /* find the WPA_IE */
+ if ((wpa_ie = wl_cfgp2p_find_wpaie((u8 *)sme->ie,
+ sme->ie_len)) != NULL) {
+ WL_DBG((" WPA IE is found\n"));
+ }
+ if (wpa_ie != NULL || wpa2_ie != NULL) {
+ wpaie = (wpa_ie != NULL) ? (u8 *)wpa_ie : (u8 *)wpa2_ie;
+ wpaie_len = (wpa_ie != NULL) ? wpa_ie->length : wpa2_ie->len;
+ wpaie_len += WPA_RSN_IE_TAG_FIXED_LEN;
+ wldev_iovar_setbuf(dev, "wpaie", wpaie, wpaie_len,
+ ioctlbuf, sizeof(ioctlbuf));
+ } else {
+ wldev_iovar_setbuf(dev, "wpaie", NULL, 0,
+ ioctlbuf, sizeof(ioctlbuf));
+ }
+
}
if (unlikely(!sme->ssid)) {
@@ -2119,7 +2161,8 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
wl->channel = ieee80211_frequency_to_channel(chan->center_freq);
WL_DBG(("channel (%d), center_req (%d)\n", wl->channel,
chan->center_freq));
- }
+ } else
+ wl->channel = 0;
WL_DBG(("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len));
err = wl_set_wpa_version(dev, sme);
if (unlikely(err))
@@ -2153,7 +2196,10 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
memcpy(&join_params.ssid.SSID, sme->ssid, join_params.ssid.SSID_len);
join_params.ssid.SSID_len = htod32(join_params.ssid.SSID_len);
wl_update_prof(wl, NULL, &join_params.ssid, WL_PROF_SSID);
- memcpy(&join_params.params.bssid, &ether_bcast, ETHER_ADDR_LEN);
+ if (sme->bssid)
+ memcpy(&join_params.params.bssid, sme->bssid, ETH_ALEN);
+ else
+ memcpy(&join_params.params.bssid, &ether_bcast, ETH_ALEN);
wl_ch_to_chanspec(wl->channel, &join_params, &join_params_size);
WL_DBG(("join_param_size %d\n", join_params_size));
@@ -2162,13 +2208,13 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
WL_INFO(("ssid \"%s\", len (%d)\n", join_params.ssid.SSID,
join_params.ssid.SSID_len));
}
+ wl_set_drv_status(wl, CONNECTING);
err = wldev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size, false);
if (unlikely(err)) {
WL_ERR(("error (%d)\n", err));
+ wl_clr_drv_status(wl, CONNECTING);
return err;
}
- wl_set_drv_status(wl, CONNECTING);
-
return err;
}
@@ -2176,21 +2222,29 @@ static s32
wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
u16 reason_code)
{
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wiphy_priv(wiphy);
scb_val_t scbval;
bool act = false;
s32 err = 0;
WL_ERR(("Reason %d\n\n\n", reason_code));
- CHECK_SYS_UP();
+ CHECK_SYS_UP(wl);
act = *(bool *) wl_read_prof(wl, WL_PROF_ACT);
if (likely(act)) {
+ /*
+ * Cancel ongoing scan to sync up with sme state machine of cfg80211.
+ */
+ if (wl->scan_request) {
+ wl_cfg80211_scan_abort(wl, dev);
+ }
+ wl_set_drv_status(wl, DISCONNECTING);
scbval.val = reason_code;
memcpy(&scbval.ea, &wl->bssid, ETHER_ADDR_LEN);
scbval.val = htod32(scbval.val);
err = wldev_ioctl(dev, WLC_DISASSOC, &scbval,
sizeof(scb_val_t), false);
if (unlikely(err)) {
+ wl_clr_drv_status(wl, DISCONNECTING);
WL_ERR(("error (%d)\n", err));
return err;
}
@@ -2204,13 +2258,13 @@ wl_cfg80211_set_tx_power(struct wiphy *wiphy,
enum nl80211_tx_power_setting type, s32 dbm)
{
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wiphy_priv(wiphy);
struct net_device *ndev = wl_to_prmry_ndev(wl);
u16 txpwrmw;
s32 err = 0;
s32 disable = 0;
- CHECK_SYS_UP();
+ CHECK_SYS_UP(wl);
switch (type) {
case NL80211_TX_POWER_AUTOMATIC:
break;
@@ -2253,13 +2307,13 @@ wl_cfg80211_set_tx_power(struct wiphy *wiphy,
static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
{
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wiphy_priv(wiphy);
struct net_device *ndev = wl_to_prmry_ndev(wl);
s32 txpwrdbm;
u8 result;
s32 err = 0;
- CHECK_SYS_UP();
+ CHECK_SYS_UP(wl);
err = wl_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
if (unlikely(err)) {
WL_ERR(("error (%d)\n", err));
@@ -2275,14 +2329,14 @@ static s32
wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev,
u8 key_idx, bool unicast, bool multicast)
{
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wiphy_priv(wiphy);
u32 index;
s32 wsec;
s32 err = 0;
s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
WL_DBG(("key index (%d)\n", key_idx));
- CHECK_SYS_UP();
+ CHECK_SYS_UP(wl);
err = wldev_iovar_getint_bsscfg(dev, "wsec", &wsec, bssidx);
if (unlikely(err)) {
WL_ERR(("WLC_GET_WSEC error (%d)\n", err));
@@ -2305,7 +2359,7 @@ static s32
wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
u8 key_idx, const u8 *mac_addr, struct key_params *params)
{
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wiphy_priv(wiphy);
struct wl_wsec_key key;
s32 err = 0;
s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
@@ -2404,10 +2458,10 @@ wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
s32 err = 0;
u8 keybuf[8];
s32 bssidx = 0;
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wiphy_priv(wiphy);
s32 mode = get_mode_by_netdev(wl, dev);
WL_DBG(("key index (%d)\n", key_idx));
- CHECK_SYS_UP();
+ CHECK_SYS_UP(wl);
bssidx = wl_cfgp2p_find_idx(wl, dev);
@@ -2505,12 +2559,12 @@ wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
u8 key_idx, bool pairwise, const u8 *mac_addr)
{
struct wl_wsec_key key;
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wiphy_priv(wiphy);
s32 err = 0;
s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
WL_DBG(("Enter\n"));
- CHECK_SYS_UP();
+ CHECK_SYS_UP(wl);
memset(&key, 0, sizeof(key));
key.index = (u32) key_idx;
@@ -2554,14 +2608,14 @@ wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
{
struct key_params params;
struct wl_wsec_key key;
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wiphy_priv(wiphy);
struct wl_security *sec;
s32 wsec;
s32 err = 0;
s32 bssidx = wl_cfgp2p_find_idx(wl, dev);
WL_DBG(("key index (%d)\n", key_idx));
- CHECK_SYS_UP();
+ CHECK_SYS_UP(wl);
memset(&key, 0, sizeof(key));
key.index = key_idx;
swap_key_to_BE(&key);
@@ -2607,7 +2661,6 @@ wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
struct net_device *dev, u8 key_idx)
{
WL_INFO(("Not supported\n"));
- CHECK_SYS_UP();
return -EOPNOTSUPP;
}
@@ -2615,13 +2668,13 @@ static s32
wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
u8 *mac, struct station_info *sinfo)
{
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wiphy_priv(wiphy);
scb_val_t scb_val;
int rssi;
s32 rate;
s32 err = 0;
- CHECK_SYS_UP();
+ CHECK_SYS_UP(wl);
if (unlikely
(memcmp(mac, wl_read_prof(wl, WL_PROF_BSSID), ETHER_ADDR_LEN))) {
WL_ERR(("Wrong Mac address\n"));
@@ -2672,9 +2725,15 @@ wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
{
s32 pm;
s32 err = 0;
+ struct wl_priv *wl = wiphy_priv(wiphy);
- CHECK_SYS_UP();
+ CHECK_SYS_UP(wl);
pm = enabled ? PM_FAST : PM_OFF;
+ /* Do not enable the power save after assoc if it is p2p interface */
+ if (wl->p2p && wl->p2p->vif_created) {
+ WL_DBG(("Do not enable the power save for p2p interfaces even after assoc\n"));
+ pm = PM_OFF;
+ }
pm = htod32(pm);
WL_DBG(("power save %s\n", (pm ? "enabled" : "disabled")));
err = wldev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm), false);
@@ -2717,7 +2776,7 @@ static __used u32 wl_find_msb(u16 bit16)
static s32 wl_cfg80211_resume(struct wiphy *wiphy)
{
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wiphy_priv(wiphy);
s32 err = 0;
if (unlikely(!wl_get_drv_status(wl, READY))) {
@@ -2737,9 +2796,8 @@ static s32 wl_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
static s32 wl_cfg80211_suspend(struct wiphy *wiphy)
#endif
{
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wiphy_priv(wiphy);
s32 err = 0;
-
if (unlikely(!wl_get_drv_status(wl, READY))) {
WL_INFO(("device is not ready : status (%d)\n",
(int)wl->status));
@@ -2763,7 +2821,7 @@ wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list,
s32 err)
{
int i, j;
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wlcfg_drv_priv;
struct net_device *primary_dev = wl_to_prmry_ndev(wl);
/* Firmware is supporting pmk list only for STA interface i.e. primary interface
@@ -2771,7 +2829,7 @@ wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list,
* Do we really need to support PMK cache in P2P in firmware?
*/
if (primary_dev != dev) {
- WL_ERR(("Not supporting Flushing pmklist on virtual"
+ WL_INFO(("Not supporting Flushing pmklist on virtual"
" interfaces than primary interface\n"));
return err;
}
@@ -2796,11 +2854,11 @@ static s32
wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_pmksa *pmksa)
{
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wiphy_priv(wiphy);
s32 err = 0;
int i;
- CHECK_SYS_UP();
+ CHECK_SYS_UP(wl);
for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
if (!memcmp(pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
ETHER_ADDR_LEN))
@@ -2816,10 +2874,10 @@ wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
err = -EINVAL;
}
WL_DBG(("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
- &wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].BSSID));
+ &wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid - 1].BSSID));
for (i = 0; i < WPA2_PMKID_LEN; i++) {
WL_DBG(("%02x\n",
- wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].
+ wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid - 1].
PMKID[i]));
}
@@ -2832,12 +2890,12 @@ static s32
wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_pmksa *pmksa)
{
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wiphy_priv(wiphy);
struct _pmkid_list pmkid;
s32 err = 0;
int i;
- CHECK_SYS_UP();
+ CHECK_SYS_UP(wl);
memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETHER_ADDR_LEN);
memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WPA2_PMKID_LEN);
@@ -2878,9 +2936,9 @@ wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
static s32
wl_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
{
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wiphy_priv(wiphy);
s32 err = 0;
- CHECK_SYS_UP();
+ CHECK_SYS_UP(wl);
memset(wl->pmk_list, 0, sizeof(*wl->pmk_list));
err = wl_update_pmklist(dev, wl->pmk_list, err);
return err;
@@ -2956,7 +3014,7 @@ wl_cfg80211_remain_on_channel(struct wiphy *wiphy, struct net_device *dev,
s32 target_channel;
s32 err = BCME_OK;
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wiphy_priv(wiphy);
dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
WL_DBG(("Enter, netdev_ifidx: %d \n", dev->ifindex));
if (likely(wl_get_drv_status(wl, SCANNING))) {
@@ -2976,12 +3034,12 @@ wl_cfg80211_remain_on_channel(struct wiphy *wiphy, struct net_device *dev,
* without turning on P2P
*/
+ p2p_on(wl) = true;
err = wl_cfgp2p_enable_discovery(wl, dev, NULL, 0);
if (unlikely(err)) {
goto exit;
}
- p2p_on(wl) = true;
}
if (p2p_on(wl))
wl_cfgp2p_discover_listen(wl, target_channel, duration);
@@ -3012,7 +3070,7 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
wifi_p2p_ie_t *p2p_ie;
wpa_ie_fixed_t *wps_ie;
const struct ieee80211_mgmt *mgmt;
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wiphy_priv(wiphy);
dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
s32 err = BCME_OK;
s32 bssidx = 0;
@@ -3467,7 +3525,7 @@ wl_cfg80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
s32 err = BCME_OK;
bcm_tlv_t *ssid_ie;
wlc_ssid_t ssid;
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wiphy_priv(wiphy);
struct wl_join_params join_params;
wpa_ie_fixed_t *wps_ie;
wpa_ie_fixed_t *wpa_ie;
@@ -3582,7 +3640,10 @@ wl_cfg80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
wldev_iovar_setint(dev, "mpc", 0);
wldev_ioctl(dev, WLC_DOWN, &ap, sizeof(s32), false);
wldev_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(s32), false);
- wldev_ioctl(dev, WLC_SET_AP, &ap, sizeof(s32), false);
+ if ((err = wldev_ioctl(dev, WLC_SET_AP, &ap, sizeof(s32), false)) < 0) {
+ WL_ERR(("setting AP mode failed %d \n", err));
+ return err;
+ }
/* find the RSN_IE */
if ((wpa2_ie = bcm_parse_tlvs((u8 *)info->tail, info->tail_len,
DOT11_MNG_RSN_ID)) != NULL) {
@@ -3757,7 +3818,6 @@ wl_cfg80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
static s32
wl_cfg80211_drv_start(struct wiphy *wiphy, struct net_device *dev)
{
- /* struct wl_priv *wl = wiphy_to_wl(wiphy); */
s32 err = 0;
printk("Android driver start command\n");
@@ -3767,7 +3827,6 @@ wl_cfg80211_drv_start(struct wiphy *wiphy, struct net_device *dev)
static s32
wl_cfg80211_drv_stop(struct wiphy *wiphy, struct net_device *dev)
{
- /* struct wl_priv *wl = wiphy_to_wl(wiphy); */
s32 err = 0;
printk("Android driver stop command\n");
@@ -3830,28 +3889,26 @@ static s32 wl_mode_to_nl80211_iftype(s32 mode)
return err;
}
-static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface,
- struct device *dev)
+static struct wireless_dev *wl_alloc_wdev(struct device *sdiofunc_dev)
{
struct wireless_dev *wdev;
s32 err = 0;
- struct wl_priv *wl;
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) + sizeof_iface);
+ wiphy_new(&wl_cfg80211_ops, sizeof(struct wl_priv));
if (unlikely(!wdev->wiphy)) {
WL_ERR(("Couldn not allocate wiphy device\n"));
err = -ENOMEM;
goto wiphy_new_out;
}
- set_wiphy_dev(wdev->wiphy, dev);
- wl = wiphy_to_wl(wdev->wiphy);
+ set_wiphy_dev(wdev->wiphy, sdiofunc_dev);
wdev->wiphy->max_scan_ie_len = WL_SCAN_IE_LEN_MAX;
- wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
+ /* Report how many SSIDs Driver can support per Scan request */
+ wdev->wiphy->max_scan_ssids = WL_SCAN_PARAMS_SSID_MAX;
wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
wdev->wiphy->interface_modes =
BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC)
@@ -3899,7 +3956,7 @@ wiphy_new_out:
static void wl_free_wdev(struct wl_priv *wl)
{
int i;
- struct wireless_dev *wdev = wl_to_wdev(wl);
+ struct wireless_dev *wdev = wl->wdev;
if (unlikely(!wdev)) {
WL_ERR(("wdev is invalid\n"));
@@ -3913,9 +3970,9 @@ static void wl_free_wdev(struct wl_priv *wl)
}
}
wiphy_unregister(wdev->wiphy);
+ wdev->wiphy->dev.parent = NULL;
wiphy_free(wdev->wiphy);
kfree(wdev);
- wl_to_wdev(wl) = NULL;
}
static s32 wl_inform_bss(struct wl_priv *wl)
@@ -3926,13 +3983,6 @@ static s32 wl_inform_bss(struct wl_priv *wl)
s32 i;
bss_list = wl->bss_list;
-#if 0
- if (unlikely(bss_list->version != WL_BSS_INFO_VERSION)) {
- WL_ERR(("Version %d != WL_BSS_INFO_VERSION\n",
- bss_list->version));
- return -EOPNOTSUPP;
- }
-#endif
WL_DBG(("scanned AP count (%d)\n", bss_list->count));
bi = next_bss(bss_list, bi);
for_each_bss(bss_list, bi, i) {
@@ -4165,33 +4215,42 @@ wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
ntoh32(e->event_type), ntoh32(e->status)));
if (wl_is_linkup(wl, e, ndev)) {
wl_link_up(wl);
+ act = true;
+ wl_update_prof(wl, e, &act, WL_PROF_ACT);
if (wl_is_ibssmode(wl, ndev)) {
printk("cfg80211_ibss_joined");
cfg80211_ibss_joined(ndev, (s8 *)&e->addr,
GFP_KERNEL);
WL_DBG(("joined in IBSS network\n"));
} else {
- printk("wl_bss_connect_done succeeded");
- wl_bss_connect_done(wl, ndev, e, data, true);
- WL_DBG(("joined in BSS network \"%s\"\n",
+ if (!wl_get_drv_status(wl, DISCONNECTING)) {
+ printk("wl_bss_connect_done succeeded");
+ wl_bss_connect_done(wl, ndev, e, data, true);
+ WL_DBG(("joined in BSS network \"%s\"\n",
((struct wlc_ssid *)
wl_read_prof(wl, WL_PROF_SSID))->SSID));
+ }
}
- act = true;
- wl_update_prof(wl, e, &act, WL_PROF_ACT);
+
} else if (wl_is_linkdown(wl, e)) {
+ if (wl->scan_request) {
+ if (wl->escan_on) {
+ wl_notify_escan_complete(wl, true);
+ } else
+ wl_iscan_aborted(wl);
+ }
if (wl_get_drv_status(wl, CONNECTED)) {
printk("link down, call cfg80211_disconnected ");
- rtnl_lock();
- cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL);
wl_clr_drv_status(wl, CONNECTED);
+ cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL);
wl_link_down(wl);
wl_init_prof(wl->profile);
- rtnl_unlock();
} else if (wl_get_drv_status(wl, CONNECTING)) {
printk("link down, during connecting");
wl_bss_connect_done(wl, ndev, e, data, false);
}
+ wl_clr_drv_status(wl, DISCONNECTING);
+
} else if (wl_is_nonetwork(wl, e)) {
printk("connect failed e->status 0x%x", (int)ntoh32(e->status));
if (wl_get_drv_status(wl, CONNECTING))
@@ -4215,24 +4274,22 @@ wl_notify_roaming_status(struct wl_priv *wl, struct net_device *ndev,
s32 err = 0;
u32 event = be32_to_cpu(e->event_type);
u32 status = be32_to_cpu(e->status);
-
WL_DBG(("Enter \n"));
if (event == WLC_E_ROAM && status == WLC_E_STATUS_SUCCESS) {
- if (test_bit(WL_STATUS_CONNECTED, &wl->status))
+ if (wl_get_drv_status(wl, CONNECTED))
wl_bss_roaming_done(wl, ndev, e, data);
else
wl_bss_connect_done(wl, ndev, e, data, true);
act = true;
wl_update_prof(wl, e, &act, WL_PROF_ACT);
}
-
return err;
}
static __used s32
wl_dev_bufvar_set(struct net_device *dev, s8 *name, s8 *buf, s32 len)
{
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wlcfg_drv_priv;
u32 buflen;
buflen = bcm_mkiovar(name, buf, len, wl->ioctl_buf, WL_IOCTL_LEN_MAX);
@@ -4245,7 +4302,7 @@ static s32
wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
s32 buf_len)
{
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wlcfg_drv_priv;
u32 len;
s32 err = 0;
@@ -4279,6 +4336,14 @@ static s32 wl_get_assoc_ies(struct wl_priv *wl, struct net_device *ndev)
assoc_info.req_len = htod32(assoc_info.req_len);
assoc_info.resp_len = htod32(assoc_info.resp_len);
assoc_info.flags = htod32(assoc_info.flags);
+ if (conn_info->req_ie_len) {
+ conn_info->req_ie_len = 0;
+ bzero(conn_info->req_ie, sizeof(conn_info->req_ie));
+ }
+ if (conn_info->resp_ie_len) {
+ conn_info->resp_ie_len = 0;
+ bzero(conn_info->resp_ie, sizeof(conn_info->resp_ie));
+ }
if (assoc_info.req_len) {
err = wl_dev_bufvar_get(ndev, "assoc_req_ies", wl->extra_buf,
WL_ASSOC_INFO_MAX);
@@ -4290,11 +4355,15 @@ static s32 wl_get_assoc_ies(struct wl_priv *wl, struct net_device *ndev)
if (assoc_info.flags & WLC_ASSOC_REQ_IS_REASSOC) {
conn_info->req_ie_len -= ETHER_ADDR_LEN;
}
- conn_info->req_ie =
- kmemdup(wl->extra_buf, conn_info->req_ie_len, GFP_KERNEL);
+ if (conn_info->req_ie_len <= MAX_REQ_LINE)
+ memcpy(conn_info->req_ie, wl->extra_buf, conn_info->req_ie_len);
+ else {
+ WL_ERR(("%s IE size %d above max %d size \n",
+ __FUNCTION__, conn_info->req_ie_len, MAX_REQ_LINE));
+ return err;
+ }
} else {
conn_info->req_ie_len = 0;
- conn_info->req_ie = NULL;
}
if (assoc_info.resp_len) {
err = wl_dev_bufvar_get(ndev, "assoc_resp_ies", wl->extra_buf,
@@ -4304,11 +4373,15 @@ static s32 wl_get_assoc_ies(struct wl_priv *wl, struct net_device *ndev)
return err;
}
conn_info->resp_ie_len = assoc_info.resp_len -sizeof(struct dot11_assoc_resp);
- conn_info->resp_ie =
- kmemdup(wl->extra_buf, conn_info->resp_ie_len, GFP_KERNEL);
+ if (conn_info->resp_ie_len <= MAX_REQ_LINE)
+ memcpy(conn_info->resp_ie, wl->extra_buf, conn_info->resp_ie_len);
+ else {
+ WL_ERR(("%s IE size %d above max %d size \n",
+ __FUNCTION__, conn_info->resp_ie_len, MAX_REQ_LINE));
+ return err;
+ }
} else {
conn_info->resp_ie_len = 0;
- conn_info->resp_ie = NULL;
}
WL_DBG(("req len (%d) resp len (%d)\n", conn_info->req_ie_len,
conn_info->resp_ie_len));
@@ -4437,6 +4510,7 @@ wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
wl_get_assoc_ies(wl, ndev);
memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
wl_update_bss_info(wl, ndev);
+ wl_update_pmklist(ndev, wl->pmk_list, err);
cfg80211_roamed(ndev,
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)
NULL,
@@ -4459,11 +4533,18 @@ wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
s32 err = 0;
WL_DBG((" enter\n"));
- wl_get_assoc_ies(wl, ndev);
- memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
- wl_update_bss_info(wl, ndev);
+ if (wl->scan_request) {
+ wl_cfg80211_scan_abort(wl, ndev);
+ }
if (wl_get_drv_status(wl, CONNECTING)) {
wl_clr_drv_status(wl, CONNECTING);
+ if (completed) {
+ wl_get_assoc_ies(wl, ndev);
+ memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN);
+ wl_update_bss_info(wl, ndev);
+ wl_update_pmklist(ndev, wl->pmk_list, err);
+ wl_set_drv_status(wl, CONNECTED);
+ }
cfg80211_connect_result(ndev,
(u8 *)&wl->bssid,
conn_info->req_ie,
@@ -4475,14 +4556,6 @@ wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
WL_DBG(("Report connect result - connection %s\n",
completed ? "succeeded" : "failed"));
}
- if (completed)
- wl_set_drv_status(wl, CONNECTED);
- else {
- if (wl->scan_request) {
- wl_cfg80211_scan_abort(wl, ndev);
- }
- }
-
return err;
}
@@ -4740,7 +4813,7 @@ static s32 wl_init_priv_mem(struct wl_priv *wl)
WL_ERR(("Ioctl buf alloc failed\n"));
goto init_priv_mem_out;
}
- wl->escan_ioctl_buf = (void *)kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL);
+ wl->escan_ioctl_buf = (void *)kzalloc(WLC_IOCTL_MAXLEN, GFP_KERNEL);
if (unlikely(!wl->escan_ioctl_buf)) {
WL_ERR(("Ioctl buf alloc failed\n"));
goto init_priv_mem_out;
@@ -4809,24 +4882,20 @@ static void wl_deinit_priv_mem(struct wl_priv *wl)
static s32 wl_create_event_handler(struct wl_priv *wl)
{
+ int ret = 0;
WL_DBG(("Enter \n"));
- sema_init(&wl->event_sync, 0);
- wl->event_tsk = kthread_run(wl_event_handler, wl, "wl_event_handler");
- if (IS_ERR(wl->event_tsk)) {
- wl->event_tsk = NULL;
- WL_ERR(("failed to create event thread\n"));
- return -ENOMEM;
- }
- return 0;
+
+ wl->event_tsk.thr_pid = DHD_PID_KT_INVALID;
+ PROC_START(wl_event_handler, wl, &wl->event_tsk, 0);
+ if (wl->event_tsk.thr_pid < 0)
+ ret = -ENOMEM;
+ return ret;
}
static void wl_destroy_event_handler(struct wl_priv *wl)
{
- if (wl->event_tsk) {
- send_sig(SIGTERM, wl->event_tsk, 1);
- kthread_stop(wl->event_tsk);
- wl->event_tsk = NULL;
- }
+ if (wl->event_tsk.thr_pid >= 0)
+ PROC_STOP(&wl->event_tsk);
}
static void wl_term_iscan(struct wl_priv *wl)
@@ -5046,6 +5115,7 @@ static void wl_notify_escan_complete(struct wl_priv *wl, bool aborted)
if (unlikely(!wl_get_drv_status(wl, SCANNING))) {
wl_clr_drv_status(wl, SCANNING);
WL_ERR(("Scan complete while device not scanning\n"));
+ wl->scan_request = NULL;
return;
}
wl_clr_drv_status(wl, SCANNING);
@@ -5152,7 +5222,9 @@ static s32 wl_escan_handler(struct wl_priv *wl,
wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
if (likely(wl->scan_request)) {
rtnl_lock();
- WL_INFO(("ESCAN COMPLETED\n"));
+ WL_INFO(("ESCAN ABORTED\n"));
+ wl->bss_list = (wl_scan_results_t *)wl->escan_info.escan_buf;
+ wl_inform_bss(wl);
wl_notify_escan_complete(wl, true);
rtnl_unlock();
}
@@ -5251,7 +5323,7 @@ s32 wl_cfg80211_sysctl_export_devaddr(void *data)
* so that wpa_supplicant can access it
*/
dhd_pub_t *dhd = (dhd_pub_t *)data;
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wlcfg_drv_priv;
wl_cfgp2p_generate_bss_mac(&dhd->mac, &wl->p2p->dev_addr, &wl->p2p->int_addr);
@@ -5271,7 +5343,7 @@ s32 wl_cfg80211_attach_post(struct net_device *ndev)
WL_ERR(("ndev is invaild\n"));
return -ENODEV;
}
- wl = WL_PRIV_GET();
+ wl = wlcfg_drv_priv;
if (wl && !wl_get_drv_status(wl, READY)) {
if (wl->wdev &&
wl_cfgp2p_supported(wl, ndev)) {
@@ -5296,7 +5368,6 @@ s32 wl_cfg80211_attach(struct net_device *ndev, void *data)
{
struct wireless_dev *wdev;
struct wl_priv *wl;
- struct wl_iface *ci;
s32 err = 0;
WL_TRACE(("In\n"));
@@ -5304,23 +5375,16 @@ s32 wl_cfg80211_attach(struct net_device *ndev, void *data)
WL_ERR(("ndev is invaild\n"));
return -ENODEV;
}
- wl_cfg80211_dev = kzalloc(sizeof(struct wl_dev), GFP_KERNEL);
- if (unlikely(!wl_cfg80211_dev)) {
- WL_ERR(("wl_cfg80211_dev is invalid\n"));
- return -ENOMEM;
- }
WL_DBG(("func %p\n", wl_cfg80211_get_sdio_func()));
- wdev = wl_alloc_wdev(sizeof(struct wl_iface), &wl_cfg80211_get_sdio_func()->dev);
+ wdev = wl_alloc_wdev(&wl_cfg80211_get_sdio_func()->dev);
if (unlikely(IS_ERR(wdev)))
return -ENOMEM;
wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS);
- wl = wdev_to_wl(wdev);
+ wl = (struct wl_priv *)wiphy_priv(wdev->wiphy);
wl->wdev = wdev;
wl->pub = data;
- ci = (struct wl_iface *)wl_to_ci(wl);
- ci->wl = wl;
ndev->ieee80211_ptr = wdev;
SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
wdev->netdev = ndev;
@@ -5343,7 +5407,7 @@ s32 wl_cfg80211_attach(struct net_device *ndev, void *data)
goto cfg80211_attach_out;
}
#endif
- wl_set_drvdata(wl_cfg80211_dev, ci);
+ wlcfg_drv_priv = wl;
return err;
cfg80211_attach_out:
@@ -5356,7 +5420,7 @@ void wl_cfg80211_detach(void)
{
struct wl_priv *wl;
- wl = WL_PRIV_GET();
+ wl = wlcfg_drv_priv;
WL_TRACE(("In\n"));
#if defined(DHD_P2P_DEV_ADDR_FROM_SYSFS) && defined(CONFIG_SYSCTL)
@@ -5367,29 +5431,30 @@ void wl_cfg80211_detach(void)
if (wl->p2p_supported)
wl_cfgp2p_deinit_priv(wl);
wl_deinit_priv(wl);
- wl_free_wdev(wl);
- wl_set_drvdata(wl_cfg80211_dev, NULL);
- kfree(wl_cfg80211_dev);
- wl_cfg80211_dev = NULL;
+ wlcfg_drv_priv = NULL;
wl_clear_sdio_func();
+ wl_free_wdev(wl);
}
static void wl_wakeup_event(struct wl_priv *wl)
{
- up(&wl->event_sync);
+ if (wl->event_tsk.thr_pid >= 0)
+ up(&wl->event_tsk.sema);
}
static s32 wl_event_handler(void *data)
{
struct net_device *netdev;
- struct wl_priv *wl = (struct wl_priv *)data;
- struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
+ struct wl_priv *wl = NULL;
struct wl_event_q *e;
+ tsk_ctl_t *tsk = (tsk_ctl_t *)data;
- sched_setscheduler(current, SCHED_FIFO, &param);
- allow_signal(SIGTERM);
- while (likely(!down_interruptible(&wl->event_sync))) {
- if (kthread_should_stop())
+ wl = (struct wl_priv *)tsk->parent;
+ complete(&tsk->completed);
+
+ while (down_interruptible (&tsk->sema) == 0) {
+ SMP_RD_BARRIER_DEPENDS();
+ if (tsk->terminated)
break;
e = wl_deq_event(wl);
if (unlikely(!e)) {
@@ -5400,7 +5465,7 @@ static s32 wl_event_handler(void *data)
netdev = dhd_idx2net((struct dhd_pub *)(wl->pub), e->emsg.ifidx);
if (!netdev)
netdev = wl_to_prmry_ndev(wl);
- if (wl->evt_handler[e->etype]) {
+ if (e->etype < WLC_E_LAST && wl->evt_handler[e->etype]) {
wl->evt_handler[e->etype] (wl, netdev, &e->emsg, e->edata);
} else {
WL_DBG(("Unknown Event (%d): ignoring\n", e->etype));
@@ -5408,6 +5473,7 @@ static s32 wl_event_handler(void *data)
wl_put_event(e);
}
WL_DBG(("%s was terminated\n", __func__));
+ complete_and_exit(&tsk->completed, 0);
return 0;
}
@@ -5415,7 +5481,7 @@ void
wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t * e, void *data)
{
u32 event_type = ntoh32(e->event_type);
- struct wl_priv *wl = WL_PRIV_GET();
+ struct wl_priv *wl = wlcfg_drv_priv;
#if (WL_DBG_LEVEL > 0)
s8 *estr = (event_type <= sizeof(wl_dbg_estr) / WL_DBG_ESTR_MAX - 1) ?
@@ -5619,14 +5685,12 @@ static s32 wl_dongle_eventmsg(struct net_device *ndev)
setbit(eventmask, WLC_E_DISASSOC_IND);
setbit(eventmask, WLC_E_DISASSOC);
setbit(eventmask, WLC_E_JOIN);
+ setbit(eventmask, WLC_E_ROAM);
setbit(eventmask, WLC_E_ASSOC_IND);
- setbit(eventmask, WLC_E_PSK_SUP);
setbit(eventmask, WLC_E_LINK);
- setbit(eventmask, WLC_E_NDIS_LINK);
setbit(eventmask, WLC_E_MIC_ERROR);
setbit(eventmask, WLC_E_PMKID_CACHE);
setbit(eventmask, WLC_E_TXFAIL);
- setbit(eventmask, WLC_E_JOIN_START);
setbit(eventmask, WLC_E_SCAN_COMPLETE);
setbit(eventmask, WLC_E_ACTION_FRAME_RX);
setbit(eventmask, WLC_E_ACTION_FRAME_COMPLETE);
@@ -5997,27 +6061,24 @@ default_conf_out:
static s32 wl_update_wiphybands(struct wl_priv *wl)
{
struct wiphy *wiphy;
- s32 phy_list;
- s8 phy;
+ s8 phylist_buf[128];
+ s8 *phy;
s32 err = 0;
- err = wldev_ioctl(wl_to_prmry_ndev(wl), WLC_GET_PHYLIST, &phy_list,
- sizeof(phy_list), false);
+ err = wldev_ioctl(wl_to_prmry_ndev(wl), WLC_GET_PHYLIST, phylist_buf,
+ sizeof(phylist_buf), false);
if (unlikely(err)) {
WL_ERR(("error (%d)\n", err));
return err;
}
-
- phy = ((char *)&phy_list)[1];
- WL_DBG(("%c phy\n", phy));
- if (phy == 'a') {
- wiphy = wl_to_wiphy(wl);
- wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a;
- } else if (phy == 'n') {
- wiphy = wl_to_wiphy(wl);
- wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
+ phy = phylist_buf;
+ for (; *phy; phy++) {
+ if (*phy == 'a' || *phy == 'n') {
+ wiphy = wl_to_wiphy(wl);
+ wiphy->bands[IEEE80211_BAND_5GHZ] =
+ &__wl_band_5ghz_a;
+ }
}
-
return err;
}
@@ -6056,7 +6117,9 @@ static s32 __wl_cfg80211_down(struct wl_priv *wl)
wl_clr_drv_status(wl, READY);
wl_clr_drv_status(wl, SCANNING);
wl_clr_drv_status(wl, SCAN_ABORTING);
+ wl_clr_drv_status(wl, CONNECTING);
wl_clr_drv_status(wl, CONNECTED);
+ wl_clr_drv_status(wl, DISCONNECTING);
if (wl_get_drv_status(wl, AP_CREATED)) {
wl_clr_drv_status(wl, AP_CREATED);
wl_clr_drv_status(wl, AP_CREATING);
@@ -6081,7 +6144,7 @@ s32 wl_cfg80211_up(void)
s32 err = 0;
WL_TRACE(("In\n"));
- wl = WL_PRIV_GET();
+ wl = wlcfg_drv_priv;
mutex_lock(&wl->usr_sync);
wl_cfg80211_attach_post(wl_to_prmry_ndev(wl));
err = __wl_cfg80211_up(wl);
@@ -6098,7 +6161,7 @@ s32 wl_cfg80211_down(void)
s32 err = 0;
WL_TRACE(("In\n"));
- wl = WL_PRIV_GET();
+ wl = wlcfg_drv_priv;
mutex_lock(&wl->usr_sync);
err = __wl_cfg80211_down(wl);
mutex_unlock(&wl->usr_sync);
@@ -6266,11 +6329,7 @@ static void wl_link_down(struct wl_priv *wl)
WL_DBG(("In\n"));
wl->link_up = false;
- kfree(conn_info->req_ie);
- conn_info->req_ie = NULL;
conn_info->req_ie_len = 0;
- kfree(conn_info->resp_ie);
- conn_info->resp_ie = NULL;
conn_info->resp_ie_len = 0;
}
@@ -6299,22 +6358,12 @@ static void wl_delay(u32 ms)
}
}
-static void wl_set_drvdata(struct wl_dev *dev, void *data)
-{
- dev->driver_data = data;
-}
-
-static void *wl_get_drvdata(struct wl_dev *dev)
-{
- return dev->driver_data;
-}
-
s32 wl_cfg80211_read_fw(s8 *buf, u32 size)
{
const struct firmware *fw_entry;
struct wl_priv *wl;
- wl = WL_PRIV_GET();
+ wl = wlcfg_drv_priv;
fw_entry = wl->fw->fw_entry;
@@ -6330,7 +6379,7 @@ void wl_cfg80211_release_fw(void)
{
struct wl_priv *wl;
- wl = WL_PRIV_GET();
+ wl = wlcfg_drv_priv;
release_firmware(wl->fw->fw_entry);
wl->fw->ptr = 0;
}
@@ -6343,7 +6392,7 @@ void *wl_cfg80211_request_fw(s8 *file_name)
WL_TRACE(("In\n"));
WL_DBG(("file name : \"%s\"\n", file_name));
- wl = WL_PRIV_GET();
+ wl = wlcfg_drv_priv;
if (!test_bit(WL_FW_LOADING_DONE, &wl->fw->status)) {
err = request_firmware(&wl->fw->fw_entry, file_name,
@@ -6388,7 +6437,7 @@ s8 *wl_cfg80211_get_fwname(void)
{
struct wl_priv *wl;
- wl = WL_PRIV_GET();
+ wl = wlcfg_drv_priv;
strcpy(wl->fw->fw_name, WL_4329_FW_FILE);
return wl->fw->fw_name;
}
@@ -6397,7 +6446,7 @@ s8 *wl_cfg80211_get_nvramname(void)
{
struct wl_priv *wl;
- wl = WL_PRIV_GET();
+ wl = wlcfg_drv_priv;
strcpy(wl->fw->nvram_name, WL_4329_NVRAM_FILE);
return wl->fw->nvram_name;
}
@@ -6408,7 +6457,7 @@ s32 wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pd
dhd_pub_t *dhd_pub;
struct ether_addr p2pif_addr;
- wl = WL_PRIV_GET();
+ wl = wlcfg_drv_priv;
dhd_pub = (dhd_pub_t *)wl->pub;
wl_cfgp2p_generate_bss_mac(&dhd_pub->mac, p2pdev_addr, &p2pif_addr);
diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.h b/drivers/net/wireless/bcmdhd/wl_cfg80211.h
index 838003bd644..a5637240c17 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfg80211.h
+++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.h
@@ -52,6 +52,7 @@ struct wl_ibss;
#define dtohchanspec(i) i
#define WL_DBG_NONE 0
+#define WL_DBG_SCAN (1 << 3)
#define WL_DBG_DBG (1 << 2)
#define WL_DBG_INFO (1 << 1)
#define WL_DBG_ERR (1 << 0)
@@ -74,6 +75,13 @@ do { \
printk args; \
} \
} while (0)
+#define WL_SCAN(args) \
+do { \
+ if (wl_dbg_level & WL_DBG_SCAN) { \
+ printk(KERN_ERR "CFG80211-SCAN) %s :", __func__); \
+ printk args; \
+ } \
+} while (0)
#if (WL_DBG_LEVEL > 0)
#define WL_DBG(args) \
do { \
@@ -87,7 +95,6 @@ do { \
#endif /* (WL_DBG_LEVEL > 0) */
#define WL_SCAN_RETRY_MAX 3 /* used for ibss scan */
-#define WL_NUM_SCAN_MAX 1
#define WL_NUM_PMKIDS_MAX MAXPMKID /* will be used
* for 2.6.33 kernel
* or later
@@ -122,6 +129,7 @@ enum wl_status {
WL_STATUS_SCAN_ABORTING,
WL_STATUS_CONNECTING,
WL_STATUS_CONNECTED,
+ WL_STATUS_DISCONNECTING,
WL_STATUS_AP_CREATING,
WL_STATUS_AP_CREATED
};
@@ -188,14 +196,6 @@ struct wl_conf {
typedef s32(*EVENT_HANDLER) (struct wl_priv *wl,
struct net_device *ndev, const wl_event_msg_t *e, void *data);
-/* representing interface of cfg80211 plane */
-struct wl_iface {
- struct wl_priv *wl;
-};
-
-struct wl_dev {
- void *driver_data; /* to store cfg80211 object information */
-};
/* bss inform structure for cfg80211 interface */
struct wl_cfg80211_bss_info {
@@ -274,10 +274,11 @@ struct wl_iscan_ctrl {
};
/* association inform */
+#define MAX_REQ_LINE 1024
struct wl_connect_info {
- u8 *req_ie;
+ u8 req_ie[MAX_REQ_LINE];
s32 req_ie_len;
- u8 *resp_ie;
+ u8 resp_ie[MAX_REQ_LINE];
s32 resp_ie_len;
};
@@ -347,7 +348,6 @@ struct wl_priv {
struct ether_addr bssid; /* bssid of currently engaged network */
/* for synchronization of main event thread */
- struct semaphore event_sync;
struct wl_profile *profile; /* holding dongle profile */
struct wl_iscan_ctrl *iscan; /* iscan controller */
@@ -357,7 +357,7 @@ struct wl_priv {
/* control firwmare and nvram paramter downloading */
struct wl_fw_ctrl *fw;
struct wl_pmk_list *pmk_list; /* wpa2 pmk list */
- struct task_struct *event_tsk; /* task of main event handler thread */
+ tsk_ctl_t event_tsk; /* task of main event handler thread */
unsigned long status; /* current dongle status */
void *pub;
u32 channel; /* current channel */
@@ -388,18 +388,11 @@ struct wl_priv {
struct p2p_info *p2p;
bool p2p_supported;
s8 last_eventmask[WL_EVENTING_MASK_LEN];
- u8 ci[0] __attribute__ ((__aligned__(NETDEV_ALIGN)));
};
-#define wl_to_dev(w) (wiphy_dev(wl->wdev->wiphy))
#define wl_to_wiphy(w) (w->wdev->wiphy)
-#define wiphy_to_wl(w) ((struct wl_priv *)(wiphy_priv(w)))
-#define wl_to_wdev(w) (w->wdev)
-#define wdev_to_wl(w) ((struct wl_priv *)(wdev_priv(w)))
#define wl_to_prmry_ndev(w) (w->wdev->netdev)
#define ndev_to_wl(n) (wdev_to_wl(n->ieee80211_ptr))
-#define ci_to_wl(c) (ci->wl)
-#define wl_to_ci(w) (&w->ci)
#define wl_to_sr(w) (w->scan_req_int)
#define wl_to_ie(w) (&w->ie)
#define iscan_to_wl(i) ((struct wl_priv *)(i->data))
@@ -499,7 +492,7 @@ extern void wl_cfg80211_set_sdio_func(void *func); /* set sdio function info */
extern struct sdio_func *wl_cfg80211_get_sdio_func(void); /* set sdio function info */
extern s32 wl_cfg80211_up(void); /* dongle up */
extern s32 wl_cfg80211_down(void); /* dongle down */
-extern s32 wl_cfg80211_notify_ifadd(struct net_device *net, s32 idx,
+extern s32 wl_cfg80211_notify_ifadd(struct net_device *net, s32 idx, s32 bssidx,
int (*_net_attach)(dhd_pub_t *dhdp, int ifidx));
extern s32 wl_cfg80211_ifdel_ops(struct net_device *net);
extern s32 wl_cfg80211_notify_ifdel(struct net_device *net);
diff --git a/drivers/net/wireless/bcmdhd/wl_cfgp2p.c b/drivers/net/wireless/bcmdhd/wl_cfgp2p.c
index 7a5619e8ec4..98271c28658 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfgp2p.c
+++ b/drivers/net/wireless/bcmdhd/wl_cfgp2p.c
@@ -176,8 +176,8 @@ wl_cfgp2p_ifdel(struct wl_priv *wl, struct ether_addr *mac)
s32 ret;
struct net_device *netdev = wl_to_prmry_ndev(wl);
- CFGP2P_INFO(("---wl p2p_ifdel %02x:%02x:%02x:%02x:%02x:%02x\n",
- mac->octet[0], mac->octet[1], mac->octet[2],
+ CFGP2P_INFO(("------primary idx %d : wl p2p_ifdel %02x:%02x:%02x:%02x:%02x:%02x\n",
+ netdev->ifindex, mac->octet[0], mac->octet[1], mac->octet[2],
mac->octet[3], mac->octet[4], mac->octet[5]));
ret = wldev_iovar_setbuf(netdev, "p2p_ifdel", mac, sizeof(*mac),
@@ -200,7 +200,7 @@ wl_cfgp2p_ifchange(struct wl_priv *wl, struct ether_addr *mac, u8 if_type,
{
wl_p2p_if_t ifreq;
s32 err;
- struct net_device *netdev = wl_to_prmry_ndev(wl);
+ struct net_device *netdev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION);
ifreq.type = if_type;
ifreq.chspec = chspec;
@@ -970,8 +970,7 @@ wl_cfgp2p_discover_listen(struct wl_priv *wl, s32 channel, u32 duration_ms)
} while (0);
s32 ret = BCME_OK;
- CFGP2P_DBG((" Enter\n"));
- CFGP2P_INFO(("Channel : %d, Duration : %d\n", channel, duration_ms));
+ CFGP2P_DBG((" Enter Channel : %d, Duration : %d\n", channel, duration_ms));
if (unlikely(wl_get_p2p_status(wl, DISCOVERY_ON) == 0)) {
CFGP2P_ERR((" Discovery is not set, so we have noting to do\n"));
@@ -996,9 +995,9 @@ wl_cfgp2p_discover_listen(struct wl_priv *wl, s32 channel, u32 duration_ms)
}
/* We will wait to receive WLC_E_P2P_DISC_LISTEN_COMPLETE from dongle ,
- * otherwise we will wait up to duration_ms + 10ms
+ * otherwise we will wait up to duration_ms + 200ms
*/
- INIT_TIMER(wl->p2p->listen_timer, wl_cfgp2p_listen_expired, duration_ms, 20);
+ INIT_TIMER(wl->p2p->listen_timer, wl_cfgp2p_listen_expired, duration_ms, 200);
#undef INIT_TIMER
exit:
@@ -1048,10 +1047,13 @@ wl_cfgp2p_action_tx_complete(struct wl_priv *wl, struct net_device *ndev,
if (event_type == WLC_E_ACTION_FRAME_COMPLETE) {
CFGP2P_INFO((" WLC_E_ACTION_FRAME_COMPLETE is received : %d\n", status));
- if (status == WLC_E_STATUS_SUCCESS)
+ if (status == WLC_E_STATUS_SUCCESS) {
wl_set_p2p_status(wl, ACTION_TX_COMPLETED);
- else
+ }
+ else {
+ wl_set_p2p_status(wl, ACTION_TX_NOACK);
CFGP2P_ERR(("WLC_E_ACTION_FRAME_COMPLETE : NO ACK\n"));
+ }
wake_up_interruptible(&wl->dongle_event_wait);
} else {
CFGP2P_INFO((" WLC_E_ACTION_FRAME_OFFCHAN_COMPLETE is received,"
@@ -1082,6 +1084,7 @@ wl_cfgp2p_tx_action_frame(struct wl_priv *wl, struct net_device *dev,
af_params->channel, af_params->dwell_time));
wl_clr_p2p_status(wl, ACTION_TX_COMPLETED);
+ wl_clr_p2p_status(wl, ACTION_TX_NOACK);
#define MAX_WAIT_TIME 2000
if (bssidx == P2PAPI_BSSCFG_PRIMARY)
bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE);
@@ -1095,7 +1098,7 @@ wl_cfgp2p_tx_action_frame(struct wl_priv *wl, struct net_device *dev,
goto exit;
}
timeout = wait_event_interruptible_timeout(wl->dongle_event_wait,
- (wl_get_p2p_status(wl, ACTION_TX_COMPLETED) == TRUE),
+ (wl_get_p2p_status(wl, ACTION_TX_COMPLETED) ||wl_get_p2p_status(wl, ACTION_TX_NOACK)),
msecs_to_jiffies(MAX_WAIT_TIME));
if (timeout > 0 && wl_get_p2p_status(wl, ACTION_TX_COMPLETED)) {
diff --git a/drivers/net/wireless/bcmdhd/wl_cfgp2p.h b/drivers/net/wireless/bcmdhd/wl_cfgp2p.h
index d62f5422708..b08504d8f95 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfgp2p.h
+++ b/drivers/net/wireless/bcmdhd/wl_cfgp2p.h
@@ -88,6 +88,7 @@ enum wl_cfgp2p_status {
WLP2P_STATUS_IF_CHANGED,
WLP2P_STATUS_LISTEN_EXPIRED,
WLP2P_STATUS_ACTION_TX_COMPLETED,
+ WLP2P_STATUS_ACTION_TX_NOACK,
WLP2P_STATUS_SCANNING
};
diff --git a/drivers/net/wireless/bcmdhd/wl_iw.c b/drivers/net/wireless/bcmdhd/wl_iw.c
index ae28c6d0215..6d546fcd396 100644
--- a/drivers/net/wireless/bcmdhd/wl_iw.c
+++ b/drivers/net/wireless/bcmdhd/wl_iw.c
@@ -792,7 +792,7 @@ wl_iw_set_power_mode(
#ifdef COEX_DHCP
g_bt->ts_dhcp_start = JF2MS;
- g_bt->dhcp_done = false;
+ g_bt->dhcp_done = FALSE;
WL_TRACE_COEX(("%s: DHCP start, pm:%d changed to pm:%d\n",
__FUNCTION__, pm, pm_local));
@@ -806,7 +806,7 @@ wl_iw_set_power_mode(
net_os_set_packet_filter(dev, 1);
#ifdef COEX_DHCP
- g_bt->dhcp_done = true;
+ g_bt->dhcp_done = TRUE;
g_bt->ts_dhcp_ok = JF2MS;
WL_TRACE_COEX(("%s: DHCP done for:%d ms, restored pm:%d\n",
__FUNCTION__, (g_bt->ts_dhcp_ok - g_bt->ts_dhcp_start), pm));
@@ -828,7 +828,7 @@ wl_iw_set_power_mode(
bool btcoex_is_sco_active(struct net_device *dev)
{
int ioc_res = 0;
- bool res = false;
+ bool res = FALSE;
int sco_id_cnt = 0;
int param27;
int i;
@@ -852,7 +852,7 @@ bool btcoex_is_sco_active(struct net_device *dev)
if (sco_id_cnt > 2) {
WL_TRACE_COEX(("%s, sco/esco detected, pkt id_cnt:%d samples:%d\n",
__FUNCTION__, sco_id_cnt, i));
- res = true;
+ res = TRUE;
break;
}
@@ -866,7 +866,7 @@ bool btcoex_is_sco_active(struct net_device *dev)
static int set_btc_esco_params(struct net_device *dev, bool trump_sco)
{
- static bool saved_status = false;
+ static bool saved_status = FALSE;
char buf_reg50va_dhcp_on[8] = { 50, 00, 00, 00, 0x22, 0x80, 0x00, 0x00 };
char buf_reg51va_dhcp_on[8] = { 51, 00, 00, 00, 0x00, 0x00, 0x00, 0x00 };
@@ -902,7 +902,7 @@ static int set_btc_esco_params(struct net_device *dev, bool trump_sco)
} else {
WL_ERROR((":%s: save btc_params failed\n",
__FUNCTION__));
- saved_status = false;
+ saved_status = FALSE;
return -1;
}
@@ -920,7 +920,7 @@ static int set_btc_esco_params(struct net_device *dev, bool trump_sco)
dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg65va_dhcp_on[0], 8);
dev_wlc_bufvar_set(dev, "btc_params", (char *)&buf_reg71va_dhcp_on[0], 8);
- saved_status = true;
+ saved_status = TRUE;
} else if (saved_status) {
@@ -946,7 +946,7 @@ static int set_btc_esco_params(struct net_device *dev, bool trump_sco)
saved_reg50, saved_reg51, saved_reg64,
saved_reg65, saved_reg71));
- saved_status = false;
+ saved_status = FALSE;
} else {
WL_ERROR((":%s att to restore not saved BTCOEX params\n",
__FUNCTION__));
@@ -6320,12 +6320,12 @@ fail:
#ifndef AP_ONLY
static int last_auto_channel = 6;
#endif
+
static int
get_softap_auto_channel(struct net_device *dev, struct ap_profile *ap)
{
int chosen = 0;
wl_uint32_list_t request;
- int rescan = 0;
int retry = 0;
int updown = 0;
int ret = 0;
@@ -6354,42 +6354,57 @@ get_softap_auto_channel(struct net_device *dev, struct ap_profile *ap)
null_ssid.SSID_len+4, buf, sizeof(buf), &mkvar_err);
ASSERT(iolen);
res |= dev_wlc_ioctl(dev, WLC_SET_VAR, buf, iolen);
+
#endif
- auto_channel_retry:
- request.count = htod32(0);
- ret = dev_wlc_ioctl(dev, WLC_START_CHANNEL_SEL, &request, sizeof(request));
- if (ret < 0) {
- WL_ERROR(("can't start auto channel scan\n"));
- goto fail;
- }
+
+ request.count = htod32(0);
+ ret = dev_wlc_ioctl(dev, WLC_START_CHANNEL_SEL, &request, sizeof(request));
+ if (ret < 0) {
+ WL_ERROR(("can't start auto channel scan\n"));
+ goto fail;
+ }
get_channel_retry:
- bcm_mdelay(500);
+ bcm_mdelay(350);
- ret = dev_wlc_ioctl(dev, WLC_GET_CHANNEL_SEL, &chosen, sizeof(chosen));
- if (ret < 0 || dtoh32(chosen) == 0) {
- if (retry++ < 3)
- goto get_channel_retry;
- else {
+ ret = dev_wlc_ioctl(dev, WLC_GET_CHANNEL_SEL, &chosen, sizeof(chosen));
+ if (ret < 0 || dtoh32(chosen) == 0) {
+ if (retry++ < 15) {
+ goto get_channel_retry;
+ } else {
+ if (ret < 0) {
WL_ERROR(("can't get auto channel sel, err = %d, "
- "chosen = %d\n", ret, chosen));
+ "chosen = 0x%04X\n", ret, (uint16)chosen));
goto fail;
+ } else {
+ ap->channel = (uint16)last_auto_channel;
+ WL_ERROR(("auto channel sel timed out. we get channel %d\n",
+ ap->channel));
}
}
- if ((chosen == 1) && (!rescan++))
- goto auto_channel_retry;
- WL_SOFTAP(("Set auto channel = %d\n", chosen));
- ap->channel = chosen;
- if ((res = dev_wlc_ioctl(dev, WLC_DOWN, &updown, sizeof(updown))) < 0) {
- WL_ERROR(("%s fail to set up err =%d\n", __FUNCTION__, res));
- goto fail;
- }
+ }
+
+ if (chosen) {
+ ap->channel = (uint16)chosen & 0x00FF;
+ WL_SOFTAP(("%s: Got auto channel = %d, attempt:%d\n",
+ __FUNCTION__, ap->channel, retry));
+ }
+
+ if ((res = dev_wlc_ioctl(dev, WLC_DOWN, &updown, sizeof(updown))) < 0) {
+ WL_ERROR(("%s fail to set up err =%d\n", __FUNCTION__, res));
+ goto fail;
+ }
+
#ifndef AP_ONLY
- if (!res)
+ if (!res || !ret)
last_auto_channel = ap->channel;
#endif
fail :
+ if (ret < 0) {
+ WL_TRACE(("%s: return value %d\n", __FUNCTION__, ret));
+ return ret;
+ }
return res;
}
@@ -6482,6 +6497,15 @@ set_ap_cfg(struct net_device *dev, struct ap_profile *ap)
goto fail;
}
WL_TRACE(("\n>in %s: apsta set result: %d \n", __FUNCTION__, res));
+
+
+ mpc = 0;
+ if ((res = dev_wlc_intvar_set(dev, "mpc", mpc))) {
+ WL_ERROR(("%s fail to set mpc\n", __FUNCTION__));
+ goto fail;
+ }
+
+
#endif
updown = 1;
@@ -6528,16 +6552,16 @@ set_ap_cfg(struct net_device *dev, struct ap_profile *ap)
if ((ap->channel == 0) && (get_softap_auto_channel(dev, ap) < 0)) {
ap->channel = 1;
- WL_ERROR(("%s auto channel failed, pick up channel=%d\n",
+ WL_ERROR(("%s auto channel failed, use channel=%d\n",
__FUNCTION__, ap->channel));
}
channel = ap->channel;
if ((res = dev_wlc_ioctl(dev, WLC_SET_CHANNEL, &channel, sizeof(channel)))) {
WL_ERROR(("%s fail to set channel\n", __FUNCTION__));
- goto fail;
}
+
if (ap_cfg_running == FALSE) {
updown = 0;
if ((res = dev_wlc_ioctl(dev, WLC_UP, &updown, sizeof(updown)))) {
@@ -6877,11 +6901,11 @@ static int wl_iw_softap_deassoc_stations(struct net_device *dev, u8 *mac)
char z_mac[6] = {0, 0, 0, 0, 0, 0};
char *sta_mac;
struct maclist *assoc_maclist = (struct maclist *) mac_buf;
- bool deauth_all = false;
+ bool deauth_all = FALSE;
if (mac == NULL) {
- deauth_all = true;
+ deauth_all = TRUE;
sta_mac = z_mac;
} else {
sta_mac = mac;
@@ -7179,7 +7203,7 @@ set_ap_mac_list(struct net_device *dev, void *buf)
if (assoc_maclist->count)
for (i = 0; i < assoc_maclist->count; i++) {
int j;
- bool assoc_mac_matched = false;
+ bool assoc_mac_matched = FALSE;
WL_SOFTAP(("\n Cheking assoc STA: "));
dhd_print_buf(&assoc_maclist->ea[i], 6, 7);
@@ -7189,7 +7213,7 @@ set_ap_mac_list(struct net_device *dev, void *buf)
if (!bcmp(&assoc_maclist->ea[i], &maclist->ea[j],
ETHER_ADDR_LEN)) {
- assoc_mac_matched = true;
+ assoc_mac_matched = TRUE;
break;
}