wlan: Add routines to support CRDA
Add support for CRDA regulatory functionality
Change-Id: I544678c343af5882328642b17af7b2cb4ff32633
CR-Fixed: NA
diff --git a/CORE/HDD/inc/wlan_hdd_cfg.h b/CORE/HDD/inc/wlan_hdd_cfg.h
index 8b1797e..de7678e 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg.h
@@ -373,6 +373,11 @@
#define CFG_INTF3_MAC_ADDR_MAX "ffffffffffff"
#define CFG_INTF3_MAC_ADDR_DEFAULT "000AF5898983"
+#define CFG_CRDA_DEFAULT_COUNTRY_CODE "gCrdaDefaultCountryCode"
+#define CFG_CRDA_DEFAULT_COUNTRY_CODE_MIN "00"
+#define CFG_CRDA_DEFAULT_COUNTRY_CODE_MAX "ZZ"
+#define CFG_CRDA_DEFAULT_COUNTRY_CODE_DEFAULT "ZZ"
+
#ifdef WLAN_SOFTAP_FEATURE
#define CFG_AP_QOS_UAPSD_MODE_NAME "gEnableApUapsd" // ACs to setup U-APSD for at assoc
#define CFG_AP_QOS_UAPSD_MODE_MIN ( 0 )
@@ -1412,6 +1417,7 @@
v_U8_t intfAddrMask;
v_MACADDR_t intfMacAddr[VOS_MAX_CONCURRENCY_PERSONA];
+ v_U8_t crdaDefaultCountryCode [3];
#ifdef WLAN_SOFTAP_FEATURE
v_BOOL_t apUapsdEnabled;
diff --git a/CORE/HDD/inc/wlan_hdd_cfg80211.h b/CORE/HDD/inc/wlan_hdd_cfg80211.h
index eb7d44c..122f156 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg80211.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg80211.h
@@ -95,6 +95,8 @@
void wlan_hdd_cfg80211_pre_voss_stop(hdd_adapter_t* pAdapter);
+int wlan_hdd_crda_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request);
+int wlan_hdd_get_crda_regd_entry(struct wiphy *wiphy, hdd_config_t *pCfg);
#endif // CONFIG_CFG80211
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index a4cb046..2430cc9 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -100,6 +100,9 @@
#define WLAN_WAIT_TIME_SESSIONOPENCLOSE 15000
#define WLAN_WAIT_TIME_ABORTSCAN 2000
+/* Maximum time to get crda entry settings */
+#define CRDA_WAIT_TIME 300
+
/* Scan Req Timeout */
#define WLAN_WAIT_TIME_SCAN_REQ 100
@@ -822,6 +825,8 @@
/* Completion variable to indicate Mc Thread Suspended */
struct completion mc_sus_event_var;
+ /* Completion variable to wlan_hdd_get_crda_regd_entry */
+ struct completion driver_crda_req;
v_BOOL_t isWlanSuspended;
@@ -959,6 +964,7 @@
#ifdef CONFIG_CFG80211
void wlan_hdd_set_monitor_tx_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter );
void hdd_cleanup_actionframe( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter );
+v_BOOL_t is_crda_regulatory_entry_valid(void);
#endif
void wlan_hdd_set_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode);
void wlan_hdd_clear_concurrency_mode(hdd_context_t *pHddCtx, tVOS_CON_MODE mode);
diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c
index 3ad2c46..10eacc3 100644
--- a/CORE/HDD/src/wlan_hdd_cfg.c
+++ b/CORE/HDD/src/wlan_hdd_cfg.c
@@ -444,6 +444,11 @@
VAR_FLAGS_OPTIONAL,
(void *)CFG_INTF3_MAC_ADDR_DEFAULT ),
+ REG_VARIABLE_STRING( CFG_CRDA_DEFAULT_COUNTRY_CODE, WLAN_PARAM_String,
+ hdd_config_t, crdaDefaultCountryCode,
+ VAR_FLAGS_OPTIONAL,
+ (void *)CFG_CRDA_DEFAULT_COUNTRY_CODE_DEFAULT ),
+
#ifdef WLAN_SOFTAP_FEATURE
REG_VARIABLE( CFG_AP_QOS_UAPSD_MODE_NAME , WLAN_PARAM_Integer,
hdd_config_t, apUapsdEnabled,
@@ -3013,6 +3018,8 @@
pConfig->WmmMode, pConfig->b80211eIsEnabled, pConfig->dot11Mode);
// Config params obtained from the registry
+ if (is_crda_regulatory_entry_valid() == VOS_TRUE)
+ sme_setRegInfo(pHddCtx->hHal, pConfig->crdaDefaultCountryCode);
smeConfig.csrConfig.RTSThreshold = pConfig->RTSThreshold;
smeConfig.csrConfig.FragmentationThreshold = pConfig->FragmentationThreshold;
smeConfig.csrConfig.shortSlotTime = pConfig->ShortSlotTimeEnabled;
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index b645567..58abfee 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -166,6 +166,13 @@
static struct ieee80211_channel hdd_channels_5_GHZ[] =
{
+ HDD5GHZCHAN(4920, 240, 0) ,
+ HDD5GHZCHAN(4940, 244, 0) ,
+ HDD5GHZCHAN(4960, 248, 0) ,
+ HDD5GHZCHAN(4980, 252, 0) ,
+ HDD5GHZCHAN(5040, 208, 0) ,
+ HDD5GHZCHAN(5060, 212, 0) ,
+ HDD5GHZCHAN(5080, 216, 0) ,
HDD5GHZCHAN(5180, 36, 0) ,
HDD5GHZCHAN(5200, 40, 0) ,
HDD5GHZCHAN(5220, 44, 0) ,
@@ -458,6 +465,12 @@
wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
| WIPHY_FLAG_OFFCHAN_TX;
#endif
+ /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
+ driver can still register regulatory callback and
+ it will get CRDA setting in wiphy->band[], but
+ driver need to determine what to do with both
+ regulatory settings */
+ wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
wiphy->max_scan_ssids = MAX_SCAN_SSID;
@@ -533,6 +546,26 @@
return 0;
}
+/* In this function we will try to get default country code from crda.
+ If the gCrdaDefaultCountryCode is configured in ini file,
+ we will try to call user space crda to get the regulatory settings for
+ that country. We will timeout if we can't get it from crda.
+ It's called by hdd_wlan_startup() after wlan_hdd_cfg80211_register.
+*/
+int wlan_hdd_get_crda_regd_entry(struct wiphy *wiphy, hdd_config_t *pCfg)
+{
+ hdd_context_t *pHddCtx = wiphy_priv(wiphy);
+ if (memcmp(pCfg->crdaDefaultCountryCode,
+ CFG_CRDA_DEFAULT_COUNTRY_CODE_DEFAULT , 2) != 0)
+ {
+ init_completion(&pHddCtx->driver_crda_req);
+ regulatory_hint(wiphy, pCfg->crdaDefaultCountryCode);
+ wait_for_completion_interruptible_timeout(&pHddCtx->driver_crda_req,
+ CRDA_WAIT_TIME);
+ }
+ return 0;
+}
+
/* In this function we will do all post VOS start initialization.
In this function we will register for all frame in which supplicant
is interested.
diff --git a/CORE/VOSS/src/vos_api.c b/CORE/VOSS/src/vos_api.c
index e724f9c..7048a05 100644
--- a/CORE/VOSS/src/vos_api.c
+++ b/CORE/VOSS/src/vos_api.c
@@ -72,7 +72,7 @@
#include "wlan_qct_wda.h"
#include "wlan_hdd_main.h"
#include <linux/vmalloc.h>
-
+#include "wlan_hdd_cfg80211.h"
#ifdef WLAN_SOFTAP_FEATURE
#include "sapApi.h"
@@ -457,6 +457,12 @@
VOS_ASSERT(0);
goto err_nv_close;
}
+#ifdef CONFIG_CFG80211
+/* call crda before sme_Open which will read NV and store the default country code */
+ wlan_hdd_get_crda_regd_entry(
+ ((hdd_context_t*)(gpVosContext->pHDDContext))->wiphy,
+ ((hdd_context_t*)(gpVosContext->pHDDContext))->cfg_ini);
+#endif
/* Now proceed to open the SME */
vStatus = sme_Open(gpVosContext->pMACContext);
diff --git a/CORE/VOSS/src/vos_nvitem.c b/CORE/VOSS/src/vos_nvitem.c
index fed6e8b..799c0bc 100644
--- a/CORE/VOSS/src/vos_nvitem.c
+++ b/CORE/VOSS/src/vos_nvitem.c
@@ -43,7 +43,15 @@
#include "vos_api.h"
#include "wlan_hdd_misc.h"
#include "vos_sched.h"
-
+#ifdef CONFIG_CFG80211
+#include "wlan_hdd_main.h"
+#include <net/cfg80211.h>
+static char crda_alpha2[2] = {0, 0}; /* country code from initial crda req */
+static char run_time_alpha2[2] = {0, 0}; /* country code from none-default country req */
+static v_BOOL_t crda_regulatory_entry_valid = VOS_FALSE;
+static v_BOOL_t crda_regulatory_run_time_entry_valid = VOS_FALSE;
+#endif
+
/*----------------------------------------------------------------------------
* Preprocessor Definitions and Constants
* -------------------------------------------------------------------------*/
@@ -371,13 +379,13 @@
{ 2472, 13 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_13,
{ 2484, 14 , RF_SUBBAND_2_4_GHZ}, //RF_CHAN_14,
#ifdef FEATURE_WLAN_INTEGRATED_SOC
- { 0, 240, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_240,
- { 0, 244, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_244,
- { 0, 248, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_248,
- { 0, 252, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_252,
- { 0, 208, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_208,
- { 0, 212, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_212,
- { 0, 216, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_216,
+ { 4920, 240, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_240,
+ { 4940, 244, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_244,
+ { 4960, 248, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_248,
+ { 4980, 252, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_252,
+ { 5040, 208, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_208,
+ { 5060, 212, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_212,
+ { 5080, 216, RF_SUBBAND_4_9_GHZ}, //RF_CHAN_216,
{ 5180, 36 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_36,
{ 5200, 40 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_40,
{ 5220, 44 , RF_SUBBAND_5_LOW_GHZ}, //RF_CHAN_44,
@@ -402,41 +410,41 @@
{ 5785, 157, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_157,
{ 5805, 161, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_161,
{ 5825, 165, RF_SUBBAND_5_HIGH_GHZ}, //RF_CHAN_165,
- { 0 , 0 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_3,
- { 0 , 0 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_4,
- { 0 , 0 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_5,
- { 0 , 0 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_6,
- { 0 , 0 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_7,
- { 0 , 0 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_8,
- { 0 , 0 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_9,
- { 0 , 0 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_10,
- { 0 , 0 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_11,
- { 0 , 0 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_242,
- { 0 , 0 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_246,
- { 0 , 0 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_250,
- { 0 , 0 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_210,
- { 0 , 0 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_214,
- { 0 , 0 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_38,
- { 0 , 0 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_42,
- { 0 , 0 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_46,
- { 0 , 0 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_50,
- { 0 , 0 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_54,
- { 0 , 0 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_58,
- { 0 , 0 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_62,
- { 0 , 0 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_102,
- { 0 , 0 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_106,
- { 0 , 0 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_110,
- { 0 , 0 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_114,
- { 0 , 0 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_118,
- { 0 , 0 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_122,
- { 0 , 0 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_126,
- { 0 , 0 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_130,
- { 0 , 0 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_134,
- { 0 , 0 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_138,
- { 0 , 0 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_151,
- { 0 , 0 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_155,
- { 0 , 0 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_159,
- { 0 , 0 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_163,
+ { 2422, 3 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_3,
+ { 2427, 4 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_4,
+ { 2432, 5 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_5,
+ { 2437, 6 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_6,
+ { 2442, 7 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_7,
+ { 2447, 8 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_8,
+ { 2452, 9 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_9,
+ { 2457, 10 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_10,
+ { 2462, 11 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_11,
+ { 4930, 242, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_242,
+ { 4950, 246, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_246,
+ { 4970, 250, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_250,
+ { 5050, 210, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_210,
+ { 5070, 214, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_214,
+ { 5190, 38 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_38,
+ { 5210, 42 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_42,
+ { 5230, 46 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_46,
+ { 5250, 50 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_50,
+ { 5270, 54 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_54,
+ { 5290, 58 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_58,
+ { 5310, 62 , NUM_RF_SUBBANDS}, //RF_CHAN_BOND_62,
+ { 5510, 102, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_102,
+ { 5530, 106, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_106,
+ { 5550, 110, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_110,
+ { 5570, 114, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_114,
+ { 5590, 118, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_118,
+ { 5610, 122, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_122,
+ { 5630, 126, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_126,
+ { 5650, 130, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_130,
+ { 5670, 134, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_134,
+ { 5690, 138, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_138,
+ { 5755, 151, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_151,
+ { 5775, 155, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_155,
+ { 5795, 159, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_159,
+ { 5815, 163, NUM_RF_SUBBANDS}, //RF_CHAN_BOND_163,
#endif
};
@@ -700,6 +708,9 @@
const v_COUNTRYCODE_t countryCode )
{
int i;
+ v_CONTEXT_t pVosContext = NULL;
+ hdd_context_t *pHddCtx = NULL;
+ struct wiphy *wiphy = NULL;
// sanity checks
if (NULL == pRegDomain)
{
@@ -721,6 +732,60 @@
("Reg domain table is empty\r\n") );
return VOS_STATUS_E_EMPTY;
}
+#ifdef CONFIG_CFG80211
+ /* If CRDA regulatory settings is valid, i.e. crda is enabled
+ and reg_notifier is called back.
+ Intercept here and redirect to the Reg domain table's CRDA
+ entry if country code is crda's country.
+ last one NUM_REG_DOMAINS-1 is reserved for crda */
+ VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+ "vos_nv_getRegDomainFromCountryCode %c%c\n",
+ countryCode[0], countryCode[1]);
+
+ if (crda_regulatory_entry_valid == VOS_TRUE)
+ {
+ if (crda_alpha2[0]==countryCode[0] && crda_alpha2[1]==countryCode[1])
+ {
+ *pRegDomain = NUM_REG_DOMAINS-1;
+ VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+ "vos_nv_getRegDomainFromCountryCode return crda init entry\n");
+ return VOS_STATUS_SUCCESS;
+ }
+ if (run_time_alpha2[0]==countryCode[0] &&
+ run_time_alpha2[1]==countryCode[1] &&
+ crda_regulatory_run_time_entry_valid == VOS_TRUE)
+ {
+ *pRegDomain = NUM_REG_DOMAINS-2;
+ VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+ "vos_nv_getRegDomainFromCountryCode return crda none-default country entry\n");
+ return VOS_STATUS_SUCCESS;
+ }
+ else
+ {
+ crda_regulatory_run_time_entry_valid = VOS_FALSE;
+ pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
+ if (NULL != pVosContext)
+ pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
+ else
+ return VOS_STATUS_E_EXISTS;
+ wiphy = pHddCtx->wiphy;
+ init_completion(&pHddCtx->driver_crda_req);
+ regulatory_hint(wiphy, countryCode);
+ wait_for_completion_interruptible_timeout(&pHddCtx->driver_crda_req,
+ CRDA_WAIT_TIME);
+ if (crda_regulatory_run_time_entry_valid == VOS_TRUE)
+ {
+ VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+ "vos_nv_getRegDomainFromCountryCode return crda new none-default country entry\n");
+ return VOS_STATUS_SUCCESS;
+ }
+ VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+ "vos_nv_getRegDomainFromCountryCode failed to get crda new none-default country entry\n");
+ return VOS_STATUS_E_EXISTS;
+ }
+ }
+#endif
+
// iterate the country info table until end of table or the country code
// is found
for (i = 0; i < countryInfoTable.countryCount &&
@@ -1602,10 +1667,11 @@
VOS_STATUS vos_nv_readDefaultCountryTable( uNvTables *tableData )
{
- VOS_STATUS status;
-
- status = vos_nv_read( VNV_DEFAULT_LOCATION, tableData, NULL, sizeof(sDefaultCountry) );
-
+ VOS_STATUS status = VOS_STATUS_SUCCESS;
+ memcpy(&tableData->defaultCountryTable, &pnvEFSTable->halnv.tables.defaultCountryTable, sizeof(sDefaultCountry));
+ pr_info("DefaultCountry is %c%c\n",
+ tableData->defaultCountryTable.countryCode[0],
+ tableData->defaultCountryTable.countryCode[1]);
return status;
}
@@ -1686,3 +1752,503 @@
return regChannels[channelEnum].enabled;
}
#endif /* FEATURE_WLAN_NON_INTEGRATED_SOC */
+
+/******************************************************************
+ Add CRDA regulatory support
+*******************************************************************/
+#ifdef CONFIG_CFG80211
+
+static int bw20_ch_index_to_bw40_ch_index(int k)
+{
+ int m = -1;
+ if (k >= RF_CHAN_1 && k <= RF_CHAN_14)
+ {
+ m = k - RF_CHAN_1 + RF_CHAN_BOND_3 ;
+ if (m > RF_CHAN_BOND_11)
+ m = RF_CHAN_BOND_11;
+ }
+ else if (k >= RF_CHAN_240 && k <= RF_CHAN_216)
+ {
+ m = k - RF_CHAN_240 + RF_CHAN_BOND_242 ;
+ if (m > RF_CHAN_BOND_214)
+ m = RF_CHAN_BOND_214;
+ }
+ else if (k >= RF_CHAN_36 && k <= RF_CHAN_64)
+ {
+ m = k - RF_CHAN_36 + RF_CHAN_BOND_38;
+ if (m > RF_CHAN_BOND_62)
+ m = RF_CHAN_BOND_62;
+ }
+ else if (k >= RF_CHAN_100 && k <= RF_CHAN_140)
+ {
+ m = k - RF_CHAN_100 + RF_CHAN_BOND_102;
+ if (m > RF_CHAN_BOND_138)
+ m = RF_CHAN_BOND_138;
+ }
+ else if (k >= RF_CHAN_149 && k <= RF_CHAN_165)
+ {
+ m = k - RF_CHAN_149 + RF_CHAN_BOND_151;
+ if (m > RF_CHAN_BOND_163)
+ m = RF_CHAN_BOND_163;
+ }
+return m;
+}
+
+/* create_crda_regulatory_entry should be called from user command or 11d country IE */
+static int create_crda_regulatory_entry(struct wiphy *wiphy,
+ struct regulatory_request *request,
+ v_U8_t nBandCapability)
+{
+ int i, j, m;
+ int k = 0, n = 0;
+
+ if (run_time_alpha2[0]==request->alpha2[0] &&
+ run_time_alpha2[1]==request->alpha2[1] &&
+ crda_regulatory_run_time_entry_valid == VOS_TRUE)
+ return 0; /* already created */
+
+ /* 20MHz channels */
+ if (nBandCapability == eCSR_BAND_24)
+ pr_info("BandCapability is set to 2G only.\n");
+ for (i=0,m=0;i<IEEE80211_NUM_BANDS;i++)
+ {
+ if (i == IEEE80211_BAND_2GHZ && nBandCapability == eCSR_BAND_5G) // 5G only
+ continue;
+ else if (i == IEEE80211_BAND_5GHZ && nBandCapability == eCSR_BAND_24) // 2G only
+ continue;
+ if (wiphy->bands[i] == NULL)
+ {
+ pr_info("error: wiphy->bands[i] is NULL, i = %d\n", i);
+ return -1;
+ }
+ // internal channels[] is one continous array for both 2G and 5G bands
+ // m is internal starting channel index for each band
+ if (i == 0)
+ m = 0;
+ else
+ m = wiphy->bands[i-1]->n_channels + m;
+ for (j=0;j<wiphy->bands[i]->n_channels;j++)
+ {
+ // k = (m + j) is internal current channel index for 20MHz channel
+ // n is internal channel index for corresponding 40MHz channel
+ k = m + j;
+ n = bw20_ch_index_to_bw40_ch_index(k);
+ if (n == -1)
+ return -1;
+ if (wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_DISABLED)
+ {
+ if (pnvEFSTable == NULL)
+ {
+ pr_info("error: pnvEFSTable is NULL, probably not parsed nv.bin yet\n");
+ return -1;
+ }
+ pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].enabled =
+ NV_CHANNEL_DISABLE;
+ pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].enabled =
+ NV_CHANNEL_DISABLE;
+ //pr_info("CH %d disabled, no bonding centered on CH %d.\n", rfChannels[k].channelNum,
+ // rfChannels[n].channelNum);
+ }
+ else if (wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_RADAR)
+ {
+ pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].enabled =
+ NV_CHANNEL_DFS;
+ // max_power is in mBm = 100 * d
+ pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].pwrLimit =
+ (tANI_S8) (wiphy->bands[i]->channels[j].max_power);
+ pr_info("CH %d is enabled and DFS, max power %d dBm.\n", rfChannels[k].channelNum,
+ pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].pwrLimit);
+ if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == 0)
+ {
+ pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].enabled =
+ NV_CHANNEL_DFS;
+ // 40MHz channel power is half of 20MHz (-3dB) ??
+ pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].pwrLimit =
+ (tANI_S8) ((wiphy->bands[i]->channels[j].max_power)-3);
+ pr_info(" CH %d is enabled for 40MHz and DFS, max power %d dBm.\n", rfChannels[n].channelNum,
+ pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].pwrLimit);
+ }
+ }
+ else // Enable is only last flag we support
+ {
+ pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].enabled =
+ NV_CHANNEL_ENABLE;
+ // max_power is in dBm
+ pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].pwrLimit =
+ (tANI_S8) (wiphy->bands[i]->channels[j].max_power);
+ pr_info("CH %d is enabled and no DFS, max power %d dBm.\n", rfChannels[k].channelNum,
+ pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].pwrLimit);
+ if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == 0)
+ {
+ pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].enabled =
+ NV_CHANNEL_ENABLE;
+ // 40MHz channel power is half of 20MHz (-3dB) ??
+ pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].pwrLimit =
+ (tANI_S8) ((wiphy->bands[i]->channels[j].max_power)-3);
+ pr_info(" CH %d is enabled for 40MHz and no DFS, max power %d dBm.\n", rfChannels[n].channelNum,
+ pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[n].pwrLimit);
+ }
+ }
+ /* ignore CRDA max_antenna_gain typical is 3dBi, nv.bin antennaGain is
+ real gain which should be provided by the real design */
+ }
+ }
+ if (k == 0)
+ return -1;
+ run_time_alpha2[0] = request->alpha2[0];
+ run_time_alpha2[1] = request->alpha2[1];
+ crda_regulatory_run_time_entry_valid = VOS_TRUE;
+return 0;
+}
+v_BOOL_t is_crda_regulatory_entry_valid(void)
+{
+return crda_regulatory_entry_valid;
+}
+
+/* Handling routines for the conversion from regd rules (start/end freq) to channel index
+start freq + 10000 = center freq of the 20MHz start channel
+end freq - 10000 = center freq of the 20MHz end channel
+start freq + 20000 = center freq of the 40MHz start channel
+end freq - 20000 = center freq of the 40MHz end channel
+*/
+static int bw20_start_freq_to_channel_index(u32 freq_khz)
+{
+int i;
+u32 center_freq = freq_khz + 10000;
+ //Has to compare from low freq to high freq
+ //RF_SUBBAND_2_4_GHZ
+ for (i=RF_CHAN_1;i<=RF_CHAN_14;i++)
+ if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
+ return i;
+#ifdef FEATURE_WLAN_INTEGRATED_SOC
+ //RF_SUBBAND_4_9_GHZ, Ch 240, 244, 248, 252, 208, 212, 216
+ for (i=RF_CHAN_240;i<=RF_CHAN_216;i++)
+ if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
+ return i;
+ //RF_SUBBAND_5_LOW_GHZ
+ for (i=RF_CHAN_36;i<=RF_CHAN_64;i++)
+ if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
+ return i;
+ //RF_SUBBAND_5_MID_GHZ
+ for (i=RF_CHAN_100;i<=RF_CHAN_140;i++)
+ if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
+ return i;
+ //RF_SUBBAND_5_HIGH_GHZ
+ for (i=RF_CHAN_149;i<=RF_CHAN_165;i++)
+ if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
+ return i;
+#endif
+return -1;
+}
+
+static int bw20_end_freq_to_channel_index(u32 freq_khz)
+{
+int i;
+u32 center_freq = freq_khz - 10000;
+ //Has to compare from high freq to low freq
+#ifdef FEATURE_WLAN_INTEGRATED_SOC
+ //RF_SUBBAND_5_HIGH_GHZ
+ for (i=RF_CHAN_165;i>=RF_CHAN_149;i--)
+ if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
+ return i;
+ //RF_SUBBAND_5_MID_GHZ
+ for (i=RF_CHAN_140;i>=RF_CHAN_100;i--)
+ if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
+ return i;
+ //RF_SUBBAND_5_LOW_GHZ
+ for (i=RF_CHAN_64;i>=RF_CHAN_36;i--)
+ if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
+ return i;
+ //RF_SUBBAND_4_9_GHZ, Ch 216, 212, 208, 252, 248, 244, 240
+ for (i=RF_CHAN_216;i>=RF_CHAN_240;i--)
+ if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
+ return i;
+#endif
+ //RF_SUBBAND_2_4_GHZ
+ for (i=RF_CHAN_14;i>=RF_CHAN_1;i--)
+ if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
+ return i;
+return -1;
+}
+
+static int bw40_start_freq_to_channel_index(u32 freq_khz)
+{
+int i;
+u32 center_freq = freq_khz + 20000;
+ //Has to compare from low freq to high freq
+ //RF_SUBBAND_2_4_GHZ
+ for (i=RF_CHAN_BOND_3;i<=RF_CHAN_BOND_11;i++)
+ if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
+ return i;
+#ifdef FEATURE_WLAN_INTEGRATED_SOC
+ //RF_SUBBAND_4_9_GHZ, Ch 242, 246, 250, 210, 214
+ for (i=RF_CHAN_BOND_242;i<=RF_CHAN_BOND_214;i++)
+ if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
+ return i;
+ //RF_SUBBAND_5_LOW_GHZ
+ for (i=RF_CHAN_BOND_38;i<=RF_CHAN_BOND_62;i++)
+ if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
+ return i;
+ //RF_SUBBAND_5_MID_GHZ
+ for (i=RF_CHAN_BOND_102;i<=RF_CHAN_BOND_138;i++)
+ if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
+ return i;
+ //RF_SUBBAND_5_HIGH_GHZ
+ for (i=RF_CHAN_BOND_151;i<=RF_CHAN_BOND_163;i++)
+ if (center_freq <= (u32) (rfChannels[i].targetFreq) * 1000)
+ return i;
+#endif
+return -1;
+}
+
+static int bw40_end_freq_to_channel_index(u32 freq_khz)
+{
+int i;
+u32 center_freq = freq_khz - 20000;
+ //Has to compare from high freq to low freq
+#ifdef FEATURE_WLAN_INTEGRATED_SOC
+ //RF_SUBBAND_5_HIGH_GHZ
+ for (i=RF_CHAN_BOND_163;i>=RF_CHAN_BOND_151;i--)
+ if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
+ return i;
+ //RF_SUBBAND_5_MID_GHZ
+ for (i=RF_CHAN_BOND_138;i>=RF_CHAN_BOND_102;i--)
+ if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
+ return i;
+ //RF_SUBBAND_5_LOW_GHZ
+ for (i=RF_CHAN_BOND_62;i>=RF_CHAN_BOND_38;i--)
+ if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
+ return i;
+ //RF_SUBBAND_4_9_GHZ, Ch 214, 210, 250, 246, 242
+ for (i=RF_CHAN_BOND_214;i>=RF_CHAN_BOND_242;i--)
+ if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
+ return i;
+#endif
+ //RF_SUBBAND_2_4_GHZ
+ for (i=RF_CHAN_BOND_11;i>=RF_CHAN_BOND_3;i--)
+ if (center_freq >= (u32) (rfChannels[i].targetFreq) * 1000)
+ return i;
+return -1;
+}
+
+static v_BOOL_t channel_in_capable_band(int j, v_U8_t nBandCapability)
+{
+ switch (nBandCapability)
+ {
+ case eCSR_BAND_ALL:
+ return VOS_TRUE;
+ case eCSR_BAND_24:
+ if (j >= RF_CHAN_1 && j <= RF_CHAN_14)
+ return VOS_TRUE;
+ if (j >= RF_CHAN_BOND_3 && j <= RF_CHAN_BOND_11)
+ return VOS_TRUE; // 2.4G 40MHz channel
+ break;
+ case eCSR_BAND_5G:
+ if (j >= RF_CHAN_240 && j <= RF_CHAN_165)
+ return VOS_TRUE;
+ if (j >= RF_CHAN_BOND_242 && j <= RF_CHAN_BOND_163)
+ return VOS_TRUE; // 2.4G 40MHz channel
+ break;
+ default:
+ break;
+ }
+ return VOS_FALSE;
+}
+
+/* create_crda_regulatory_entry_from_regd should be called during init time */
+static int create_crda_regulatory_entry_from_regd(struct wiphy *wiphy,
+ struct regulatory_request *request,
+ v_U8_t nBandCapability)
+{
+ int i, j, n, domain_id;
+ int bw20_start_channel_index, bw20_end_channel_index;
+ int bw40_start_channel_index, bw40_end_channel_index;
+
+ if (wiphy == NULL || wiphy->regd == NULL)
+ {
+ wiphy_dbg(wiphy, "error: wiphy->regd is NULL\n");
+ return -1;
+ }
+ if (crda_regulatory_entry_valid == VOS_FALSE)
+ domain_id = NUM_REG_DOMAINS-1; /* init time */
+ else
+ domain_id = NUM_REG_DOMAINS-2; /* none-default country */
+ for (n = 0; n < NUM_RF_CHANNELS; n++)
+ pnvEFSTable->halnv.tables.regDomains[domain_id].channels[n].enabled = NV_CHANNEL_DISABLE;
+
+ for (i=0;i<wiphy->regd->n_reg_rules;i++)
+ {
+ wiphy_dbg(wiphy, "info: crda rule %d --------------------------------------------\n", i);
+ bw20_start_channel_index =
+ bw20_start_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.start_freq_khz);
+ bw20_end_channel_index =
+ bw20_end_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
+ if (bw20_start_channel_index == -1 || bw20_end_channel_index == -1)
+ {
+ wiphy_dbg(wiphy, "error: crda freq not supported, start freq (KHz) %d end freq %d\n",
+ wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
+ wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
+ continue; // skip this rull, but continue to next rule
+ }
+ wiphy_dbg(wiphy, "20MHz start freq (KHz) %d end freq %d start ch index %d end ch index %d\n",
+ wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
+ wiphy->regd->reg_rules[i].freq_range.end_freq_khz,
+ bw20_start_channel_index, bw20_end_channel_index);
+ for (j=bw20_start_channel_index;j<=bw20_end_channel_index;j++)
+ {
+ if (channel_in_capable_band(j, nBandCapability) == VOS_FALSE)
+ {
+ wiphy_dbg(wiphy, "info: CH %d is not in capable band\n",
+ rfChannels[j].channelNum);
+ continue; // skip this channel, continue to next
+ }
+ if (wiphy->regd->reg_rules[i].flags & NL80211_RRF_DFS)
+ {
+ pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_DFS;
+ wiphy_dbg(wiphy, "info: CH %d is DFS, max EIRP (mBm) is %d\n", rfChannels[j].channelNum,
+ wiphy->regd->reg_rules[i].power_rule.max_eirp);
+ }
+ else
+ {
+ pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_ENABLE;
+ wiphy_dbg(wiphy, "info: CH %d is enabled, no DFS, max EIRP (mBm) is %d\n", rfChannels[j].channelNum,
+ wiphy->regd->reg_rules[i].power_rule.max_eirp);
+ }
+ /* max_eirp is in mBm (= 100 * dBm) unit */
+ pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].pwrLimit =
+ (tANI_S8) ((wiphy->regd->reg_rules[i].power_rule.max_eirp)/100);
+ }
+ /* ignore CRDA max_antenna_gain typical is 3dBi, nv.bin antennaGain is
+ real gain which should be provided by the real design */
+ if (wiphy->regd->reg_rules[i].freq_range.max_bandwidth_khz == 40000)
+ {
+ wiphy_dbg(wiphy, "info: 40MHz (channel bonding) is allowed\n");
+ bw40_start_channel_index =
+ bw40_start_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.start_freq_khz);
+ bw40_end_channel_index =
+ bw40_end_freq_to_channel_index(wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
+ if (bw40_start_channel_index == -1 || bw40_end_channel_index == -1)
+ {
+ wiphy_dbg(wiphy, "error: crda freq not supported, start_freq_khz %d end_freq_khz %d\n",
+ wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
+ wiphy->regd->reg_rules[i].freq_range.end_freq_khz);
+ continue; // skip this rull, but continue to next rule
+ }
+ wiphy_dbg(wiphy, "40MHz start freq (KHz) %d end freq %d start ch index %d end ch index %d\n",
+ wiphy->regd->reg_rules[i].freq_range.start_freq_khz,
+ wiphy->regd->reg_rules[i].freq_range.end_freq_khz,
+ bw40_start_channel_index, bw40_end_channel_index);
+ for (j=bw40_start_channel_index;j<=bw40_end_channel_index;j++)
+ {
+ if (channel_in_capable_band(j, nBandCapability) == VOS_FALSE)
+ continue; // skip this channel, continue to next
+ if (wiphy->regd->reg_rules[i].flags & NL80211_RRF_DFS)
+ {
+ pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_DFS;
+ wiphy_dbg(wiphy, "info: 40MHz centered on CH %d is DFS\n", rfChannels[j].channelNum);
+ }
+ else
+ {
+ pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].enabled = NV_CHANNEL_ENABLE;
+ wiphy_dbg(wiphy, "info: 40MHz centered on CH %d is enabled, no DFS\n", rfChannels[j].channelNum);
+ }
+ /* set 40MHz channel power as half (- 3 dB) of 20MHz */
+ pnvEFSTable->halnv.tables.regDomains[domain_id].channels[j].pwrLimit =
+ (tANI_S8) (((wiphy->regd->reg_rules[i].power_rule.max_eirp)/100)-3);
+ }
+ }
+ }
+ /* ToDo update other (than DFS) crda regulatory flags (NO_OUTDOOR,
+ NO_OFDM, PASSIVE_SCAN, NO_IBSS) to pnvEFSTable which doesn't add
+ these flags and has no implementation yet. */
+ if (crda_regulatory_entry_valid == VOS_FALSE)
+ { /* init time */
+ crda_alpha2[0] = request->alpha2[0];
+ crda_alpha2[1] = request->alpha2[1];
+ crda_regulatory_entry_valid = VOS_TRUE;
+ }
+ else
+ { /* none-default country */
+ run_time_alpha2[0] = request->alpha2[0];
+ run_time_alpha2[1] = request->alpha2[1];
+ crda_regulatory_run_time_entry_valid = VOS_TRUE;
+ }
+ return 0;
+}
+
+/*
+ * Function: wlan_hdd_crda_reg_notifier
+ * This function is called from cfg80211 core to provide regulatory settings
+ * after new country is requested or intersected (init, user input or 11d)
+ * This function is used to create a CRDA regulatory settings entry into internal
+ * regulatory setting table.
+ */
+int wlan_hdd_crda_reg_notifier(struct wiphy *wiphy,
+ struct regulatory_request *request)
+{
+ hdd_context_t *pHddCtx = wiphy_priv(wiphy);
+ wiphy_dbg(wiphy, "info: cfg80211 reg_notifier callback for country"
+ " %c%c\n", request->alpha2[0], request->alpha2[1]);
+ if (request->initiator == NL80211_REGDOM_SET_BY_USER)
+ {
+ wiphy_dbg(wiphy, "info: set by user\n");
+ if (create_crda_regulatory_entry(wiphy, request, pHddCtx->cfg_ini->nBandCapability) != 0)
+ return 0;
+ // ToDo
+ /* Don't change default country code to CRDA country code by user req */
+ /* Shouldcall sme_ChangeCountryCode to send a message to trigger read
+ regd for new country settings */
+ //sme_ChangeCountryCode(pHddCtx->hHal, NULL,
+ // &country_code[0], pAdapter, pHddCtx->pvosContext);
+ }
+ else if (request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE)
+ {
+ wiphy_dbg(wiphy, "info: set by country IE\n");
+ if (create_crda_regulatory_entry(wiphy, request, pHddCtx->cfg_ini->nBandCapability) != 0)
+ return 0;
+ // ToDo
+ /* Intersect of 11d and crda settings */
+
+ /* Don't change default country code to CRDA country code by 11d req */
+ /* for every adapter call sme_ChangeCountryCode to trigger read regd
+ for intersected new country settings */
+ // sme_ChangeCountryCode(pHddCtx->hHal, NULL,
+ // &country_code[0], pAdapter, pHddCtx->pvosContext);
+ }
+ else if (request->initiator == NL80211_REGDOM_SET_BY_DRIVER)
+ {
+ wiphy_dbg(wiphy, "info: set by driver\n");
+ /* if set by driver itself, it means driver can accept the crda
+ regulatory settings and wiphy->regd should be populated with crda
+ settings. iwiphy->bands doesn't seem to set ht40 flags in kernel
+ correctly, this may be fixed by later kernel */
+ if (create_crda_regulatory_entry_from_regd(wiphy, request, pHddCtx->cfg_ini->nBandCapability) == 0)
+ {
+ pr_info("crda entry created.\n");
+ if (crda_alpha2[0] == request->alpha2[0] && crda_alpha2[1] == request->alpha2[1])
+ { /* first CRDA request should be from init time */
+ /* Change default country code to CRDA country code, assume indoor */
+ pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[0] = request->alpha2[0];
+ pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[1] = request->alpha2[1];
+ pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[2] = 'I';
+ pnvEFSTable->halnv.tables.defaultCountryTable.regDomain = NUM_REG_DOMAINS-1;
+ wiphy_dbg(wiphy, "info: init time default country code is %c%c%c\n",
+ pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[0],
+ pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[1],
+ pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[2]);
+ }
+ else /* second or later CRDA request after init time */
+ {
+ wiphy_dbg(wiphy, "info: crda none-default country code is %c%c\n",
+ request->alpha2[0], request->alpha2[1]);
+ }
+ // hdd will read regd for this country after complete
+ }
+ complete(&pHddCtx->driver_crda_req);
+
+ /* Haven't seen any condition that will set by driver after init.
+ If we do, then we should also call sme_ChangeCountryCode */
+ }
+return 0;
+}
+#endif