diff options
author | Greg Goldman <ggoldman@broadcom.com> | 2013-02-04 17:22:52 -0800 |
---|---|---|
committer | Ziyan <jaraidaniel@gmail.com> | 2016-05-01 23:35:13 +0200 |
commit | ea65f9349bbbff1d0762293e08c4adf4b78a8cc3 (patch) | |
tree | 66f5847eb6673c7332c8bfb5cb37fbc46d7d65e7 | |
parent | ffe8f8f92f172624b89ee43dff63bca88b95a9e3 (diff) | |
download | kernel_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.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/bcmdhd/dhd.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/bcmdhd/dhd_common.c | 29 | ||||
-rw-r--r-- | drivers/net/wireless/bcmdhd/dhd_linux.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/bcmdhd/dhd_sdio.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/bcmdhd/include/epivers.h | 16 | ||||
-rw-r--r-- | drivers/net/wireless/bcmdhd/wl_android.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/bcmdhd/wl_cfg80211.c | 149 | ||||
-rw-r--r-- | drivers/net/wireless/bcmdhd/wl_cfg80211.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/bcmdhd/wldev_common.c | 28 | ||||
-rw-r--r-- | drivers/net/wireless/bcmdhd/wldev_common.h | 3 |
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); |