summaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
authorDmitry Shmidt <dimitrysh@google.com>2012-07-11 17:39:51 -0700
committerVarun Wadekar <vwadekar@nvidia.com>2012-07-13 17:07:30 +0530
commit566a38e51de6086128e1bd4ec4a5dff0480adc84 (patch)
treec8a042bf39e2e8ec0a5f311f71182a87aafbaf49 /drivers/net
parente427c9d851f40445afe5bb3986c6fb7df8fcbf34 (diff)
net: wireless: bcmdhd: Update wiphy bands on country and band change
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_linux.c17
-rw-r--r--drivers/net/wireless/bcmdhd/wl_cfg80211.c39
-rw-r--r--drivers/net/wireless/bcmdhd/wldev_common.c29
-rw-r--r--drivers/net/wireless/bcmdhd/wldev_common.h1
4 files changed, 59 insertions, 27 deletions
diff --git a/drivers/net/wireless/bcmdhd/dhd_linux.c b/drivers/net/wireless/bcmdhd/dhd_linux.c
index 25733977544b..243d8e4def9f 100644
--- a/drivers/net/wireless/bcmdhd/dhd_linux.c
+++ b/drivers/net/wireless/bcmdhd/dhd_linux.c
@@ -4917,8 +4917,23 @@ void dhd_bus_country_set(struct net_device *dev, wl_country_t *cspec)
{
dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
- if (dhd && dhd->pub.up)
+ if (dhd && dhd->pub.up) {
memcpy(&dhd->pub.dhd_cspec, cspec, sizeof(wl_country_t));
+#ifdef WL_CFG80211
+ wl_update_wiphybands(NULL);
+#endif
+ }
+}
+
+void dhd_bus_band_set(struct net_device *dev, uint band)
+{
+ dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+
+ if (dhd && dhd->pub.up) {
+#ifdef WL_CFG80211
+ wl_update_wiphybands(NULL);
+#endif
+ }
}
void dhd_net_if_lock(struct net_device *dev)
diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.c b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
index 47cfb9a58210..81aa7fb45794 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfg80211.c
+++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
@@ -8005,7 +8005,6 @@ static int wl_construct_reginfo(struct wl_priv *wl, s32 bw_cap)
#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
band_chan_arr[index].center_freq =
ieee80211_channel_to_frequency(channel);
- (void)band;
#else
band_chan_arr[index].center_freq =
ieee80211_channel_to_frequency(channel, band);
@@ -8071,18 +8070,23 @@ s32 wl_update_wiphybands(struct wl_priv *wl)
s32 err = 0;
s32 index = 0;
s32 nmode = 0;
+ bool rollback_lock = false;
s32 bw_cap = 0;
s32 cur_band = -1;
- if (wl == NULL)
+
+ if (wl == NULL) {
wl = wlcfg_drv_priv;
+ mutex_lock(&wl->usr_sync);
+ rollback_lock = true;
+ }
dev = wl_to_prmry_ndev(wl);
memset(bandlist, 0, sizeof(bandlist));
err = wldev_ioctl(dev, WLC_GET_BANDLIST, bandlist,
sizeof(bandlist), false);
if (unlikely(err)) {
- WL_ERR(("error (%d)\n", err));
- return err;
+ WL_ERR(("error read bandlist (%d)\n", err));
+ goto end_bands;
}
wiphy = wl_to_wiphy(wl);
wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
@@ -8092,24 +8096,29 @@ s32 wl_update_wiphybands(struct wl_priv *wl)
sizeof(s32), false);
if (unlikely(err)) {
WL_ERR(("error (%d)\n", err));
- return err;
+ goto end_bands;
}
err = wldev_iovar_getint(dev, "nmode", &nmode);
- if (err) {
- return err;
- }
-
- err = wldev_iovar_getint(dev, "mimo_bw_cap", &bw_cap);
- if (err) {
- return err;
+ if (unlikely(err)) {
+ WL_ERR(("error reading nmode (%d)\n", err));
+ } else {
+ /* For nmodeonly check bw cap */
+ err = wldev_iovar_getint(dev, "mimo_bw_cap", &bw_cap);
+ if (unlikely(err)) {
+ WL_ERR(("error get mimo_bw_cap (%d)\n", err));
+ }
}
err = wl_construct_reginfo(wl, bw_cap);
if (err) {
WL_ERR(("wl_construct_reginfo() fails err=%d\n", err));
- return err;
+ if (err != BCME_UNSUPPORTED)
+ goto end_bands;
+ /* Ignore error if "chanspecs" command is not supported */
+ err = 0;
}
+
if ((cur_band == WLC_BAND_2G) ||
(cur_band == WLC_BAND_5G)) {
bandlist[0] = 1;
@@ -8145,6 +8154,10 @@ s32 wl_update_wiphybands(struct wl_priv *wl)
}
wiphy_apply_custom_regulatory(wiphy, &brcm_regdom);
+
+end_bands:
+ if (rollback_lock)
+ mutex_unlock(&wl->usr_sync);
return err;
}
diff --git a/drivers/net/wireless/bcmdhd/wldev_common.c b/drivers/net/wireless/bcmdhd/wldev_common.c
index 67a19d6d6f5b..c964552b9454 100644
--- a/drivers/net/wireless/bcmdhd/wldev_common.c
+++ b/drivers/net/wireless/bcmdhd/wldev_common.c
@@ -328,6 +328,8 @@ int wldev_set_band(
if ((band == WLC_BAND_AUTO) || (band == WLC_BAND_5G) || (band == WLC_BAND_2G)) {
error = wldev_ioctl(dev, WLC_SET_BAND, &band, sizeof(band), 1);
+ if (!error)
+ dhd_bus_band_set(dev, band);
}
return error;
}
@@ -357,20 +359,21 @@ int wldev_set_country(
__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);
- get_customized_country_code((char *)&cspec.country_abbrev, &cspec);
- error = wldev_iovar_setbuf(dev, "country", &cspec, sizeof(cspec),
- smbuf, sizeof(smbuf), NULL);
- if (error < 0) {
- WLDEV_ERROR(("%s: set country for %s as %s rev %d failed\n",
+
+ cspec.rev = -1;
+ memcpy(cspec.country_abbrev, country_code, WLC_CNTRY_BUF_SZ);
+ memcpy(cspec.ccode, country_code, WLC_CNTRY_BUF_SZ);
+ get_customized_country_code((char *)&cspec.country_abbrev, &cspec);
+ error = wldev_iovar_setbuf(dev, "country", &cspec, sizeof(cspec),
+ smbuf, sizeof(smbuf), NULL);
+ if (error < 0) {
+ WLDEV_ERROR(("%s: set country for %s as %s rev %d failed\n",
+ __FUNCTION__, country_code, cspec.ccode, cspec.rev));
+ return error;
+ }
+ dhd_bus_country_set(dev, &cspec);
+ WLDEV_ERROR(("%s: set country for %s as %s rev %d\n",
__FUNCTION__, country_code, cspec.ccode, cspec.rev));
- return error;
}
- dhd_bus_country_set(dev, &cspec);
- WLDEV_ERROR(("%s: set country for %s as %s rev %d\n",
- __FUNCTION__, country_code, cspec.ccode, cspec.rev));
return 0;
}
diff --git a/drivers/net/wireless/bcmdhd/wldev_common.h b/drivers/net/wireless/bcmdhd/wldev_common.h
index 344db0f26dbc..49652af3e60d 100644
--- a/drivers/net/wireless/bcmdhd/wldev_common.h
+++ b/drivers/net/wireless/bcmdhd/wldev_common.h
@@ -86,6 +86,7 @@ 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);
extern int wldev_set_country(struct net_device *dev, char *country_code);
+extern void dhd_bus_band_set(struct net_device *dev, uint band);
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);