aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Goldman <ggoldman@broadcom.com>2013-02-04 17:22:52 -0800
committerZiyan <jaraidaniel@gmail.com>2016-05-01 23:35:13 +0200
commitea65f9349bbbff1d0762293e08c4adf4b78a8cc3 (patch)
tree66f5847eb6673c7332c8bfb5cb37fbc46d7d65e7
parentffe8f8f92f172624b89ee43dff63bca88b95a9e3 (diff)
downloadkernel_samsung_tuna-ea65f9349bbbff1d0762293e08c4adf4b78a8cc3.zip
kernel_samsung_tuna-ea65f9349bbbff1d0762293e08c4adf4b78a8cc3.tar.gz
kernel_samsung_tuna-ea65f9349bbbff1d0762293e08c4adf4b78a8cc3.tar.bz2
net: wireless: bcmdhd: Update to Version 1.28-27
- Disable SDIO in-band interrupt explicitly to avoid problems with SDIO Host when generating SDIO Interrupt on DAT1 created unwanted CRC error - Fix handling when bcmsdh_probe() called twice - Fix handling the packet list properly in the corner cases - Remove unnecessary delay during P2P connection process - Fix issue finding peer with VSDB - Get AP beacon and DTIM to set proper DTIM skipping Change-Id: I7ee923727d0c3ad34c83b5ec1dda8e2aa5ea5834 Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
-rw-r--r--drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c8
-rw-r--r--drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c4
-rw-r--r--drivers/net/wireless/bcmdhd/dhd.h2
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_common.c29
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_linux.c6
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_sdio.c4
-rw-r--r--drivers/net/wireless/bcmdhd/include/epivers.h16
-rw-r--r--drivers/net/wireless/bcmdhd/wl_android.c4
-rw-r--r--drivers/net/wireless/bcmdhd/wl_cfg80211.c149
-rw-r--r--drivers/net/wireless/bcmdhd/wl_cfg80211.h2
-rw-r--r--drivers/net/wireless/bcmdhd/wldev_common.c28
-rw-r--r--drivers/net/wireless/bcmdhd/wldev_common.h3
12 files changed, 176 insertions, 79 deletions
diff --git a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c
index 180336a..046bd02 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 362913 2012-10-15 11:26:11Z $
+ * $Id: bcmsdh_sdmmc.c 379078 2013-01-16 00:41:36Z $
*/
#include <typedefs.h>
@@ -250,9 +250,9 @@ sdioh_enable_func_intr(void)
return SDIOH_API_RC_FAIL;
}
- /* Enable F1 and F2 interrupts, set master enable */
- reg |= (INTR_CTL_FUNC1_EN | INTR_CTL_FUNC2_EN | INTR_CTL_MASTER_EN);
-
+ /* Enable F1 and F2 interrupts, clear master enable */
+ reg &= ~INTR_CTL_MASTER_EN;
+ reg |= (INTR_CTL_FUNC1_EN | INTR_CTL_FUNC2_EN);
sdio_writeb(gInstance->func[0], reg, SDIOD_CCCR_INTEN, &err);
sdio_release_host(gInstance->func[0]);
diff --git a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c
index 079a89f..e913640 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 363783 2012-10-19 06:27:14Z $
+ * $Id: bcmsdh_sdmmc_linux.c 381548 2013-01-28 17:25:38Z $
*/
#include <typedefs.h>
@@ -136,6 +136,8 @@ static int bcmsdh_sdmmc_probe(struct sdio_func *func,
#endif
sd_trace(("F2 found, calling bcmsdh_probe...\n"));
ret = bcmsdh_probe(&func->dev);
+ if (ret < 0 && gInstance)
+ gInstance->func[2] = NULL;
}
} else {
ret = -ENODEV;
diff --git a/drivers/net/wireless/bcmdhd/dhd.h b/drivers/net/wireless/bcmdhd/dhd.h
index 8a1e3d2..8486616 100644
--- a/drivers/net/wireless/bcmdhd/dhd.h
+++ b/drivers/net/wireless/bcmdhd/dhd.h
@@ -683,6 +683,8 @@ extern uint dhd_force_tx_queueing;
#define CUSTOM_SUSPEND_BCN_LI_DTIM DEFAULT_SUSPEND_BCN_LI_DTIM
#endif
+#define MAX_DTIM_SKIP_BEACON_ITERVAL 100 /* max allowed associated AP beacon for dtim skip */
+
#ifdef SDTEST
/* Echo packet generator (SDIO), pkts/s */
extern uint dhd_pktgen;
diff --git a/drivers/net/wireless/bcmdhd/dhd_common.c b/drivers/net/wireless/bcmdhd/dhd_common.c
index 5b4c22a..bb76556 100644
--- a/drivers/net/wireless/bcmdhd/dhd_common.c
+++ b/drivers/net/wireless/bcmdhd/dhd_common.c
@@ -1637,11 +1637,10 @@ bool dhd_is_associated(dhd_pub_t *dhd, void *bss_buf, int *retval)
int
dhd_get_suspend_bcn_li_dtim(dhd_pub_t *dhd)
{
- int bcn_li_dtim;
+ int bcn_li_dtim = 1; /* deafult no dtim skip setting */
int ret = -1;
int dtim_assoc = 0;
-
- bcn_li_dtim = dhd->suspend_bcn_li_dtim;
+ int ap_beacon = 0;
/* Check if associated */
if (dhd_is_associated(dhd, NULL, NULL) == FALSE) {
@@ -1649,21 +1648,34 @@ dhd_get_suspend_bcn_li_dtim(dhd_pub_t *dhd)
goto exit;
}
- /* if assoc grab ap's dtim value */
+ /* read associated AP beacon interval */
+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_BCNPRD,
+ &ap_beacon, sizeof(ap_beacon), FALSE, 0)) < 0) {
+ DHD_ERROR(("%s get beacon failed code %d\n", __FUNCTION__, ret));
+ goto exit;
+ }
+
+ /* if associated APs Beacon more that 100msec do no dtim skip */
+ if (ap_beacon > MAX_DTIM_SKIP_BEACON_ITERVAL) {
+ DHD_ERROR(("%s NO dtim skip for AP with beacon %d ms\n", __FUNCTION__, ap_beacon));
+ goto exit;
+ }
+
+ /* read associated ap's dtim setup */
if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_DTIMPRD,
&dtim_assoc, sizeof(dtim_assoc), FALSE, 0)) < 0) {
DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret));
goto exit;
}
- DHD_ERROR(("%s bcn_li_dtim=%d DTIM=%d Listen=%d\n",
- __FUNCTION__, bcn_li_dtim, dtim_assoc, LISTEN_INTERVAL));
-
/* if not assocated just eixt */
if (dtim_assoc == 0) {
goto exit;
}
+ /* attemp to use platform defined dtim skip interval */
+ bcn_li_dtim = dhd->suspend_bcn_li_dtim;
+
/* check if sta listen interval fits into AP dtim */
if (dtim_assoc > LISTEN_INTERVAL) {
/* AP DTIM to big for our Listen Interval : no dtim skiping */
@@ -1679,6 +1691,9 @@ dhd_get_suspend_bcn_li_dtim(dhd_pub_t *dhd)
DHD_TRACE(("%s agjust dtim_skip as %d\n", __FUNCTION__, bcn_li_dtim));
}
+ DHD_ERROR(("%s beacon=%d bcn_li_dtim=%d DTIM=%d Listen=%d\n",
+ __FUNCTION__, ap_beacon, bcn_li_dtim, dtim_assoc, LISTEN_INTERVAL));
+
exit:
return bcn_li_dtim;
}
diff --git a/drivers/net/wireless/bcmdhd/dhd_linux.c b/drivers/net/wireless/bcmdhd/dhd_linux.c
index 39fae20..7682495 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 377078 2013-01-04 01:16:17Z $
+ * $Id: dhd_linux.c 380566 2013-01-23 05:29:02Z $
*/
#include <typedefs.h>
@@ -1645,6 +1645,8 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan)
if (ifp == NULL) {
DHD_ERROR(("%s: ifp is NULL. drop packet\n",
__FUNCTION__));
+ pnext = PKTNEXT(dhdp->osh, pktbuf);
+ PKTSETNEXT(wl->sh.osh, pktbuf, NULL);
PKTFREE(dhdp->osh, pktbuf, TRUE);
continue;
}
@@ -1657,6 +1659,8 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan)
#endif /* PROP_TXSTATUS_VSDB */
DHD_ERROR(("%s: net device is NOT registered yet. drop packet\n",
__FUNCTION__));
+ pnext = PKTNEXT(dhdp->osh, pktbuf);
+ PKTSETNEXT(wl->sh.osh, pktbuf, NULL);
PKTFREE(dhdp->osh, pktbuf, TRUE);
continue;
}
diff --git a/drivers/net/wireless/bcmdhd/dhd_sdio.c b/drivers/net/wireless/bcmdhd/dhd_sdio.c
index 42c1ab8..c634293 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 377078 2013-01-04 01:16:17Z $
+ * $Id: dhd_sdio.c 378263 2013-01-11 03:03:05Z $
*/
#include <typedefs.h>
@@ -4167,7 +4167,7 @@ dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex)
while (ready != enable && !dhd_timeout_expired(&tmo))
ready = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IORDY, NULL);
- DHD_INFO(("%s: enable 0x%02x, ready 0x%02x (waited %uus)\n",
+ DHD_ERROR(("%s: enable 0x%02x, ready 0x%02x (waited %uus)\n",
__FUNCTION__, enable, ready, tmo.elapsed));
diff --git a/drivers/net/wireless/bcmdhd/include/epivers.h b/drivers/net/wireless/bcmdhd/include/epivers.h
index b42819f..7f5a971 100644
--- a/drivers/net/wireless/bcmdhd/include/epivers.h
+++ b/drivers/net/wireless/bcmdhd/include/epivers.h
@@ -30,26 +30,26 @@
#define EPI_MINOR_VERSION 28
-#define EPI_RC_NUMBER 24
+#define EPI_RC_NUMBER 27
-#define EPI_INCREMENTAL_NUMBER 0
+#define EPI_INCREMENTAL_NUMBER 1
#define EPI_BUILD_NUMBER 0
-#define EPI_VERSION 1, 28, 24, 0
+#define EPI_VERSION 1, 28, 27, 1
-#define EPI_VERSION_NUM 0x011c1800
+#define EPI_VERSION_NUM 0x011c1b01
-#define EPI_VERSION_DEV 1.28.24
+#define EPI_VERSION_DEV 1.28.27
/* Driver Version String, ASCII, 32 chars max */
#ifdef BCMINTERNAL
-#define EPI_VERSION_STR "1.28.24 (r BCMINT)"
+#define EPI_VERSION_STR "1.28.27.1 (r BCMINT)"
#else
#ifdef WLTEST
-#define EPI_VERSION_STR "1.28.24 (r WLTEST)"
+#define EPI_VERSION_STR "1.28.27.1 (r WLTEST)"
#else
-#define EPI_VERSION_STR "1.28.24 (r)"
+#define EPI_VERSION_STR "1.28.27.1 (r)"
#endif
#endif /* BCMINTERNAL */
diff --git a/drivers/net/wireless/bcmdhd/wl_android.c b/drivers/net/wireless/bcmdhd/wl_android.c
index 4b3d88b..26f88e2 100644
--- a/drivers/net/wireless/bcmdhd/wl_android.c
+++ b/drivers/net/wireless/bcmdhd/wl_android.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: wl_android.c 374529 2012-12-13 14:24:13Z $
+ * $Id: wl_android.c 379859 2013-01-19 13:16:55Z $
*/
#include <linux/module.h>
@@ -590,7 +590,7 @@ int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)
#ifdef WL_CFG80211
else if (strnicmp(command, CMD_COUNTRY, strlen(CMD_COUNTRY)) == 0) {
char *country_code = command + strlen(CMD_COUNTRY) + 1;
- bytes_written = wldev_set_country(net, country_code, true);
+ bytes_written = wldev_set_country(net, country_code, true, true);
}
#endif /* WL_CFG80211 */
#if defined(PNO_SUPPORT) && !defined(WL_SCHED_SCAN)
diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.c b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
index db5f2cd..193dbe0 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfg80211.c
+++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.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: wl_cfg80211.c 376971 2013-01-03 14:06:06Z $
+ * $Id: wl_cfg80211.c 381665 2013-01-29 02:34:22Z $
*/
#include <typedefs.h>
@@ -331,8 +331,10 @@ static u32 wl_get_ielen(struct wl_priv *wl);
static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *dev);
static void wl_free_wdev(struct wl_priv *wl);
+#ifdef CONFIG_CFG80211_INTERNAL_REGDB
static int
wl_cfg80211_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request);
+#endif /* CONFIG_CFG80211_INTERNAL_REGDB */
static s32 wl_inform_bss(struct wl_priv *wl);
static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi, u8 is_roam_done);
@@ -3922,8 +3924,10 @@ wl_cfg80211_af_searching_channel(struct wl_priv *wl, struct net_device *dev)
wait_for_completion_timeout(&wl->act_frm_scan,
msecs_to_jiffies(MAX_WAIT_TIME));
}
- if (!wl_get_drv_status(wl, FINDING_COMMON_CHANNEL, dev))
+ if ((wl->afx_hdl->peer_chan != WL_INVALID) ||
+ !(wl_get_drv_status(wl, FINDING_COMMON_CHANNEL, dev)))
break;
+
wl->afx_hdl->retry++;
WL_AF_TX_KEEP_PRI_CONNECTION_VSDB(wl);
@@ -4189,14 +4193,16 @@ wl_cfg80211_send_action_frame(struct wiphy *wiphy, struct net_device *dev,
goto exit;
}
+ wl_clr_drv_status(wl, SCANNING, wl->afx_hdl->dev);
+ /*
+ * Abort scan even for VSDB scenarios. Scan gets aborted in firmware
+ * but after the check of piggyback algorithm.
+ * To take care of current piggback algo, lets abort the scan here itself.
+ */
+ wl_notify_escan_complete(wl, dev, true, true);
/* Suspend P2P discovery's search-listen to prevent it from
* starting a scan or changing the channel.
*/
- wl_clr_drv_status(wl, SCANNING, wl->afx_hdl->dev);
-/* Do not abort scan for VSDB. Scan will be aborted in firmware if necessary */
-#ifndef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
- wl_notify_escan_complete(wl, dev, true, true);
-#endif /* not WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */
wl_cfgp2p_discover_enable_search(wl, false);
/* update channel */
@@ -4275,6 +4281,7 @@ exit:
return ack;
}
+#define MAX_NUM_OF_ASSOCIATED_DEV 64
static s32
wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *ndev,
struct ieee80211_channel *channel, bool offchan,
@@ -4344,6 +4351,20 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *ndev,
goto exit;
} else if (ieee80211_is_disassoc(mgmt->frame_control) ||
ieee80211_is_deauth(mgmt->frame_control)) {
+ char mac_buf[MAX_NUM_OF_ASSOCIATED_DEV *
+ sizeof(struct ether_addr) + sizeof(uint)] = {0};
+ int num_associated = 0;
+ struct maclist *assoc_maclist = (struct maclist *)mac_buf;
+ if (!bcmp((const uint8 *)BSSID_BROADCAST,
+ (const struct ether_addr *)mgmt->da, ETHER_ADDR_LEN)) {
+ assoc_maclist->count = MAX_NUM_OF_ASSOCIATED_DEV;
+ err = wldev_ioctl(ndev, WLC_GET_ASSOCLIST,
+ assoc_maclist, sizeof(mac_buf), false);
+ if (err < 0)
+ WL_ERR(("WLC_GET_ASSOCLIST error %d\n", err));
+ else
+ num_associated = assoc_maclist->count;
+ }
memcpy(scb_val.ea.octet, mgmt->da, ETH_ALEN);
scb_val.val = mgmt->u.disassoc.reason_code;
err = wldev_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scb_val,
@@ -4353,7 +4374,9 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *ndev,
WL_DBG(("Disconnect STA : %s scb_val.val %d\n",
bcm_ether_ntoa((const struct ether_addr *)mgmt->da, eabuf),
scb_val.val));
- wl_delay(400);
+ if (num_associated) {
+ wl_delay(400);
+ }
cfg80211_mgmt_tx_status(ndev, *cookie, buf, len, true, GFP_KERNEL);
goto exit;
@@ -5104,20 +5127,14 @@ exit:
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
s32
-wl_cfg80211_parse_set_ies(
+wl_cfg80211_parse_ap_ies(
struct net_device *dev,
struct cfg80211_beacon_data *info,
- struct parsed_ies *ies,
- u32 dev_role,
- s32 bssidx)
+ struct parsed_ies *ies)
{
- struct wl_priv *wl = wlcfg_drv_priv;
struct parsed_ies prb_ies;
s32 err = BCME_OK;
- memset(ies, 0, sizeof(struct parsed_ies));
- memset(&prb_ies, 0, sizeof(struct parsed_ies));
-
/* Parse Beacon IEs */
if (wl_cfg80211_parse_ies((u8 *)info->tail,
info->tail_len, ies) < 0) {
@@ -5126,6 +5143,27 @@ wl_cfg80211_parse_set_ies(
goto fail;
}
+ /* Parse Probe Response IEs */
+ if (wl_cfg80211_parse_ies((u8 *)info->proberesp_ies,
+ info->proberesp_ies_len, &prb_ies) < 0) {
+ WL_ERR(("PROBE RESP get IEs failed \n"));
+ err = -EINVAL;
+ }
+
+fail:
+
+ return err;
+}
+
+s32
+wl_cfg80211_set_ies(
+ struct net_device *dev,
+ struct cfg80211_beacon_data *info,
+ s32 bssidx)
+{
+ struct wl_priv *wl = wlcfg_drv_priv;
+ s32 err = BCME_OK;
+
/* Set Beacon IEs to FW */
if ((err = wl_cfgp2p_set_management_ie(wl, dev, bssidx,
VNDR_IE_BEACON_FLAG, (u8 *)info->tail,
@@ -5135,14 +5173,6 @@ wl_cfg80211_parse_set_ies(
WL_DBG(("Applied Vndr IEs for Beacon \n"));
}
- /* Parse Probe Response IEs */
- if (wl_cfg80211_parse_ies((u8 *)info->proberesp_ies,
- info->proberesp_ies_len, &prb_ies) < 0) {
- WL_ERR(("PRB RESP get IEs failed \n"));
- err = -EINVAL;
- goto fail;
- }
-
/* Set Probe Response IEs to FW */
if ((err = wl_cfgp2p_set_management_ie(wl, dev, bssidx,
VNDR_IE_PRBRSP_FLAG, (u8 *)info->proberesp_ies,
@@ -5152,8 +5182,6 @@ wl_cfg80211_parse_set_ies(
WL_DBG(("Applied Vndr IEs for Probe Resp \n"));
}
-fail:
-
return err;
}
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0) */
@@ -5236,6 +5264,10 @@ wl_cfg80211_del_station(
struct wl_priv *wl = wiphy_priv(wiphy);
scb_val_t scb_val;
s8 eabuf[ETHER_ADDR_STR_LEN];
+ char mac_buf[MAX_NUM_OF_ASSOCIATED_DEV *
+ sizeof(struct ether_addr) + sizeof(uint)] = {0};
+ struct maclist *assoc_maclist = (struct maclist *)mac_buf;
+ int num_associated = 0, err;
WL_DBG(("Entry\n"));
if (mac_addr == NULL) {
@@ -5259,15 +5291,25 @@ wl_cfg80211_del_station(
}
}
+ assoc_maclist->count = MAX_NUM_OF_ASSOCIATED_DEV;
+ err = wldev_ioctl(ndev, WLC_GET_ASSOCLIST,
+ assoc_maclist, sizeof(mac_buf), false);
+ if (err < 0)
+ WL_ERR(("WLC_GET_ASSOCLIST error %d\n", err));
+ else
+ num_associated = assoc_maclist->count;
+
memcpy(scb_val.ea.octet, mac_addr, ETHER_ADDR_LEN);
scb_val.val = DOT11_RC_DEAUTH_LEAVING;
- if (wldev_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scb_val,
- sizeof(scb_val_t), true))
- WL_ERR(("WLC_SCB_DEAUTHENTICATE_FOR_REASON failed\n"));
+ err = wldev_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scb_val,
+ sizeof(scb_val_t), true);
+ if (err < 0)
+ WL_ERR(("WLC_SCB_DEAUTHENTICATE_FOR_REASON err %d\n", err));
WL_DBG(("Disconnect STA : %s scb_val.val %d\n",
bcm_ether_ntoa((const struct ether_addr *)mac_addr, eabuf),
scb_val.val));
- wl_delay(400);
+ if (num_associated)
+ wl_delay(400);
return 0;
}
@@ -5309,9 +5351,8 @@ wl_cfg80211_start_ap(
goto fail;
}
- /* Set IEs to FW */
- if ((err = wl_cfg80211_parse_set_ies(dev, &info->beacon,
- &ies, dev_role, bssidx) < 0)) {
+ /* Parse IEs */
+ if ((err = wl_cfg80211_parse_ap_ies(dev, &info->beacon, &ies) < 0)) {
WL_ERR(("Set IEs failed \n"));
goto fail;
}
@@ -5331,6 +5372,10 @@ wl_cfg80211_start_ap(
WL_DBG(("** AP/GO Created **\n"));
+ /* Set IEs to FW */
+ if ((err = wl_cfg80211_set_ies(dev, &info->beacon, bssidx) < 0))
+ WL_ERR(("Set IEs failed \n"));
+
fail:
if (err) {
WL_ERR(("ADD/SET beacon failed\n"));
@@ -5430,9 +5475,14 @@ wl_cfg80211_change_beacon(
dev_role = NL80211_IFTYPE_P2P_GO;
}
+ /* Parse IEs */
+ if ((err = wl_cfg80211_parse_ap_ies(dev, info, &ies) < 0)) {
+ WL_ERR(("Parse IEs failed \n"));
+ goto fail;
+ }
+
/* Set IEs to FW */
- if ((err = wl_cfg80211_parse_set_ies(dev, info,
- &ies, dev_role, bssidx) < 0)) {
+ if ((err = wl_cfg80211_set_ies(dev, info, bssidx) < 0)) {
WL_ERR(("Set IEs failed \n"));
goto fail;
}
@@ -5733,6 +5783,11 @@ s32 wl_mode_to_nl80211_iftype(s32 mode)
return err;
}
+/* Kernel Network Support->Wireless->Regulatory rules database
+ options should be enabled and regulatory CRDA regdb table populated in Kernel
+ for proper country reg notification
+*/
+#ifdef CONFIG_CFG80211_INTERNAL_REGDB
static int
wl_cfg80211_reg_notifier(
struct wiphy *wiphy,
@@ -5749,20 +5804,30 @@ wl_cfg80211_reg_notifier(
WL_DBG(("ccode: %c%c Initiator: %d\n",
request->alpha2[0], request->alpha2[1], request->initiator));
- /* We support only REGDOM_SET_BY_USER as of now */
- if (request->initiator != NL80211_REGDOM_SET_BY_USER) {
- WL_ERR(("reg_notifier for intiator:%d not supported \n",
+ /* We support only REGDOM_SET_BY_USER and by
+ NL80211_REGDOM_SET_BY_COUNTRY_IE (11d) right now
+ */
+ if ((request->initiator != NL80211_REGDOM_SET_BY_USER) &&
+ (request->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE)) {
+ WL_ERR(("reg_notifier for intiator:%d not supported : set default\n",
request->initiator));
- return -ENOTSUPP;
+ /* in case of no supported country by regdb
+ lets driver setup platform default Locale
+ */
}
+ WL_ERR(("Set country code %c%c from %s\n",
+ request->alpha2[0], request->alpha2[1],
+ ((request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) ? " 11d AP" : "User")));
+
if ((ret = wldev_set_country(wl_to_prmry_ndev(wl), request->alpha2,
- false)) < 0) {
+ false, (request->initiator == NL80211_REGDOM_SET_BY_USER ? true : false))) < 0) {
WL_ERR(("set country Failed :%d\n", ret));
}
return ret;
}
+#endif /* CONFIG_CFG80211_INTERNAL_REGDB */
static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev)
{
@@ -5833,7 +5898,9 @@ static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev
wdev->wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME;
#endif
+#ifdef CONFIG_CFG80211_INTERNAL_REGDB
wdev->wiphy->reg_notifier = wl_cfg80211_reg_notifier;
+#endif /* CONFIG_CFG80211_INTERNAL_REGDB */
WL_DBG(("Registering custom regulatory)\n"));
wdev->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
@@ -7760,7 +7827,7 @@ static s32 wl_escan_handler(struct wl_priv *wl,
p2p_dev_addr = wl_cfgp2p_retreive_p2p_dev_addr(bi, bi_length);
if (p2p_dev_addr && !memcmp(p2p_dev_addr,
wl->afx_hdl->tx_dst_addr.octet, ETHER_ADDR_LEN)) {
- s32 channel = CHSPEC_CHANNEL(
+ s32 channel = wf_chspec_ctlchan(
wl_chspec_driver_to_host(bi->chanspec));
WL_DBG(("ACTION FRAME SCAN : Peer " MACDBG " found, channel : %d\n",
MAC2STRDBG(wl->afx_hdl->tx_dst_addr.octet), channel));
diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.h b/drivers/net/wireless/bcmdhd/wl_cfg80211.h
index aaab95b..fc30089 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfg80211.h
+++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.h
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: wl_cfg80211.h 374275 2012-12-12 11:44:18Z $
+ * $Id: wl_cfg80211.h 378667 2013-01-14 10:11:50Z $
*/
#ifndef _wl_cfg80211_h_
diff --git a/drivers/net/wireless/bcmdhd/wldev_common.c b/drivers/net/wireless/bcmdhd/wldev_common.c
index 639a4d3..18008e0 100644
--- a/drivers/net/wireless/bcmdhd/wldev_common.c
+++ b/drivers/net/wireless/bcmdhd/wldev_common.c
@@ -335,7 +335,7 @@ int wldev_set_band(
}
int wldev_set_country(
- struct net_device *dev, char *country_code, bool notify)
+ struct net_device *dev, char *country_code, bool notify, bool user_enforced)
{
int error = -1;
wl_country_t cspec = {{0}, 0, {0}};
@@ -345,20 +345,26 @@ int wldev_set_country(
if (!country_code)
return error;
- error = wldev_iovar_getbuf(dev, "country", &cspec, sizeof(cspec),
- smbuf, sizeof(smbuf), NULL);
- if (error < 0)
+ bzero(&scbval, sizeof(scb_val_t));
+ error = wldev_iovar_getbuf(dev, "country", NULL, 0, &cspec, sizeof(cspec), NULL);
+ if (error < 0) {
WLDEV_ERROR(("%s: get country failed = %d\n", __FUNCTION__, error));
+ return error;
+ }
if ((error < 0) ||
- (strncmp(country_code, smbuf, WLC_CNTRY_BUF_SZ) != 0)) {
- bzero(&scbval, sizeof(scb_val_t));
- error = wldev_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t), true);
- if (error < 0) {
- WLDEV_ERROR(("%s: set country failed due to Disassoc error %d\n",
- __FUNCTION__, error));
- return error;
+ (strncmp(country_code, cspec.ccode, WLC_CNTRY_BUF_SZ) != 0)) {
+
+ if (user_enforced) {
+ bzero(&scbval, sizeof(scb_val_t));
+ error = wldev_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t), true);
+ if (error < 0) {
+ WLDEV_ERROR(("%s: set country failed due to Disassoc error %d\n",
+ __FUNCTION__, error));
+ return error;
+ }
}
+
cspec.rev = -1;
memcpy(cspec.country_abbrev, country_code, WLC_CNTRY_BUF_SZ);
memcpy(cspec.ccode, country_code, WLC_CNTRY_BUF_SZ);
diff --git a/drivers/net/wireless/bcmdhd/wldev_common.h b/drivers/net/wireless/bcmdhd/wldev_common.h
index 15c3f02..e63620f 100644
--- a/drivers/net/wireless/bcmdhd/wldev_common.h
+++ b/drivers/net/wireless/bcmdhd/wldev_common.h
@@ -86,7 +86,8 @@ s32 wldev_iovar_setint_bsscfg(
extern void get_customized_country_code(char *country_iso_code, wl_country_t *cspec);
extern void dhd_bus_country_set(struct net_device *dev, wl_country_t *cspec, bool notify);
extern void dhd_bus_band_set(struct net_device *dev, uint band);
-extern int wldev_set_country(struct net_device *dev, char *country_code, bool notify);
+extern int wldev_set_country(struct net_device *dev, char *country_code, bool notify,
+ bool user_enforced);
extern int net_os_wake_lock(struct net_device *dev);
extern int net_os_wake_unlock(struct net_device *dev);
extern int net_os_wake_lock_timeout(struct net_device *dev);