diff --git a/drivers/wireless/ieee80211/bcm43xxx/Kconfig b/drivers/wireless/ieee80211/bcm43xxx/Kconfig index fc4a504e3a..4d5f57c95e 100644 --- a/drivers/wireless/ieee80211/bcm43xxx/Kconfig +++ b/drivers/wireless/ieee80211/bcm43xxx/Kconfig @@ -138,6 +138,12 @@ config IEEE80211_BROADCOM_LOWPOWER ---help--- This parameter should be enable the bcmf lower power mode +config IEEE80211_BROADCOM_DEFAULT_COUNTRY + string "Broadcom BCMF default country code" + default "" + ---help--- + This parameter should be set the default country code + if IEEE80211_BROADCOM_LOWPOWER config IEEE80211_BROADCOM_LOWPOWER_TIMEOUT diff --git a/drivers/wireless/ieee80211/bcm43xxx/bcmf_driver.c b/drivers/wireless/ieee80211/bcm43xxx/bcmf_driver.c index a7b4a4a5ad..ab604b1bff 100644 --- a/drivers/wireless/ieee80211/bcm43xxx/bcmf_driver.c +++ b/drivers/wireless/ieee80211/bcm43xxx/bcmf_driver.c @@ -1744,3 +1744,40 @@ int bcmf_wl_get_ssid(FAR struct bcmf_dev_s *priv, struct iwreq *iwr) return ret; } + +int bcmf_wl_set_country_code(FAR struct bcmf_dev_s *priv, + int interface, FAR void *code) +{ + uint8_t country[4] = + { + 0 + }; + + uint32_t out_len; + + memcpy(country, code, 2); + + /* Why out_len = 4 ? Padding bytes to ensure array is + * terminating with null byte + */ + + out_len = sizeof(country); + + return bcmf_cdc_iovar_request(priv, interface, true, + IOVAR_STR_COUNTRY, country, + &out_len); +} + +int bcmf_wl_set_country(FAR struct bcmf_dev_s *priv, FAR struct iwreq *iwr) +{ + int interface; + + interface = bcmf_wl_get_interface(priv, iwr); + + if (interface < 0) + { + return -EINVAL; + } + + return bcmf_wl_set_country_code(priv, interface, iwr->u.data.pointer); +} diff --git a/drivers/wireless/ieee80211/bcm43xxx/bcmf_driver.h b/drivers/wireless/ieee80211/bcm43xxx/bcmf_driver.h index 56c10f88f7..1d8a4fc18e 100644 --- a/drivers/wireless/ieee80211/bcm43xxx/bcmf_driver.h +++ b/drivers/wireless/ieee80211/bcm43xxx/bcmf_driver.h @@ -148,6 +148,9 @@ int bcmf_wl_active(FAR struct bcmf_dev_s *priv, bool active); int bcmf_wl_set_pm(FAR struct bcmf_dev_s *priv, int mode); +int bcmf_wl_set_country_code(FAR struct bcmf_dev_s *priv, + int interface, FAR void *code); + /* IOCTLs AP scan interface implementation */ int bcmf_wl_start_scan(FAR struct bcmf_dev_s *priv, struct iwreq *iwr); @@ -179,4 +182,6 @@ int bcmf_wl_get_rssi(FAR struct bcmf_dev_s *priv, struct iwreq *iwr); int bcmf_wl_get_iwrange(FAR struct bcmf_dev_s *priv, struct iwreq *iwr); +int bcmf_wl_set_country(FAR struct bcmf_dev_s *priv, struct iwreq *iwr); + #endif /* __DRIVERS_WIRELESS_IEEE80211_BCM43XXX_BCMF_DRIVER_H */ diff --git a/drivers/wireless/ieee80211/bcm43xxx/bcmf_netdev.c b/drivers/wireless/ieee80211/bcm43xxx/bcmf_netdev.c index a2476f1806..e02c38379a 100644 --- a/drivers/wireless/ieee80211/bcm43xxx/bcmf_netdev.c +++ b/drivers/wireless/ieee80211/bcm43xxx/bcmf_netdev.c @@ -695,6 +695,12 @@ static int bcmf_ifup(FAR struct net_driver_s *dev) goto errout_in_wl_active; } + if (strnlen(CONFIG_IEEE80211_BROADCOM_DEFAULT_COUNTRY, 2) == 2) + { + bcmf_wl_set_country_code(priv, CHIP_STA_INTERFACE, + CONFIG_IEEE80211_BROADCOM_DEFAULT_COUNTRY); + } + /* Instantiate MAC address from priv->bc_dev.d_mac.ether.ether_addr_octet */ #ifdef CONFIG_NET_ICMPv6 @@ -1127,6 +1133,10 @@ static int bcmf_ioctl(FAR struct net_driver_s *dev, int cmd, ret = bcmf_wl_get_iwrange(priv, (struct iwreq *)arg); break; + case SIOCSIWCOUNTRY: /* Set country code */ + ret = bcmf_wl_set_country(priv, (struct iwreq *)arg); + break; + default: nerr("ERROR: Unrecognized IOCTL command: %x\n", cmd); ret = -ENOTTY; /* Special return value for this case */