aboutsummaryrefslogtreecommitdiffstats
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/bcmsdh.c7
-rw-r--r--drivers/net/wireless/bcmdhd/bcmsdh_linux.c11
-rw-r--r--drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c62
-rw-r--r--drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c4
-rw-r--r--drivers/net/wireless/bcmdhd/dhd.h16
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_cfg80211.c9
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_custom_gpio.c6
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_linux.c37
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_sdio.c19
-rw-r--r--drivers/net/wireless/bcmdhd/include/epivers.h8
-rw-r--r--drivers/net/wireless/bcmdhd/include/sbchipc.h7
-rw-r--r--drivers/net/wireless/bcmdhd/include/sdioh.h6
-rw-r--r--drivers/net/wireless/bcmdhd/include/wlioctl.h60
-rw-r--r--drivers/net/wireless/bcmdhd/wl_android.c2
-rw-r--r--drivers/net/wireless/bcmdhd/wl_cfg80211.c117
-rw-r--r--drivers/net/wireless/bcmdhd/wl_cfg80211.h22
-rw-r--r--drivers/net/wireless/bcmdhd/wl_cfgp2p.c28
-rw-r--r--drivers/net/wireless/bcmdhd/wl_cfgp2p.h5
-rw-r--r--drivers/net/wireless/bcmdhd/wldev_common.c5
20 files changed, 289 insertions, 144 deletions
diff --git a/drivers/net/wireless/bcmdhd/Makefile b/drivers/net/wireless/bcmdhd/Makefile
index eda803e..0e9ca24 100644
--- a/drivers/net/wireless/bcmdhd/Makefile
+++ b/drivers/net/wireless/bcmdhd/Makefile
@@ -25,6 +25,8 @@ endif
ifneq ($(CONFIG_CFG80211),)
bcmdhd-objs += wl_cfg80211.o wl_cfgp2p.o wl_linux_mon.o
DHDCFLAGS += -DWL_CFG80211
+DHDCFLAGS += -DCUSTOM_ROAM_TRIGGER_SETTING=-70
+DHDCFLAGS += -DCUSTOM_ROAM_DELTA_SETTING=15
endif
ifneq ($(CONFIG_DHD_USE_SCHED_SCAN),)
DHDCFLAGS += -DWL_SCHED_SCAN
diff --git a/drivers/net/wireless/bcmdhd/bcmsdh.c b/drivers/net/wireless/bcmdhd/bcmsdh.c
index f67b13a..89320b6 100644
--- a/drivers/net/wireless/bcmdhd/bcmsdh.c
+++ b/drivers/net/wireless/bcmdhd/bcmsdh.c
@@ -22,7 +22,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: bcmsdh.c 300445 2011-12-03 05:37:20Z $
+ * $Id: bcmsdh.c 344235 2012-07-11 23:47:18Z $
*/
/**
@@ -362,9 +362,10 @@ bcmsdh_cis_read(void *sdh, uint func, uint8 *cis, uint length)
}
bcopy(cis, tmp_buf, length);
for (tmp_ptr = tmp_buf, ptr = cis; ptr < (cis + length - 4); tmp_ptr++) {
- ptr += sprintf((char*)ptr, "%.2x ", *tmp_ptr & 0xff);
+ ptr += snprintf((char*)ptr, (cis + length - ptr - 4),
+ "%.2x ", *tmp_ptr & 0xff);
if ((((tmp_ptr - tmp_buf) + 1) & 0xf) == 0)
- ptr += sprintf((char *)ptr, "\n");
+ ptr += snprintf((char *)ptr, (cis + length - ptr -4), "\n");
}
MFREE(bcmsdh->osh, tmp_buf, length);
}
diff --git a/drivers/net/wireless/bcmdhd/bcmsdh_linux.c b/drivers/net/wireless/bcmdhd/bcmsdh_linux.c
index d257dda..91232bd 100644
--- a/drivers/net/wireless/bcmdhd/bcmsdh_linux.c
+++ b/drivers/net/wireless/bcmdhd/bcmsdh_linux.c
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: bcmsdh_linux.c 312788 2012-02-03 23:06:32Z $
+ * $Id: bcmsdh_linux.c 352863 2012-08-24 04:48:50Z $
*/
/**
@@ -404,6 +404,10 @@ bcmsdh_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* match this pci device with what we support */
/* we can't solely rely on this to believe it is our SDIO Host Controller! */
if (!bcmsdh_chipmatch(pdev->vendor, pdev->device)) {
+ if (pdev->vendor == VENDOR_BROADCOM) {
+ SDLX_MSG(("%s: Unknown Broadcom device (vendor: %#x, device: %#x).\n",
+ __FUNCTION__, pdev->vendor, pdev->device));
+ }
return -ENODEV;
}
@@ -684,6 +688,11 @@ extern int sd_uhsimode;
module_param(sd_uhsimode, int, 0);
#endif
+#ifdef BCMSDIOH_TXGLOM
+extern uint sd_txglom;
+module_param(sd_txglom, uint, 0);
+#endif
+
#ifdef BCMSDH_MODULE
EXPORT_SYMBOL(bcmsdh_attach);
EXPORT_SYMBOL(bcmsdh_detach);
diff --git a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c
index 374154f..db051a4 100644
--- a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c
+++ b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: bcmsdh_sdmmc.c 314904 2012-02-14 21:36:04Z $
+ * $Id: bcmsdh_sdmmc.c 351910 2012-08-21 22:39:46Z $
*/
#include <typedefs.h>
@@ -799,41 +799,49 @@ sdioh_request_byte(sdioh_info_t *sd, uint rw, uint func, uint regaddr, uint8 *by
#if defined(MMC_SDIO_ABORT)
/* to allow abort command through F1 */
else if (regaddr == SDIOD_CCCR_IOABORT) {
- sdio_claim_host(gInstance->func[func]);
- /*
- * this sdio_f0_writeb() can be replaced with another api
- * depending upon MMC driver change.
- * As of this time, this is temporaray one
- */
- sdio_writeb(gInstance->func[func], *byte, regaddr, &err_ret);
- sdio_release_host(gInstance->func[func]);
+ if (gInstance->func[func]) {
+ sdio_claim_host(gInstance->func[func]);
+ /*
+ * this sdio_f0_writeb() can be replaced with another api
+ * depending upon MMC driver change.
+ * As of this time, this is temporaray one
+ */
+ sdio_writeb(gInstance->func[func],
+ *byte, regaddr, &err_ret);
+ sdio_release_host(gInstance->func[func]);
+ }
}
#endif /* MMC_SDIO_ABORT */
else if (regaddr < 0xF0) {
sd_err(("bcmsdh_sdmmc: F0 Wr:0x%02x: write disallowed\n", regaddr));
} else {
/* Claim host controller, perform F0 write, and release */
- sdio_claim_host(gInstance->func[func]);
- sdio_f0_writeb(gInstance->func[func], *byte, regaddr, &err_ret);
- sdio_release_host(gInstance->func[func]);
+ if (gInstance->func[func]) {
+ sdio_claim_host(gInstance->func[func]);
+ sdio_f0_writeb(gInstance->func[func],
+ *byte, regaddr, &err_ret);
+ sdio_release_host(gInstance->func[func]);
+ }
}
} else {
/* Claim host controller, perform Fn write, and release */
- sdio_claim_host(gInstance->func[func]);
- sdio_writeb(gInstance->func[func], *byte, regaddr, &err_ret);
- sdio_release_host(gInstance->func[func]);
+ if (gInstance->func[func]) {
+ sdio_claim_host(gInstance->func[func]);
+ sdio_writeb(gInstance->func[func], *byte, regaddr, &err_ret);
+ sdio_release_host(gInstance->func[func]);
+ }
}
} else { /* CMD52 Read */
/* Claim host controller, perform Fn read, and release */
- sdio_claim_host(gInstance->func[func]);
-
- if (func == 0) {
- *byte = sdio_f0_readb(gInstance->func[func], regaddr, &err_ret);
- } else {
- *byte = sdio_readb(gInstance->func[func], regaddr, &err_ret);
+ if (gInstance->func[func]) {
+ sdio_claim_host(gInstance->func[func]);
+ if (func == 0) {
+ *byte = sdio_f0_readb(gInstance->func[func], regaddr, &err_ret);
+ } else {
+ *byte = sdio_readb(gInstance->func[func], regaddr, &err_ret);
+ }
+ sdio_release_host(gInstance->func[func]);
}
-
- sdio_release_host(gInstance->func[func]);
}
if (err_ret) {
@@ -1012,7 +1020,13 @@ sdioh_request_packet(sdioh_info_t *sd, uint fix_inc, uint write, uint func,
pkt_len -= xfred_len;
xfred_len = 0;
}
- pkt_len = (pkt_len + 3) & 0xFFFFFFFC;
+
+ /* Align Patch */
+ if (!write || pkt_len < 32)
+ pkt_len = (pkt_len + 3) & 0xFFFFFFFC;
+ else if (pkt_len % DHD_SDALIGN)
+ pkt_len += DHD_SDALIGN - (pkt_len % DHD_SDALIGN);
+
#ifdef CONFIG_MMC_MSM7X00A
if ((pkt_len % 64) == 32) {
sd_trace(("%s: Rounding up TX packet +=32\n", __FUNCTION__));
diff --git a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c
index a78faeb..c93e41c 100644
--- a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c
+++ b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: bcmsdh_sdmmc_linux.c 312783 2012-02-03 22:53:56Z $
+ * $Id: bcmsdh_sdmmc_linux.c 331154 2012-05-04 00:41:40Z $
*/
#include <typedefs.h>
@@ -188,7 +188,6 @@ static int bcmsdh_sdmmc_suspend(struct device *pdev)
if (dhd_os_check_wakelock(bcmsdh_get_drvdata()))
return -EBUSY;
-
sdio_flags = sdio_get_host_pm_caps(func);
if (!(sdio_flags & MMC_PM_KEEP_POWER)) {
@@ -202,7 +201,6 @@ static int bcmsdh_sdmmc_suspend(struct device *pdev)
sd_err(("%s: error while trying to keep power\n", __FUNCTION__));
return ret;
}
-
#if defined(OOB_INTR_ONLY)
bcmsdh_oob_intr_set(0);
#endif /* defined(OOB_INTR_ONLY) */
diff --git a/drivers/net/wireless/bcmdhd/dhd.h b/drivers/net/wireless/bcmdhd/dhd.h
index 725a909..34616d3 100644
--- a/drivers/net/wireless/bcmdhd/dhd.h
+++ b/drivers/net/wireless/bcmdhd/dhd.h
@@ -24,7 +24,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: dhd.h 333052 2012-05-12 02:09:28Z $
+ * $Id: dhd.h 344123 2012-07-11 09:33:49Z $
*/
/****************
@@ -608,6 +608,20 @@ extern uint dhd_pktgen_len;
#endif
+/* hooks for custom Roaming Trigger setting via Makefile */
+#define DEFAULT_ROAM_TRIGGER_VALUE -75 /* dBm default roam trigger all band */
+#define DEFAULT_ROAM_TRIGGER_SETTING -1
+#ifndef CUSTOM_ROAM_TRIGGER_SETTING
+#define CUSTOM_ROAM_TRIGGER_SETTING DEFAULT_ROAM_TRIGGER_VALUE
+#endif
+
+/* hooks for custom Roaming Romaing setting via Makefile */
+#define DEFAULT_ROAM_DELTA_VALUE 10 /* dBm default roam delta all band */
+#define DEFAULT_ROAM_DELTA_SETTING -1
+#ifndef CUSTOM_ROAM_DELTA_SETTING
+#define CUSTOM_ROAM_DELTA_SETTING DEFAULT_ROAM_DELTA_VALUE
+#endif
+
/* optionally set by a module_param_string() */
#define MOD_PARAM_PATHLEN 2048
extern char fw_path[MOD_PARAM_PATHLEN];
diff --git a/drivers/net/wireless/bcmdhd/dhd_cfg80211.c b/drivers/net/wireless/bcmdhd/dhd_cfg80211.c
index 970216e..351c372 100644
--- a/drivers/net/wireless/bcmdhd/dhd_cfg80211.c
+++ b/drivers/net/wireless/bcmdhd/dhd_cfg80211.c
@@ -69,6 +69,9 @@ s32 dhd_cfg80211_down(struct wl_priv *wl)
return 0;
}
+/*
+ * dhd_cfg80211_set_p2p_info : gets called when GO or GC created
+ */
s32 dhd_cfg80211_set_p2p_info(struct wl_priv *wl, int val)
{
dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
@@ -83,7 +86,7 @@ s32 dhd_cfg80211_set_p2p_info(struct wl_priv *wl, int val)
dhd_arp_offload_set(dhd, 0);
dhd_arp_offload_enable(dhd, false);
#endif /* ARP_OFFLOAD_SUPPORT */
-
+ /* diable all filtering in p2p mode */
dhd_os_set_packet_filter(dhd, 0);
/* Setup timeout if Beacons are lost and roam is off to report link down */
@@ -94,6 +97,9 @@ s32 dhd_cfg80211_set_p2p_info(struct wl_priv *wl, int val)
return 0;
}
+/*
+ * dhd_cfg80211_clean_p2p_info : gets called when GO or GC terminated
+ */
s32 dhd_cfg80211_clean_p2p_info(struct wl_priv *wl)
{
dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
@@ -108,7 +114,6 @@ s32 dhd_cfg80211_clean_p2p_info(struct wl_priv *wl)
dhd_arp_offload_set(dhd, dhd_arp_mode);
dhd_arp_offload_enable(dhd, true);
#endif /* ARP_OFFLOAD_SUPPORT */
-
dhd_os_set_packet_filter(dhd, 1);
/* Setup timeout if Beacons are lost and roam is off to report link down */
diff --git a/drivers/net/wireless/bcmdhd/dhd_custom_gpio.c b/drivers/net/wireless/bcmdhd/dhd_custom_gpio.c
index 9750eeb..de519a5 100644
--- a/drivers/net/wireless/bcmdhd/dhd_custom_gpio.c
+++ b/drivers/net/wireless/bcmdhd/dhd_custom_gpio.c
@@ -20,7 +20,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
-* $Id: dhd_custom_gpio.c,v 1.2.42.1 2010-10-19 00:41:09 Exp $
+* $Id: dhd_custom_gpio.c 339054 2012-06-15 04:56:55Z $
*/
#include <typedefs.h>
@@ -97,13 +97,13 @@ int dhd_customer_oob_irq_map(unsigned long *irq_flags_ptr)
#endif /* CUSTOMER_HW2 */
if (dhd_oob_gpio_num < 0) {
- WL_ERROR(("%s: ERROR customer specific Host GPIO is NOT defined \n",
+ WL_ERROR(("%s: ERROR customer specific Host GPIO is NOT defined\n",
__FUNCTION__));
return (dhd_oob_gpio_num);
}
WL_ERROR(("%s: customer specific Host GPIO number is (%d)\n",
- __FUNCTION__, dhd_oob_gpio_num));
+ __FUNCTION__, dhd_oob_gpio_num));
#if defined CUSTOMER_HW
host_oob_irq = MSM_GPIO_TO_INT(dhd_oob_gpio_num);
diff --git a/drivers/net/wireless/bcmdhd/dhd_linux.c b/drivers/net/wireless/bcmdhd/dhd_linux.c
index d32ce11..a189d63 100644
--- a/drivers/net/wireless/bcmdhd/dhd_linux.c
+++ b/drivers/net/wireless/bcmdhd/dhd_linux.c
@@ -22,7 +22,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: dhd_linux.c 333885 2012-05-18 00:39:03Z $
+ * $Id: dhd_linux.c 352789 2012-08-24 00:01:33Z $
*/
#include <typedefs.h>
@@ -327,8 +327,8 @@ uint dhd_console_ms = 0;
module_param(dhd_console_ms, uint, 0644);
#endif /* defined(DHD_DEBUG) */
-/* ARP offload agent mode : Enable ARP Host Auto-Reply and ARP Peer Auto-Reply */
-uint dhd_arp_mode = 0xb;
+/* ARP offload agent mode : enable ARP Peer Auto-Reply */
+uint dhd_arp_mode = ARP_OL_AGENT | ARP_OL_PEER_AUTO_REPLY;
module_param(dhd_arp_mode, uint, 0);
/* ARP offload enable */
@@ -1026,7 +1026,7 @@ dhd_op_if(dhd_if_t *ifp)
#endif
netif_stop_queue(ifp->net);
unregister_netdev(ifp->net);
- ret = DHD_DEL_IF;
+ ret = DHD_DEL_IF; /* Make sure the free_netdev() is called */
#ifdef WL_CFG80211
if (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211) {
@@ -1361,10 +1361,11 @@ dhd_start_xmit(struct sk_buff *skb, struct net_device *net)
done:
- if (ret)
+ if (ret) {
dhd->pub.dstats.tx_dropped++;
- else
+ } else {
dhd->pub.tx_packets++;
+ }
DHD_OS_WAKE_UNLOCK(&dhd->pub);
@@ -2648,7 +2649,9 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen)
}
sema_init(&dhd->proto_sem, 1);
+#ifdef DHDTHREAD
sema_init(&dhd->sdsem, 1);
+#endif
#ifdef PROP_TXSTATUS
spin_lock_init(&dhd->wlfc_spinlock);
@@ -2987,6 +2990,8 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
char *ptr;
uint32 listen_interval = LISTEN_INTERVAL; /* Default Listen Interval in Beacons */
uint16 chipID;
+ int roam_trigger[2] = {CUSTOM_ROAM_TRIGGER_SETTING, WLC_BAND_ALL};
+ int roam_delta[2] = {CUSTOM_ROAM_DELTA_SETTING, WLC_BAND_ALL};
#if defined(SOFTAP)
uint dtim = 1;
#endif
@@ -3154,6 +3159,14 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0)
DHD_ERROR(("%s assoc_listen failed %d\n", __FUNCTION__, ret));
+ /* custom romaing setting */
+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_ROAM_TRIGGER, roam_trigger,
+ sizeof(roam_trigger), TRUE, 0)) < 0)
+ DHD_ERROR(("%s: roam trigger set failed %d\n", __FUNCTION__, ret));
+ if ((dhd_wl_ioctl_cmd(dhd, WLC_SET_ROAM_DELTA, roam_delta,
+ sizeof(roam_delta), TRUE, 0)) < 0)
+ DHD_ERROR(("%s: roam delta set failed %d\n", __FUNCTION__, ret));
+
/* Set PowerSave mode */
dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)&power_mode, sizeof(power_mode), TRUE, 0);
@@ -3212,6 +3225,7 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
setbit(eventmask, WLC_E_SET_SSID);
setbit(eventmask, WLC_E_PRUNE);
setbit(eventmask, WLC_E_AUTH);
+ setbit(eventmask, WLC_E_ASSOC);
setbit(eventmask, WLC_E_REASSOC);
setbit(eventmask, WLC_E_REASSOC_IND);
setbit(eventmask, WLC_E_DEAUTH);
@@ -3226,8 +3240,10 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
setbit(eventmask, WLC_E_MIC_ERROR);
setbit(eventmask, WLC_E_ASSOC_REQ_IE);
setbit(eventmask, WLC_E_ASSOC_RESP_IE);
+#ifndef WL_CFG80211
setbit(eventmask, WLC_E_PMKID_CACHE);
setbit(eventmask, WLC_E_TXFAIL);
+#endif
setbit(eventmask, WLC_E_JOIN_START);
setbit(eventmask, WLC_E_SCAN_COMPLETE);
#ifdef WLMEDIA_HTSF
@@ -4326,6 +4342,13 @@ dhd_dev_reset(struct net_device *dev, uint8 flag)
dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+ if (flag == TRUE) {
+ /* Issue wl down command before resetting the chip */
+ if (dhd_wl_ioctl_cmd(&dhd->pub, WLC_DOWN, NULL, 0, TRUE, 0) < 0) {
+ DHD_TRACE(("%s: wl down failed\n", __FUNCTION__));
+ }
+ }
+
ret = dhd_bus_devreset(&dhd->pub, flag);
if (ret) {
DHD_ERROR(("%s: dhd_bus_devreset: %d\n", __FUNCTION__, ret));
@@ -4506,7 +4529,7 @@ static void dhd_hang_process(struct work_struct *work)
wl_iw_send_priv_event(dev, "HANG");
#endif
#if defined(WL_CFG80211)
- wl_cfg80211_hang(dev, WLAN_REASON_UNSPECIFIED);
+ wl_cfg80211_hang(dev, WLAN_REASON_DRIVER_ERROR);
#endif
}
}
diff --git a/drivers/net/wireless/bcmdhd/dhd_sdio.c b/drivers/net/wireless/bcmdhd/dhd_sdio.c
index e578d70..09dc45a 100644
--- a/drivers/net/wireless/bcmdhd/dhd_sdio.c
+++ b/drivers/net/wireless/bcmdhd/dhd_sdio.c
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: dhd_sdio.c 326662 2012-04-10 06:38:08Z $
+ * $Id: dhd_sdio.c 352730 2012-08-23 20:55:11Z $
*/
#include <typedefs.h>
@@ -1375,7 +1375,13 @@ dhd_bus_txctl(struct dhd_bus *bus, uchar *msg, uint msglen)
/* Send from dpc */
bus->ctrl_frame_buf = frame;
bus->ctrl_frame_len = len;
- dhd_wait_for_event(bus->dhd, &bus->ctrl_frame_stat);
+ if (!bus->dpc_sched) {
+ bus->dpc_sched = TRUE;
+ dhd_sched_dpc(bus->dhd);
+ }
+ if (bus->ctrl_frame_stat) {
+ dhd_wait_for_event(bus->dhd, &bus->ctrl_frame_stat);
+ }
if (bus->ctrl_frame_stat == FALSE) {
DHD_INFO(("%s: ctrl_frame_stat == FALSE\n", __FUNCTION__));
ret = 0;
@@ -1487,7 +1493,7 @@ dhd_bus_rxctl(struct dhd_bus *bus, uchar *msg, uint msglen)
dhd_os_sdunlock(bus->dhd);
#endif /* DHD_DEBUG */
} else if (pending == TRUE) {
- /* signal pending */
+ /* possibly fw hangs so never responsed back */
DHD_ERROR(("%s: signal pending\n", __FUNCTION__));
return -EINTR;
} else {
@@ -5192,7 +5198,7 @@ done:
}
#endif /* DHD_DEBUG */
-#ifdef DHD_DEBUG
+#if (defined DHD_DEBUG)
static void
dhd_dump_cis(uint fn, uint8 *cis)
{
@@ -5468,12 +5474,11 @@ dhdsdio_probe_attach(struct dhd_bus *bus, osl_t *osh, void *sdh, void *regsva,
clkctl = bcmsdh_cfg_read(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err);
if (err || ((clkctl & ~SBSDIO_AVBITS) != DHD_INIT_CLKCTL1)) {
- DHD_ERROR(("dhdsdio_probe: ChipClkCSR access: err %d wrote 0x%02x read 0x%02x\n",
- err, DHD_INIT_CLKCTL1, clkctl));
+ DHD_ERROR(("%s: ChipClkCSR access: err %d wrote 0x%02x read 0x%02x\n",
+ __FUNCTION__, err, DHD_INIT_CLKCTL1, clkctl));
goto fail;
}
-
#ifdef DHD_DEBUG
if (DHD_INFO_ON()) {
uint fn, numfn;
diff --git a/drivers/net/wireless/bcmdhd/include/epivers.h b/drivers/net/wireless/bcmdhd/include/epivers.h
index 5df25c1..37c07e6 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 195
-#define EPI_INCREMENTAL_NUMBER 75
+#define EPI_INCREMENTAL_NUMBER 104
#define EPI_BUILD_NUMBER 0
-#define EPI_VERSION 5, 90, 195, 75
+#define EPI_VERSION 5, 90, 195, 104
-#define EPI_VERSION_NUM 0x055ac34b
+#define EPI_VERSION_NUM 0x055ac368
#define EPI_VERSION_DEV 5.90.195
-#define EPI_VERSION_STR "5.90.195.75"
+#define EPI_VERSION_STR "5.90.195.104"
#endif
diff --git a/drivers/net/wireless/bcmdhd/include/sbchipc.h b/drivers/net/wireless/bcmdhd/include/sbchipc.h
index aa4df44..78ced30 100644
--- a/drivers/net/wireless/bcmdhd/include/sbchipc.h
+++ b/drivers/net/wireless/bcmdhd/include/sbchipc.h
@@ -5,7 +5,7 @@
* JTAG, 0/1/2 UARTs, clock frequency control, a watchdog interrupt timer,
* GPIO interface, extbus, and support for serial and parallel flashes.
*
- * $Id: sbchipc.h 333924 2012-05-18 04:48:52Z $
+ * $Id: sbchipc.h 343982 2012-07-11 00:29:37Z $
*
* Copyright (C) 1999-2011, Broadcom Corporation
*
@@ -1726,6 +1726,11 @@ typedef volatile struct {
#define SECI_MODE_SHIFT 4
#define SECI_UPD_SECI (1 << 7)
+#define SECI_SLIP_ESC_CHAR 0xDB
+#define SECI_SIGNOFF_0 SECI_SLIP_ESC_CHAR
+#define SECI_SIGNOFF_1 0
+#define SECI_REFRESH_REQ 0xDA
+
#define CLKCTL_STS_SECI_CLK_REQ (1 << 8)
#define CLKCTL_STS_SECI_CLK_AVAIL (1 << 24)
diff --git a/drivers/net/wireless/bcmdhd/include/sdioh.h b/drivers/net/wireless/bcmdhd/include/sdioh.h
index 5f47d6f..1d820d1 100644
--- a/drivers/net/wireless/bcmdhd/include/sdioh.h
+++ b/drivers/net/wireless/bcmdhd/include/sdioh.h
@@ -22,7 +22,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: sdioh.h 300017 2011-12-01 20:30:27Z $
+ * $Id: sdioh.h 345478 2012-07-18 06:45:15Z $
*/
#ifndef _SDIOH_H
@@ -90,6 +90,10 @@
#define SD3_PresetVal_SDR50 0x06a
#define SD3_PresetVal_SDR104 0x06c
#define SD3_PresetVal_DDR50 0x06e
+/* SDIO3.0 Revx specific Registers */
+#define SD3_Tuning_Info_Register 0x0EC
+#define SD3_WL_BT_reset_register 0x0F0
+
/* preset value indices */
#define SD3_PRESETVAL_INITIAL_IX 0
diff --git a/drivers/net/wireless/bcmdhd/include/wlioctl.h b/drivers/net/wireless/bcmdhd/include/wlioctl.h
index e543bfa..122b5a4 100644
--- a/drivers/net/wireless/bcmdhd/include/wlioctl.h
+++ b/drivers/net/wireless/bcmdhd/include/wlioctl.h
@@ -24,7 +24,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: wlioctl.h 331292 2012-05-04 09:04:23Z $
+ * $Id: wlioctl.h 353331 2012-08-27 06:04:47Z $
*/
@@ -83,44 +83,6 @@ typedef struct wl_af_params {
#include <packed_section_start.h>
-
-
-
-#define LEGACY2_WL_BSS_INFO_VERSION 108
-
-
-typedef struct wl_bss_info_108 {
- uint32 version;
- uint32 length;
- struct ether_addr BSSID;
- uint16 beacon_period;
- uint16 capability;
- uint8 SSID_len;
- uint8 SSID[32];
- struct {
- uint count;
- uint8 rates[16];
- } rateset;
- chanspec_t chanspec;
- uint16 atim_window;
- uint8 dtim_period;
- int16 RSSI;
- int8 phy_noise;
-
- uint8 n_cap;
- uint32 nbss_cap;
- uint8 ctl_ch;
- uint32 reserved32[1];
- uint8 flags;
- uint8 reserved[3];
- uint8 basic_mcs[MCSSET_LEN];
-
- uint16 ie_offset;
- uint32 ie_length;
-
-
-} wl_bss_info_108_t;
-
#define WL_BSS_INFO_VERSION 109
@@ -157,23 +119,13 @@ typedef struct wl_bss_info {
} wl_bss_info_t;
-typedef struct wl_bsscfg {
- uint32 wsec;
- uint32 WPA_auth;
- uint32 wsec_index;
- uint32 associated;
- uint32 BSS;
- uint32 phytest_on;
- struct ether_addr prev_BSSID;
- struct ether_addr BSSID;
-} wl_bsscfg_t;
-typedef struct wl_bss_config {
- uint32 atim_window;
- uint32 beacon_period;
- uint32 chanspec;
-} wl_bss_config_t;
+#define WL_BSS_FLAGS_FROM_BEACON 0x01
+#define WL_BSS_FLAGS_FROM_CACHE 0x02
+#define WL_BSS_FLAGS_RSSI_ONCHANNEL 0x04
+
+#define VHT_BI_SGI_80MHZ 0x00000100
typedef struct wlc_ssid {
uint32 SSID_len;
diff --git a/drivers/net/wireless/bcmdhd/wl_android.c b/drivers/net/wireless/bcmdhd/wl_android.c
index 4fcdcd3..ce74f0f 100644
--- a/drivers/net/wireless/bcmdhd/wl_android.c
+++ b/drivers/net/wireless/bcmdhd/wl_android.c
@@ -736,7 +736,7 @@ int wifi_set_power(int on, unsigned long msec)
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
int wifi_get_mac_addr(unsigned char *buf)
{
- DHD_ERROR(("%s\n", __FUNCTION__));
+ DHD_TRACE(("%s\n", __FUNCTION__));
if (!buf)
return -EINVAL;
if (wifi_control_data && wifi_control_data->get_mac_addr) {
diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.c b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
index 87d971a..dcd06e5 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfg80211.c
+++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
@@ -188,6 +188,8 @@ static s32 wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
static s32 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
struct net_device *dev, u8 key_idx);
static s32 wl_cfg80211_resume(struct wiphy *wiphy);
+static s32 wl_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
+ struct net_device *dev, u64 cookie);
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)
static s32 wl_cfg80211_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
#else
@@ -358,6 +360,7 @@ static s32 wl_iscan_done(struct wl_priv *wl);
static s32 wl_iscan_pending(struct wl_priv *wl);
static s32 wl_iscan_inprogress(struct wl_priv *wl);
static s32 wl_iscan_aborted(struct wl_priv *wl);
+static void wl_scan_timeout_process(struct work_struct *work);
/*
* find most significant bit set
@@ -951,7 +954,7 @@ wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, struct net_device *dev)
struct net_device *ndev = wl_to_prmry_ndev(wl);
WL_ERR(("Firmware returned an error (%d) from p2p_ifdel"
"HANG Notification sent to %s\n", ret, ndev->name));
- wl_cfg80211_hang(ndev, WLAN_REASON_UNSPECIFIED);
+ wl_cfg80211_hang(ndev, WLAN_REASON_DRIVER_ERROR);
}
/* Wait for any pending scan req to get aborted from the sysioc context */
@@ -1518,6 +1521,8 @@ wl_do_escan(struct wl_priv *wl, struct wiphy *wiphy, struct net_device *ndev,
s32 passive_scan;
wl_scan_results_t *results;
WL_SCAN(("Enter \n"));
+
+ mutex_lock(&wl->usr_sync);
wl->escan_info.ndev = ndev;
wl->escan_info.wiphy = wiphy;
wl->escan_info.escan_state = WL_ESCAN_STATE_SCANING;
@@ -1526,7 +1531,7 @@ wl_do_escan(struct wl_priv *wl, struct wiphy *wiphy, struct net_device *ndev,
&passive_scan, sizeof(passive_scan), false);
if (unlikely(err)) {
WL_ERR(("error (%d)\n", err));
- return err;
+ goto exit;
}
results = (wl_scan_results_t *) wl->escan_info.escan_buf;
results->version = 0;
@@ -1534,6 +1539,8 @@ wl_do_escan(struct wl_priv *wl, struct wiphy *wiphy, struct net_device *ndev,
results->buflen = WL_SCAN_RESULTS_FIXED_SIZE;
err = wl_run_escan(wl, ndev, request, WL_SCAN_ACTION_START);
+exit:
+ mutex_unlock(&wl->usr_sync);
return err;
}
@@ -1750,6 +1757,7 @@ wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
wl->scan_busy_count++;
if (wl->scan_busy_count > WL_SCAN_BUSY_MAX) {
wl->scan_busy_count = 0;
+ WL_ERR(("Continuous scan failures!! Exercising FW hang recovery\n"));
net_os_send_hang_message(ndev);
}
}
@@ -2660,7 +2668,7 @@ wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev,
WL_ERR(("WLC_GET_WSEC error (%d)\n", err));
return err;
}
- if (wsec & WEP_ENABLED) {
+ if (wsec == WEP_ENABLED) {
/* Just select a new current key */
index = (u32) key_idx;
index = htod32(index);
@@ -3069,6 +3077,7 @@ wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
s32 pm;
s32 err = 0;
struct wl_priv *wl = wiphy_priv(wiphy);
+ dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
CHECK_SYS_UP(wl);
@@ -3077,7 +3086,7 @@ wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
return err;
}
- pm = enabled ? PM_FAST : PM_OFF;
+ pm = enabled ? ((dhd->in_suspend) ? PM_MAX : PM_FAST) : PM_OFF;
pm = htod32(pm);
err = wldev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm), true);
if (unlikely(err)) {
@@ -3511,6 +3520,7 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *ndev,
wifi_p2p_ie_t *p2p_ie;
wpa_ie_fixed_t *wps_ie;
scb_val_t scb_val;
+ wifi_wfd_ie_t *wfd_ie;
const struct ieee80211_mgmt *mgmt;
struct wl_priv *wl = wiphy_priv(wiphy);
struct net_device *dev = NULL;
@@ -3518,6 +3528,7 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *ndev,
s32 bssidx = 0;
u32 p2pie_len = 0;
u32 wpsie_len = 0;
+ u32 wfdie_len = 0;
u32 id;
u32 retry = 0;
bool ack = false;
@@ -3567,6 +3578,11 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *ndev,
/* Total length of P2P Information Element */
p2pie_len = p2p_ie->len + sizeof(p2p_ie->len) + sizeof(p2p_ie->id);
}
+ if ((wfd_ie = wl_cfgp2p_find_wfdie((u8 *)(buf + ie_offset), ie_len))
+ != NULL) {
+ /* Total length of WFD Information Element */
+ wfdie_len = wfd_ie->len + sizeof(wfd_ie->len) + sizeof(wfd_ie->id);
+ }
if ((wps_ie = wl_cfgp2p_find_wpsie((u8 *)(buf + ie_offset), ie_len))
!= NULL) {
/* Order of Vendor IE is 1) WPS IE +
@@ -3578,7 +3594,7 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *ndev,
sizeof(wps_ie->tag);
wl_cfgp2p_set_management_ie(wl, dev, bssidx,
VNDR_IE_PRBRSP_FLAG,
- (u8 *)wps_ie, wpsie_len + p2pie_len);
+ (u8 *)wps_ie, wpsie_len + p2pie_len+ wfdie_len);
}
cfg80211_mgmt_tx_status(ndev, *cookie, buf, len, true, GFP_KERNEL);
goto exit;
@@ -4087,11 +4103,13 @@ wl_cfg80211_add_set_beacon(struct wiphy *wiphy, struct net_device *dev,
wpa_ie_fixed_t *wpa_ie;
bcm_tlv_t *wpa2_ie;
wifi_p2p_ie_t *p2p_ie;
+ wifi_wfd_ie_t *wfd_ie;
bool is_bssup = false;
bool update_bss = false;
bool pbc = false;
u16 wpsie_len = 0;
u16 p2pie_len = 0;
+ u32 wfdie_len = 0;
u8 beacon_ie[IE_MAX_LEN];
s32 ie_offset = 0;
s32 bssidx = 0;
@@ -4149,10 +4167,24 @@ wl_cfg80211_add_set_beacon(struct wiphy *wiphy, struct net_device *dev,
} else {
WL_ERR(("No P2PIE in beacon \n"));
}
+ /* find the WFD IEs */
+ if ((wfd_ie = wl_cfgp2p_find_wfdie((u8 *)info->tail, info->tail_len)) != NULL) {
+ /* Total length of P2P Information Element */
+ wfdie_len = wfd_ie->len + sizeof(wfd_ie->len) + sizeof(wfd_ie->id);
+ if ((wpsie_len + p2pie_len + wfdie_len) < IE_MAX_LEN) {
+ memcpy(&beacon_ie[wpsie_len + p2pie_len], wfd_ie, wfdie_len);
+ } else {
+ WL_ERR(("Found WFD IE but there is no space, (%d)(%d)(%d)\n",
+ wpsie_len, p2pie_len, wfdie_len));
+ wfdie_len = 0;
+ }
+ } else {
+ WL_ERR(("No WFDIE in beacon \n"));
+ }
/* add WLC_E_PROBREQ_MSG event to respose probe_request from STA */
wl_add_remove_eventmsg(dev, WLC_E_PROBREQ_MSG, pbc);
wl_cfgp2p_set_management_ie(wl, dev, bssidx, VNDR_IE_BEACON_FLAG,
- beacon_ie, wpsie_len + p2pie_len);
+ beacon_ie, wpsie_len + p2pie_len + wfdie_len);
/* find the RSN_IE */
if ((wpa2_ie = bcm_parse_tlvs((u8 *)info->tail, info->tail_len,
@@ -4555,6 +4587,7 @@ static struct cfg80211_ops wl_cfg80211_ops = {
.set_channel = wl_cfg80211_set_channel,
.set_beacon = wl_cfg80211_add_set_beacon,
.add_beacon = wl_cfg80211_add_set_beacon,
+ .mgmt_tx_cancel_wait = wl_cfg80211_mgmt_tx_cancel_wait,
#ifdef WL_SCHED_SCAN
.sched_scan_start = wl_cfg80211_sched_scan_start,
.sched_scan_stop = wl_cfg80211_sched_scan_stop,
@@ -4623,8 +4656,10 @@ static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev
#endif
WIPHY_FLAG_4ADDR_STATION;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
- wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
+ /* wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM; */
#endif
+ /* AP_SME flag can be advertised to remove patch from wpa_supplicant */
+ wdev->wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME;
WL_DBG(("Registering custom regulatory)\n"));
wdev->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
wiphy_apply_custom_regulatory(wdev->wiphy, &brcm_regdom);
@@ -4714,8 +4749,9 @@ static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
}
notif_bss_info->rssi = dtoh16(bi->RSSI);
memcpy(mgmt->bssid, &bi->BSSID, ETHER_ADDR_LEN);
- mgmt_type = wl->active_scan ?
- IEEE80211_STYPE_PROBE_RESP : IEEE80211_STYPE_BEACON;
+ mgmt_type = (bi->flags & WL_BSS_FLAGS_FROM_BEACON) ?
+ IEEE80211_STYPE_BEACON : IEEE80211_STYPE_PROBE_RESP;
+
if (!memcmp(bi->SSID, sr->ssid.SSID, bi->SSID_len)) {
mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | mgmt_type);
}
@@ -4744,7 +4780,7 @@ static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
return -EINVAL;
}
- WL_DBG(("SSID : \"%s\", rssi %d, channel %d, capability : 0x04%x, bssid %pM "
+ WL_DBG(("SSID : \"%s\", rssi %d, channel %d, capability : 0x04%x, bssid %pM"
"mgmt_type %d frame_len %d\n", bi->SSID,
notif_bss_info->rssi, notif_bss_info->channel,
mgmt->u.beacon.capab_info, &bi->BSSID, mgmt_type,
@@ -5421,7 +5457,7 @@ wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
conn_info->req_ie_len,
conn_info->resp_ie,
conn_info->resp_ie_len,
- completed ? WLAN_STATUS_SUCCESS : WLAN_STATUS_AUTH_TIMEOUT,
+ completed ? WLAN_STATUS_SUCCESS : e->reason,
GFP_KERNEL);
if (completed)
WL_INFO(("Report connect result - connection succeeded\n"));
@@ -6018,7 +6054,9 @@ static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted)
unsigned long flags;
WL_DBG(("Enter \n"));
- wl->scan_busy_count = 0;
+ if(!aborted)
+ wl->scan_busy_count = 0;
+
if (!wl_get_drv_status(wl, SCANNING, ndev)) {
wl_clr_drv_status(wl, SCANNING, ndev);
WL_ERR(("Scan complete while device not scanning\n"));
@@ -6175,13 +6213,30 @@ static void wl_scan_timeout(unsigned long data)
{
struct wl_priv *wl = (struct wl_priv *)data;
+ schedule_work(&wl->work_scan_timeout);
+}
+
+static void wl_scan_timeout_process(struct work_struct *work)
+{
+ struct wl_priv *wl;
+
+ wl = (wl_priv_t *)container_of(work, wl_priv_t, work_scan_timeout);
+
if (wl->scan_request) {
WL_ERR(("timer expired\n"));
if (wl->escan_on)
- wl_notify_escan_complete(wl, wl->escan_info.ndev, true, false);
+ wl_notify_escan_complete(wl, wl->escan_info.ndev, true, true);
else
wl_notify_iscan_complete(wl_to_iscan(wl), true);
}
+
+ /* Assume FW is in bad state if there are continuous scan timeouts */
+ wl->scan_busy_count++;
+ if (wl->scan_busy_count > WL_SCAN_BUSY_MAX) {
+ wl->scan_busy_count = 0;
+ WL_ERR(("Continuous scan timeouts!! Exercising FW hang recovery\n"));
+ net_os_send_hang_message(wl->escan_info.ndev);
+ }
}
static void wl_iscan_timer(unsigned long data)
@@ -6273,7 +6328,9 @@ static s32 wl_notify_escan_complete(struct wl_priv *wl,
WL_DBG(("Enter \n"));
- wl->scan_busy_count = 0;
+ if(!aborted)
+ wl->scan_busy_count = 0;
+
if (wl->scan_request) {
if (wl->scan_request->dev == wl->p2p_net)
dev = wl_to_prmry_ndev(wl);
@@ -6344,8 +6401,11 @@ static s32 wl_escan_handler(struct wl_priv *wl,
u32 i;
wifi_p2p_ie_t * p2p_ie;
u8 *p2p_dev_addr = NULL;
+
WL_DBG((" enter event type : %d, status : %d \n",
ntoh32(e->event_type), ntoh32(e->status)));
+
+ mutex_lock(&wl->usr_sync);
/* P2P SCAN is coming from primary interface */
if (wl_get_p2p_status(wl, SCANNING)) {
if (wl_get_drv_status_all(wl, SENDING_ACT_FRM))
@@ -6358,7 +6418,7 @@ static s32 wl_escan_handler(struct wl_priv *wl,
!wl_get_drv_status(wl, SCANNING, ndev)) {
WL_ERR(("escan is not ready ndev %p wl->escan_on %d drv_status 0x%x\n",
ndev, wl->escan_on, wl_get_drv_status(wl, SCANNING, ndev)));
- return err;
+ goto exit;
}
if (status == WLC_E_STATUS_PARTIAL) {
@@ -6448,7 +6508,6 @@ static s32 wl_escan_handler(struct wl_priv *wl,
bss->RSSI = bi->RSSI;
bss->flags |= WLC_BSS_RSSI_ON_CHANNEL;
}
-
goto exit;
}
}
@@ -6456,7 +6515,6 @@ static s32 wl_escan_handler(struct wl_priv *wl,
list->version = dtoh32(bi->version);
list->buflen += bi_length;
list->count++;
-
}
}
@@ -6469,12 +6527,10 @@ static s32 wl_escan_handler(struct wl_priv *wl,
if (wl->afx_hdl->peer_chan == WL_INVALID)
complete(&wl->act_frm_scan);
} else if ((likely(wl->scan_request)) || (wl->sched_scan_running)) {
- mutex_lock(&wl->usr_sync);
WL_INFO(("ESCAN COMPLETED\n"));
wl->bss_list = (wl_scan_results_t *)wl->escan_info.escan_buf;
wl_inform_bss(wl);
wl_notify_escan_complete(wl, ndev, false, false);
- mutex_unlock(&wl->usr_sync);
}
}
else if (status == WLC_E_STATUS_ABORT) {
@@ -6486,14 +6542,15 @@ static s32 wl_escan_handler(struct wl_priv *wl,
if (wl->afx_hdl->peer_chan == WL_INVALID)
complete(&wl->act_frm_scan);
} else if ((likely(wl->scan_request)) || (wl->sched_scan_running)) {
- mutex_lock(&wl->usr_sync);
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, ndev, true, false);
- mutex_unlock(&wl->usr_sync);
}
}
+ else if (status == WLC_E_STATUS_NEWSCAN) {
+ /* Do Nothing. Ignore this event */
+ }
else {
WL_ERR(("unexpected Escan Event %d : abort\n", status));
wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
@@ -6504,14 +6561,13 @@ static s32 wl_escan_handler(struct wl_priv *wl,
if (wl->afx_hdl->peer_chan == WL_INVALID)
complete(&wl->act_frm_scan);
} else if ((likely(wl->scan_request)) || (wl->sched_scan_running)) {
- mutex_lock(&wl->usr_sync);
wl->bss_list = (wl_scan_results_t *)wl->escan_info.escan_buf;
wl_inform_bss(wl);
wl_notify_escan_complete(wl, ndev, true, false);
- mutex_unlock(&wl->usr_sync);
}
}
exit:
+ mutex_unlock(&wl->usr_sync);
return err;
}
@@ -6574,6 +6630,7 @@ static s32 wl_init_priv(struct wl_priv *wl)
return -ENOMEM;
wl_init_event_handler(wl);
mutex_init(&wl->usr_sync);
+ INIT_WORK(&wl->work_scan_timeout, wl_scan_timeout_process);
err = wl_init_scan(wl);
if (err)
return err;
@@ -6593,6 +6650,7 @@ static void wl_deinit_priv(struct wl_priv *wl)
wl_link_down(wl);
del_timer_sync(&wl->scan_timeout);
wl_term_iscan(wl);
+ cancel_work_sync(&wl->work_scan_timeout);
wl_deinit_priv_mem(wl);
unregister_netdevice_notifier(&wl_cfg80211_netdev_notifier);
}
@@ -7097,6 +7155,10 @@ static int wl_construct_reginfo(struct wl_priv *wl, s32 bw_cap)
band = IEEE80211_BAND_5GHZ;
ht40_allowed = (bw_cap == WLC_N_BW_20ALL) ? FALSE : TRUE;
}
+ else {
+ WL_ERR(("Invalid Channel received %x\n", channel));
+ continue;
+ }
for (j = 0; (j < *n_cnt && (*n_cnt < array_size)); j++) {
if (band_chan_arr[j].hw_value == channel) {
@@ -7225,6 +7287,7 @@ s32 wl_update_wiphybands(struct wl_priv *wl)
wiphy->bands[IEEE80211_BAND_2GHZ] =
&__wl_band_2ghz;
index = IEEE80211_BAND_2GHZ;
+
if (bandlist[i] == WLC_BAND_2G && bw_cap == WLC_N_BW_40ALL)
wiphy->bands[index]->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
}
@@ -7234,6 +7297,7 @@ s32 wl_update_wiphybands(struct wl_priv *wl)
wiphy->bands[index]->ht_cap.ht_supported = TRUE;
wiphy->bands[index]->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
wiphy->bands[index]->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
+ wiphy->bands[index]->ht_cap.mcs.rx_mask[0] = 0xff;
}
}
@@ -7771,3 +7835,10 @@ void wl_cfg80211_enable_trace(int level)
{
wl_dbg_level |= WL_DBG_DBG;
}
+
+static s32
+wl_cfg80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
+ struct net_device *dev, u64 cookie)
+{
+ return 0;
+}
diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.h b/drivers/net/wireless/bcmdhd/wl_cfg80211.h
index 49bed70..10a50e1 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfg80211.h
+++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.h
@@ -61,13 +61,24 @@ struct wl_ibss;
/* 0 invalidates all debug messages. default is 1 */
#define WL_DBG_LEVEL 0xFF
-#define WL_ERR(args) \
+#if defined(DHD_DEBUG)
+#define WL_ERR(args) \
do { \
- if (wl_dbg_level & WL_DBG_ERR) { \
+ if (wl_dbg_level & WL_DBG_ERR) { \
printk(KERN_ERR "CFG80211-ERROR) %s : ", __func__); \
printk args; \
} \
} while (0)
+#else /* defined(DHD_DEBUG) */
+#define WL_ERR(args) \
+do { \
+ if ((wl_dbg_level & WL_DBG_ERR) && net_ratelimit()) { \
+ printk(KERN_INFO "CFG80211-ERROR) %s : ", __func__); \
+ printk args; \
+ } \
+} while (0)
+#endif /* defined(DHD_DEBUG) */
+
#ifdef WL_INFO
#undef WL_INFO
#endif
@@ -142,6 +153,8 @@ do { \
#define WL_SCB_TIMEOUT 20
#endif
+#define WLAN_REASON_DRIVER_ERROR WLAN_REASON_UNSPECIFIED
+
/* driver status */
enum wl_status {
WL_STATUS_READY = 0,
@@ -387,7 +400,7 @@ struct afx_hdl {
};
/* private data of cfg80211 interface */
-struct wl_priv {
+typedef struct wl_priv {
struct wireless_dev *wdev; /* representing wl cfg80211 device */
struct wireless_dev *p2p_wdev; /* representing wl cfg80211 device for P2P */
@@ -457,7 +470,8 @@ struct wl_priv {
u16 hostapd_chan; /* remember chan requested by framework for hostapd */
u16 deauth_reason; /* Place holder to save deauth/disassoc reasons */
u16 scan_busy_count;
-};
+ struct work_struct work_scan_timeout;
+} wl_priv_t;
static inline struct wl_bss_info *next_bss(struct wl_scan_results *list, struct wl_bss_info *bss)
{
diff --git a/drivers/net/wireless/bcmdhd/wl_cfgp2p.c b/drivers/net/wireless/bcmdhd/wl_cfgp2p.c
index bdcfa95..f06ae50 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfgp2p.c
+++ b/drivers/net/wireless/bcmdhd/wl_cfgp2p.c
@@ -641,8 +641,8 @@ wl_cfgp2p_enable_discovery(struct wl_priv *wl, struct net_device *dev,
}
set_ie:
ret = wl_cfgp2p_set_management_ie(wl, dev,
- wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE),
- VNDR_IE_PRBREQ_FLAG, ie, ie_len);
+ wl_cfgp2p_find_idx(wl, dev),
+ VNDR_IE_PRBREQ_FLAG, ie, ie_len);
if (unlikely(ret < 0)) {
CFGP2P_ERR(("set probreq ie occurs error %d\n", ret));
@@ -846,6 +846,11 @@ exit:
/* Check whether the given IE looks like WFA P2P IE. */
#define wl_cfgp2p_is_p2p_ie(ie, tlvs, len) wl_cfgp2p_has_ie(ie, tlvs, len, \
(const uint8 *)WFA_OUI, WFA_OUI_LEN, WFA_OUI_TYPE_P2P)
+ /* Check whether the given IE looks like WFA WFDisplay IE. */
+#define WFA_OUI_TYPE_WFD 0x0a /* WiFi Display OUI TYPE */
+#define wl_cfgp2p_is_wfd_ie(ie, tlvs, len) wl_cfgp2p_has_ie(ie, tlvs, len, \
+ (const uint8 *)WFA_OUI, WFA_OUI_LEN, WFA_OUI_TYPE_WFD)
+
/* Delete and Set a management vndr ie to firmware
* Parameters:
* @wl : wl_private data
@@ -970,7 +975,8 @@ wl_cfgp2p_set_management_ie(struct wl_priv *wl, struct net_device *ndev, s32 bss
ie_len = ie_buf[pos++];
if ((ie_id == DOT11_MNG_VS_ID) &&
(wl_cfgp2p_is_wps_ie(&ie_buf[pos-2], NULL, 0) ||
- wl_cfgp2p_is_p2p_ie(&ie_buf[pos-2], NULL, 0))) {
+ wl_cfgp2p_is_p2p_ie(&ie_buf[pos-2], NULL, 0) ||
+ wl_cfgp2p_is_wfd_ie(&ie_buf[pos-2], NULL, 0))) {
CFGP2P_INFO(("DELELED ID : %d, Len : %d , OUI :"
"%02x:%02x:%02x\n", ie_id, ie_len, ie_buf[pos],
ie_buf[pos+1], ie_buf[pos+2]));
@@ -996,7 +1002,8 @@ wl_cfgp2p_set_management_ie(struct wl_priv *wl, struct net_device *ndev, s32 bss
ie_len = ie_buf[pos++];
if ((ie_id == DOT11_MNG_VS_ID) &&
(wl_cfgp2p_is_wps_ie(&ie_buf[pos-2], NULL, 0) ||
- wl_cfgp2p_is_p2p_ie(&ie_buf[pos-2], NULL, 0))) {
+ wl_cfgp2p_is_p2p_ie(&ie_buf[pos-2], NULL, 0) ||
+ wl_cfgp2p_is_wfd_ie(&ie_buf[pos-2], NULL, 0))) {
CFGP2P_INFO(("ADDED ID : %d, Len : %d , OUI :"
"%02x:%02x:%02x\n", ie_id, ie_len, ie_buf[pos],
ie_buf[pos+1], ie_buf[pos+2]));
@@ -1107,6 +1114,19 @@ wl_cfgp2p_find_p2pie(u8 *parse, u32 len)
return NULL;
}
+wifi_wfd_ie_t *
+wl_cfgp2p_find_wfdie(u8 *parse, u32 len)
+{
+ bcm_tlv_t *ie;
+
+ while ((ie = bcm_parse_tlvs(parse, (int)len, DOT11_MNG_VS_ID))) {
+ if (wl_cfgp2p_is_wfd_ie((uint8*)ie, &parse, &len)) {
+ return (wifi_wfd_ie_t *)ie;
+ }
+ }
+ return NULL;
+}
+
static s32
wl_cfgp2p_vndr_ie(struct wl_priv *wl, struct net_device *ndev, s32 bssidx, s32 pktflag,
s8 *oui, s32 ie_id, s8 *data, s32 data_len, s32 delete)
diff --git a/drivers/net/wireless/bcmdhd/wl_cfgp2p.h b/drivers/net/wireless/bcmdhd/wl_cfgp2p.h
index 05323ed..03a645a 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfgp2p.h
+++ b/drivers/net/wireless/bcmdhd/wl_cfgp2p.h
@@ -31,6 +31,8 @@
struct wl_priv;
extern u32 wl_dbg_level;
+typedef struct wifi_p2p_ie wifi_wfd_ie_t;
+
/* Enumeration of the usages of the BSSCFGs used by the P2P Library. Do not
* confuse this with a bsscfg index. This value is an index into the
* saved_ie[] array of structures which in turn contains a bsscfg index field.
@@ -192,6 +194,9 @@ wl_cfgp2p_find_wpsie(u8 *parse, u32 len);
extern wifi_p2p_ie_t *
wl_cfgp2p_find_p2pie(u8 *parse, u32 len);
+extern wifi_wfd_ie_t *
+wl_cfgp2p_find_wfdie(u8 *parse, u32 len);
+
extern s32
wl_cfgp2p_set_management_ie(struct wl_priv *wl, struct net_device *ndev, s32 bssidx,
s32 pktflag, const u8 *vndr_ie, u32 vndr_ie_len);
diff --git a/drivers/net/wireless/bcmdhd/wldev_common.c b/drivers/net/wireless/bcmdhd/wldev_common.c
index 51a8064..7bea3dc 100644
--- a/drivers/net/wireless/bcmdhd/wldev_common.c
+++ b/drivers/net/wireless/bcmdhd/wldev_common.c
@@ -334,8 +334,11 @@ int wldev_set_country(
scb_val_t scbval;
char smbuf[WLC_IOCTL_SMLEN];
- if (!country_code)
+ if (!country_code) {
+ WLDEV_ERROR(("%s: set country failed for %s\n",
+ __FUNCTION__, country_code));
return error;
+ }
error = wldev_iovar_getbuf(dev, "country", &cspec, sizeof(cspec),
smbuf, sizeof(smbuf), NULL);