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