Enhanced regulatory domain support
Following are the high-level changes in this feature:
1) Reduce the number of regulatory domains that are available from 9 to 4.
That is, only 4 out of the 9 regulatory domains in the NV.bin file would
be used and supported.
2) Add compulsory linux regulatory support to the wlan driver. The
support is added under the flag CONFIG_ENABLE_LINUX_REG.
3) Remove the WCNSS_qcom_cfg.ini item gCRDADefaultCountryCode
Change-Id: I5eef8ca53aafad69044d5468b50a3d266ee8ac1c
CRs-fixed: 538940
diff --git a/CORE/HDD/inc/wlan_hdd_cfg.h b/CORE/HDD/inc/wlan_hdd_cfg.h
index 758ae02..193fe72 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg.h
@@ -416,11 +416,6 @@
#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"
-
#define CFG_AP_QOS_UAPSD_MODE_NAME "gEnableApUapsd" // ACs to setup U-APSD for at assoc
#define CFG_AP_QOS_UAPSD_MODE_MIN ( 0 )
#define CFG_AP_QOS_UAPSD_MODE_MAX ( 1 )
@@ -2004,10 +1999,8 @@
v_MACADDR_t IbssBssid;
v_U32_t AdHocChannel5G;
v_U32_t AdHocChannel24G;
-
v_U8_t intfAddrMask;
v_MACADDR_t intfMacAddr[VOS_MAX_CONCURRENCY_PERSONA];
- v_U8_t crdaDefaultCountryCode [3];
v_BOOL_t apUapsdEnabled;
v_BOOL_t apRandomBssidEnabled;
@@ -2017,7 +2010,7 @@
v_U8_t MinFramesProcThres;
v_U8_t apCntryCode[4];
v_BOOL_t apDisableIntraBssFwd;
- v_U8_t nEnableListenMode;
+ v_U8_t nEnableListenMode;
v_U32_t nAPAutoShutOff;
v_U8_t apStartChannelNum;
v_U8_t apEndChannelNum;
diff --git a/CORE/HDD/inc/wlan_hdd_cfg80211.h b/CORE/HDD/inc/wlan_hdd_cfg80211.h
index 82b124f..c87f5e5 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg80211.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg80211.h
@@ -155,12 +155,14 @@
void wlan_hdd_cfg80211_pre_voss_stop(hdd_adapter_t* pAdapter);
+#ifdef CONFIG_ENABLE_LINUX_REG
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
-void wlan_hdd_crda_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request);
+void wlan_hdd_linux_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request);
#else
-int wlan_hdd_crda_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request);
+int wlan_hdd_linux_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request);
#endif
-int wlan_hdd_get_crda_regd_entry(struct wiphy *wiphy, hdd_config_t *pCfg);
+#endif
+
extern v_VOID_t hdd_connSetConnectionState( hdd_station_ctx_t *pHddStaCtx,
eConnectionState connState );
VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel);
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index 05f0b6c..753fef6 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -135,8 +135,9 @@
/** Maximum time(ms) to wait for tdls initiator to start direct communication **/
#define WAIT_TIME_TDLS_INITIATOR 600
-/* Maximum time to get crda entry settings */
-#define CRDA_WAIT_TIME 300
+
+/* Maximum time to get linux regulatory entry settings */
+#define LINUX_REG_WAIT_TIME 300
/* Scan Req Timeout */
#define WLAN_WAIT_TIME_SCAN_REQ 100
@@ -942,8 +943,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;
+ /* Completion variable for regulatory hint */
+ struct completion linux_reg_req;
v_BOOL_t isWlanSuspended;
@@ -1126,7 +1127,7 @@
void hdd_abort_mac_scan(hdd_context_t *pHddCtx, tANI_U8 sessionId);
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);
+
void crda_regulatory_entry_default(v_U8_t *countryCode, int domain_id);
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 921c174..2f32b20 100644
--- a/CORE/HDD/src/wlan_hdd_cfg.c
+++ b/CORE/HDD/src/wlan_hdd_cfg.c
@@ -623,11 +623,6 @@
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 ),
-
REG_VARIABLE( CFG_AP_QOS_UAPSD_MODE_NAME , WLAN_PARAM_Integer,
hdd_config_t, apUapsdEnabled,
VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
@@ -4332,6 +4327,7 @@
hdd_config_t *pConfig = pHddCtx->cfg_ini;
+
vos_mem_zero( &smeConfig, sizeof( smeConfig ) );
VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
@@ -4339,8 +4335,7 @@
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 6d80f66..a4a98d3 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -631,25 +631,18 @@
)
{
int i, j;
- hdd_context_t *pHddCtx = wiphy_priv(wiphy);
ENTER();
/* Now bind the underlying wlan device with wiphy */
set_wiphy_dev(wiphy, dev);
wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
- if (memcmp(pHddCtx->cfg_ini->crdaDefaultCountryCode,
- CFG_CRDA_DEFAULT_COUNTRY_CODE_DEFAULT , 2) != 0)
- {
- wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
- }
- else
- {
- /* This will disable updating of NL channels from passive to
- * active if a beacon is received on passive channel. */
- wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
- wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
- }
+
+ /* This will disable updating of NL channels from passive to
+ * active if a beacon is received on passive channel. */
+ wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
+ wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
+
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
| WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
@@ -679,12 +672,15 @@
wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
#endif/*FEATURE_WLAN_SCAN_PNO*/
+#ifdef CONFIG_ENABLE_LINUX_REG
/* even with WIPHY_FLAG_CUSTOM_REGULATORY,
driver can still register regulatory callback and
- it will get CRDA setting in wiphy->band[], but
+ it will get regulatory settings in wiphy->band[], but
driver need to determine what to do with both
regulatory settings */
- wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
+
+ wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
+#endif
wiphy->max_scan_ssids = MAX_SCAN_SSID;
@@ -796,39 +792,6 @@
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_init.
-*/
-int wlan_hdd_get_crda_regd_entry(struct wiphy *wiphy, hdd_config_t *pCfg)
-{
- hdd_context_t *pHddCtx = wiphy_priv(wiphy);
- int status;
-
- if (memcmp(pCfg->crdaDefaultCountryCode,
- CFG_CRDA_DEFAULT_COUNTRY_CODE_DEFAULT , 2) != 0)
- {
- INIT_COMPLETION(pHddCtx->driver_crda_req);
- regulatory_hint(wiphy, pCfg->crdaDefaultCountryCode);
- status = wait_for_completion_interruptible_timeout(
- &pHddCtx->driver_crda_req,
- msecs_to_jiffies(CRDA_WAIT_TIME));
- if (!status)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR,"%s: timeout waiting for CRDA REQ",
- __func__);
- }
-
- /* if the country is not found from current regulatory.bin,
- fall back to world domain */
- if (is_crda_regulatory_entry_valid() == VOS_FALSE)
- crda_regulatory_entry_default(pCfg->crdaDefaultCountryCode, NUM_REG_DOMAINS-1);
- }
- return 0;
-}
-
/* In this function we are updating channel list when,
regulatory domain is FCC and country code is US.
Here In FCC standard 5GHz UNII-1 Bands are indoor only.
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
index bcb02c0..6770234 100644
--- a/CORE/HDD/src/wlan_hdd_main.c
+++ b/CORE/HDD/src/wlan_hdd_main.c
@@ -604,7 +604,6 @@
if ((SIOCDEVPRIVATE + 1) == cmd)
{
hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
- struct wiphy *wiphy = pHddCtx->wiphy;
VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
"%s: Received %s cmd from Wi-Fi GUI***", __func__, command);
@@ -649,14 +648,6 @@
"%s: SME Change Country code fail ret=%d\n",__func__, ret);
}
- /* If you get a 00 country code it means you are world roaming.
- In case of world roaming, country code should be updated by
- DRIVER COUNTRY */
- if (memcmp(pHddCtx->cfg_ini->crdaDefaultCountryCode,
- CFG_CRDA_DEFAULT_COUNTRY_CODE_DEFAULT , 2) == 0)
- {
- regulatory_hint(wiphy, "00");
- }
}
/*
command should be a string having format
@@ -5444,7 +5435,7 @@
init_completion(&pHddCtx->req_bmps_comp_var);
init_completion(&pHddCtx->scan_info.scan_req_completion_event);
init_completion(&pHddCtx->scan_info.abortscan_event_var);
- init_completion(&pHddCtx->driver_crda_req);
+ init_completion(&pHddCtx->linux_reg_req);
spin_lock_init(&pHddCtx->schedScan_lock);
diff --git a/CORE/VOSS/src/vos_api.c b/CORE/VOSS/src/vos_api.c
index 621d38e..600186b 100644
--- a/CORE/VOSS/src/vos_api.c
+++ b/CORE/VOSS/src/vos_api.c
@@ -397,10 +397,6 @@
VOS_ASSERT(0);
goto err_nv_close;
}
-/* 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);
/* 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 402f1a0..29043d1 100644
--- a/CORE/VOSS/src/vos_nvitem.c
+++ b/CORE/VOSS/src/vos_nvitem.c
@@ -66,10 +66,19 @@
#include "wlan_nv_parser.h"
#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;
+
+static v_REGDOMAIN_t cur_reg_domain = REGDOMAIN_COUNT;
+#ifdef CONFIG_ENABLE_LINUX_REG
+static v_BOOL_t kernel_reg_request_made = VOS_FALSE;
+static v_BOOL_t driver_callback_called = VOS_FALSE;
+static char linux_reg_cc[2] = {0, 0};
+static v_BOOL_t linux_regulatory_init = VOS_FALSE;
+static v_REGDOMAIN_t temp_reg_domain = REGDOMAIN_COUNT;
+#else
+static v_BOOL_t driver_regulatory_init = VOS_FALSE;
+static char driver_reg_cc[2] = {0, 0};
+#endif
+
/*----------------------------------------------------------------------------
* Preprocessor Definitions and Constants
@@ -108,6 +117,157 @@
/*----------------------------------------------------------------------------
* Static Variable Definitions
* -------------------------------------------------------------------------*/
+
+#ifdef CONFIG_ENABLE_LINUX_REG
+
+static CountryInfoTable_t countryInfoTable =
+{
+ /* the first entry in the table is always the world domain */
+ 138,
+ {
+ {REGDOMAIN_WORLD, {'0', '0'}}, // WORLD DOMAIN
+ {REGDOMAIN_FCC, {'A', 'D'}}, // ANDORRA
+ {REGDOMAIN_ETSI, {'A', 'E'}}, //UAE
+ {REGDOMAIN_ETSI, {'A', 'L'}}, //ALBANIA
+ {REGDOMAIN_ETSI, {'A', 'M'}}, //ARMENIA
+ {REGDOMAIN_ETSI, {'A', 'N'}}, //NETHERLANDS ANTILLES
+ {REGDOMAIN_FCC, {'A', 'R'}}, //ARGENTINA
+ {REGDOMAIN_FCC, {'A', 'S'}}, //AMERICAN SOMOA
+ {REGDOMAIN_ETSI, {'A', 'T'}}, //AUSTRIA
+ {REGDOMAIN_FCC, {'A', 'U'}}, //AUSTRALIA
+ {REGDOMAIN_ETSI , {'A', 'W'}}, //ARUBA
+ {REGDOMAIN_ETSI, {'A', 'Z'}}, //AZERBAIJAN
+ {REGDOMAIN_ETSI, {'B', 'A'}}, //BOSNIA AND HERZEGOVINA
+ {REGDOMAIN_FCC, {'B', 'B'}}, //BARBADOS
+ {REGDOMAIN_ETSI, {'B', 'D'}}, //BANGLADESH
+ {REGDOMAIN_ETSI, { 'B', 'E'}}, //BELGIUM
+ {REGDOMAIN_ETSI, {'B', 'G'}}, //BULGARIA
+ {REGDOMAIN_ETSI, {'B', 'H'}}, //BAHRAIN
+ {REGDOMAIN_ETSI, {'B', 'L'}}, //
+ {REGDOMAIN_FCC, {'B', 'M'}}, //BERMUDA
+ {REGDOMAIN_ETSI, {'B', 'N'}}, //BRUNEI DARUSSALAM
+ {REGDOMAIN_ETSI, {'B', 'O'}}, //BOLIVIA
+ {REGDOMAIN_ETSI, {'B', 'R'}}, //BRAZIL
+ {REGDOMAIN_FCC, {'B', 'S'}}, //BAHAMAS
+ {REGDOMAIN_ETSI, {'B', 'Y'}}, //BELARUS
+ {REGDOMAIN_ETSI, {'B', 'Z'}}, //BELIZE
+ {REGDOMAIN_FCC, {'C', 'A'}}, //CANADA
+ {REGDOMAIN_ETSI, {'C', 'H'}}, //SWITZERLAND
+ {REGDOMAIN_ETSI, {'C', 'L'}}, //CHILE
+ {REGDOMAIN_FCC, {'C', 'N'}}, //CHINA
+ {REGDOMAIN_FCC, {'C', 'O'}}, //COLOMBIA
+ {REGDOMAIN_ETSI, {'C', 'R'}}, //COSTA RICA
+ {REGDOMAIN_ETSI, {'C', 'S'}},
+ {REGDOMAIN_ETSI, {'C', 'Y'}}, //CYPRUS
+ {REGDOMAIN_ETSI, {'C', 'Z'}}, //CZECH REPUBLIC
+ {REGDOMAIN_ETSI, {'D', 'E'}}, //GERMANY
+ {REGDOMAIN_ETSI, {'D', 'K'}}, //DENMARK
+ {REGDOMAIN_FCC, {'D', 'O'}}, //DOMINICAN REPUBLIC
+ {REGDOMAIN_ETSI, {'D', 'Z'}}, //ALGERIA
+ {REGDOMAIN_ETSI, {'E', 'C'}}, //ECUADOR
+ {REGDOMAIN_ETSI, {'E', 'E'}}, //ESTONIA
+ {REGDOMAIN_ETSI, {'E', 'G'}}, //EGYPT
+ {REGDOMAIN_ETSI, {'E', 'S'}}, //SPAIN
+ {REGDOMAIN_ETSI, {'F', 'I'}}, //FINLAND
+ {REGDOMAIN_ETSI, {'F', 'R'}}, //FRANCE
+ {REGDOMAIN_ETSI, {'G', 'B'}}, //UNITED KINGDOM
+ {REGDOMAIN_FCC, {'G', 'D'}}, //GRENADA
+ {REGDOMAIN_ETSI, {'G', 'E'}}, //GEORGIA
+ {REGDOMAIN_ETSI, {'G', 'F'}}, //FRENCH GUIANA
+ {REGDOMAIN_ETSI, {'G', 'L'}}, //GREENLAND
+ {REGDOMAIN_ETSI, {'G', 'P'}}, //GUADELOUPE
+ {REGDOMAIN_ETSI, {'G', 'R'}}, //GREECE
+ {REGDOMAIN_FCC, {'G', 'T'}}, //GUATEMALA
+ {REGDOMAIN_FCC, {'G', 'U'}}, //GUAM
+ {REGDOMAIN_ETSI, {'H', 'U'}}, //HUNGARY
+ {REGDOMAIN_FCC, {'I', 'D'}}, //INDONESIA
+ {REGDOMAIN_ETSI, {'I', 'E'}}, //IRELAND
+ {REGDOMAIN_ETSI, {'I', 'L'}}, //ISRAEL
+ {REGDOMAIN_ETSI, {'I', 'N'}}, //INDIA
+ {REGDOMAIN_ETSI, {'I', 'R'}}, //IRAN, ISLAMIC REPUBLIC OF
+ {REGDOMAIN_ETSI, {'I', 'S'}}, //ICELNAD
+ {REGDOMAIN_ETSI, {'I', 'T'}}, //ITALY
+ {REGDOMAIN_FCC, {'J', 'M'}}, //JAMAICA
+ {REGDOMAIN_JAPAN, {'J', 'P'}}, //JAPAN
+ {REGDOMAIN_ETSI, {'J', 'O'}}, //JORDAN
+ {REGDOMAIN_ETSI, {'K', 'E'}}, //KENYA
+ {REGDOMAIN_ETSI, {'K', 'H'}}, //CAMBODIA
+ {REGDOMAIN_ETSI, {'K', 'P'}}, //KOREA, DEMOCRATIC PEOPLE's REPUBLIC OF
+ {REGDOMAIN_ETSI, {'K', 'R'}}, //KOREA, REPUBLIC OF
+ {REGDOMAIN_ETSI, {'K', 'W'}}, //KUWAIT
+ {REGDOMAIN_ETSI, {'K', 'Z'}}, //KAZAKHSTAN
+ {REGDOMAIN_ETSI, {'L', 'B'}}, //LEBANON
+ {REGDOMAIN_ETSI, {'L', 'I'}}, //LIECHTENSTEIN
+ {REGDOMAIN_ETSI, {'L', 'K'}}, //SRI-LANKA
+ {REGDOMAIN_ETSI, {'L', 'T'}}, //LITHUANIA
+ {REGDOMAIN_ETSI, {'L', 'U'}}, //LUXEMBOURG
+ {REGDOMAIN_ETSI, {'L','V'}}, //LATVIA
+ {REGDOMAIN_ETSI, {'M', 'A'}}, //MOROCCO
+ {REGDOMAIN_ETSI, {'M', 'C'}}, //MONACO
+ {REGDOMAIN_ETSI, {'M', 'K'}}, //MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF
+ {REGDOMAIN_FCC, {'M','N'}}, //MONGOLIA
+ {REGDOMAIN_FCC, {'M', 'O'}}, //MACAO
+ {REGDOMAIN_FCC, {'M', 'P'}}, //NORTHERN MARIANA ISLANDS
+ {REGDOMAIN_ETSI, {'M', 'Q'}}, //MARTINIQUE
+ {REGDOMAIN_FCC, {'M', 'T'}}, //MALTA
+ {REGDOMAIN_ETSI, {'M', 'U'}}, //MAURITIUS
+ {REGDOMAIN_ETSI, {'M', 'W'}}, //MALAWI
+ {REGDOMAIN_FCC, {'M', 'X'}}, //MEXICO
+ {REGDOMAIN_ETSI, {'M', 'Y'}}, //MALAYSIA
+ {REGDOMAIN_ETSI, {'N', 'G'}}, //NIGERIA
+ {REGDOMAIN_FCC, {'N', 'I'}}, //NICARAGUA
+ {REGDOMAIN_ETSI, {'N', 'L'}}, //NETHERLANDS
+ {REGDOMAIN_ETSI, {'N', 'O'}}, //NORWAY
+ {REGDOMAIN_ETSI, {'N', 'P'}}, //NEPAL
+ {REGDOMAIN_FCC, {'N', 'Z'}}, //NEW-ZEALAND
+ {REGDOMAIN_FCC, {'O', 'M'}}, //OMAN
+ {REGDOMAIN_FCC, {'P', 'A'}}, //PANAMA
+ {REGDOMAIN_ETSI, {'P', 'E'}}, //PERU
+ {REGDOMAIN_ETSI, {'P', 'F'}}, //FRENCH POLYNESIA
+ {REGDOMAIN_ETSI, {'P', 'G'}}, //PAPUA NEW GUINEA
+ {REGDOMAIN_FCC, {'P', 'H'}}, //PHILIPPINES
+ {REGDOMAIN_ETSI, {'P', 'K'}}, //PAKISTAN
+ {REGDOMAIN_ETSI, {'P', 'L'}}, //POLAND
+ {REGDOMAIN_FCC, {'P', 'R'}}, //PUERTO RICO
+ {REGDOMAIN_FCC, {'P', 'S'}}, //PALESTINIAN TERRITORY, OCCUPIED
+ {REGDOMAIN_ETSI, {'P', 'T'}}, //PORTUGAL
+ {REGDOMAIN_FCC, {'P', 'Y'}}, //PARAGUAY
+ {REGDOMAIN_ETSI, {'Q', 'A'}}, //QATAR
+ {REGDOMAIN_ETSI, {'R', 'E'}}, //REUNION
+ {REGDOMAIN_ETSI, {'R', 'O'}}, //ROMAINIA
+ {REGDOMAIN_ETSI, {'R', 'S'}}, //SERBIA
+ {REGDOMAIN_ETSI, {'R', 'U'}}, //RUSSIA
+ {REGDOMAIN_FCC, {'R', 'W'}}, //RWANDA
+ {REGDOMAIN_ETSI, {'S', 'A'}}, //SAUDI ARABIA
+ {REGDOMAIN_ETSI, {'S', 'E'}}, //SWEDEN
+ {REGDOMAIN_ETSI, {'S', 'G'}}, //SINGAPORE
+ {REGDOMAIN_ETSI, {'S', 'I'}}, //SLOVENNIA
+ {REGDOMAIN_ETSI, {'S', 'K'}}, //SLOVAKIA
+ {REGDOMAIN_ETSI, {'S', 'V'}}, //EL SALVADOR
+ {REGDOMAIN_ETSI, {'S', 'Y'}}, //SYRIAN ARAB REPUBLIC
+ {REGDOMAIN_ETSI, {'T', 'H'}}, //THAILAND
+ {REGDOMAIN_ETSI, {'T', 'N'}}, //TUNISIA
+ {REGDOMAIN_ETSI, {'T', 'R'}}, //TURKEY
+ {REGDOMAIN_ETSI, {'T', 'T'}}, //TRINIDAD AND TOBAGO
+ {REGDOMAIN_FCC, {'T', 'W'}}, //TAIWAN, PRIVINCE OF CHINA
+ {REGDOMAIN_FCC, {'T', 'Z'}}, //TANZANIA, UNITED REPUBLIC OF
+ {REGDOMAIN_ETSI, {'U', 'A'}}, //UKRAINE
+ {REGDOMAIN_ETSI, {'U', 'G'}}, //UGANDA
+ {REGDOMAIN_FCC, {'U', 'S'}}, //USA
+ {REGDOMAIN_ETSI, {'U', 'Y'}}, //URUGUAY
+ {REGDOMAIN_FCC, {'U', 'Z'}}, //UZBEKISTAN
+ {REGDOMAIN_ETSI, {'V', 'E'}}, //VENEZUELA
+ {REGDOMAIN_FCC, {'V', 'I'}}, //VIRGIN ISLANDS, US
+ {REGDOMAIN_ETSI, {'V', 'N'}}, //VIETNAM
+ {REGDOMAIN_ETSI, {'Y', 'E'}}, //YEMEN
+ {REGDOMAIN_ETSI, {'Y', 'T'}}, //MAYOTTE
+ {REGDOMAIN_ETSI, {'Z', 'A'}}, //SOUTH AFRICA
+ {REGDOMAIN_ETSI, {'Z', 'W'}}, //ZIMBABWE
+ }
+};
+
+#else
+
// cache of country info table;
// this is re-initialized from data on binary file
// loaded on driver initialization if available
@@ -371,13 +531,16 @@
{ REGDOMAIN_ETSI, {'Z', 'W'}}, //ZIMBABWE
}
};
+
+#endif
+
typedef struct nvEFSTable_s
{
v_U32_t nvValidityBitmap;
sHalNv halnv;
} nvEFSTable_t;
nvEFSTable_t *gnvEFSTable;
-/* EFS Table to send the NV structure to HAL*/
+/* EFS Table to send the NV structure to HAL*/
static nvEFSTable_t *pnvEFSTable;
static v_U8_t *pnvEncodedBuf;
static v_U8_t *pDictFile;
@@ -708,8 +871,8 @@
}
pnvEFSTable->nvValidityBitmap = gnvEFSTable->nvValidityBitmap;
- /* Copy the valid fields to the NV Global structure */
- if (vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid) ==
+ /* Copy the valid fields to the NV Global structure */
+ if (vos_nv_getValidity(VNV_FIELD_IMAGE, &itemIsValid) ==
VOS_STATUS_SUCCESS)
{
if (itemIsValid == VOS_TRUE) {
@@ -720,22 +883,22 @@
}
}
- if (vos_nv_getValidity(VNV_RATE_TO_POWER_TABLE, &itemIsValid) ==
+ if (vos_nv_getValidity(VNV_RATE_TO_POWER_TABLE, &itemIsValid) ==
VOS_STATUS_SUCCESS)
{
if (itemIsValid == VOS_TRUE)
{
- if(vos_nv_read( VNV_RATE_TO_POWER_TABLE,
+ if(vos_nv_read( VNV_RATE_TO_POWER_TABLE,
(v_VOID_t *)&pnvEFSTable->halnv.tables.pwrOptimum[0],
NULL, sizeof(tRateGroupPwr) * NUM_RF_SUBBANDS ) != VOS_STATUS_SUCCESS)
goto error;
}
}
- if (vos_nv_getValidity(VNV_REGULARTORY_DOMAIN_TABLE, &itemIsValid) ==
+ if (vos_nv_getValidity(VNV_REGULARTORY_DOMAIN_TABLE, &itemIsValid) ==
VOS_STATUS_SUCCESS)
{
-
+
if (itemIsValid == VOS_TRUE)
{
if(vos_nv_read( VNV_REGULARTORY_DOMAIN_TABLE,
@@ -745,7 +908,7 @@
}
}
- if (vos_nv_getValidity(VNV_DEFAULT_LOCATION, &itemIsValid) ==
+ if (vos_nv_getValidity(VNV_DEFAULT_LOCATION, &itemIsValid) ==
VOS_STATUS_SUCCESS)
{
if (itemIsValid == VOS_TRUE)
@@ -756,20 +919,20 @@
goto error;
}
}
-
- if (vos_nv_getValidity(VNV_TPC_POWER_TABLE, &itemIsValid) ==
+
+ if (vos_nv_getValidity(VNV_TPC_POWER_TABLE, &itemIsValid) ==
VOS_STATUS_SUCCESS)
{
if (itemIsValid == VOS_TRUE)
{
- if(vos_nv_read( VNV_TPC_POWER_TABLE,
+ if(vos_nv_read( VNV_TPC_POWER_TABLE,
(v_VOID_t *)&pnvEFSTable->halnv.tables.plutCharacterized[0],
NULL, sizeof(tTpcPowerTable) * NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
goto error;
}
}
-
- if (vos_nv_getValidity(VNV_TPC_PDADC_OFFSETS, &itemIsValid) ==
+
+ if (vos_nv_getValidity(VNV_TPC_PDADC_OFFSETS, &itemIsValid) ==
VOS_STATUS_SUCCESS)
{
if (itemIsValid == VOS_TRUE)
@@ -780,7 +943,7 @@
goto error;
}
}
- if (vos_nv_getValidity(VNV_RSSI_CHANNEL_OFFSETS, &itemIsValid) ==
+ if (vos_nv_getValidity(VNV_RSSI_CHANNEL_OFFSETS, &itemIsValid) ==
VOS_STATUS_SUCCESS)
{
if (itemIsValid == VOS_TRUE)
@@ -791,8 +954,8 @@
goto error;
}
}
-
- if (vos_nv_getValidity(VNV_HW_CAL_VALUES, &itemIsValid) ==
+
+ if (vos_nv_getValidity(VNV_HW_CAL_VALUES, &itemIsValid) ==
VOS_STATUS_SUCCESS)
{
if (itemIsValid == VOS_TRUE)
@@ -803,7 +966,7 @@
}
}
- if (vos_nv_getValidity(VNV_FW_CONFIG, &itemIsValid) ==
+ if (vos_nv_getValidity(VNV_FW_CONFIG, &itemIsValid) ==
VOS_STATUS_SUCCESS)
{
if (itemIsValid == VOS_TRUE)
@@ -814,59 +977,59 @@
}
}
- if (vos_nv_getValidity(VNV_ANTENNA_PATH_LOSS, &itemIsValid) ==
+ if (vos_nv_getValidity(VNV_ANTENNA_PATH_LOSS, &itemIsValid) ==
VOS_STATUS_SUCCESS)
{
if (itemIsValid == VOS_TRUE)
{
if(vos_nv_read( VNV_ANTENNA_PATH_LOSS,
- (v_VOID_t *)&pnvEFSTable->halnv.tables.antennaPathLoss[0], NULL,
+ (v_VOID_t *)&pnvEFSTable->halnv.tables.antennaPathLoss[0], NULL,
sizeof(tANI_S16)*NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
goto error;
}
}
- if (vos_nv_getValidity(VNV_PACKET_TYPE_POWER_LIMITS, &itemIsValid) ==
+ if (vos_nv_getValidity(VNV_PACKET_TYPE_POWER_LIMITS, &itemIsValid) ==
VOS_STATUS_SUCCESS)
{
if (itemIsValid == VOS_TRUE)
{
- if(vos_nv_read( VNV_PACKET_TYPE_POWER_LIMITS,
- (v_VOID_t *)&pnvEFSTable->halnv.tables.pktTypePwrLimits[0], NULL,
+ if(vos_nv_read( VNV_PACKET_TYPE_POWER_LIMITS,
+ (v_VOID_t *)&pnvEFSTable->halnv.tables.pktTypePwrLimits[0], NULL,
sizeof(tANI_S16)*NUM_802_11_MODES*NUM_RF_CHANNELS ) != VOS_STATUS_SUCCESS)
goto error;
}
}
- if (vos_nv_getValidity(VNV_OFDM_CMD_PWR_OFFSET, &itemIsValid) ==
+ if (vos_nv_getValidity(VNV_OFDM_CMD_PWR_OFFSET, &itemIsValid) ==
VOS_STATUS_SUCCESS)
{
if (itemIsValid == VOS_TRUE)
{
- if(vos_nv_read( VNV_OFDM_CMD_PWR_OFFSET,
- (v_VOID_t *)&pnvEFSTable->halnv.tables.ofdmCmdPwrOffset, NULL,
+ if(vos_nv_read( VNV_OFDM_CMD_PWR_OFFSET,
+ (v_VOID_t *)&pnvEFSTable->halnv.tables.ofdmCmdPwrOffset, NULL,
sizeof(sOfdmCmdPwrOffset)) != VOS_STATUS_SUCCESS)
goto error;
}
}
- if (vos_nv_getValidity(VNV_TX_BB_FILTER_MODE, &itemIsValid) ==
+ if (vos_nv_getValidity(VNV_TX_BB_FILTER_MODE, &itemIsValid) ==
VOS_STATUS_SUCCESS)
{
if (itemIsValid == VOS_TRUE)
{
- if(vos_nv_read(VNV_TX_BB_FILTER_MODE,
- (v_VOID_t *)&pnvEFSTable->halnv.tables.txbbFilterMode, NULL,
+ if(vos_nv_read(VNV_TX_BB_FILTER_MODE,
+ (v_VOID_t *)&pnvEFSTable->halnv.tables.txbbFilterMode, NULL,
sizeof(sTxBbFilterMode)) != VOS_STATUS_SUCCESS)
goto error;
}
}
- if (vos_nv_getValidity(VNV_TABLE_VIRTUAL_RATE, &itemIsValid) ==
+ if (vos_nv_getValidity(VNV_TABLE_VIRTUAL_RATE, &itemIsValid) ==
VOS_STATUS_SUCCESS)
{
if (itemIsValid == VOS_TRUE)
{
- if(vos_nv_read(VNV_TABLE_VIRTUAL_RATE,
- (v_VOID_t *)&pnvEFSTable->halnv.tables.pwrOptimum_virtualRate, NULL,
+ if(vos_nv_read(VNV_TABLE_VIRTUAL_RATE,
+ (v_VOID_t *)&pnvEFSTable->halnv.tables.pwrOptimum_virtualRate, NULL,
sizeof(gnvEFSTable->halnv.tables.pwrOptimum_virtualRate)) != VOS_STATUS_SUCCESS)
goto error;
}
@@ -900,138 +1063,7 @@
gnvEFSTable=NULL;
return VOS_STATUS_SUCCESS;
}
-/**------------------------------------------------------------------------
- \brief vos_nv_getRegDomainFromCountryCode() - get the regulatory domain of
- a country given its country code
- The \a vos_nv_getRegDomainFromCountryCode() returns the regulatory domain of
- a country given its country code. This is done from reading a cached
- copy of the binary file.
- \param pRegDomain - pointer to regulatory domain
- \param countryCode - country code
- \return VOS_STATUS_SUCCESS - regulatory domain is found for the given country
- VOS_STATUS_E_FAULT - invalid pointer error
- VOS_STATUS_E_EMPTY - country code table is empty
- VOS_STATUS_E_EXISTS - given country code does not exist in table
- \sa
- -------------------------------------------------------------------------*/
-VOS_STATUS vos_nv_getRegDomainFromCountryCode( v_REGDOMAIN_t *pRegDomain,
- const v_COUNTRYCODE_t countryCode )
-{
- int i;
- v_CONTEXT_t pVosContext = NULL;
- hdd_context_t *pHddCtx = NULL;
- struct wiphy *wiphy = NULL;
- int status;
- // sanity checks
- if (NULL == pRegDomain)
- {
- VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("Invalid reg domain pointer\r\n") );
- return VOS_STATUS_E_FAULT;
- }
- *pRegDomain = REGDOMAIN_COUNT;
- if (NULL == countryCode)
- {
- VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("Country code array is NULL\r\n") );
- return VOS_STATUS_E_FAULT;
- }
- if (0 == countryInfoTable.countryCount)
- {
- VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("Reg domain table is empty\r\n") );
- return VOS_STATUS_E_EMPTY;
- }
- /* 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_INFO_HIGH,
- "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_INFO_HIGH,
- "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_INFO_HIGH,
- "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;
- if (NULL == pHddCtx)
- {
- VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("Invalid pHddCtx pointer\r\n") );
- return VOS_STATUS_E_FAULT;
- }
-
- wiphy = pHddCtx->wiphy;
- INIT_COMPLETION(pHddCtx->driver_crda_req);
- regulatory_hint(wiphy, countryCode);
- status = wait_for_completion_interruptible_timeout(
- &pHddCtx->driver_crda_req,
- msecs_to_jiffies(CRDA_WAIT_TIME));
- if (!status)
- {
- VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- "%s: Timeout waiting for CRDA REQ", __func__);
- }
-
- if (crda_regulatory_run_time_entry_valid == VOS_TRUE)
- {
- VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
- "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;
- }
- }
-
- // iterate the country info table until end of table or the country code
- // is found
- for (i = 0; i < countryInfoTable.countryCount &&
- REGDOMAIN_COUNT == *pRegDomain; i++)
- {
- if (memcmp(countryCode, countryInfoTable.countryInfo[i].countryCode,
- VOS_COUNTRY_CODE_LEN) == 0)
- {
- // country code is found
- *pRegDomain = countryInfoTable.countryInfo[i].regDomain;
- }
- }
- if (REGDOMAIN_COUNT != *pRegDomain)
- {
- return VOS_STATUS_SUCCESS;
- }
- else
- {
- VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
- ("country code is not found\r\n"));
- return VOS_STATUS_E_EXISTS;
- }
-}
/**------------------------------------------------------------------------
\brief vos_nv_getSupportedCountryCode() - get the list of supported
country codes
@@ -1049,6 +1081,7 @@
sufficient
\sa
-------------------------------------------------------------------------*/
+
VOS_STATUS vos_nv_getSupportedCountryCode( v_BYTE_t *pBuffer, v_SIZE_t *pBufferSize,
v_SIZE_t paddingSize )
{
@@ -1059,7 +1092,7 @@
if ( NULL == pBuffer || providedBufferSize < *pBufferSize )
{
VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
- ("Insufficient memory for country code list\r\n"));
+ ("Insufficient memory for country code list"));
return VOS_STATUS_E_NOMEM;
}
for (i = 0; i < countryInfoTable.countryCount; i++)
@@ -1231,7 +1264,7 @@
gnvEFSTable->nvValidityBitmap = newNvValidityBitmap;
status = wlan_write_to_efs((v_U8_t*)gnvEFSTable,sizeof(nvEFSTable_t));
if (! VOS_IS_STATUS_SUCCESS(status)) {
- VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, ("vos_nv_write_to_efs failed!!!\r\n"));
+ VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, ("vos_nv_write_to_efs failed!!!"));
status = VOS_STATUS_E_FAULT;
}
}
@@ -1292,7 +1325,7 @@
v_SIZE_t itemSize;
v_BOOL_t itemIsValid = VOS_TRUE;
- // sanity check
+ /* sanity check */
if (VNV_TYPE_COUNT <= type)
{
VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
@@ -1302,13 +1335,13 @@
if (NULL == outputVoidBuffer)
{
VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("Buffer provided is NULL\r\n") );
+ ("Buffer provided is NULL") );
return VOS_STATUS_E_FAULT;
}
if (0 == bufferSize)
{
VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("NV type=%d is invalid\r\n"), type );
+ ("NV type=%d is invalid"), type );
return VOS_STATUS_E_INVAL;
}
// check if the NV item has valid data
@@ -1316,7 +1349,7 @@
if (!itemIsValid)
{
VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
- "NV type=%d does not have valid data\r\n", type );
+ "NV type=%d does not have valid data", type );
return VOS_STATUS_E_EMPTY;
}
switch(type)
@@ -1325,7 +1358,7 @@
itemSize = sizeof(gnvEFSTable->halnv.fields);
if(bufferSize != itemSize) {
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
+ ("type = %d buffer size=%d is less than data size=%d"), type, bufferSize,
itemSize);
status = VOS_STATUS_E_INVAL;
}
@@ -1337,7 +1370,7 @@
itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum);
if(bufferSize != itemSize) {
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
+ ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
itemSize);
status = VOS_STATUS_E_INVAL;
}
@@ -1349,7 +1382,7 @@
itemSize = sizeof(gnvEFSTable->halnv.tables.regDomains);
if(bufferSize != itemSize) {
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
+ ("type = %d buffer size=%d is less than data size=%d"), type, bufferSize,
itemSize);
status = VOS_STATUS_E_INVAL;
}
@@ -1361,7 +1394,7 @@
itemSize = sizeof(gnvEFSTable->halnv.tables.defaultCountryTable);
if(bufferSize != itemSize) {
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
+ ("type = %d buffer size=%d is less than data size=%d"), type, bufferSize,
itemSize);
status = VOS_STATUS_E_INVAL;
}
@@ -1373,7 +1406,7 @@
itemSize = sizeof(gnvEFSTable->halnv.tables.plutCharacterized);
if(bufferSize != itemSize) {
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
+ ("type = %d buffer size=%d is less than data size=%d"), type, bufferSize,
itemSize);
status = VOS_STATUS_E_INVAL;
}
@@ -1385,7 +1418,7 @@
itemSize = sizeof(gnvEFSTable->halnv.tables.plutPdadcOffset);
if(bufferSize != itemSize) {
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
+ ("type = %d buffer size=%d is less than data size=%d"), type, bufferSize,
itemSize);
status = VOS_STATUS_E_INVAL;
}
@@ -1400,7 +1433,7 @@
if(bufferSize != itemSize) {
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
+ ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
itemSize);
status = VOS_STATUS_E_INVAL;
}
@@ -1415,7 +1448,7 @@
if(bufferSize != itemSize) {
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
+ ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
itemSize);
status = VOS_STATUS_E_INVAL;
}
@@ -1424,13 +1457,13 @@
}
break;
case VNV_FW_CONFIG:
-
+
itemSize = sizeof(gnvEFSTable->halnv.tables.fwConfig);
-
+
if(bufferSize != itemSize) {
-
+
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
+ ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
itemSize);
status = VOS_STATUS_E_INVAL;
}
@@ -1442,7 +1475,7 @@
itemSize = sizeof(gnvEFSTable->halnv.tables.antennaPathLoss);
if(bufferSize != itemSize) {
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
+ ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
itemSize);
status = VOS_STATUS_E_INVAL;
}
@@ -1454,7 +1487,7 @@
itemSize = sizeof(gnvEFSTable->halnv.tables.pktTypePwrLimits);
if(bufferSize != itemSize) {
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
+ ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
itemSize);
status = VOS_STATUS_E_INVAL;
}
@@ -1466,7 +1499,7 @@
itemSize = sizeof(gnvEFSTable->halnv.tables.ofdmCmdPwrOffset);
if(bufferSize != itemSize) {
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
+ ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
itemSize);
status = VOS_STATUS_E_INVAL;
}
@@ -1478,7 +1511,7 @@
itemSize = sizeof(gnvEFSTable->halnv.tables.txbbFilterMode);
if(bufferSize != itemSize) {
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
+ ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
itemSize);
status = VOS_STATUS_E_INVAL;
}
@@ -1492,7 +1525,7 @@
itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum_virtualRate);
if(bufferSize != itemSize) {
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
+ ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
itemSize);
status = VOS_STATUS_E_INVAL;
}
@@ -1527,7 +1560,7 @@
VOS_STATUS status = VOS_STATUS_SUCCESS;
v_SIZE_t itemSize;
- // sanity check
+ /* sanity check */
if (VNV_TYPE_COUNT <= type)
{
VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
@@ -1537,13 +1570,13 @@
if (NULL == inputVoidBuffer)
{
VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("Buffer provided is NULL\r\n") );
+ ("Buffer provided is NULL") );
return VOS_STATUS_E_FAULT;
}
if (0 == bufferSize)
{
VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("NV type=%d is invalid\r\n"), type );
+ ("NV type=%d is invalid"), type );
return VOS_STATUS_E_INVAL;
}
switch(type)
@@ -1552,7 +1585,7 @@
itemSize = sizeof(gnvEFSTable->halnv.fields);
if(bufferSize != itemSize) {
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
+ ("type = %d buffer size=%d is less than data size=%d"), type, bufferSize,
itemSize);
status = VOS_STATUS_E_INVAL;
}
@@ -1564,7 +1597,7 @@
itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum);
if(bufferSize != itemSize) {
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
+ ("type = %d buffer size=%d is less than data size=%d"), type, bufferSize,
itemSize);
status = VOS_STATUS_E_INVAL;
}
@@ -1576,7 +1609,7 @@
itemSize = sizeof(gnvEFSTable->halnv.tables.regDomains);
if(bufferSize != itemSize) {
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
+ ("type = %d buffer size=%d is less than data size=%d"), type, bufferSize,
itemSize);
status = VOS_STATUS_E_INVAL;
}
@@ -1588,7 +1621,7 @@
itemSize = sizeof(gnvEFSTable->halnv.tables.defaultCountryTable);
if(bufferSize != itemSize) {
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
+ ("type = %d buffer size=%d is less than data size=%d"), type, bufferSize,
itemSize);
status = VOS_STATUS_E_INVAL;
}
@@ -1600,7 +1633,7 @@
itemSize = sizeof(gnvEFSTable->halnv.tables.plutCharacterized);
if(bufferSize != itemSize) {
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
+ ("type = %d buffer size=%d is less than data size=%d"), type, bufferSize,
itemSize);
status = VOS_STATUS_E_INVAL;
}
@@ -1612,7 +1645,7 @@
itemSize = sizeof(gnvEFSTable->halnv.tables.plutPdadcOffset);
if(bufferSize != itemSize) {
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
+ ("type = %d buffer size=%d is less than data size=%d"), type, bufferSize,
itemSize);
status = VOS_STATUS_E_INVAL;
}
@@ -1627,7 +1660,7 @@
if(bufferSize != itemSize) {
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
+ ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
itemSize);
status = VOS_STATUS_E_INVAL;
}
@@ -1642,7 +1675,7 @@
if(bufferSize != itemSize) {
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
+ ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
itemSize);
status = VOS_STATUS_E_INVAL;
}
@@ -1651,13 +1684,13 @@
}
break;
case VNV_FW_CONFIG:
-
+
itemSize = sizeof(gnvEFSTable->halnv.tables.fwConfig);
-
+
if(bufferSize != itemSize) {
-
+
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
+ ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
itemSize);
status = VOS_STATUS_E_INVAL;
}
@@ -1669,7 +1702,7 @@
itemSize = sizeof(gnvEFSTable->halnv.tables.antennaPathLoss);
if(bufferSize != itemSize) {
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
+ ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
itemSize);
status = VOS_STATUS_E_INVAL;
}
@@ -1682,7 +1715,7 @@
itemSize = sizeof(gnvEFSTable->halnv.tables.pktTypePwrLimits);
if(bufferSize != itemSize) {
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
+ ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
itemSize);
status = VOS_STATUS_E_INVAL;
}
@@ -1695,7 +1728,7 @@
itemSize = sizeof(gnvEFSTable->halnv.tables.ofdmCmdPwrOffset);
if(bufferSize != itemSize) {
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
+ ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
itemSize);
status = VOS_STATUS_E_INVAL;
}
@@ -1708,7 +1741,7 @@
itemSize = sizeof(gnvEFSTable->halnv.tables.txbbFilterMode);
if(bufferSize != itemSize) {
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
+ ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
itemSize);
status = VOS_STATUS_E_INVAL;
}
@@ -1716,13 +1749,13 @@
memcpy(&gnvEFSTable->halnv.tables.txbbFilterMode,inputVoidBuffer,bufferSize);
}
break;
-
+
case VNV_TABLE_VIRTUAL_RATE:
itemSize = sizeof(gnvEFSTable->halnv.tables.pwrOptimum_virtualRate);
if(bufferSize != itemSize) {
VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- ("type = %d buffer size=%d is less than data size=%d\r\n"),type, bufferSize,
+ ("type = %d buffer size=%d is less than data size=%d"),type, bufferSize,
itemSize);
status = VOS_STATUS_E_INVAL;
}
@@ -1739,13 +1772,13 @@
// set NV item to have valid data
status = vos_nv_setValidity( type, VOS_TRUE );
if (! VOS_IS_STATUS_SUCCESS(status)) {
- VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, ("vos_nv_setValidity failed!!!\r\n"));
+ VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, ("vos_nv_setValidity failed!!!"));
status = VOS_STATUS_E_FAULT;
}
status = wlan_write_to_efs((v_U8_t*)gnvEFSTable,sizeof(nvEFSTable_t));
if (! VOS_IS_STATUS_SUCCESS(status)) {
- VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, ("vos_nv_write_to_efs failed!!!\r\n"));
+ VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, ("vos_nv_write_to_efs failed!!!"));
status = VOS_STATUS_E_FAULT;
}
}
@@ -1771,7 +1804,7 @@
{
VOS_STATUS status = VOS_STATUS_SUCCESS;
int i, count;
-
+
//TODO: Dont want to use pMac here...can we instead store the curRegDomain in NV
// or pass it as a parameter to NV from SME?
@@ -1803,7 +1836,7 @@
//center channels for 2.4 Ghz 40 MHz channels
for( i = RF_CHAN_BOND_3; i <= RF_CHAN_BOND_11; i++ )
{
-
+
if( regChannels[i].enabled )
{
channels40MHz[count].chanId = rfChannels[i].channelNum;
@@ -1813,7 +1846,7 @@
//center channels for 5 Ghz 40 MHz channels
for( i = RF_CHAN_BOND_38; i <= RF_CHAN_BOND_163; i++ )
{
-
+
if( regChannels[i].enabled )
{
channels40MHz[count].chanId = rfChannels[i].channelNum;
@@ -1881,7 +1914,7 @@
-------------------------------------------------------------------------*/
VOS_STATUS vos_nv_readDefaultCountryTable( uNvTables *tableData )
{
-
+
VOS_STATUS status = VOS_STATUS_SUCCESS;
memcpy(&tableData->defaultCountryTable, &pnvEFSTable->halnv.tables.defaultCountryTable, sizeof(sDefaultCountry));
pr_info("DefaultCountry is %c%c\n",
@@ -1891,7 +1924,7 @@
}
/**------------------------------------------------------------------------
- \brief vos_nv_getBuffer -
+ \brief vos_nv_getBuffer -
\param pBuffer - to return the buffer address
pSize - buffer size.
\return status of the NV read operation
@@ -1963,7 +1996,7 @@
}
/**------------------------------------------------------------------------
- \brief vos_nv_setRegDomain -
+ \brief vos_nv_setRegDomain -
\param clientCtxt - Client Context, Not used for PRIMA
regId - Regulatory Domain ID
\return status set REG domain operation
@@ -1973,7 +2006,7 @@
{
v_CONTEXT_t pVosContext = NULL;
hdd_context_t *pHddCtx = NULL;
- struct wiphy *wiphy = NULL;
+
/* Client Context Argumant not used for PRIMA */
if (regId >= REGDOMAIN_COUNT)
{
@@ -1990,20 +2023,11 @@
/* Set correct channel information based on REG Domain */
regChannels = pnvEFSTable->halnv.tables.regDomains[regId].channels;
- /* when CRDA is not running then we are world roaming.
- In this case if 11d is enabled, then country code should
- be update on basis of world roaming */
- if ((NULL != pHddCtx) && (memcmp(pHddCtx->cfg_ini->crdaDefaultCountryCode,
- CFG_CRDA_DEFAULT_COUNTRY_CODE_DEFAULT , 2) == 0))
- {
- wiphy = pHddCtx->wiphy;
- regulatory_hint(wiphy, "00");
- }
return VOS_STATUS_SUCCESS;
}
/**------------------------------------------------------------------------
- \brief vos_nv_getChannelEnabledState -
+ \brief vos_nv_getChannelEnabledState -
\param rfChannel - input channel enum to know evabled state
\return eNVChannelEnabledType enabled state for channel
* enabled
@@ -2039,691 +2063,973 @@
}
/******************************************************************
- Add CRDA regulatory support
+ Add driver/linux regulatory support
*******************************************************************/
+#ifdef CONFIG_ENABLE_LINUX_REG
+
+/* 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;
+
+ /* 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;
+
+ 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 */
+
+ /* 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;
+
+ /* 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;
+
+ /* 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;
+
+ 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 */
+
+ /* 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;
+
+ /* 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; /* 5G 40MHz channel */
+ break;
+ default:
+ break;
+ }
+ return VOS_FALSE;
+}
+
+
+/* create_linux_regulatory_entry should */
+static void create_linux_regulatory_entry_driver(struct wiphy *wiphy,
+ struct regulatory_request *request,
+ v_U8_t nBandCapability,
+ v_REGDOMAIN_t domain_id)
+{
+ int i, j, n;
+ int bw20_start_channel_index, bw20_end_channel_index;
+ int bw40_start_channel_index, bw40_end_channel_index;
+
+
+ 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: 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: 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 rule, 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 & IEEE80211_CHAN_PASSIVE_SCAN) ||
+ (wiphy->regd->reg_rules[i].flags & IEEE80211_CHAN_RADAR))
+ {
+ 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 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: req 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 & IEEE80211_CHAN_PASSIVE_SCAN) ||
+ (wiphy->regd->reg_rules[i].flags & IEEE80211_CHAN_RADAR))
+ {
+ 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);
+ }
+ }
+ }
+
+}
+
+/*
+ note: these functions may get used at a later point in time
+
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;
+ 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;
+ 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;
+ 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;
+ 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;
+ m = k - RF_CHAN_149 + RF_CHAN_BOND_151;
+ if (m > RF_CHAN_BOND_163)
+ m = RF_CHAN_BOND_163;
}
-return m;
+
+ return m;
}
-void crda_regulatory_entry_default(v_U8_t *countryCode, int domain_id)
+
+static int create_linux_regulatory_entry_other(struct wiphy *wiphy,
+ struct regulatory_request *request,
+ v_U8_t nBandCapability,
+ v_REGDOMAIN_t domain_id)
{
- int k;
- pr_info("Country %c%c domain_id %d\n enable ch 1 - 11.\n",
- countryCode[0], countryCode[1], domain_id);
- for (k = RF_CHAN_1; k <= RF_CHAN_11; k++) {
- pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
- NV_CHANNEL_ENABLE;
- /* Max Tx Power 20dBm */
- pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 20;
- }
- /* enable ch 12 to ch 14 passive scan */
- pr_info(" enable ch 12 - 14 to scan passively by setting DFS flag.\n");
- for (k = RF_CHAN_12; k <= MAX_2_4GHZ_CHANNEL; k++) {
- pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
- NV_CHANNEL_DFS;
- pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 0;
- }
- pr_info(" enable 5GHz to scan passively by setting DFS flag.\n");
- for (k = MIN_5GHZ_CHANNEL; k <= MAX_5GHZ_CHANNEL; k++) {
- pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
- NV_CHANNEL_DFS;
- pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 0;
- }
-#ifdef PASSIVE_SCAN_4_9GHZ
- pr_info(" enable 4.9 GHz to scan passively by setting DFS flag.\n");
- for (k = RF_CHAN_240; k <= RF_CHAN_216; k++) {
- pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
- NV_CHANNEL_DFS;
- pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit = 0;
- }
-#endif
- if (domain_id == NUM_REG_DOMAINS-1)
- { /* init time */
- crda_alpha2[0] = countryCode[0];
- crda_alpha2[1] = countryCode[1];
- crda_regulatory_entry_valid = VOS_TRUE;
- pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[0] = countryCode[0];
- pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[1] = countryCode[1];
- pnvEFSTable->halnv.tables.defaultCountryTable.countryCode[2] = 'I';
- pnvEFSTable->halnv.tables.defaultCountryTable.regDomain = NUM_REG_DOMAINS-1;
- }
- if (domain_id == NUM_REG_DOMAINS-2)
- { /* none-default country */
- run_time_alpha2[0] = countryCode[0];
- run_time_alpha2[1] = countryCode[1];
- crda_regulatory_run_time_entry_valid = VOS_TRUE;
- }
-}
+ int i, j, m;
+ int k = 0, n = 0;
-static int crda_regulatory_entry_post_processing(struct wiphy *wiphy,
- struct regulatory_request *request,
- v_U8_t nBandCapability,
- int domain_id)
-{
- if (request->alpha2[0] == '0' && request->alpha2[1] == '0') {
- pr_info("Country 00 special handling to enable passive scan.\n");
- crda_regulatory_entry_default(request->alpha2, domain_id);
- }
- return 0;
-}
+ if (pnvEFSTable == NULL)
+ {
+ pr_info("error: pnvEFSTable is NULL, probably not parsed nv.bin yet\n");
+ return -1;
+ }
-/* 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 */
+ //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++)
+
+ 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
+
+ //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++)
+
+ 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) 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;
+ 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);
+
+ pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
+ NV_CHANNEL_DISABLE;
+ pnvEFSTable->halnv.tables.regDomains[domain_id].channels[n].enabled =
+ NV_CHANNEL_DISABLE;
}
+
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 * dBm
- pnvEFSTable->halnv.tables.regDomains[NUM_REG_DOMAINS-2].channels[k].pwrLimit =
- (tANI_S8) ((wiphy->bands[i]->channels[j].max_power)/100);
- 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)/100)-3);
- }
+ pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
+ NV_CHANNEL_DFS;
+
+ // max_power is in mBm = 100 * dBm
+ pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit =
+ (tANI_S8) ((wiphy->bands[i]->channels[j].max_power)/100);
+ if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == 0)
+ {
+ pnvEFSTable->halnv.tables.regDomains[domain_id].channels[n].enabled =
+ NV_CHANNEL_DFS;
+ // 40MHz channel power is half of 20MHz (-3dB) ??
+ pnvEFSTable->halnv.tables.regDomains[domain_id].channels[n].pwrLimit =
+ (tANI_S8) (((wiphy->bands[i]->channels[j].max_power)/100)-3);
+ }
}
+
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)/100);
- 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)/100)-3);
- }
+ pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].enabled =
+ NV_CHANNEL_ENABLE;
+
+ // max_power is in dBm
+ pnvEFSTable->halnv.tables.regDomains[domain_id].channels[k].pwrLimit =
+ (tANI_S8) ((wiphy->bands[i]->channels[j].max_power)/100);
+ if ((wiphy->bands[i]->channels[j].flags & IEEE80211_CHAN_NO_HT40) == 0)
+ {
+ pnvEFSTable->halnv.tables.regDomains[domain_id].channels[n].enabled =
+ NV_CHANNEL_ENABLE;
+
+ // 40MHz channel power is half of 20MHz (-3dB) ??
+ pnvEFSTable->halnv.tables.regDomains[domain_id].channels[n].pwrLimit =
+ (tANI_S8) (((wiphy->bands[i]->channels[j].max_power)/100)-3);
+ }
}
- /* ignore CRDA max_antenna_gain typical is 3dBi, nv.bin antennaGain is
- real gain which should be provided by the real design */
+
+ // ignore 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;
- crda_regulatory_entry_post_processing(wiphy, request, nBandCapability, NUM_REG_DOMAINS-2);
-return 0;
-}
-v_BOOL_t is_crda_regulatory_entry_valid(void)
-{
-return crda_regulatory_entry_valid;
+
+ return 0;
}
-/* 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)
+/**------------------------------------------------------------------------
+ \brief vos_nv_getRegDomainFromCountryCode() - get the regulatory domain of
+ a country given its country code
+ The \a vos_nv_getRegDomainFromCountryCode() returns the regulatory domain of
+ a country given its country code. This is done from reading a cached
+ copy of the binary file.
+ \param pRegDomain - pointer to regulatory domain
+ \param countryCode - country code
+ \return VOS_STATUS_SUCCESS - regulatory domain is found for the given country
+ VOS_STATUS_E_FAULT - invalid pointer error
+ VOS_STATUS_E_EMPTY - country code table is empty
+ VOS_STATUS_E_EXISTS - given country code does not exist in table
+ \sa
+ -------------------------------------------------------------------------*/
+VOS_STATUS vos_nv_getRegDomainFromCountryCode( v_REGDOMAIN_t *pRegDomain,
+ const v_COUNTRYCODE_t countryCode )
{
-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;
- //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;
-return -1;
-}
+ v_CONTEXT_t pVosContext = NULL;
+ hdd_context_t *pHddCtx = NULL;
+ struct wiphy *wiphy = NULL;
+ int i;
-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
- //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;
- //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;
-}
+ /* sanity checks */
+ if (NULL == pRegDomain)
+ {
+ VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+ ("Invalid reg domain pointer") );
+ return VOS_STATUS_E_FAULT;
+ }
-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;
- //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;
-return -1;
-}
+ *pRegDomain = REGDOMAIN_COUNT;
-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
- //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;
- //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;
-}
+ if (NULL == countryCode)
+ {
+ VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+ ("Country code array is NULL"));
+ return VOS_STATUS_E_FAULT;
+ }
-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;
-}
+ if (0 == countryInfoTable.countryCount)
+ {
+ VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+ ("Reg domain table is empty") );
+ return VOS_STATUS_E_EMPTY;
+ }
-/* 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;
+ pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
- 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)
+ if (NULL != pVosContext)
+ pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext);
+ else
+ return VOS_STATUS_E_EXISTS;
+
+ if (NULL == pHddCtx)
+ {
+ VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+ ("Invalid pHddCtx pointer") );
+ return VOS_STATUS_E_FAULT;
+ }
+
+ wiphy = pHddCtx->wiphy;
+
+
+ /* We need to query the kernel to get the regulatory information
+ for this country */
+
+
+ if (VOS_FALSE == linux_regulatory_init) {
+
+ /* linux regulatory has not been initialized yet; so the country
+ information stored with us would not be correct */
+
+ /* lookup the country in the local database */
+
+ VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
+ ("init time regdomain request") );
+
+ temp_reg_domain = REGDOMAIN_COUNT;
+ for (i = 0; i < countryInfoTable.countryCount &&
+ REGDOMAIN_COUNT == temp_reg_domain; i++)
+ {
+ if (memcmp(countryCode, countryInfoTable.countryInfo[i].countryCode,
+ VOS_COUNTRY_CODE_LEN) == 0)
{
- 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);
+ /* country code is found */
+ /* record the temporary regulatory_domain as well */
+ temp_reg_domain = countryInfoTable.countryInfo[i].regDomain;
}
- else
+ }
+
+ if (REGDOMAIN_COUNT == temp_reg_domain) {
+ /* the country was not found in the driver database */
+ /* therefore switch to world regulatory domain */
+
+ *pRegDomain = REGDOMAIN_WORLD;
+ cur_reg_domain = *pRegDomain;
+ linux_reg_cc[0] = '0';
+ linux_reg_cc[1] = '0';
+ pnvEFSTable->halnv.tables.defaultCountryTable.regDomain =
+ *pRegDomain;
+
+ /* since it is the world domain, we are guaranteed
+ the entry exists in the kernel regulatory database */
+
+ kernel_reg_request_made = VOS_TRUE;
+ driver_callback_called = VOS_FALSE;
+
+ init_completion(&pHddCtx->linux_reg_req);
+ regulatory_hint(wiphy, linux_reg_cc);
+ wait_for_completion_interruptible_timeout(&pHddCtx->linux_reg_req,
+ LINUX_REG_WAIT_TIME);
+
+ VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
+ ("country code is not found in driver db"));
+
+ linux_regulatory_init = VOS_TRUE;
+ return VOS_STATUS_E_EXISTS;
+ }
+
+ else {
+ /* the country code was found in the driver database */
+ /* now get the regulatory information from the kernel
+ database */
+
+ VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
+ ("country code found in driver db"));
+
+ kernel_reg_request_made = VOS_TRUE;
+ driver_callback_called = VOS_FALSE;
+
+ init_completion(&pHddCtx->linux_reg_req);
+ regulatory_hint(wiphy, countryCode);
+ wait_for_completion_interruptible_timeout(&pHddCtx->linux_reg_req,
+ LINUX_REG_WAIT_TIME);
+
+ /* if the country information does not exist with the kernel, then
+ the driver callback would not be called */
+
+ if (VOS_TRUE == driver_callback_called) {
+
+ /* the driver callback was called. this means the country
+ regulatory information was found in the kernel database.
+ The callback would have updated the internal database. Here
+ update the country and the return value for the regulatory
+ domain */
+
+ *pRegDomain = temp_reg_domain;
+ cur_reg_domain = temp_reg_domain;
+ linux_reg_cc[0] = countryCode[0];
+ linux_reg_cc[1] = countryCode[1];
+ pnvEFSTable->halnv.tables.defaultCountryTable.regDomain =
+ *pRegDomain;
+
+ VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
+ ("country code is found in kernel db"));
+
+ linux_regulatory_init = VOS_TRUE;
+ return VOS_STATUS_SUCCESS;
+ }
+ else {
+
+ /* the country information has not been found in the kernel
+ database, revert to world domain */
+
+ *pRegDomain = REGDOMAIN_WORLD;
+ cur_reg_domain = *pRegDomain;
+ linux_reg_cc[0] = '0';
+ linux_reg_cc[1] = '0';
+ pnvEFSTable->halnv.tables.defaultCountryTable.regDomain =
+ *pRegDomain;
+
+ /* since it is the world domain, we are guaranteed
+ the entry exists in the kernel regulatory database */
+
+ kernel_reg_request_made = VOS_TRUE;
+ driver_callback_called = VOS_FALSE;
+
+ init_completion(&pHddCtx->linux_reg_req);
+ regulatory_hint(wiphy, linux_reg_cc);
+ wait_for_completion_interruptible_timeout(&pHddCtx->linux_reg_req,
+ LINUX_REG_WAIT_TIME);
+
+ VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
+ ("country code is not found in kernel db"));
+
+ linux_regulatory_init = VOS_TRUE;
+ return VOS_STATUS_E_EXISTS;
+ }
+ }
+ }
+ else {
+ /* it is not the init time query but a runtime query. So first
+ compare the country code with the existing current country code
+ . If both are same there is no need to query any database */
+
+ VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
+ ("run time regdomain request"));
+
+ if ((countryCode[0] == linux_reg_cc[0]) &&
+ (countryCode[1] == linux_reg_cc[1])) {
+
+ /* country code already exists */
+ *pRegDomain = cur_reg_domain;
+
+ VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
+ ("NOT NEW country code"));
+
+ return VOS_STATUS_SUCCESS;
+ }
+ else {
+
+ /* first lookup the country in the local database */
+
+ VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
+ ("NEW country code"));
+
+ for (i = 0; i < countryInfoTable.countryCount &&
+ REGDOMAIN_COUNT == temp_reg_domain; i++)
{
- 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);
+ if (memcmp(countryCode, countryInfoTable.countryInfo[i].countryCode,
+ VOS_COUNTRY_CODE_LEN) == 0)
+ {
+ /* country code is found */
+ /* record the temporary regulatory_domain as well */
+ temp_reg_domain = countryInfoTable.countryInfo[i].regDomain;
+ }
}
- /* 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;
- }
- crda_regulatory_entry_post_processing(wiphy, request, nBandCapability, domain_id);
- return 0;
+
+ if (REGDOMAIN_COUNT == temp_reg_domain) {
+
+ /* the country was not found in the driver database */
+ /* therefore switch to world regulatory domain */
+
+ *pRegDomain = REGDOMAIN_WORLD;
+ cur_reg_domain = *pRegDomain;
+ linux_reg_cc[0] = countryCode[0];
+ linux_reg_cc[1] = countryCode[1];
+
+ /* since it is the world domain, we are guaranteed
+ the entry exists in the kernel regulatory database */
+
+ kernel_reg_request_made = VOS_TRUE;
+ driver_callback_called = VOS_FALSE;
+
+ init_completion(&pHddCtx->linux_reg_req);
+ regulatory_hint(wiphy, linux_reg_cc);
+ wait_for_completion_interruptible_timeout(&pHddCtx->linux_reg_req,
+ LINUX_REG_WAIT_TIME);
+
+ VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
+ ("country code is not found in driver db"));
+
+ return VOS_STATUS_E_EXISTS;
+ }
+
+ else {
+
+ /* the country code was found in the driver database */
+ /* now get the regulatory information from the kernel
+ database */
+
+ VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
+ ("country code found in driver db"));
+
+ kernel_reg_request_made = VOS_TRUE;
+ driver_callback_called = VOS_FALSE;
+
+ init_completion(&pHddCtx->linux_reg_req);
+ regulatory_hint(wiphy, countryCode);
+ wait_for_completion_interruptible_timeout(&pHddCtx->linux_reg_req,
+ LINUX_REG_WAIT_TIME);
+
+ /* if the country information does not exist with the kernel,
+ then the driver callback would not be called */
+
+ if (VOS_TRUE == driver_callback_called) {
+
+ /* the driver callback was called. this means the country
+ regulatory information was found in the kernel database.
+ The callback would have updated the internal database. Here
+ update the country and the return value for the regulatory
+ domain */
+
+ *pRegDomain = temp_reg_domain;
+ cur_reg_domain = temp_reg_domain;
+ linux_reg_cc[0] = countryCode[0];
+ linux_reg_cc[1] = countryCode[1];
+
+ VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
+ ("country code is found in kernel db"));
+
+ return VOS_STATUS_SUCCESS;
+ }
+ else {
+
+ /* the country information has not been found in the kernel
+ database, revert to world domain */
+
+ *pRegDomain = REGDOMAIN_WORLD;
+ cur_reg_domain = *pRegDomain;
+ linux_reg_cc[0] = countryCode[0];
+ linux_reg_cc[1] = countryCode[1];
+
+ /* since it is the world domain, we are guaranteed
+ the entry exists in the kernel regulatory database */
+
+ kernel_reg_request_made = VOS_TRUE;
+ driver_callback_called = VOS_FALSE;
+
+ init_completion(&pHddCtx->linux_reg_req);
+ regulatory_hint(wiphy, linux_reg_cc);
+ wait_for_completion_interruptible_timeout(&pHddCtx->linux_reg_req,
+ LINUX_REG_WAIT_TIME);
+
+ VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
+ ("country code is not found in kernel db"));
+
+ return VOS_STATUS_E_EXISTS;
+ }
+ }
+ }
+ }
}
/*
- * Function: wlan_hdd_crda_reg_notifier
+ * Function: wlan_hdd_linux_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.
*/
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
-void wlan_hdd_crda_reg_notifier(struct wiphy *wiphy,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
+void wlan_hdd_linux_reg_notifier(struct wiphy *wiphy,
struct regulatory_request *request)
#else
-int wlan_hdd_crda_reg_notifier(struct wiphy *wiphy,
+void wlan_hdd_linux_reg_notifier(struct wiphy *wiphy,
struct regulatory_request *request)
#endif
{
+
+ v_REGDOMAIN_t reg_domain = REGDOMAIN_COUNT;
hdd_context_t *pHddCtx = wiphy_priv(wiphy);
- v_REGDOMAIN_t domainIdCurrent;
- tANI_U8 ccode[WNI_CFG_COUNTRY_CODE_LEN];
- tANI_U8 uBufLen = WNI_CFG_COUNTRY_CODE_LEN;
- tANI_U8 nBandCapability;
- int i,j,k,m;
+
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)
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
- return;
-#else
- return 0;
-#endif
- // 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);
+ " %c%c\n", request->alpha2[0], request->alpha2[1]);
+
+ /* first check if this callback is in response to the driver callback */
+
+ if (VOS_TRUE == kernel_reg_request_made) {
+
+
+ /* this is the driver query to the kernel. the regulatory domain was
+ temporarily calculated by the entity that made the kernel query.
+ Use that to update the internal database */
+
+ reg_domain = temp_reg_domain;
+ create_linux_regulatory_entry_driver(wiphy, request,
+ pHddCtx->cfg_ini->nBandCapability,
+ reg_domain);
+
+ driver_callback_called = VOS_TRUE;
+ kernel_reg_request_made = VOS_FALSE;
+
}
- 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)
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
- return;
-#else
- return 0;
-#endif
- // ToDo
- /* Intersect of 11d and crda settings */
+ else {
- /* 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);
+
+ /* this callback is not in response to driver callback.
+ we should contact the lower layers(sme_ChangeCountryCode ??)
+ with this information. Depending on whether the lower layer
+ recommends changing the country code or not, we can update the
+ internal database */
+
+ /*
+ ret_val = create_linux_regulatory_entry_other(wiphy, request,
+ pHddCtx->cfg_ini->nBandCapability,
+ reg_domain);
+ */
+
}
- else if (request->initiator == NL80211_REGDOM_SET_BY_DRIVER ||
- (request->initiator == NL80211_REGDOM_SET_BY_CORE))
- {
- if ( eHAL_STATUS_SUCCESS != sme_GetCountryCode(pHddCtx->hHal, ccode, &uBufLen))
- {
- wiphy_dbg(wiphy, "info: set by driver CCODE ERROR\n");
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
- return;
-#else
- return 0;
-#endif
- }
- if (eHAL_STATUS_SUCCESS != sme_GetRegulatoryDomainForCountry (pHddCtx->hHal,
- ccode, (v_REGDOMAIN_t *) &domainIdCurrent))
- {
- wiphy_dbg(wiphy, "info: set by driver ERROR\n");
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
- return;
-#else
- return 0;
-#endif
- }
- wiphy_dbg(wiphy, "country: %c%c set by driver\n",ccode[0],ccode[1]);
- /* 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 (memcmp(pHddCtx->cfg_ini->crdaDefaultCountryCode,
- CFG_CRDA_DEFAULT_COUNTRY_CODE_DEFAULT , 2) != 0)
- {
- 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);
- }
- else
- {
- nBandCapability = pHddCtx->cfg_ini->nBandCapability;
- for (i=0, m=0; i<IEEE80211_NUM_BANDS; i++)
- {
- if (NULL == wiphy->bands[i])
- {
- VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
- "error: wiphy->bands[i] is NULL, i = %d", i);
- continue;
- }
- // internal channels[] is one continous array for both 2G and 5G bands
- // m is internal starting channel index for each band
- if (0 == i)
- {
- m = 0;
- }
- else
- {
- m = wiphy->bands[i-1]?wiphy->bands[i-1]->n_channels + m:m;
- }
+ complete(&pHddCtx->linux_reg_req);
- 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;
- if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == nBandCapability) // 5G only
- {
- // Enable social channels for P2P
- if ((2412 == wiphy->bands[i]->channels[j].center_freq ||
- 2437 == wiphy->bands[i]->channels[j].center_freq ||
- 2462 == wiphy->bands[i]->channels[j].center_freq ) &&
- NV_CHANNEL_ENABLE == regChannels[k].enabled)
- {
- wiphy->bands[i]->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
- }
- else
- {
- wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED;
- }
- continue;
- }
- else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == nBandCapability) // 2G only
- {
- wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED;
- continue;
- }
-
- if (NV_CHANNEL_DISABLE == regChannels[k].enabled ||
- NV_CHANNEL_INVALID == regChannels[k].enabled)
- {
- wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_DISABLED;
- }
- else if (NV_CHANNEL_DFS == regChannels[k].enabled)
- {
- wiphy->bands[i]->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
- |IEEE80211_CHAN_RADAR);
- wiphy->bands[i]->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
- }
- else
- {
- wiphy->bands[i]->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
- |IEEE80211_CHAN_PASSIVE_SCAN
- |IEEE80211_CHAN_NO_IBSS
- |IEEE80211_CHAN_RADAR);
- }
- }
- }
- /* Haven't seen any condition that will set by driver after init.
- If we do, then we should also call sme_ChangeCountryCode */
- if (wiphy->bands[IEEE80211_BAND_5GHZ])
- {
- for (j=0; j<wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
- {
- // p2p UNII-1 band channels are passive when domain is FCC.
- if ((wiphy->bands[IEEE80211_BAND_5GHZ ]->channels[j].center_freq == 5180 ||
- wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5200 ||
- wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5220 ||
- wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5240) &&
- (ccode[0]== 'U'&& ccode[1]=='S'))
- {
- wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
- }
- else if ((wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5180 ||
- wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5200 ||
- wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5220 ||
- wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].center_freq == 5240) &&
- (ccode[0]!= 'U'&& ccode[1]!='S'))
- {
- wiphy->bands[IEEE80211_BAND_5GHZ]->channels[j].flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
- }
- }
- }
- if (request->initiator == NL80211_REGDOM_SET_BY_CORE)
- {
- request->processed = 1;
- }
- }
- }
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
return;
-#else
- return 0;
-#endif
}
+
+
+#else
+
+/**------------------------------------------------------------------------
+ \brief vos_nv_getRegDomainFromCountryCode() - get the regulatory domain of
+ a country given its country code
+ The \a vos_nv_getRegDomainFromCountryCode() returns the regulatory domain of
+ a country given its country code. This is done from reading a cached
+ copy of the binary file.
+ \param pRegDomain - pointer to regulatory domain
+ \param countryCode - country code
+ \return VOS_STATUS_SUCCESS - regulatory domain is found for the given country
+ VOS_STATUS_E_FAULT - invalid pointer error
+ VOS_STATUS_E_EMPTY - country code table is empty
+ VOS_STATUS_E_EXISTS - given country code does not exist in table
+ \sa
+ -------------------------------------------------------------------------*/
+VOS_STATUS vos_nv_getRegDomainFromCountryCode( v_REGDOMAIN_t *pRegDomain,
+ const v_COUNTRYCODE_t countryCode )
+{
+ int i;
+
+ if (NULL == pRegDomain)
+ {
+ VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+ ("Invalid reg domain pointer") );
+ return VOS_STATUS_E_FAULT;
+ }
+
+ *pRegDomain = REGDOMAIN_COUNT;
+
+ if (NULL == countryCode)
+ {
+ VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+ ("Country code array is NULL") );
+ return VOS_STATUS_E_FAULT;
+ }
+
+ if (0 == countryInfoTable.countryCount)
+ {
+ VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
+ ("Reg domain table is empty") );
+ return VOS_STATUS_E_EMPTY;
+ }
+
+ if (VOS_FALSE == driver_regulatory_init) {
+
+ /*
+ iterate the country info table until end of table or the country code
+ is found
+ */
+
+ for (i = 0; i < countryInfoTable.countryCount &&
+ REGDOMAIN_COUNT == *pRegDomain; i++)
+ {
+ if (memcmp(countryCode, countryInfoTable.countryInfo[i].countryCode,
+ VOS_COUNTRY_CODE_LEN) == 0)
+ {
+ /* country code is found */
+ *pRegDomain = countryInfoTable.countryInfo[i].regDomain;
+ }
+ }
+
+ if (REGDOMAIN_COUNT != *pRegDomain)
+ {
+ driver_reg_cc[0] = countryCode[0];
+ driver_reg_cc[1] = countryCode[1];
+ cur_reg_domain = *pRegDomain;
+ driver_regulatory_init = VOS_TRUE;
+
+ VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
+ ("init time country code is found in driver db"));
+
+ return VOS_STATUS_SUCCESS;
+ }
+ else
+ {
+ VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
+ ("init time country code is not found in driver db"));
+
+ return VOS_STATUS_E_EXISTS;
+ }
+ }
+ else {
+ if ((countryCode[0] == driver_reg_cc[0]) &&
+ (countryCode[1] == driver_reg_cc[1])) {
+
+ *pRegDomain = cur_reg_domain;
+
+ VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
+ ("run time country code has not changed"));
+
+ return VOS_STATUS_SUCCESS;
+ }
+ else {
+
+ /* iterate the country info table until end of table or the
+ country code is found
+ */
+
+ for (i = 0; i < countryInfoTable.countryCount &&
+ REGDOMAIN_COUNT == *pRegDomain; i++)
+ {
+ if (memcmp(countryCode, countryInfoTable.countryInfo[i].countryCode,
+ VOS_COUNTRY_CODE_LEN) == 0)
+ {
+ /* country code is found */
+ *pRegDomain = countryInfoTable.countryInfo[i].regDomain;
+ }
+ }
+
+ if (REGDOMAIN_COUNT != *pRegDomain)
+ {
+ driver_reg_cc[0] = countryCode[0];
+ driver_reg_cc[1] = countryCode[1];
+ cur_reg_domain = *pRegDomain;
+
+ VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
+ ("run time country code is found in driver db"));
+
+ return VOS_STATUS_SUCCESS;
+ }
+ else
+ {
+ VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_WARN,
+ ("run time country code is not found in driver db"));
+
+ driver_reg_cc[0] = 0;
+ driver_reg_cc[1] = 0;
+ driver_regulatory_init = VOS_FALSE;
+
+ return VOS_STATUS_E_EXISTS;
+ }
+ }
+ }
+}
+
+#endif
diff --git a/Kbuild b/Kbuild
index ebb304d..df99973 100644
--- a/Kbuild
+++ b/Kbuild
@@ -13,7 +13,7 @@
WLAN_ROOT := drivers/staging/prima
endif
-ifeq ($(KERNEL_BUILD),0)
+ifeq ($(KERNEL_BUILD), 0)
# These are configurable via Kconfig for kernel-based builds
# Need to explicitly configure for Android-based builds
@@ -40,6 +40,9 @@
CONFIG_WLAN_FEATURE_11W := y
endif
+ #Flag to enable new Linux Regulatory implementation
+ CONFIG_ENABLE_LINUX_REG := y
+
endif
# Feature flags which are not (currently) configurable via Kconfig
@@ -642,6 +645,10 @@
CDEFINES += -DWLAN_OPEN_SOURCE
endif
+ifeq ($(CONFIG_ENABLE_LINUX_REG), y)
+CDEFINES += -DCONFIG_ENABLE_LINUX_REG
+endif
+
# Fix build for GCC 4.7
EXTRA_CFLAGS += -Wno-maybe-uninitialized -Wno-unused-function
diff --git a/Kconfig b/Kconfig
index f0fde2b..d3f811b 100644
--- a/Kconfig
+++ b/Kconfig
@@ -45,4 +45,8 @@
bool "Enable Fast Transition (11r) feature"
default n
+config CONFIG_ENABLE_LINUX_REG
+ bool "Enable linux regulatory feature"
+ default n
+
endif # PRIMA_WLAN || PRONTO_WLAN