summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2014-07-12 02:33:24 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2014-07-12 02:33:24 -0700
commit1a6ec3e5f851e9bebc9b73afcd3c6d274bbcc0f7 (patch)
tree6f304316300e61bbf0ed4c0c407c27ac9628b665
parent97e60837cb0bdbba1554ce408561bbd8188c8383 (diff)
parent4a98de7e55fe9afb03acd9ddb127aa3f3b411ba3 (diff)
Merge "Release 1.0.0.144 QCACLD WLAN Driver"
-rw-r--r--CORE/HDD/inc/wlan_hdd_cfg.h40
-rw-r--r--CORE/HDD/inc/wlan_hdd_main.h20
-rw-r--r--CORE/HDD/inc/wlan_hdd_wext.h2
-rw-r--r--CORE/HDD/src/wlan_hdd_assoc.c11
-rw-r--r--CORE/HDD/src/wlan_hdd_cfg.c53
-rw-r--r--CORE/HDD/src/wlan_hdd_cfg80211.c109
-rw-r--r--CORE/HDD/src/wlan_hdd_hostapd.c21
-rw-r--r--CORE/HDD/src/wlan_hdd_ipa.c668
-rw-r--r--CORE/HDD/src/wlan_hdd_softap_tx_rx.c5
-rw-r--r--CORE/HDD/src/wlan_hdd_wext.c2
-rw-r--r--CORE/MAC/inc/aniGlobal.h13
-rw-r--r--CORE/MAC/inc/qwlan_version.h4
-rw-r--r--CORE/MAC/inc/sirApi.h3
-rw-r--r--CORE/MAC/inc/sirMacProtDef.h3
-rw-r--r--CORE/MAC/inc/wniCfgAp.h15
-rw-r--r--CORE/MAC/inc/wniCfgSta.h9
-rw-r--r--CORE/MAC/src/cfg/cfgUtil/cfg.txt13
-rw-r--r--CORE/MAC/src/pe/lim/limProcessActionFrame.c14
-rw-r--r--CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c34
-rw-r--r--CORE/MAC/src/pe/lim/limSerDesUtils.c4
-rw-r--r--CORE/MAC/src/pe/lim/limSession.c20
-rw-r--r--CORE/SAP/inc/sapApi.h2
-rw-r--r--CORE/SAP/src/sapModule.c2
-rw-r--r--CORE/SERVICES/COMMON/wdi_in.h7
-rw-r--r--CORE/SERVICES/HIF/PCIe/copy_engine.c60
-rw-r--r--CORE/SERVICES/HIF/PCIe/copy_engine_api.h14
-rw-r--r--CORE/SERVICES/HIF/PCIe/hif_pci.c42
-rw-r--r--CORE/SERVICES/HIF/PCIe/if_pci.c10
-rw-r--r--CORE/SERVICES/HIF/PCIe/if_pci.h9
-rw-r--r--CORE/SERVICES/WMA/wma.c7
-rw-r--r--CORE/SME/inc/csrApi.h2
-rw-r--r--CORE/SME/inc/csrInternal.h1
-rw-r--r--CORE/SME/inc/sme_Api.h1
-rw-r--r--CORE/SME/src/csr/csrApiRoam.c34
-rw-r--r--CORE/SME/src/sme_common/sme_Api.c29
-rw-r--r--CORE/VOSS/src/vos_api.c22
-rwxr-xr-x[-rw-r--r--]firmware_bin/WCNSS_cfg.datbin10810 -> 10842 bytes
-rwxr-xr-xfirmware_bin/WCNSS_qcom_cfg.ini3
-rw-r--r--tools/athdiag/athdiag.c23
39 files changed, 1225 insertions, 106 deletions
diff --git a/CORE/HDD/inc/wlan_hdd_cfg.h b/CORE/HDD/inc/wlan_hdd_cfg.h
index fd5ab0b7e242..0aaea7aab02b 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg.h
@@ -1524,6 +1524,11 @@ typedef enum
#define CFG_DISABLE_DFS_CH_SWITCH_MAX ( 1 )
#define CFG_DISABLE_DFS_CH_SWITCH_DEFAULT ( 0 )
+#define CFG_ENABLE_DFS_MASTER_CAPABILITY "gEnableDFSMasterCap"
+#define CFG_ENABLE_DFS_MASTER_CAPABILITY_MIN ( 0 )
+#define CFG_ENABLE_DFS_MASTER_CAPABILITY_MAX ( 1 )
+#define CFG_ENABLE_DFS_MASTER_CAPABILITY_DEFAULT ( 0 )
+
#define CFG_ENABLE_DFS_PHYERR_FILTEROFFLOAD_NAME "dfsPhyerrFilterOffload"
#define CFG_ENABLE_DFS_PHYERR_FILTEROFFLOAD_MIN ( 0 )
#define CFG_ENABLE_DFS_PHYERR_FILTEROFFLOAD_MAX ( 1 )
@@ -2653,6 +2658,33 @@ This feature requires the dependent cfg.ini "gRoamPrefer5GHz" set to 1 */
#define CFG_ROAMING_OFFLOAD_DEFAULT (0)
#endif
+#ifdef IPA_UC_OFFLOAD
+#define CFG_IPA_UC_OFFLOAD_ENABLED_NAME "IpaUcOffloadEnabled"
+#define CFG_IPA_UC_OFFLOAD_ENABLED_MIN ( 0 )
+#define CFG_IPA_UC_OFFLOAD_ENABLED_MAX ( 1 )
+#define CFG_IPA_UC_OFFLOAD_ENABLED_DEFAULT ( 0 )
+
+#define CFG_IPA_UC_TX_BUF_COUNT_NAME "IpaUcTxBufCount"
+#define CFG_IPA_UC_TX_BUF_COUNT_MIN ( 0 )
+#define CFG_IPA_UC_TX_BUF_COUNT_MAX ( 2048 )
+#define CFG_IPA_UC_TX_BUF_COUNT_DEFAULT ( 512 )
+
+#define CFG_IPA_UC_TX_BUF_SIZE_NAME "IpaUcTxBufSize"
+#define CFG_IPA_UC_TX_BUF_SIZE_MIN ( 0 )
+#define CFG_IPA_UC_TX_BUF_SIZE_MAX ( 4096 )
+#define CFG_IPA_UC_TX_BUF_SIZE_DEFAULT ( 2048 )
+
+#define CFG_IPA_UC_RX_IND_RING_COUNT_NAME "IpaUcRxIndRingCount"
+#define CFG_IPA_UC_RX_IND_RING_COUNT_MIN ( 0 )
+#define CFG_IPA_UC_RX_IND_RING_COUNT_MAX ( 2048 )
+#define CFG_IPA_UC_RX_IND_RING_COUNT_DEFAULT ( 1024 )
+
+#define CFG_IPA_UC_TX_PARTITION_BASE_NAME "IpaUcTxPartitionBase"
+#define CFG_IPA_UC_TX_PARTITION_BASE_MIN ( 0 )
+#define CFG_IPA_UC_TX_PARTITION_BASE_MAX ( 9000 )
+#define CFG_IPA_UC_TX_PARTITION_BASE_DEFAULT ( 3000 )
+#endif /* IPA_UC_OFFLOAD */
+
/*---------------------------------------------------------------------------
Type declarations
-------------------------------------------------------------------------*/
@@ -3140,6 +3172,7 @@ typedef struct
v_U8_t wowEnable;
v_U8_t maxNumberOfPeers;
v_U8_t disableDFSChSwitch;
+ v_U8_t enableDFSMasterCap;
#ifndef QCA_WIFI_ISOC
v_U16_t thermalTempMinLevel0;
v_U16_t thermalTempMaxLevel0;
@@ -3227,6 +3260,13 @@ typedef struct
v_BOOL_t isRoamOffloadEnabled;
#endif
+#ifdef IPA_UC_OFFLOAD
+ v_U8_t IpaUcOffloadEnabled;
+ v_U32_t IpaUcTxBufCount;
+ v_U32_t IpaUcTxBufSize;
+ v_U32_t IpaUcRxIndRingCount;
+ v_U32_t IpaUcTxPartitionBase;
+#endif /* IPA_UC_OFFLOAD */
} hdd_config_t;
#ifdef WLAN_FEATURE_MBSSID
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index a41aa5cfa7fd..bafc0abdaa23 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -1415,6 +1415,26 @@ struct hdd_context_s
#ifdef IPA_OFFLOAD
void *hdd_ipa;
+#ifdef IPA_UC_OFFLOAD
+ /* CE resources */
+ v_U32_t ce_sr_base_paddr;
+ v_U32_t ce_sr_ring_size;
+ v_U32_t ce_reg_paddr;
+
+ /* WLAN TX:IPA->WLAN */
+ v_U32_t tx_comp_ring_base_paddr;
+ v_U32_t tx_comp_ring_size;
+ v_U32_t tx_num_alloc_buffer;
+
+ /* WLAN RX:WLAN->IPA */
+ v_U32_t rx_rdy_ring_base_paddr;
+ v_U32_t rx_rdy_ring_size;
+ v_U32_t rx_proc_done_idx_paddr;
+
+ /* IPA UC doorbell registers paddr */
+ v_U32_t tx_comp_doorbell_paddr;
+ v_U32_t rx_ready_doorbell_paddr;
+#endif /* IPA_UC_OFFLOAD */
#endif
/* MC/BC Filter state variable
* This always contains the value that is currently
diff --git a/CORE/HDD/inc/wlan_hdd_wext.h b/CORE/HDD/inc/wlan_hdd_wext.h
index b858ed6e58fb..ced7250f16b1 100644
--- a/CORE/HDD/inc/wlan_hdd_wext.h
+++ b/CORE/HDD/inc/wlan_hdd_wext.h
@@ -389,6 +389,8 @@ extern int iw_set_three_ints_getnone(struct net_device *dev, struct iw_request_i
extern int hdd_priv_get_data(struct iw_point *p_priv_data,
union iwreq_data *wrqu);
+extern void *mem_alloc_copy_from_user_helper(const void *wrqu_data, size_t len);
+
extern VOS_STATUS wlan_hdd_get_linkspeed_for_peermac(hdd_adapter_t *pAdapter,
tSirMacAddr macAddress);
void hdd_clearRoamProfileIe( hdd_adapter_t *pAdapter);
diff --git a/CORE/HDD/src/wlan_hdd_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c
index 2c4b04887d2a..8689543f1446 100644
--- a/CORE/HDD/src/wlan_hdd_assoc.c
+++ b/CORE/HDD/src/wlan_hdd_assoc.c
@@ -1183,7 +1183,11 @@ static VOS_STATUS hdd_roamRegisterSTA( hdd_adapter_t *pAdapter,
WLANTL_STA_CONNECTED : WLANTL_STA_AUTHENTICATED;
// Register the Station with TL...
VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "%s: HDD register TL ucInitState=%d", __func__, staDesc.ucInitState );
-#ifdef IPA_OFFLOAD
+
+ /* Incase Micro controller data path offload enabled,
+ * All the traffic routed to WLAN host driver, do not need to
+ * route IPA. It should be routed kernel network stack */
+#if defined(IPA_OFFLOAD) && !defined(IPA_UC_OFFLOAD)
if (hdd_ipa_is_enabled(pHddCtx)) {
vosStatus = WLANTL_RegisterSTAClient( pHddCtx->pvosContext,
hdd_ipa_process_rxt,
@@ -2464,7 +2468,10 @@ VOS_STATUS hdd_roamRegisterTDLSSTA( hdd_adapter_t *pAdapter,
staDesc.ucInitState = WLANTL_STA_CONNECTED ;
/* Register the Station with TL... */
-#ifdef IPA_OFFLOAD
+ /* Incase Micro controller data path offload enabled,
+ * All the traffic routed to WLAN host driver, do not need to
+ * route IPA. It should be routed kernel network stack */
+#if defined(IPA_OFFLOAD) && !defined(IPA_UC_OFFLOAD)
if (hdd_ipa_is_enabled(pHddCtx)) {
vosStatus = WLANTL_RegisterSTAClient( pVosContext,
hdd_ipa_process_rxt,
diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c
index 830dfc7d0cb8..9bade3404a5a 100644
--- a/CORE/HDD/src/wlan_hdd_cfg.c
+++ b/CORE/HDD/src/wlan_hdd_cfg.c
@@ -2609,6 +2609,13 @@ REG_TABLE_ENTRY g_registry_table[] =
CFG_DISABLE_DFS_CH_SWITCH_MIN,
CFG_DISABLE_DFS_CH_SWITCH_MAX ),
+ REG_VARIABLE( CFG_ENABLE_DFS_MASTER_CAPABILITY, WLAN_PARAM_Integer,
+ hdd_config_t, enableDFSMasterCap,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_ENABLE_DFS_MASTER_CAPABILITY_DEFAULT,
+ CFG_ENABLE_DFS_MASTER_CAPABILITY_MIN,
+ CFG_ENABLE_DFS_MASTER_CAPABILITY_MAX ),
+
REG_VARIABLE( CFG_ENABLE_FIRST_SCAN_2G_ONLY_NAME, WLAN_PARAM_Integer,
hdd_config_t, enableFirstScan2GOnly,
VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
@@ -3653,6 +3660,43 @@ REG_TABLE_ENTRY g_registry_table[] =
CFG_REORDER_OFFLOAD_SUPPORT_MIN,
CFG_REORDER_OFFLOAD_SUPPORT_MAX ),
#endif
+
+#ifdef IPA_UC_OFFLOAD
+ REG_VARIABLE( CFG_IPA_UC_OFFLOAD_ENABLED_NAME, WLAN_PARAM_Integer,
+ hdd_config_t, IpaUcOffloadEnabled,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK,
+ CFG_IPA_UC_OFFLOAD_ENABLED_DEFAULT,
+ CFG_IPA_UC_OFFLOAD_ENABLED_MIN,
+ CFG_IPA_UC_OFFLOAD_ENABLED_MAX ),
+
+ REG_VARIABLE( CFG_IPA_UC_TX_BUF_COUNT_NAME, WLAN_PARAM_Integer,
+ hdd_config_t, IpaUcTxBufCount,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK,
+ CFG_IPA_UC_TX_BUF_COUNT_DEFAULT,
+ CFG_IPA_UC_TX_BUF_COUNT_MIN,
+ CFG_IPA_UC_TX_BUF_COUNT_MAX ),
+
+ REG_VARIABLE( CFG_IPA_UC_TX_BUF_SIZE_NAME, WLAN_PARAM_Integer,
+ hdd_config_t, IpaUcTxBufSize,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK,
+ CFG_IPA_UC_TX_BUF_SIZE_DEFAULT,
+ CFG_IPA_UC_TX_BUF_SIZE_MIN,
+ CFG_IPA_UC_TX_BUF_SIZE_MAX ),
+
+ REG_VARIABLE( CFG_IPA_UC_RX_IND_RING_COUNT_NAME, WLAN_PARAM_Integer,
+ hdd_config_t, IpaUcRxIndRingCount,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK,
+ CFG_IPA_UC_RX_IND_RING_COUNT_DEFAULT,
+ CFG_IPA_UC_RX_IND_RING_COUNT_MIN,
+ CFG_IPA_UC_RX_IND_RING_COUNT_MAX ),
+
+ REG_VARIABLE( CFG_IPA_UC_TX_PARTITION_BASE_NAME, WLAN_PARAM_Integer,
+ hdd_config_t, IpaUcTxPartitionBase,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK,
+ CFG_IPA_UC_TX_PARTITION_BASE_DEFAULT,
+ CFG_IPA_UC_TX_PARTITION_BASE_MIN,
+ CFG_IPA_UC_TX_PARTITION_BASE_MAX ),
+#endif /* IPA_UC_OFFLOAD */
};
#ifdef WLAN_FEATURE_MBSSID
@@ -5314,6 +5358,15 @@ v_BOOL_t hdd_update_config_dat( hdd_context_t *pHddCtx )
fStatus = FALSE;
hddLog(LOGE,"Failure: Could not pass on WNI_CFG_11D_ENABLED configuration info to CCM");
}
+
+ if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_DFS_MASTER_ENABLED,
+ pConfig->enableDFSMasterCap, NULL,
+ eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) {
+ fStatus = FALSE;
+ hddLog(LOGE,
+ "Failure: Could not set value for WNI_CFG_DFS_MASTER_ENABLED");
+ }
+
if(ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_HEART_BEAT_THRESHOLD, pConfig->HeartbeatThresh24,
NULL, eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
{
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index e3775aebc4bd..541d96fb075c 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -3551,7 +3551,9 @@ int wlan_hdd_cfg80211_init(struct device *dev,
wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,4,0))
- wiphy->flags |= WIPHY_FLAG_DFS_OFFLOAD;
+ if (pCfg->enableDFSMasterCap) {
+ wiphy->flags |= WIPHY_FLAG_DFS_OFFLOAD;
+ }
#endif
wiphy->max_ap_assoc_sta = pCfg->maxNumberOfPeers;
@@ -4126,6 +4128,54 @@ static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
return;
}
+static void wlan_hdd_add_obss_scan_param_ie(hdd_adapter_t* pHostapdAdapter,
+ v_U8_t *genie, v_U8_t *total_ielen)
+{
+ beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
+ int left = pBeacon->tail_len;
+ v_U8_t *ptr = pBeacon->tail;
+ v_U8_t elem_id, elem_len;
+ v_U16_t ielen = 0;
+
+ if ( NULL == ptr || 0 == left )
+ return;
+
+ while (left >= 2)
+ {
+ elem_id = ptr[0];
+ elem_len = ptr[1];
+ left -= 2;
+ if (elem_len > left)
+ {
+ hddLog( VOS_TRACE_LEVEL_ERROR,
+ "****Invalid IEs eid = %d elem_len=%d left=%d*****",
+ elem_id, elem_len, left);
+ return;
+ }
+
+ if (WLAN_EID_OVERLAP_BSS_SCAN_PARAM == elem_id)
+ {
+ ielen = ptr[1] + 2;
+ if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
+ {
+ vos_mem_copy(&genie[*total_ielen], ptr, ielen);
+ *total_ielen += ielen;
+ }
+ else
+ {
+ hddLog( VOS_TRACE_LEVEL_ERROR,
+ "IE Length is too big "
+ "IEs eid=%d elem_len=%d total_ie_lent=%d",
+ elem_id, elem_len, *total_ielen);
+ }
+ }
+
+ left -= elem_len;
+ ptr += (elem_len + 2);
+ }
+ return;
+}
+
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
struct beacon_parameters *params)
@@ -4180,6 +4230,10 @@ static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
}
+ if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
+ {
+ wlan_hdd_add_obss_scan_param_ie(pHostapdAdapter, genie, &total_ielen);
+ }
vos_mem_copy(updateIE.bssid, pHostapdAdapter->macAddressCurrent.bytes,
sizeof(tSirMacAddr));
@@ -4458,23 +4512,24 @@ static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device
(WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
}
+#ifdef QCA_HT_2040_COEX
/* set channel bonding mode for 2.4G */
if ( channel <= 14 )
{
- tSmeConfigParams smeConfig;
- sme_GetConfigParam(pHddCtx->hHal, &smeConfig);
-
switch (channel_type)
{
case NL80211_CHAN_HT20:
- smeConfig.csrConfig.channelBondingMode24GHz = 0;
- sme_UpdateConfig(pHddCtx->hHal, &smeConfig);
+ sme_SetPhyCBMode24G(pHddCtx->hHal,
+ PHY_SINGLE_CHANNEL_CENTERED);
break;
case NL80211_CHAN_HT40MINUS:
+ sme_SetPhyCBMode24G(pHddCtx->hHal,
+ PHY_DOUBLE_CHANNEL_HIGH_PRIMARY);
+ break;
case NL80211_CHAN_HT40PLUS:
- smeConfig.csrConfig.channelBondingMode24GHz = 1;
- sme_UpdateConfig(pHddCtx->hHal, &smeConfig);
+ sme_SetPhyCBMode24G(pHddCtx->hHal,
+ PHY_DOUBLE_CHANNEL_LOW_PRIMARY);
break;
default:
@@ -4484,6 +4539,7 @@ static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device
return -EINVAL;
}
}
+#endif
}
}
else
@@ -4609,6 +4665,19 @@ static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
sizeof(pConfig->acsAllowedChnls));
}
+#ifdef QCA_HT_2040_COEX
+ if ((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)&&
+ pHddCtx->cfg_ini->ht2040CoexEnabled)
+ {
+ tSmeConfigParams smeConfig;
+
+ vos_mem_zero(&smeConfig, sizeof (tSmeConfigParams));
+ sme_GetConfigParam(hHal, &smeConfig);
+ smeConfig.csrConfig.obssEnabled = 1;
+ sme_UpdateConfig (hHal, &smeConfig);
+ }
+#endif
+
if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
{
pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
@@ -5428,8 +5497,8 @@ static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
updateIE.smeSessionId = pAdapter->sessionId;
updateIE.ieBufferlength = 0;
updateIE.pAdditionIEBuffer = NULL;
- updateIE.append = VOS_TRUE;
- updateIE.notify = VOS_TRUE;
+ updateIE.append = VOS_FALSE;
+ updateIE.notify = VOS_FALSE;
if (sme_UpdateAddIE(WLAN_HDD_GET_HAL_CTX(pAdapter),
&updateIE, eUPDATE_IE_PROBE_BCN) == eHAL_STATUS_FAILURE) {
hddLog(LOGE, FL("Could not pass on PROBE_RSP_BCN data to PE"));
@@ -13576,6 +13645,26 @@ int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
"Do not allow suspend"));
return -EAGAIN;
}
+
+ /* If RADAR detection is in progress (HDD), prevent suspend. The flag
+ * "dfs_cac_block_tx" is set to TRUE when RADAR is found and stay TRUE until
+ * CAC is done for a SoftAP which is in started state.
+ */
+ status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
+
+ while (NULL != pAdapterNode && VOS_STATUS_SUCCESS == status) {
+ pAdapter = pAdapterNode->pAdapter;
+ if (WLAN_HDD_SOFTAP == pAdapter->device_mode &&
+ BSS_START == WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter)->bssState &&
+ VOS_TRUE == WLAN_HDD_GET_AP_CTX_PTR(pAdapter)->dfs_cac_block_tx) {
+ hddLog(VOS_TRACE_LEVEL_DEBUG,
+ FL("RADAR detection in progress, do not allow suspend"));
+ return -EAGAIN;
+ }
+ status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
+ pAdapterNode = pNext;
+ }
+
#ifdef QCA_WIFI_2_0
/* Stop ongoing scan on each interface */
status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c
index e53abcf72f68..7cf487bd8cea 100644
--- a/CORE/HDD/src/wlan_hdd_hostapd.c
+++ b/CORE/HDD/src/wlan_hdd_hostapd.c
@@ -3716,24 +3716,21 @@ static int iw_softap_setwpsie(struct net_device *dev,
u_int16_t length;
ENTER();
- if(!wrqu->data.length || wrqu->data.length <= QCSAP_MAX_WSC_IE)
+ if(!wrqu->data.length || wrqu->data.length < QCSAP_MAX_WSC_IE)
return 0;
- wps_genie = kmalloc(wrqu->data.length, GFP_KERNEL);
+ wps_genie = mem_alloc_copy_from_user_helper(wrqu->data.pointer,
+ wrqu->data.length);
- if(NULL == wps_genie) {
- hddLog(LOG1, "unable to allocate memory");
- return -ENOMEM;
- }
- fwps_genie = wps_genie;
- if (copy_from_user((void *)wps_genie,
- wrqu->data.pointer, wrqu->data.length))
- {
- hddLog(LOG1, "%s: failed to copy data to user buffer", __func__);
- kfree(fwps_genie);
+ if (NULL == wps_genie) {
+ hddLog(LOG1,
+ "%s: failed to alloc memory and copy data from user buffer",
+ __func__);
return -EFAULT;
}
+ fwps_genie = wps_genie;
+
pSap_WPSIe = vos_mem_malloc(sizeof(tSap_WPSIE));
if (NULL == pSap_WPSIe)
{
diff --git a/CORE/HDD/src/wlan_hdd_ipa.c b/CORE/HDD/src/wlan_hdd_ipa.c
index 74c971aed003..066fc832eb61 100644
--- a/CORE/HDD/src/wlan_hdd_ipa.c
+++ b/CORE/HDD/src/wlan_hdd_ipa.c
@@ -58,6 +58,21 @@ Include Files
#define HDD_IPA_IPV6_NAME_EXT "_ipv6"
#define HDD_IPA_RX_INACTIVITY_MSEC_DELAY 1000
+#ifdef IPA_UC_OFFLOAD
+#define HDD_IPA_UC_WLAN_HDR_DES_MAC_OFFSET 12
+#define HDD_IPA_UC_WLAN_8023_HDR_SIZE 14
+#endif /* IPA_UC_OFFLOAD */
+
+#ifdef IPA_UC_OFFLOAD
+typedef enum {
+ HDD_IPA_UC_OPCODE_TX_SUSPEND = 0,
+ HDD_IPA_UC_OPCODE_TX_RESUME = 1,
+ HDD_IPA_UC_OPCODE_RX_SUSPEND = 2,
+ HDD_IPA_UC_OPCODE_RX_RESUME = 3,
+ /* keep this last */
+ HDD_IPA_UC_OPCODE_MAX
+} hdd_ipa_uc_op_code;
+#endif /* IPA_UC_OFFLOAD */
struct llc_snap_hdr {
uint8_t dsap;
@@ -87,6 +102,43 @@ static struct hdd_ipa_tx_hdr ipa_tx_hdr = {
}
};
+#ifdef IPA_UC_OFFLOAD
+struct frag_header {
+ uint32
+ reserved16:16,
+ length:16;
+ uint32 reserved32;
+} __packed;
+
+struct ipa_header {
+ uint32
+ reserved:24,
+ vdev_id:8;
+} __packed;
+
+struct hdd_ipa_uc_tx_hdr {
+ struct frag_header frag_hd;
+ struct ipa_header ipa_hd;
+ struct ethhdr eth;
+} __packed;
+
+/* For Tx pipes, use 802.3 Header format */
+struct hdd_ipa_uc_tx_hdr ipa_uc_tx_hdr = {
+ {
+ 0x00000000,
+ 0x00000000
+ },
+ {
+ 0x00000000
+ },
+ {
+ {0x00, 0x03, 0x7f, 0xaa, 0xbb, 0xcc},
+ {0x00, 0x03, 0x7f, 0xdd, 0xee, 0xff},
+ 0x0008
+ }
+};
+#endif /* IPA_UC_OFFLOAD */
+
/*
+----------+----------+--------------+--------+
| Reserved | QCMAP ID | interface id | STA ID |
@@ -103,9 +155,27 @@ struct hdd_ipa_rx_hdr {
struct ethhdr eth;
} __packed;
+#ifdef IPA_UC_OFFLOAD
+struct hdd_ipa_uc_rx_hdr {
+ struct ethhdr eth;
+} __packed;
+#endif /* IPA_UC_OFFLOAD */
+
#define HDD_IPA_WLAN_CLD_HDR_LEN sizeof(struct hdd_ipa_cld_hdr)
+#ifdef IPA_UC_OFFLOAD
+#define HDD_IPA_UC_WLAN_CLD_HDR_LEN 0
+#endif /* IPA_UC_OFFLOAD */
+
#define HDD_IPA_WLAN_TX_HDR_LEN sizeof(ipa_tx_hdr)
+#ifdef IPA_UC_OFFLOAD
+#define HDD_IPA_UC_WLAN_TX_HDR_LEN sizeof(ipa_uc_tx_hdr)
+#endif /* IPA_UC_OFFLOAD */
+
#define HDD_IPA_WLAN_RX_HDR_LEN sizeof(struct hdd_ipa_rx_hdr)
+#ifdef IPA_UC_OFFLOAD
+#define HDD_IPA_UC_WLAN_RX_HDR_LEN sizeof(struct hdd_ipa_uc_rx_hdr)
+#endif /* IPA_UC_OFFLOAD */
+
#define HDD_IPA_WLAN_HDR_DES_MAC_OFFSET 0
#define HDD_IPA_GET_IFACE_ID(_data) \
@@ -231,6 +301,15 @@ struct hdd_ipa_priv {
struct notifier_block ipv4_notifier;
uint32_t curr_prod_bw;
uint32_t curr_cons_bw;
+
+#ifdef IPA_UC_OFFLOAD
+ uint8_t sap_num_connected_sta;
+ uint32_t tx_pipe_handle;
+ uint32_t rx_pipe_handle;
+ v_BOOL_t resource_loading;
+ v_BOOL_t resource_unloading;
+ v_BOOL_t pending_cons_req;
+#endif /* IPA_UC_OFFLOAD */
};
enum hdd_ipa_evt {
@@ -244,8 +323,16 @@ struct hdd_ipa_rxt {
adf_nbuf_t rx_buf_list;
};
+#ifdef IPA_UC_OFFLOAD
+static const char *op_string[] = {
+ "TX_SUSPEND",
+ "TX_RESUME",
+ "RX_SUSPEND",
+ "RX_RESUME",
+};
+#endif /* IPA_UC_OFFLOAD */
+
static struct hdd_ipa_priv *ghdd_ipa;
-static void hdd_ipa_process_evt(int evt, void *priv);
#define HDD_IPA_ENABLE_MASK BIT(0)
#define HDD_IPA_PRE_FILTER_ENABLE_MASK BIT(1)
@@ -256,11 +343,32 @@ static void hdd_ipa_process_evt(int evt, void *priv);
#define HDD_IPA_IS_CONFIG_ENABLED(_hdd_ctx, _mask)\
(((_hdd_ctx)->cfg_ini->IpaConfig & (_mask)) == (_mask))
+/* Local Function Prototypes */
+static void hdd_ipa_process_evt(int evt, void *priv);
+static void hdd_ipa_i2w_cb(void *priv, enum ipa_dp_evt_type evt,
+ unsigned long data);
+static void hdd_ipa_w2i_cb(void *priv, enum ipa_dp_evt_type evt,
+ unsigned long data);
+#ifdef IPA_UC_OFFLOAD
+static void hdd_ipa_uc_rm_notify_handler(void *context,
+ void *rxpkt,
+ u_int16_t staid);
+#endif /* IPA_UC_OFFLOAD */
+
bool hdd_ipa_is_enabled(hdd_context_t *hdd_ctx)
{
return HDD_IPA_IS_CONFIG_ENABLED(hdd_ctx, HDD_IPA_ENABLE_MASK);
}
+v_U8_t hdd_ipa_uc_is_enabled(struct hdd_ipa_priv *hdd_ipa)
+{
+#ifdef IPA_UC_OFFLOAD
+ return hdd_ipa->hdd_ctx->cfg_ini->IpaUcOffloadEnabled;
+#else
+ return 0;
+#endif /* IPA_UC_OFFLOAD */
+}
+
static inline bool hdd_ipa_is_pre_filter_enabled(struct hdd_ipa_priv *hdd_ipa)
{
hdd_context_t *hdd_ctx = hdd_ipa->hdd_ctx;
@@ -357,6 +465,327 @@ static bool hdd_ipa_can_send_to_ipa(hdd_adapter_t *adapter, struct hdd_ipa_priv
return false;
}
+#ifdef IPA_UC_OFFLOAD
+static int hdd_ipa_uc_enable_pipes(struct hdd_ipa_priv *hdd_ipa)
+{
+ int result;
+
+ /* ACTIVATE TX PIPE */
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO,
+ "%s: Enable TX PIPE", __func__);
+ result = ipa_enable_wdi_pipe(hdd_ipa->tx_pipe_handle);
+ if (result) {
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
+ "%s: Enable TX PIPE fail, code %d",
+ __func__, result);
+ return result;
+ }
+ result = ipa_resume_wdi_pipe(hdd_ipa->tx_pipe_handle);
+ if (result) {
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
+ "%s: Resume TX PIPE fail, code %d",
+ __func__, result);
+ return result;
+ }
+ WLANTL_SetUcActive(hdd_ipa->hdd_ctx->pvosContext,
+ VOS_TRUE, VOS_TRUE);
+
+ /* ACTIVATE RX PIPE */
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO,
+ "%s: Enable RX PIPE", __func__);
+ result = ipa_enable_wdi_pipe(hdd_ipa->rx_pipe_handle);
+ if (result) {
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
+ "%s: Enable RX PIPE fail, code %d",
+ __func__, result);
+ return result;
+ }
+ result = ipa_resume_wdi_pipe(hdd_ipa->rx_pipe_handle);
+ if (result) {
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
+ "%s: Resume RX PIPE fail, code %d",
+ __func__, result);
+ return result;
+ }
+ WLANTL_SetUcActive(hdd_ipa->hdd_ctx->pvosContext,
+ VOS_TRUE, VOS_FALSE);
+
+ return 0;
+}
+
+static int hdd_ipa_uc_disable_pipes(struct hdd_ipa_priv *hdd_ipa)
+{
+ int result;
+
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO,
+ "%s: Disable RX PIPE", __func__);
+ WLANTL_SetUcActive(hdd_ipa->hdd_ctx->pvosContext,
+ VOS_FALSE, VOS_FALSE);
+ result = ipa_suspend_wdi_pipe(hdd_ipa->rx_pipe_handle);
+ if (result) {
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
+ "%s: Suspend RX PIPE fail, code %d",
+ __func__, result);
+ return result;
+ }
+ result = ipa_disable_wdi_pipe(hdd_ipa->rx_pipe_handle);
+ if (result) {
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
+ "%s: Disable RX PIPE fail, code %d",
+ __func__, result);
+ return result;
+ }
+
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO,
+ "%s: Disable TX PIPE", __func__);
+ WLANTL_SetUcActive(hdd_ipa->hdd_ctx->pvosContext,
+ VOS_FALSE, VOS_TRUE);
+ result = ipa_suspend_wdi_pipe(hdd_ipa->tx_pipe_handle);
+ if (result) {
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
+ "%s: Suspend TX PIPE fail, code %d",
+ __func__, result);
+ return result;
+ }
+ result = ipa_disable_wdi_pipe(hdd_ipa->tx_pipe_handle);
+ if (result) {
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
+ "%s: Disable TX PIPE fail, code %d",
+ __func__, result);
+ return result;
+ }
+
+ return 0;
+}
+
+static int hdd_ipa_uc_handle_first_con(struct hdd_ipa_priv *hdd_ipa)
+{
+ hdd_ipa->resource_loading = VOS_TRUE;
+ /* If RM feature enabled
+ * Request PROD Resource first
+ * PROD resource may return sync or async manners */
+ if ((hdd_ipa_is_rm_enabled(hdd_ipa)) &&
+ (!ipa_rm_request_resource(IPA_RM_RESOURCE_WLAN_PROD))) {
+ /* RM PROD request sync return
+ * enable pipe immediately */
+ if (hdd_ipa_uc_enable_pipes(hdd_ipa)) {
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
+ "%s: IPA WDI Pipes activate fail", __func__);
+ return -EBUSY;
+ }
+ hdd_ipa->resource_loading = VOS_FALSE;
+ } else {
+ /* RM Disabled
+ * Just enabled all the PIPEs */
+ if (hdd_ipa_uc_enable_pipes(hdd_ipa)) {
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
+ "%s: IPA WDI Pipes activate fail", __func__);
+ return -EBUSY;
+ }
+ hdd_ipa->resource_loading = VOS_FALSE;
+ }
+ return 0;
+}
+
+static int hdd_ipa_uc_handle_last_discon(struct hdd_ipa_priv *hdd_ipa)
+{
+ hdd_ipa->resource_unloading = VOS_TRUE;
+ hdd_ipa_uc_disable_pipes(hdd_ipa);
+ if ((hdd_ipa_is_rm_enabled(hdd_ipa)) &&
+ (!ipa_rm_release_resource(IPA_RM_RESOURCE_WLAN_PROD))) {
+ /* Sync return success from IPA
+ * Enable/resume all the PIPEs */
+ hdd_ipa->resource_unloading = VOS_FALSE;
+ } else {
+ hdd_ipa->resource_unloading = VOS_FALSE;
+ }
+ return 0;
+}
+
+void hdd_ipa_uc_rm_notify_handler(void *context,
+ void *rxpkt,
+ u_int16_t staid)
+{
+ enum ipa_rm_event event_code;
+ struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
+
+ if (!hdd_ipa_is_rm_enabled(hdd_ipa))
+ return;
+
+ vos_mem_copy(&event_code, rxpkt, sizeof(event_code));
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%s, event code %d",
+ __func__, event_code);
+
+ switch(event_code) {
+ case IPA_RM_RESOURCE_GRANTED:
+ /* Differed RM Granted */
+ hdd_ipa_uc_enable_pipes(hdd_ipa);
+ hdd_ipa->resource_loading = VOS_FALSE;
+ if (hdd_ipa->pending_cons_req) {
+ ipa_rm_notify_completion(IPA_RM_RESOURCE_GRANTED,
+ IPA_RM_RESOURCE_WLAN_CONS);
+ }
+ hdd_ipa->pending_cons_req = VOS_FALSE;
+ break;
+
+ case IPA_RM_RESOURCE_RELEASED:
+ /* Differed RM Released */
+ hdd_ipa->resource_unloading = VOS_FALSE;
+ if (hdd_ipa->pending_cons_req) {
+ ipa_rm_notify_completion(IPA_RM_RESOURCE_RELEASED,
+ IPA_RM_RESOURCE_WLAN_CONS);
+ }
+ hdd_ipa->pending_cons_req = VOS_FALSE;
+ break;
+
+ default:
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
+ "%s, invalid event code %d",
+ __func__, event_code);
+ break;
+ }
+}
+
+void hdd_ipa_uc_rm_notify_defer(void *hdd_ipa, enum ipa_rm_event event)
+{
+ pVosSchedContext sched_ctx = get_vos_sched_ctxt();
+ struct VosTlshimPkt *pkt;
+ v_U8_t *event_code_pkt;
+
+ if (unlikely(!sched_ctx))
+ return;
+
+ pkt = vos_alloc_tlshim_pkt(sched_ctx);
+ if (!pkt) {
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
+ "%s, alloc fail", __func__);
+ return;
+ }
+
+ event_code_pkt = vos_mem_malloc(sizeof(unsigned int));
+ vos_mem_copy(event_code_pkt, &event, 1);
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO_HIGH,
+ "%s, posted event %d", __func__, event);
+ pkt->callback = (vos_tlshim_cb)hdd_ipa_uc_rm_notify_handler;
+ pkt->context = hdd_ipa;
+ pkt->Rxpkt = (void *) event_code_pkt;
+ pkt->staId = 0;
+ vos_indicate_rxpkt(sched_ctx, pkt);
+}
+
+static void hdd_ipa_uc_op_cb(v_U8_t op_code)
+{
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG,
+ "%s, OPCODE %s", __func__, op_string[op_code]);
+}
+
+static hdd_adapter_t *hdd_ipa_uc_get_adapter(struct hdd_ipa_priv *hdd_ipa,
+ uint8_t iface_id)
+{
+ uint8_t i;
+
+ /* This revisit needed for performance */
+ for (i = 0; i < HDD_IPA_MAX_IFACE; i++) {
+ if ((hdd_ipa->iface_context[i].adapter != NULL) &&
+ (hdd_ipa->iface_context[i].adapter->sessionId == iface_id)) {
+ return hdd_ipa->iface_context[i].adapter;
+ }
+ }
+ return NULL;
+}
+
+static VOS_STATUS hdd_ipa_uc_ol_init(hdd_context_t *hdd_ctx)
+{
+ struct ipa_wdi_in_params pipe_in;
+ struct ipa_wdi_out_params pipe_out;
+ struct hdd_ipa_priv *ipa_ctxt = (struct hdd_ipa_priv *)hdd_ctx->hdd_ipa;
+
+ vos_mem_zero(&pipe_in, sizeof(struct ipa_wdi_in_params));
+ vos_mem_zero(&pipe_out, sizeof(struct ipa_wdi_out_params));
+
+ /* TX PIPE */
+ pipe_in.sys.ipa_ep_cfg.nat.nat_en = IPA_BYPASS_NAT;
+ pipe_in.sys.ipa_ep_cfg.hdr.hdr_len = HDD_IPA_UC_WLAN_TX_HDR_LEN;
+ pipe_in.sys.ipa_ep_cfg.hdr.hdr_ofst_pkt_size_valid = 1;
+ pipe_in.sys.ipa_ep_cfg.hdr.hdr_ofst_pkt_size = 0;
+ pipe_in.sys.ipa_ep_cfg.hdr.hdr_additional_const_len =
+ HDD_IPA_UC_WLAN_8023_HDR_SIZE;
+ pipe_in.sys.ipa_ep_cfg.mode.mode = IPA_BASIC;
+ pipe_in.sys.client = IPA_CLIENT_WLAN1_CONS;
+ pipe_in.sys.desc_fifo_sz = hdd_ctx->cfg_ini->IpaDescSize;
+ pipe_in.sys.priv = hdd_ctx->hdd_ipa;
+ pipe_in.sys.ipa_ep_cfg.hdr_ext.hdr_little_endian = true;
+ pipe_in.sys.notify = hdd_ipa_i2w_cb;
+ if (!hdd_ipa_is_rm_enabled(ghdd_ipa)) {
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO,
+ "%s: IPA RM DISABLED, IPA AWAKE", __func__);
+ pipe_in.sys.keep_ipa_awake = TRUE;
+ }
+
+ pipe_in.u.dl.comp_ring_base_pa = hdd_ctx->tx_comp_ring_base_paddr;
+ pipe_in.u.dl.comp_ring_size = hdd_ctx->tx_comp_ring_size * 4;
+ pipe_in.u.dl.ce_ring_base_pa = hdd_ctx->ce_sr_base_paddr;
+ pipe_in.u.dl.ce_door_bell_pa = hdd_ctx->ce_reg_paddr;
+ pipe_in.u.dl.ce_ring_size = hdd_ctx->ce_sr_ring_size * 8;
+ pipe_in.u.dl.num_tx_buffers = hdd_ctx->tx_num_alloc_buffer;
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO_HIGH,
+ "MAX TX COMP ELEMENT %d",
+ (unsigned int)hdd_ctx->cfg_ini->IpaUcTxBufCount);
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO_HIGH,
+ "TX COMP RING SIZE %d",
+ (unsigned int)pipe_in.u.dl.comp_ring_size);
+
+ /* Connect WDI IPA PIPE */
+ ipa_connect_wdi_pipe(&pipe_in, &pipe_out);
+ /* Micro Controller Doorbell register */
+ hdd_ctx->tx_comp_doorbell_paddr = (v_U32_t)pipe_out.uc_door_bell_pa;
+ /* WLAN TX PIPE Handle */
+ ipa_ctxt->tx_pipe_handle = pipe_out.clnt_hdl;
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO_HIGH,
+ "TX COMP IPA DOORBELL %x",
+ (unsigned int)hdd_ctx->tx_comp_doorbell_paddr);
+
+ /* RX PIPE */
+ pipe_in.sys.ipa_ep_cfg.nat.nat_en = IPA_BYPASS_NAT;
+ pipe_in.sys.ipa_ep_cfg.hdr.hdr_len = HDD_IPA_UC_WLAN_RX_HDR_LEN;
+ pipe_in.sys.ipa_ep_cfg.hdr.hdr_ofst_metadata_valid = 0;
+ pipe_in.sys.ipa_ep_cfg.hdr.hdr_metadata_reg_valid = 1;
+ pipe_in.sys.ipa_ep_cfg.mode.mode = IPA_BASIC;
+ pipe_in.sys.client = IPA_CLIENT_WLAN1_PROD;
+ pipe_in.sys.desc_fifo_sz = hdd_ctx->cfg_ini->IpaDescSize +
+ sizeof(struct sps_iovec);
+ pipe_in.sys.notify = hdd_ipa_w2i_cb;
+ if (!hdd_ipa_is_rm_enabled(ghdd_ipa)) {
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
+ "%s: IPA RM DISABLED, IPA AWAKE", __func__);
+ pipe_in.sys.keep_ipa_awake = TRUE;
+ }
+
+ pipe_in.u.ul.rdy_ring_base_pa = hdd_ctx->rx_rdy_ring_base_paddr;
+ pipe_in.u.ul.rdy_ring_size = hdd_ctx->rx_rdy_ring_size;
+ pipe_in.u.ul.rdy_ring_rp_pa = hdd_ctx->rx_proc_done_idx_paddr;
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO_HIGH,
+ "RX RING SIZE %d",
+ (unsigned int)pipe_in.u.ul.rdy_ring_size);
+
+ ipa_connect_wdi_pipe(&pipe_in, &pipe_out);
+ hdd_ctx->rx_ready_doorbell_paddr = pipe_out.uc_door_bell_pa;
+ ipa_ctxt->rx_pipe_handle = pipe_out.clnt_hdl;
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO_HIGH,
+ "RX READY IPA DOORBELL %x",
+ (unsigned int)hdd_ctx->rx_ready_doorbell_paddr);
+
+ WLANTL_SetUcDoorbellPaddr((pVosContextType)(hdd_ctx->pvosContext),
+ (v_U32_t)hdd_ctx->tx_comp_doorbell_paddr,
+ (v_U32_t)hdd_ctx->rx_ready_doorbell_paddr);
+
+ WLANTL_RegisterOPCbFnc((pVosContextType)(hdd_ctx->pvosContext),
+ hdd_ipa_uc_op_cb);
+
+ return VOS_STATUS_SUCCESS;
+}
+#endif /* IPA_UC_OFFLOAD */
+
static int hdd_ipa_rm_request(struct hdd_ipa_priv *hdd_ipa)
{
int ret = 0;
@@ -401,13 +830,33 @@ static void hdd_ipa_rm_notify(void *user_data, enum ipa_rm_event event,
switch(event) {
case IPA_RM_RESOURCE_GRANTED:
- atomic_set(&hdd_ipa->rm_state, HDD_IPA_RM_GRANTED);
- hdd_ipa->stats.rm_grant++;
- hdd_ipa_process_evt(HDD_IPA_RM_GRANT_EVT, NULL);
+ if (!hdd_ipa_uc_is_enabled(hdd_ipa)) {
+ atomic_set(&hdd_ipa->rm_state, HDD_IPA_RM_GRANTED);
+ hdd_ipa->stats.rm_grant++;
+ hdd_ipa_process_evt(HDD_IPA_RM_GRANT_EVT, NULL);
+ }
+#ifdef IPA_UC_OFFLOAD
+ else {
+ /* RM Notification comes with ISR context
+ * it should be serialized into differed thread to avoid
+ * ISR sleep problem */
+ if (hdd_ipa->resource_loading) {
+ hdd_ipa_uc_rm_notify_defer(hdd_ipa, event);
+ } else {
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
+ "UCResource Grntd with invalid status");
+ }
+ }
+#endif /* IPA_UC_OFFLOAD */
break;
+
case IPA_RM_RESOURCE_RELEASED:
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "RM Release not expected!");
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "RM Release");
+#ifdef IPA_UC_OFFLOAD
+ hdd_ipa->resource_unloading = VOS_FALSE;
+#endif /* IPA_UC_OFFLOAD */
break;
+
default:
HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Unknow RM Evt: %d", event);
break;
@@ -416,11 +865,23 @@ static void hdd_ipa_rm_notify(void *user_data, enum ipa_rm_event event,
static int hdd_ipa_rm_cons_release(void)
{
+#ifdef IPA_UC_OFFLOAD
+ /* Do Nothing */
+#endif /* IPA_UC_OFFLOAD */
return 0;
}
static int hdd_ipa_rm_cons_request(void)
{
+#ifdef IPA_UC_OFFLOAD
+ if ((ghdd_ipa->resource_loading) || (ghdd_ipa->resource_unloading)) {
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL,
+ "%s: ipa resource loading/unloading in progress",
+ __func__);
+ ghdd_ipa->pending_cons_req = VOS_TRUE;
+ return -EINPROGRESS;
+ }
+#endif /* IPA_UC_OFFLOAD */
return 0;
}
@@ -432,8 +893,9 @@ int hdd_ipa_set_perf_level(hdd_context_t *hdd_ctx, uint64_t tx_packets,
struct ipa_rm_perf_profile profile;
int ret;
- if (!hdd_ipa_is_enabled(hdd_ctx) ||
- !hdd_ipa_is_clk_scaling_enabled(hdd_ipa))
+ if ((!hdd_ipa_is_enabled(hdd_ctx)) ||
+ (!hdd_ipa_is_clk_scaling_enabled(hdd_ipa)) ||
+ (hdd_ipa_uc_is_enabled(hdd_ipa)))
return 0;
memset(&profile, 0, sizeof(profile));
@@ -508,8 +970,9 @@ static int hdd_ipa_setup_rm(struct hdd_ipa_priv *hdd_ipa)
ret = ipa_rm_create_resource(&create_params);
if (ret) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Create RM resource failed: %d",
- ret);
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
+ "Create RM resource failed: %d",
+ ret);
goto setup_rm_fail;
}
@@ -787,8 +1250,18 @@ static void hdd_ipa_process_evt(int evt, void *priv)
continue;
}
- cld_hdr = (struct hdd_ipa_cld_hdr *) skb_push(buf,
+#ifdef IPA_UC_OFFLOAD
+ if (hdd_ipa_uc_is_enabled(hdd_ipa)) {
+ cld_hdr = (struct hdd_ipa_cld_hdr *) skb_push(
+ buf,
+ HDD_IPA_UC_WLAN_CLD_HDR_LEN);
+ } else
+#endif /* IPA_UC_OFFLOAD */
+ {
+ cld_hdr = (struct hdd_ipa_cld_hdr *) skb_push(
+ buf,
HDD_IPA_WLAN_CLD_HDR_LEN);
+ }
cld_hdr->sta_id = rxt->sta_id;
cld_hdr->iface_id = iface_context->iface_id;
@@ -1029,7 +1502,15 @@ static void hdd_ipa_w2i_cb(void *priv, enum ipa_dp_evt_type evt,
case IPA_RECEIVE:
skb = (adf_nbuf_t) data;
- iface_id = HDD_IPA_GET_IFACE_ID(skb->data);
+#ifdef IPA_UC_OFFLOAD
+ if (hdd_ipa_uc_is_enabled(hdd_ipa)) {
+ iface_id = (uint8_t)skb->cb[0];
+ } else
+#endif /* IPA_UC_OFFLOAD */
+ {
+ iface_id = HDD_IPA_GET_IFACE_ID(skb->data);
+ }
+
if (iface_id >= HDD_IPA_MAX_IFACE) {
HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
"IPA_RECEIVE: Invalid iface_id: %u",
@@ -1038,12 +1519,25 @@ static void hdd_ipa_w2i_cb(void *priv, enum ipa_dp_evt_type evt,
return;
}
- adapter = hdd_ipa->iface_context[iface_id].adapter;
+#ifdef IPA_UC_OFFLOAD
+ if (hdd_ipa_uc_is_enabled(hdd_ipa)) {
+ adapter = hdd_ipa_uc_get_adapter(hdd_ipa, iface_id);
+ } else
+#endif /* IPA_UC_OFFLOAD */
+ {
+ adapter = hdd_ipa->iface_context[iface_id].adapter;
+ }
HDD_IPA_DBG_DUMP(VOS_TRACE_LEVEL_DEBUG, "w2i -- skb", skb->data,
8);
-
- skb_pull(skb, HDD_IPA_WLAN_CLD_HDR_LEN);
+#ifdef IPA_UC_OFFLOAD
+ if (hdd_ipa_uc_is_enabled(hdd_ipa)) {
+ skb_pull(skb, HDD_IPA_UC_WLAN_CLD_HDR_LEN);
+ } else
+#endif /* IPA_UC_OFFLOAD */
+ {
+ skb_pull(skb, HDD_IPA_WLAN_CLD_HDR_LEN);
+ }
hdd_ipa->stats.rx_ipa_excep++;
hdd_ipa_send_skb_to_network(skb, adapter);
@@ -1378,6 +1872,9 @@ static int hdd_ipa_add_header_info(struct hdd_ipa_priv *hdd_ipa,
struct ipa_ioc_add_hdr *ipa_hdr = NULL;
int ret = -EINVAL;
struct hdd_ipa_tx_hdr *tx_hdr = NULL;
+#ifdef IPA_UC_OFFLOAD
+ struct hdd_ipa_uc_tx_hdr *uc_tx_hdr = NULL;
+#endif /* IPA_UC_OFFLOAD */
ifname = adapter->dev->name;
@@ -1398,23 +1895,37 @@ static int hdd_ipa_add_header_info(struct hdd_ipa_priv *hdd_ipa,
ipa_hdr->commit = 0;
ipa_hdr->num_hdrs = 1;
- tx_hdr = (struct hdd_ipa_tx_hdr *)ipa_hdr->hdr[0].hdr;
+#ifdef IPA_UC_OFFLOAD
+ if (hdd_ipa_uc_is_enabled(hdd_ipa)) {
+ uc_tx_hdr = (struct hdd_ipa_uc_tx_hdr *)ipa_hdr->hdr[0].hdr;
+ memcpy(uc_tx_hdr, &ipa_uc_tx_hdr, HDD_IPA_UC_WLAN_TX_HDR_LEN);
+ memcpy(uc_tx_hdr->eth.h_source, mac_addr, ETH_ALEN);
+ snprintf(ipa_hdr->hdr[0].name, IPA_RESOURCE_NAME_MAX, "%s%s",
+ ifname, HDD_IPA_IPV4_NAME_EXT);
+ ipa_hdr->hdr[0].hdr_len = HDD_IPA_UC_WLAN_TX_HDR_LEN;
+ ipa_hdr->hdr[0].is_partial = 1;
+ ipa_hdr->hdr[0].hdr_hdl = 0;
+ ret = ipa_add_hdr(ipa_hdr);
+ } else
+#endif /* IPA_UC_OFFLOAD */
+ {
+ tx_hdr = (struct hdd_ipa_tx_hdr *)ipa_hdr->hdr[0].hdr;
- /* Set the Source MAC */
- memcpy(tx_hdr, &ipa_tx_hdr, HDD_IPA_WLAN_TX_HDR_LEN);
- memcpy(tx_hdr->eth.h_source, mac_addr, ETH_ALEN);
+ /* Set the Source MAC */
+ memcpy(tx_hdr, &ipa_tx_hdr, HDD_IPA_WLAN_TX_HDR_LEN);
+ memcpy(tx_hdr->eth.h_source, mac_addr, ETH_ALEN);
- snprintf(ipa_hdr->hdr[0].name, IPA_RESOURCE_NAME_MAX, "%s%s",
+ snprintf(ipa_hdr->hdr[0].name, IPA_RESOURCE_NAME_MAX, "%s%s",
ifname, HDD_IPA_IPV4_NAME_EXT);
- ipa_hdr->hdr[0].hdr_len = HDD_IPA_WLAN_TX_HDR_LEN;
- ipa_hdr->hdr[0].is_partial = 1;
- ipa_hdr->hdr[0].hdr_hdl = 0;
-
- /* Set the type to IPV4 in the header*/
- tx_hdr->llc_snap.eth_type = cpu_to_be16(ETH_P_IP);
+ ipa_hdr->hdr[0].hdr_len = HDD_IPA_WLAN_TX_HDR_LEN;
+ ipa_hdr->hdr[0].is_partial = 1;
+ ipa_hdr->hdr[0].hdr_hdl = 0;
- ret = ipa_add_hdr(ipa_hdr);
+ /* Set the type to IPV4 in the header*/
+ tx_hdr->llc_snap.eth_type = cpu_to_be16(ETH_P_IP);
+ ret = ipa_add_hdr(ipa_hdr);
+ }
if (ret) {
HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "%s IPv4 add hdr failed: %d",
ifname, ret);
@@ -1428,8 +1939,10 @@ static int hdd_ipa_add_header_info(struct hdd_ipa_priv *hdd_ipa,
snprintf(ipa_hdr->hdr[0].name, IPA_RESOURCE_NAME_MAX, "%s%s",
ifname, HDD_IPA_IPV6_NAME_EXT);
- /* Set the type to IPV6 in the header*/
- tx_hdr->llc_snap.eth_type = cpu_to_be16(ETH_P_IPV6);
+ if (!hdd_ipa_uc_is_enabled(hdd_ipa)) {
+ /* Set the type to IPV6 in the header*/
+ tx_hdr->llc_snap.eth_type = cpu_to_be16(ETH_P_IPV6);
+ }
ret = ipa_add_hdr(ipa_hdr);
@@ -1640,7 +2153,16 @@ int hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id,
IPA_RESOURCE_NAME_MAX);
msg_ex->num_of_attribs = 1;
msg_ex->attribs[0].attrib_type = WLAN_HDR_ATTRIB_MAC_ADDR;
- msg_ex->attribs[0].offset = HDD_IPA_WLAN_HDR_DES_MAC_OFFSET;
+#ifdef IPA_UC_OFFLOAD
+ if (hdd_ipa_uc_is_enabled(hdd_ipa)) {
+ msg_ex->attribs[0].offset =
+ HDD_IPA_UC_WLAN_HDR_DES_MAC_OFFSET;
+ } else
+#endif /* IPA_UC_OFFLOAD */
+ {
+ msg_ex->attribs[0].offset =
+ HDD_IPA_WLAN_HDR_DES_MAC_OFFSET;
+ }
memcpy(msg_ex->attribs[0].u.mac_addr, mac_addr,
IPA_MAC_ADDR_SIZE);
@@ -1653,9 +2175,41 @@ int hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id,
return ret;
}
hdd_ipa->stats.send_msg++;
+#ifdef IPA_UC_OFFLOAD
+ if (!hdd_ipa_uc_is_enabled(hdd_ipa)) {
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO,
+ "%s: Evt: %d, IPA UC OFFLOAD NOT ENABLED",
+ msg_ex->name, meta.msg_type);
+ } else {
+ hdd_ipa->sap_num_connected_sta++;
+ hdd_ipa->pending_cons_req = VOS_FALSE;
+ /* Enable IPA UC Data PIPEs when first STA connected */
+ if (1 == hdd_ipa->sap_num_connected_sta) {
+ ret = hdd_ipa_uc_handle_first_con(hdd_ipa);
+ if (!ret) {
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
+ "%s: handle 1st con ret %d",
+ msg_ex->name, ret);
+ }
+ }
+ }
+#endif /* IPA_UC_OFFLOAD */
+ return ret;
- return 0;
case WLAN_CLIENT_DISCONNECT:
+#ifdef IPA_UC_OFFLOAD
+ if (!hdd_ipa_uc_is_enabled(hdd_ipa)) {
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
+ "%s: Evt: %d, IPA UC OFFLOAD NOT ENABLED",
+ msg_ex->name, meta.msg_type);
+ return 0;
+ }
+ hdd_ipa->sap_num_connected_sta--;
+ /* Disable IPA UC TX PIPE when last STA disconnected */
+ if (!hdd_ipa->sap_num_connected_sta) {
+ hdd_ipa_uc_handle_last_discon(hdd_ipa);
+ }
+#endif /* IPA_UC_OFFLOAD */
break;
default:
@@ -1910,7 +2464,6 @@ static int hdd_ipa_debugfs_init(struct hdd_ipa_priv *hdd_ipa)
#endif
return 0;
}
-
static void hdd_ipa_debugfs_remove(struct hdd_ipa_priv *hdd_ipa)
{
#ifdef WLAN_OPEN_SOURCE
@@ -1961,22 +2514,33 @@ VOS_STATUS hdd_ipa_init(hdd_context_t *hdd_ctx)
if (ret)
goto fail_setup_rm;
- ret = hdd_ipa_setup_sys_pipe(hdd_ipa);
- if (ret)
- goto fail_create_sys_pipe;
+#ifdef IPA_UC_OFFLOAD
+ if (hdd_ipa_uc_is_enabled(hdd_ipa)) {
+ hdd_ipa->sap_num_connected_sta = 0;
+ hdd_ipa_uc_ol_init(hdd_ctx);
+ } else
+#endif /* IPA_UC_OFFLOAD */
+ {
+ ret = hdd_ipa_setup_sys_pipe(hdd_ipa);
+ if (ret)
+ goto fail_create_sys_pipe;
- ret = hdd_ipa_rx_pipe_desc_alloc();
- if (ret)
- goto fail_alloc_rx_pipe_desc;
+ ret = hdd_ipa_rx_pipe_desc_alloc();
+ if (ret)
+ goto fail_alloc_rx_pipe_desc;
+ }
ret = hdd_ipa_debugfs_init(hdd_ipa);
if (ret)
goto fail_alloc_rx_pipe_desc;
- hdd_ipa->ipv4_notifier.notifier_call = hdd_ipa_ipv4_changed;
- ret = register_inetaddr_notifier(&hdd_ipa->ipv4_notifier);
- if (ret)
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
+
+ if (!hdd_ipa_uc_is_enabled(hdd_ipa)) {
+ hdd_ipa->ipv4_notifier.notifier_call = hdd_ipa_ipv4_changed;
+ ret = register_inetaddr_notifier(&hdd_ipa->ipv4_notifier);
+ if (ret)
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
"WLAN IPv4 local filter register failed");
+ }
return VOS_STATUS_SUCCESS;
fail_alloc_rx_pipe_desc:
@@ -2011,11 +2575,27 @@ VOS_STATUS hdd_ipa_cleanup(hdd_context_t *hdd_ctx)
msleep(5);
HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "IPA Pending");
}
- hdd_ipa_rx_pipe_desc_free();
- hdd_ipa_teardown_sys_pipe(hdd_ipa);
+
+#ifdef IPA_UC_OFFLOAD
+ if (hdd_ipa_uc_is_enabled(hdd_ipa)) {
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO,
+ "%s: Disconnect TX PIPE", __func__);
+ ipa_disconnect_wdi_pipe(hdd_ipa->tx_pipe_handle);
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO,
+ "%s: Disconnect RX PIPE", __func__);
+ ipa_disconnect_wdi_pipe(hdd_ipa->rx_pipe_handle);
+ } else
+#endif /* IPA_UC_OFFLOAD */
+ {
+ hdd_ipa_rx_pipe_desc_free();
+ hdd_ipa_teardown_sys_pipe(hdd_ipa);
+ }
+
hdd_ipa_destory_rm_resource(hdd_ipa);
- unregister_inetaddr_notifier(&hdd_ipa->ipv4_notifier);
+ if (!hdd_ipa_uc_is_enabled(hdd_ipa)) {
+ unregister_inetaddr_notifier(&hdd_ipa->ipv4_notifier);
+ }
adf_os_mem_free(hdd_ipa);
hdd_ctx->hdd_ipa = NULL;
diff --git a/CORE/HDD/src/wlan_hdd_softap_tx_rx.c b/CORE/HDD/src/wlan_hdd_softap_tx_rx.c
index fa46aff46b38..e5894a760c17 100644
--- a/CORE/HDD/src/wlan_hdd_softap_tx_rx.c
+++ b/CORE/HDD/src/wlan_hdd_softap_tx_rx.c
@@ -2000,7 +2000,10 @@ VOS_STATUS hdd_softap_RegisterSTA( hdd_adapter_t *pAdapter,
staDesc.ucIsReplayCheckValid = VOS_FALSE;
// Register the Station with TL...
-#ifdef IPA_OFFLOAD
+ /* Incase Micro controller data path offload enabled,
+ * All the traffic routed to WLAN host driver, do not need to
+ * route IPA. It should be routed kernel network stack */
+#if defined(IPA_OFFLOAD) && !defined(IPA_UC_OFFLOAD)
if (hdd_ipa_is_enabled(pHddCtx)) {
vosStatus = WLANTL_RegisterSTAClient( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
hdd_ipa_process_rxt,
diff --git a/CORE/HDD/src/wlan_hdd_wext.c b/CORE/HDD/src/wlan_hdd_wext.c
index 38c8fd6e2f1a..edff1b2a3762 100644
--- a/CORE/HDD/src/wlan_hdd_wext.c
+++ b/CORE/HDD/src/wlan_hdd_wext.c
@@ -578,7 +578,7 @@ int wlan_hdd_set_filter(hdd_context_t *pHddCtx, tpPacketFilterCfg pRequest,
\return - On Success pointer to buffer, On failure NULL
--------------------------------------------------------------------------*/
-static void *mem_alloc_copy_from_user_helper(const void *wrqu_data, size_t len)
+void *mem_alloc_copy_from_user_helper(const void *wrqu_data, size_t len)
{
u8 *ptr = NULL;
diff --git a/CORE/MAC/inc/aniGlobal.h b/CORE/MAC/inc/aniGlobal.h
index 208f21c783ed..6f9fe2f63d49 100644
--- a/CORE/MAC/inc/aniGlobal.h
+++ b/CORE/MAC/inc/aniGlobal.h
@@ -1037,6 +1037,19 @@ typedef struct sMacOpenParameters
/* dfs radar pri multiplier */
tANI_S32 dfsRadarPriMultiplier;
+#ifdef IPA_UC_OFFLOAD
+ /* IPA Micro controller data path offload enable flag */
+ tANI_U8 ucOffloadEnabled;
+ /* IPA Micro controller data path offload TX buffer count */
+ tANI_U32 ucTxBufCount;
+ /* IPA Micro controller data path offload TX buffer size */
+ tANI_U32 ucTxBufSize;
+ /* IPA Micro controller data path offload RX indication ring count */
+ tANI_U32 ucRxIndRingCount;
+ /* IPA Micro controller data path offload TX partition base */
+ tANI_U32 ucTxPartitionBase;
+#endif /* IPA_UC_OFFLOAD */
+
} tMacOpenParameters;
typedef struct sHalMacStartParameters
diff --git a/CORE/MAC/inc/qwlan_version.h b/CORE/MAC/inc/qwlan_version.h
index 40a1d705d763..6d2945400680 100644
--- a/CORE/MAC/inc/qwlan_version.h
+++ b/CORE/MAC/inc/qwlan_version.h
@@ -42,9 +42,9 @@ BRIEF DESCRIPTION:
#define QWLAN_VERSION_MINOR 0
#define QWLAN_VERSION_PATCH 0
#define QWLAN_VERSION_EXTRA ""
-#define QWLAN_VERSION_BUILD 143
+#define QWLAN_VERSION_BUILD 144
-#define QWLAN_VERSIONSTR "1.0.0.143"
+#define QWLAN_VERSIONSTR "1.0.0.144"
#ifdef QCA_WIFI_2_0
diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h
index 54eb1c5dd3bd..7243b28c7a39 100644
--- a/CORE/MAC/inc/sirApi.h
+++ b/CORE/MAC/inc/sirApi.h
@@ -735,6 +735,9 @@ typedef struct sSirSmeStartBssReq
#endif
tSirAddIeParams addIeParams;
+
+ tANI_BOOLEAN obssEnabled;
+
} tSirSmeStartBssReq, *tpSirSmeStartBssReq;
#define GET_IE_LEN_IN_BSS(lenInBss) ( lenInBss + sizeof(lenInBss) - \
diff --git a/CORE/MAC/inc/sirMacProtDef.h b/CORE/MAC/inc/sirMacProtDef.h
index 66e89745692b..b2505e6ec525 100644
--- a/CORE/MAC/inc/sirMacProtDef.h
+++ b/CORE/MAC/inc/sirMacProtDef.h
@@ -251,6 +251,9 @@
#define SIR_MAC_ACTION_VENDOR_SPECIFIC_CATEGORY 0x7F
#define SIR_MAC_ACTION_P2P_SUBTYPE_PRESENCE_RSP 2
+// Public Action for 20/40 BSS Coexistence
+#define SIR_MAC_ACTION_2040_BSS_COEXISTENCE 0
+
#ifdef WLAN_FEATURE_11W
//11w SA query request/response action frame category code
#define SIR_MAC_SA_QUERY_REQ 0
diff --git a/CORE/MAC/inc/wniCfgAp.h b/CORE/MAC/inc/wniCfgAp.h
index f82061567a18..7232ae7eb0b1 100644
--- a/CORE/MAC/inc/wniCfgAp.h
+++ b/CORE/MAC/inc/wniCfgAp.h
@@ -357,6 +357,7 @@
#define WNI_CFG_DEBUG_P2P_REMAIN_ON_CHANNEL 310
#define WNI_CFG_TDLS_OFF_CHANNEL_ENABLED 311
#define WNI_CFG_IBSS_ATIM_WIN_SIZE 312
+#define WNI_CFG_DFS_MASTER_ENABLED 313
/*
* String parameter lengths
@@ -2619,10 +2620,18 @@
#define WNI_CFG_IBSS_ATIM_WIN_SIZE_APMAX 100
#define WNI_CFG_IBSS_ATIM_WIN_SIZE_APDEF 0
-#define CFG_PARAM_MAX_NUM 313
-#define CFG_AP_IBUF_MAX_SIZE 253
+#define WNI_CFG_DFS_MASTER_ENABLED_STAMIN 0
+#define WNI_CFG_DFS_MASTER_ENABLED_STAMAX 1
+#define WNI_CFG_DFS_MASTER_ENABLED_STADEF 0
+
+#define WNI_CFG_DFS_MASTER_ENABLED_APMIN 0
+#define WNI_CFG_DFS_MASTER_ENABLED_APMAX 1
+#define WNI_CFG_DFS_MASTER_ENABLED_APDEF 0
+
+#define CFG_PARAM_MAX_NUM 314
+#define CFG_AP_IBUF_MAX_SIZE 254
#define CFG_AP_SBUF_MAX_SIZE 3414
-#define CFG_STA_IBUF_MAX_SIZE 248
+#define CFG_STA_IBUF_MAX_SIZE 249
#define CFG_STA_SBUF_MAX_SIZE 3380
#define CFG_SEM_MAX_NUM 19
diff --git a/CORE/MAC/inc/wniCfgSta.h b/CORE/MAC/inc/wniCfgSta.h
index 6b7bede23aa7..f5ade66a74ae 100644
--- a/CORE/MAC/inc/wniCfgSta.h
+++ b/CORE/MAC/inc/wniCfgSta.h
@@ -351,6 +351,7 @@
#define WNI_CFG_DEBUG_P2P_REMAIN_ON_CHANNEL 310
#define WNI_CFG_TDLS_OFF_CHANNEL_ENABLED 311
#define WNI_CFG_IBSS_ATIM_WIN_SIZE 312
+#define WNI_CFG_DFS_MASTER_ENABLED 313
/*
* String parameter lengths
@@ -1688,8 +1689,12 @@
#define WNI_CFG_IBSS_ATIM_WIN_SIZE_STAMAX 100
#define WNI_CFG_IBSS_ATIM_WIN_SIZE_STADEF 0
-#define CFG_PARAM_MAX_NUM 313
-#define CFG_STA_IBUF_MAX_SIZE 248
+#define WNI_CFG_DFS_MASTER_ENABLED_STAMIN 0
+#define WNI_CFG_DFS_MASTER_ENABLED_STAMAX 1
+#define WNI_CFG_DFS_MASTER_ENABLED_STADEF 0
+
+#define CFG_PARAM_MAX_NUM 314
+#define CFG_STA_IBUF_MAX_SIZE 249
#define CFG_STA_SBUF_MAX_SIZE 3380
#define CFG_SEM_MAX_NUM 19
diff --git a/CORE/MAC/src/cfg/cfgUtil/cfg.txt b/CORE/MAC/src/cfg/cfgUtil/cfg.txt
index 8b0fb9b2ce4f..670bc4e07cb0 100644
--- a/CORE/MAC/src/cfg/cfgUtil/cfg.txt
+++ b/CORE/MAC/src/cfg/cfgUtil/cfg.txt
@@ -1422,7 +1422,6 @@ V RW NP RESTART
NONE
0 1 1
-
*
* Wait for CNF Timeout. CNF include (RE)ASSOC, DISASSOC, AUTH, DEAUTH,
* DUMMY packet
@@ -4672,3 +4671,15 @@ NONE
V RW NP
NONE
0 100 0
+
+*
+* DFS Master capability (11h) enable/disable
+*
+
+WNI_CFG_DFS_MASTER_ENABLED I 4 7
+V RW NP
+NONE
+0 1 0
+V RW NP
+NONE
+0 1 0
diff --git a/CORE/MAC/src/pe/lim/limProcessActionFrame.c b/CORE/MAC/src/pe/lim/limProcessActionFrame.c
index aaf5676b6f50..015c9ff7b3bc 100644
--- a/CORE/MAC/src/pe/lim/limProcessActionFrame.c
+++ b/CORE/MAC/src/pe/lim/limProcessActionFrame.c
@@ -2545,6 +2545,20 @@ limProcessActionFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo,tpPESession ps
}
}
break;
+
+ case SIR_MAC_ACTION_2040_BSS_COEXISTENCE:
+ {
+ tpSirMacMgmtHdr pHdr;
+ tANI_U32 frameLen;
+
+ pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
+ frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+
+ limSendSmeMgmtFrameInd(pMac, pHdr->fc.subType,
+ (tANI_U8*)pHdr, frameLen + sizeof(tSirMacMgmtHdr), 0,
+ WDA_GET_RX_CH( pRxPacketInfo ), psessionEntry, 0);
+ }
+
#ifdef FEATURE_WLAN_TDLS
case SIR_MAC_TDLS_DIS_RSP:
{
diff --git a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
index b324740f527e..3677bfce124c 100644
--- a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
+++ b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
@@ -773,7 +773,12 @@ __limHandleSmeStartBssRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
if (pSmeStartBssReq->channelId)
{
channelNumber = pSmeStartBssReq->channelId;
- psessionEntry->htSupportedChannelWidthSet = (pSmeStartBssReq->cbMode)?1:0; // This is already merged value of peer and self - done by csr in csrGetCBModeFromIes
+ if (pSmeStartBssReq->obssEnabled)
+ psessionEntry->htSupportedChannelWidthSet =
+ IS_DOT11_MODE_HT(psessionEntry->dot11mode)?1:0;
+ else
+ psessionEntry->htSupportedChannelWidthSet =
+ (pSmeStartBssReq->cbMode)?1:0;
psessionEntry->htRecommendedTxWidthSet = psessionEntry->htSupportedChannelWidthSet;
psessionEntry->htSecondaryChannelOffset = pSmeStartBssReq->cbMode;
VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
@@ -1013,12 +1018,25 @@ __limHandleSmeStartBssRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
if (wlan_cfgGetInt(pMac, WNI_CFG_11H_ENABLED, &val) != eSIR_SUCCESS)
limLog(pMac, LOGP, FL("Fail to get WNI_CFG_11H_ENABLED "));
psessionEntry->lim11hEnable = val;
+
+ if (psessionEntry->lim11hEnable &&
+ (eSIR_INFRA_AP_MODE == pMlmStartReq->bssType))
+ {
+ if (wlan_cfgGetInt(pMac, WNI_CFG_DFS_MASTER_ENABLED, &val) !=
+ eSIR_SUCCESS)
+ {
+ limLog(pMac, LOGE,
+ FL("Fail to get WNI_CFG_DFS_MASTER_ENABLED"));
+ }
+ psessionEntry->lim11hEnable = val;
+ }
}
if (!psessionEntry->lim11hEnable)
{
if (cfgSetInt(pMac, WNI_CFG_LOCAL_POWER_CONSTRAINT, 0) != eSIR_SUCCESS)
- limLog(pMac, LOGP, FL("Fail to get WNI_CFG_11H_ENABLED "));
+ limLog(pMac, LOGE, FL
+ ("Fail to set value for WNI_CFG_LOCAL_POWER_CONSTRAINT"));
}
psessionEntry ->limPrevSmeState = psessionEntry->limSmeState;
@@ -3800,9 +3818,9 @@ __limHandleSmeStopBssRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
psessionEntry->addIeParams.probeRespDataLen = 0;
psessionEntry->addIeParams.probeRespData_buff = NULL;
- vos_mem_free(psessionEntry->addIeParams.probeRespBCNData_buff);
- psessionEntry->addIeParams.probeRespBCNDataLen = 0;
- psessionEntry->addIeParams.probeRespBCNData_buff = NULL;
+ vos_mem_free(psessionEntry->addIeParams.assocRespData_buff);
+ psessionEntry->addIeParams.assocRespDataLen = 0;
+ psessionEntry->addIeParams.assocRespData_buff = NULL;
vos_mem_free(psessionEntry->addIeParams.probeRespBCNData_buff);
psessionEntry->addIeParams.probeRespBCNDataLen = 0;
@@ -4817,19 +4835,13 @@ static void __limProcessSmeSetHT2040Mode(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf)
switch(pSetHT2040Mode->cbMode)
{
case PHY_SINGLE_CHANNEL_CENTERED:
- psessionEntry->htSupportedChannelWidthSet = eHT_CHANNEL_WIDTH_20MHZ;
psessionEntry->htSecondaryChannelOffset = PHY_SINGLE_CHANNEL_CENTERED;
- psessionEntry->htRecommendedTxWidthSet = eHT_CHANNEL_WIDTH_20MHZ;
break;
case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
- psessionEntry->htSupportedChannelWidthSet = eHT_CHANNEL_WIDTH_40MHZ;
psessionEntry->htSecondaryChannelOffset = PHY_DOUBLE_CHANNEL_LOW_PRIMARY;
- psessionEntry->htRecommendedTxWidthSet = eHT_CHANNEL_WIDTH_40MHZ;
break;
case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
- psessionEntry->htSupportedChannelWidthSet = eHT_CHANNEL_WIDTH_40MHZ;
psessionEntry->htSecondaryChannelOffset = PHY_DOUBLE_CHANNEL_HIGH_PRIMARY;
- psessionEntry->htRecommendedTxWidthSet = eHT_CHANNEL_WIDTH_40MHZ;
break;
default:
limLog(pMac, LOGE,FL("Invalid cbMode"));
diff --git a/CORE/MAC/src/pe/lim/limSerDesUtils.c b/CORE/MAC/src/pe/lim/limSerDesUtils.c
index 957c5e1f7a49..c9f0a6f23654 100644
--- a/CORE/MAC/src/pe/lim/limSerDesUtils.c
+++ b/CORE/MAC/src/pe/lim/limSerDesUtils.c
@@ -762,6 +762,10 @@ limStartBssReqSerDes(tpAniSirGlobal pMac, tpSirSmeStartBssReq pStartBssReq, tANI
len -= sizeof(tSirAddIeParams);
pBuf += sizeof(tSirAddIeParams);
+ /* extract obssEnabled */
+ pStartBssReq->obssEnabled = *pBuf++;
+ len--;
+
if (len)
{
limLog(pMac, LOGW, FL("Extra bytes left in SME_START_BSS_REQ, len=%d"), len);
diff --git a/CORE/MAC/src/pe/lim/limSession.c b/CORE/MAC/src/pe/lim/limSession.c
index f2bc5caf750c..2fde47292ef2 100644
--- a/CORE/MAC/src/pe/lim/limSession.c
+++ b/CORE/MAC/src/pe/lim/limSession.c
@@ -561,6 +561,26 @@ void peDeleteSession(tpAniSirGlobal pMac, tpPESession psessionEntry)
psessionEntry->pSchBeaconFrameEnd = NULL;
}
+ /* Must free the buffer before peSession invalid */
+ if (NULL != psessionEntry->addIeParams.probeRespData_buff)
+ {
+ vos_mem_free(psessionEntry->addIeParams.probeRespData_buff);
+ psessionEntry->addIeParams.probeRespData_buff = NULL;
+ psessionEntry->addIeParams.probeRespDataLen = 0;
+ }
+ if (NULL != psessionEntry->addIeParams.assocRespData_buff)
+ {
+ vos_mem_free(psessionEntry->addIeParams.assocRespData_buff);
+ psessionEntry->addIeParams.assocRespData_buff = NULL;
+ psessionEntry->addIeParams.assocRespDataLen = 0;
+ }
+ if (NULL != psessionEntry->addIeParams.probeRespBCNData_buff)
+ {
+ vos_mem_free(psessionEntry->addIeParams.probeRespBCNData_buff);
+ psessionEntry->addIeParams.probeRespBCNData_buff = NULL;
+ psessionEntry->addIeParams.probeRespBCNDataLen = 0;
+ }
+
psessionEntry->valid = FALSE;
return;
}
diff --git a/CORE/SAP/inc/sapApi.h b/CORE/SAP/inc/sapApi.h
index de886cf438b2..59be68eff820 100644
--- a/CORE/SAP/inc/sapApi.h
+++ b/CORE/SAP/inc/sapApi.h
@@ -536,7 +536,7 @@ typedef struct sSapDfsNolInfo
{
v_U8_t dfs_channel_number;
eSapDfsChanStatus_t radar_status_flag;
- unsigned long radar_found_timestamp;
+ v_U64_t radar_found_timestamp;
} tSapDfsNolInfo;
typedef struct sSapDfsInfo
diff --git a/CORE/SAP/src/sapModule.c b/CORE/SAP/src/sapModule.c
index 4733f38a7768..1333f11918b1 100644
--- a/CORE/SAP/src/sapModule.c
+++ b/CORE/SAP/src/sapModule.c
@@ -3403,7 +3403,7 @@ WLANSAP_Set_DfsNol(v_PVOID_t pSapCtx, eSapDfsNolType conf)
/* mark the timestamp */
pMac->sap.SapDfsInfo.sapDfsChannelNolList[i]
- .radar_found_timestamp = vos_timer_get_system_time();
+ .radar_found_timestamp = vos_get_monotonic_boottime();
} else {
/* mark the channel available */
pMac->sap.SapDfsInfo.sapDfsChannelNolList[i].
diff --git a/CORE/SERVICES/COMMON/wdi_in.h b/CORE/SERVICES/COMMON/wdi_in.h
index 5983f3b00dee..976d0b08cc5d 100644
--- a/CORE/SERVICES/COMMON/wdi_in.h
+++ b/CORE/SERVICES/COMMON/wdi_in.h
@@ -1257,6 +1257,13 @@ ol_tx_queue_log_display(ol_txrx_pdev_handle pdev);
#define wdi_in_seq_num_trace_display ol_txrx_seq_num_trace_display
#define wdi_in_pn_trace_display ol_txrx_pn_trace_display
+#ifdef IPA_UC_OFFLOAD
+#define wdi_in_ipa_uc_get_resource ol_txrx_ipa_uc_get_resource
+#define wdi_in_ipa_uc_set_doorbell_paddr ol_txrx_ipa_uc_set_doorbell_paddr
+#define wdi_in_ipa_uc_set_active ol_txrx_ipa_uc_set_active
+#define wdi_in_ipa_uc_register_op_cb ol_txrx_ipa_uc_register_op_cb
+#endif /* IPA_UC_OFFLOAD */
+
#include <ol_txrx_osif_api.h>
#define wdi_in_osif_vdev_register ol_txrx_osif_vdev_register
diff --git a/CORE/SERVICES/HIF/PCIe/copy_engine.c b/CORE/SERVICES/HIF/PCIe/copy_engine.c
index 106541a4766e..ddad00a2d61f 100644
--- a/CORE/SERVICES/HIF/PCIe/copy_engine.c
+++ b/CORE/SERVICES/HIF/PCIe/copy_engine.c
@@ -1549,3 +1549,63 @@ CE_fini(struct CE_handle *copyeng)
}
A_FREE(CE_state);
}
+
+#ifdef IPA_UC_OFFLOAD
+/*
+ * Copy engine should release resource to micro controller
+ * Micro controller needs
+ - Copy engine source descriptor base address
+ - Copy engine source descriptor size
+ - PCI BAR address to access copy engine regiser
+ */
+void CE_ipaGetResource(struct CE_handle *ce,
+ a_uint32_t *ce_sr_base_paddr,
+ a_uint32_t *ce_sr_ring_size,
+ a_uint32_t *ce_reg_paddr)
+{
+ struct CE_state *CE_state = (struct CE_state *)ce;
+ a_uint32_t ring_loop;
+ struct CE_src_desc *ce_desc;
+ a_uint32_t bar_value;
+ struct hif_pci_softc *sc = CE_state->sc;
+
+ if (CE_RUNNING != CE_state->state)
+ {
+ *ce_sr_base_paddr = 0;
+ *ce_sr_ring_size = 0;
+ return;
+ }
+
+ /* Update default value for descriptor */
+ for (ring_loop = 0; ring_loop < CE_state->src_ring->nentries; ring_loop++)
+ {
+ ce_desc = (struct CE_src_desc *)
+ ((char *)CE_state->src_ring->base_addr_owner_space +
+ ring_loop * (sizeof(struct CE_src_desc)));
+ /* Source pointer and ID,
+ * should be updated by uc dynamically
+ * ce_desc->src_ptr = buffer;
+ * ce_desc->meta_data = transfer_id; */
+ /* No Byte SWAP */
+ ce_desc->byte_swap = 0;
+ /* DL size
+ * pdev->download_len =
+ * sizeof(struct htt_host_tx_desc_t) +
+ * HTT_TX_HDR_SIZE_OUTER_HDR_MAX +
+ * HTT_TX_HDR_SIZE_802_1Q +
+ * HTT_TX_HDR_SIZE_LLC_SNAP +
+ * ol_cfg_tx_download_size(pdev->ctrl_pdev); */
+ ce_desc->nbytes = 60;
+ /* Single fragment No gather */
+ ce_desc->gather = 0;
+ }
+
+ /* Get BAR address */
+ hif_read_bar(CE_state->sc, &bar_value);
+
+ *ce_sr_base_paddr = (a_uint32_t)CE_state->src_ring->base_addr_CE_space;
+ *ce_sr_ring_size = (a_uint32_t)CE_state->src_ring->nentries;
+ *ce_reg_paddr = bar_value + CE_BASE_ADDRESS(CE_state->id) + SR_WR_INDEX_ADDRESS;
+ return;
+}
+#endif /* IPA_UC_OFFLOAD */
diff --git a/CORE/SERVICES/HIF/PCIe/copy_engine_api.h b/CORE/SERVICES/HIF/PCIe/copy_engine_api.h
index 4fcbcc030595..1aaea6d8dee2 100644
--- a/CORE/SERVICES/HIF/PCIe/copy_engine_api.h
+++ b/CORE/SERVICES/HIF/PCIe/copy_engine_api.h
@@ -424,5 +424,19 @@ struct CE_sendlist {
#define ATH_ISR_SCHED 0x0001 /* Schedule the bottom half for execution */
#define ATH_ISR_NOTMINE 0x0002 /* This was not my interrupt - for shared IRQ's */
+#ifdef IPA_UC_OFFLOAD
+/*
+ * Copy engine should release resource to micro controller
+ * Micro controller needs
+ - Copy engine source descriptor base address
+ - Copy engine source descriptor size
+ - PCI BAR address to access copy engine regiser
+ */
+void CE_ipaGetResource(struct CE_handle *ce,
+ a_uint32_t *ce_sr_base_paddr,
+ a_uint32_t *ce_sr_ring_size,
+ a_uint32_t *ce_reg_paddr);
+#endif /* IPA_UC_OFFLOAD */
+
#endif /* CONFIG_COPY_ENGINE_SUPPORT */
#endif /* __COPY_ENGINE_API_H__ */
diff --git a/CORE/SERVICES/HIF/PCIe/hif_pci.c b/CORE/SERVICES/HIF/PCIe/hif_pci.c
index 6364600d6948..bd749f6c1229 100644
--- a/CORE/SERVICES/HIF/PCIe/hif_pci.c
+++ b/CORE/SERVICES/HIF/PCIe/hif_pci.c
@@ -68,6 +68,9 @@ static DEFINE_SPINLOCK(pciwar_lock);
OSDRV_CALLBACKS HIF_osDrvcallback;
#define HIF_PCI_DEBUG ATH_DEBUG_MAKE_MODULE_MASK(0)
+#ifdef IPA_UC_OFFLOAD
+#define HIF_PCI_IPA_UC_ASSIGNED_CE 5
+#endif /* IPA_UC_OFFLOAD */
#if defined(DEBUG)
static ATH_DEBUG_MASK_DESCRIPTION g_HIFDebugDescription[] = {
@@ -124,7 +127,11 @@ static struct CE_attr host_CE_config_wlan[] =
{ /* CE2 */ CE_ATTR_FLAGS, 0, 0, 2048, 32, NULL, },/* target->host WMI */
{ /* CE3 */ CE_ATTR_FLAGS, 0, 32, 2048, 0, NULL, },/* host->target WMI */
{ /* CE4 */ CE_ATTR_FLAGS | CE_ATTR_DISABLE_INTR, 0, CE_HTT_H2T_MSG_SRC_NENTRIES , 256, 0, NULL, }, /* host->target HTT */
+#ifndef IPA_UC_OFFLOAD
{ /* CE5 */ CE_ATTR_FLAGS, 0, 0, 0, 0, NULL, }, /* unused */
+#else
+ { /* CE5 */ CE_ATTR_FLAGS | CE_ATTR_DISABLE_INTR, 0, 1024, 512, 0, NULL, }, /* ipa_uc->target HTC control */
+#endif /* IPA_UC_OFFLOAD */
{ /* CE6 */ CE_ATTR_FLAGS, 0, 0, 0, 0, NULL, }, /* Target autonomous HIF_memcpy */
{ /* CE7 */ CE_ATTR_FLAGS, 0, 2, DIAG_TRANSFER_LIMIT, 2, NULL, }, /* ce_diag, the Diagnostic Window */
};
@@ -143,7 +150,11 @@ static struct CE_pipe_config target_CE_config_wlan[] = {
{ /* CE3 */ 3, PIPEDIR_OUT, 32, 2048, CE_ATTR_FLAGS, 0, }, /* host->target WMI */
{ /* CE4 */ 4, PIPEDIR_OUT, 256, 256, CE_ATTR_FLAGS, 0, }, /* host->target HTT */
/* NB: 50% of src nentries, since tx has 2 frags */
+#ifndef IPA_UC_OFFLOAD
{ /* CE5 */ 5, PIPEDIR_OUT, 32, 2048, CE_ATTR_FLAGS, 0, }, /* unused */
+#else
+ { /* CE5 */ 5, PIPEDIR_OUT, 1024, 64, CE_ATTR_FLAGS, 0, }, /* ipa_uc->target HTC control */
+#endif /* IPA_UC_OFFLOAD */
{ /* CE6 */ 6, PIPEDIR_INOUT, 32, 4096, CE_ATTR_FLAGS, 0, },/* Reserved for target autonomous HIF_memcpy */
/* CE7 used only by Host */
};
@@ -865,6 +876,12 @@ HIFMapServiceToPipe(HIF_DEVICE *hif_device, a_uint16_t ServiceId, a_uint8_t *ULP
*DLPipe = 2;
break;
+#ifdef IPA_UC_OFFLOAD
+ case WDI_IPA_TX_SVC:
+ *ULPipe = 5;
+ break;
+#endif /* IPA_UC_OFFLOAD */
+
/* pipe 5 unused */
/* pipe 6 reserved */
/* pipe 7 reserved */
@@ -1978,7 +1995,13 @@ static struct service_to_pipe target_service_to_CE_map_wlan[] = {
PIPEDIR_IN, /* in = DL = target -> host */
1,
},
-
+#ifdef IPA_UC_OFFLOAD
+ {
+ WDI_IPA_TX_SVC,
+ PIPEDIR_OUT, /* in = DL = target -> host */
+ 5,
+ },
+#endif /* IPA_UC_OFFLOAD */
/* (Additions here) */
{ /* Must be last */
@@ -2705,3 +2728,20 @@ void HIFsuspendwow(HIF_DEVICE *hif_device)
struct hif_pci_softc *sc = hif_state->sc;
adf_os_atomic_set(&sc->wow_done, 1);
}
+
+#ifdef IPA_UC_OFFLOAD
+void HIFIpaGetCEResource(HIF_DEVICE *hif_device,
+ A_UINT32 *ce_sr_base_paddr,
+ A_UINT32 *ce_sr_ring_size,
+ A_UINT32 *ce_reg_paddr)
+{
+ struct HIF_CE_state *hif_state = (struct HIF_CE_state *)hif_device;
+ struct HIF_CE_pipe_info *pipe_info =
+ &(hif_state->pipe_info[HIF_PCI_IPA_UC_ASSIGNED_CE]);
+ struct CE_handle *ce_hdl = pipe_info->ce_hdl;
+
+ CE_ipaGetResource(ce_hdl, ce_sr_base_paddr, ce_sr_ring_size, ce_reg_paddr);
+ return;
+}
+#endif /* IPA_UC_OFFLOAD */
+
diff --git a/CORE/SERVICES/HIF/PCIe/if_pci.c b/CORE/SERVICES/HIF/PCIe/if_pci.c
index e44588a33536..0a918664b970 100644
--- a/CORE/SERVICES/HIF/PCIe/if_pci.c
+++ b/CORE/SERVICES/HIF/PCIe/if_pci.c
@@ -2094,3 +2094,13 @@ void hif_set_fw_info(void *ol_sc, u32 target_fw_version)
{
((struct ol_softc *)ol_sc)->target_fw_version = target_fw_version;
}
+
+#ifdef IPA_UC_OFFLOAD
+/* Micro controller needs PCI BAR address to access CE register */
+void hif_read_bar(struct hif_pci_softc *sc, u32 *bar_value)
+{
+ pci_read_config_dword(sc->pdev, 0x10, bar_value);
+ *bar_value = pci_resource_start(sc->pdev, 0);
+}
+#endif /* IPA_UC_OFFLOAD */
+
diff --git a/CORE/SERVICES/HIF/PCIe/if_pci.h b/CORE/SERVICES/HIF/PCIe/if_pci.h
index 899686081460..0cdb61d754f2 100644
--- a/CORE/SERVICES/HIF/PCIe/if_pci.h
+++ b/CORE/SERVICES/HIF/PCIe/if_pci.h
@@ -136,6 +136,15 @@ void hif_deinit_adf_ctx(void *ol_sc);
void hif_get_hw_info(void *ol_sc, u32 *version, u32 *revision);
void hif_set_fw_info(void *ol_sc, u32 target_fw_version);
+#ifdef IPA_UC_OFFLOAD
+/*
+ * Micro controller needs PCI BAR address to access CE register
+ * If Micro controller data path enabled, control path will
+ * try to get PCI BAR address and will send to IPA driver
+ */
+void hif_read_bar(struct hif_pci_softc *sc, u32 *bar_value);
+#endif /* IPA_UC_OFFLOAD */
+
/*
* A firmware interrupt to the Host is indicated by the
* low bit of SCRATCH_3_ADDRESS being set.
diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c
index c815dad1ed08..60a23f18d116 100644
--- a/CORE/SERVICES/WMA/wma.c
+++ b/CORE/SERVICES/WMA/wma.c
@@ -4303,6 +4303,13 @@ VOS_STATUS WDA_open(v_VOID_t *vos_context, v_VOID_t *os_ctx,
/* initialize default target config */
wma_set_default_tgt_config(wma_handle);
+#ifdef IPA_UC_OFFLOAD
+ olCfg.is_uc_offload_enabled = mac_params->ucOffloadEnabled;
+ olCfg.uc_tx_buffer_count = mac_params->ucTxBufCount;
+ olCfg.uc_tx_buffer_size = mac_params->ucTxBufSize;
+ olCfg.uc_rx_indication_ring_count = mac_params->ucRxIndRingCount;
+ olCfg.uc_tx_partition_base = mac_params->ucTxPartitionBase;
+#endif /* IPA_UC_OFFLOAD*/
/* Allocate cfg handle */
olCfg.is_full_reorder_offload = mac_params->reorderOffload;
((pVosContextType) vos_context)->cfg_ctx =
diff --git a/CORE/SME/inc/csrApi.h b/CORE/SME/inc/csrApi.h
index f9b9fc7e7d78..c2b55b986776 100644
--- a/CORE/SME/inc/csrApi.h
+++ b/CORE/SME/inc/csrApi.h
@@ -1216,6 +1216,8 @@ typedef struct tagCsrConfigParam
tANI_BOOLEAN isRoamOffloadEnabled;
#endif
+ tANI_BOOLEAN obssEnabled;
+
}tCsrConfigParam;
//Tush
diff --git a/CORE/SME/inc/csrInternal.h b/CORE/SME/inc/csrInternal.h
index 01b66cc089a6..ba0085860d60 100644
--- a/CORE/SME/inc/csrInternal.h
+++ b/CORE/SME/inc/csrInternal.h
@@ -693,6 +693,7 @@ typedef struct tagCsrConfig
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
tANI_BOOLEAN isRoamOffloadEnabled;
#endif
+ tANI_BOOLEAN obssEnabled;
}tCsrConfig;
typedef struct tagCsrChannelPowerInfo
diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h
index 1dff4c3b8013..03e57b612ed1 100644
--- a/CORE/SME/inc/sme_Api.h
+++ b/CORE/SME/inc/sme_Api.h
@@ -3512,6 +3512,7 @@ tANI_S16 sme_GetHTConfig(tHalHandle hHal, tANI_U8 session_id, tANI_U16 ht_capab)
VOS_STATUS sme_notify_ht2040_mode(tHalHandle hHal, tANI_U16 staId,
v_MACADDR_t macAddrSTA, v_U8_t sessionId, tANI_U8 channel_type);
eHalStatus sme_SetHT2040Mode(tHalHandle hHal, tANI_U8 sessionId, tANI_U8 channel_type);
+eHalStatus sme_SetPhyCBMode24G(tHalHandle hHal, ePhyChanBondState phyCBMode);
#endif
#ifdef QCA_WIFI_2_0
diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c
index 065ff1c7d072..0282204940d2 100644
--- a/CORE/SME/src/csr/csrApiRoam.c
+++ b/CORE/SME/src/csr/csrApiRoam.c
@@ -1866,6 +1866,7 @@ eHalStatus csrChangeDefaultConfigParam(tpAniSirGlobal pMac, tCsrConfigParam *pPa
pMac->roam.configParam.isRoamOffloadEnabled =
pParam->isRoamOffloadEnabled;
#endif
+ pMac->roam.configParam.obssEnabled = pParam->obssEnabled;
}
return status;
@@ -2014,6 +2015,8 @@ eHalStatus csrGetConfigParam(tpAniSirGlobal pMac, tCsrConfigParam *pParam)
#endif
csrSetChannels(pMac, pParam);
+ pParam->obssEnabled = pMac->roam.configParam.obssEnabled;
+
status = eHAL_STATUS_SUCCESS;
}
return (status);
@@ -14487,6 +14490,8 @@ eHalStatus csrSendMBStartBssReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, eCs
vos_mem_copy(pBuf, &pParam->addIeParams, sizeof( pParam->addIeParams ));
pBuf += sizeof(pParam->addIeParams);
+ *pBuf++ = (tANI_U8)pMac->roam.configParam.obssEnabled;
+
msgLen = (tANI_U16)(sizeof(tANI_U32 ) + (pBuf - wTmpBuf)); //msg_header + msg
pMsg->length = pal_cpu_to_be16(msgLen);
@@ -18248,26 +18253,31 @@ csrRoamUpdateAddIEs(tpAniSirGlobal pMac,
tANI_U8 *pLocalBuffer = NULL;
eHalStatus status;
- /* following buffer will be freed by consumer (PE) */
- pLocalBuffer = vos_mem_malloc(pUpdateIE->ieBufferlength);
-
- if (NULL == pLocalBuffer)
+ if (pUpdateIE->ieBufferlength != 0)
{
- smsLog(pMac, LOGE, FL("Memory Allocation Failure!!!"));
- return eHAL_STATUS_FAILED_ALLOC;
+ /* Following buffer will be freed by consumer (PE) */
+ pLocalBuffer = vos_mem_malloc(pUpdateIE->ieBufferlength);
+ if (NULL == pLocalBuffer)
+ {
+ smsLog(pMac, LOGE, FL("Memory Allocation Failure!!!"));
+ return eHAL_STATUS_FAILED_ALLOC;
+ }
+ vos_mem_copy(pLocalBuffer, pUpdateIE->pAdditionIEBuffer,
+ pUpdateIE->ieBufferlength);
}
- pUpdateAddIEs = vos_mem_malloc(sizeof(tpSirUpdateIEsInd));
+ pUpdateAddIEs = vos_mem_malloc( sizeof(tSirUpdateIEsInd) );
if (NULL == pUpdateAddIEs)
{
- smsLog(pMac, LOGE, FL("Memory Allocation Failure!!!"));
- vos_mem_free(pLocalBuffer);
+ smsLog(pMac, LOGE, FL("Memory Allocation Failure!!!"));
+ if (pLocalBuffer != NULL)
+ {
+ vos_mem_free(pLocalBuffer);
+ }
return eHAL_STATUS_FAILED_ALLOC;
}
- vos_mem_copy(pLocalBuffer, pUpdateIE->pAdditionIEBuffer,
- pUpdateIE->ieBufferlength);
- vos_mem_zero(pUpdateAddIEs, sizeof(tpSirUpdateIEsInd));
+ vos_mem_zero(pUpdateAddIEs, sizeof(tSirUpdateIEsInd));
pUpdateAddIEs->msgType =
pal_cpu_to_be16((tANI_U16)eWNI_SME_UPDATE_ADDITIONAL_IES);
diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c
index 1d5734872f48..9e5718593b89 100644
--- a/CORE/SME/src/sme_common/sme_Api.c
+++ b/CORE/SME/src/sme_common/sme_Api.c
@@ -11796,6 +11796,35 @@ eHalStatus sme_SetHT2040Mode(tHalHandle hHal, tANI_U8 sessionId, tANI_U8 channel
}
return (status);
}
+
+/* ---------------------------------------------------------------------------
+
+ \fn sme_SetPhyCBMode24G
+
+ \brief Changes PHY channel bonding mode
+
+ \param hHal - The handle returned by macOpen.
+
+ \param cbMode new channel bonding mode which is to set
+
+ \return eHalStatus SUCCESS.
+
+ -------------------------------------------------------------------------------*/
+eHalStatus sme_SetPhyCBMode24G(tHalHandle hHal, ePhyChanBondState phyCBMode)
+{
+ tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
+
+ if (NULL == pMac)
+ {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
+ "%s: invalid context", __func__);
+ return eHAL_STATUS_FAILURE;
+ }
+
+ pMac->roam.configParam.channelBondingMode24GHz = phyCBMode;
+
+ return eHAL_STATUS_SUCCESS;
+}
#endif
/*
diff --git a/CORE/VOSS/src/vos_api.c b/CORE/VOSS/src/vos_api.c
index 650fdb1f29ea..e66ad493435e 100644
--- a/CORE/VOSS/src/vos_api.c
+++ b/CORE/VOSS/src/vos_api.c
@@ -454,6 +454,15 @@ VOS_STATUS vos_open( v_CONTEXT_t *pVosContext, v_SIZE_t hddContextSize )
macOpenParms.reorderOffload = pHddCtx->cfg_ini->reorderOffloadSupport;
#endif
+#ifdef IPA_UC_OFFLOAD
+ /* IPA micro controller data path offload resource config item */
+ macOpenParms.ucOffloadEnabled = pHddCtx->cfg_ini->IpaUcOffloadEnabled;
+ macOpenParms.ucTxBufCount = pHddCtx->cfg_ini->IpaUcTxBufCount;
+ macOpenParms.ucTxBufSize = pHddCtx->cfg_ini->IpaUcTxBufSize;
+ macOpenParms.ucRxIndRingCount = pHddCtx->cfg_ini->IpaUcRxIndRingCount;
+ macOpenParms.ucTxPartitionBase = pHddCtx->cfg_ini->IpaUcTxPartitionBase;
+#endif /* IPA_UC_OFFLOAD */
+
vStatus = WDA_open( gpVosContext, gpVosContext->pHDDContext,
#if defined (QCA_WIFI_2_0) && \
!defined (QCA_WIFI_ISOC)
@@ -582,6 +591,19 @@ VOS_STATUS vos_open( v_CONTEXT_t *pVosContext, v_SIZE_t hddContextSize )
goto err_sme_close;
}
+#ifdef IPA_UC_OFFLOAD
+ WLANTL_GetIpaUcResource(gpVosContext,
+ &((hdd_context_t*)(gpVosContext->pHDDContext))->ce_sr_base_paddr,
+ &((hdd_context_t*)(gpVosContext->pHDDContext))->ce_sr_ring_size,
+ &((hdd_context_t*)(gpVosContext->pHDDContext))->ce_reg_paddr,
+ &((hdd_context_t*)(gpVosContext->pHDDContext))->tx_comp_ring_base_paddr,
+ &((hdd_context_t*)(gpVosContext->pHDDContext))->tx_comp_ring_size,
+ &((hdd_context_t*)(gpVosContext->pHDDContext))->tx_num_alloc_buffer,
+ &((hdd_context_t*)(gpVosContext->pHDDContext))->rx_rdy_ring_base_paddr,
+ &((hdd_context_t*)(gpVosContext->pHDDContext))->rx_rdy_ring_size,
+ &((hdd_context_t*)(gpVosContext->pHDDContext))->rx_proc_done_idx_paddr);
+#endif /* IPA_UC_OFFLOAD */
+
VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO_HIGH,
"%s: VOSS successfully Opened", __func__);
diff --git a/firmware_bin/WCNSS_cfg.dat b/firmware_bin/WCNSS_cfg.dat
index 1c7b8edb4766..066840f1dee7 100644..100755
--- a/firmware_bin/WCNSS_cfg.dat
+++ b/firmware_bin/WCNSS_cfg.dat
Binary files differ
diff --git a/firmware_bin/WCNSS_qcom_cfg.ini b/firmware_bin/WCNSS_qcom_cfg.ini
index 403aa8fe1e05..e96a5af61a13 100755
--- a/firmware_bin/WCNSS_qcom_cfg.ini
+++ b/firmware_bin/WCNSS_qcom_cfg.ini
@@ -163,6 +163,9 @@ g11dSupportEnabled=1
g11hSupportEnabled=1
+# DFS Master Capability
+gEnableDFSMasterCap=1
+
# ESE Support and fast transition
EseEnabled=0
ImplicitQosIsEnabled=0
diff --git a/tools/athdiag/athdiag.c b/tools/athdiag/athdiag.c
index c0f13da6af0f..582bd0e7640b 100644
--- a/tools/athdiag/athdiag.c
+++ b/tools/athdiag/athdiag.c
@@ -109,6 +109,8 @@
#define AR6320V1_REG_PART2_START_ADDR 0x27000 /*STEREO_BASE_ADDRESS*/
#define AR6320V1_REG_PART2_LEN (0x60000 - 0x27000) /*USB_BASE_ADDRESS - STEREO_BASE_ADDRESS*/
+/* For Rome version 2.x */
+
#define AR6320V2_DRAM_START_ADDR 0x400000 // dram start
#define AR6320V2_DUMP_DRAM_LEN 0x70000 // dram length
#define AR6320V2_IRAM_START_ADDR 0x980000 // iram start
@@ -116,6 +118,15 @@
#define AR6320V2_AXI_START_ADDR 0xa0000 // axi start
#define AR6320V2_AXI_LEN 0x18000 // axi length
+/* For Rome version 3.x */
+
+#define AR6320V3_DRAM_START_ADDR 0x400000 // dram start
+#define AR6320V3_DUMP_DRAM_LEN 0xa8000 // dram length
+#define AR6320V3_IRAM_START_ADDR 0x980000 // iram start
+#define AR6320V3_IRAM_LEN 0x38000 // iram length
+#define AR6320V3_AXI_START_ADDR 0xa0000 // axi start
+#define AR6320V3_AXI_LEN 0x18000 // axi length
+
struct ath_target_reg_info {
A_UINT32 reg_start;
A_UINT32 reg_len;
@@ -140,13 +151,20 @@ static const struct ath_target_reg_info reg_ar6320_v1[] = {
static const struct ath_target_reg_info reg_ar6320_v2[] = {
{AR6320V2_DRAM_START_ADDR, AR6320V2_DUMP_DRAM_LEN, "DRAM", "fwdump_rome_v2_dram"},
{AR6320V2_IRAM_START_ADDR, AR6320V2_IRAM_LEN, "IRAM", "fwdump_rome_v2_iram"},
- {AR6320V2_AXI_START_ADDR, AR6320V2_AXI_LEN, "AXI", "fwdump_rome_v2_axi"},
+ {AR6320V2_AXI_START_ADDR, AR6320V2_AXI_LEN, "AXI", "fwdump_rome_v2_axi" },
+ {0, 0, 0, 0}
+};
+
+static const struct ath_target_reg_info reg_ar6320_v3[] = {
+ {AR6320V3_DRAM_START_ADDR, AR6320V3_DUMP_DRAM_LEN, "DRAM", "fwdump_rome_v3_dram"},
+ {AR6320V3_IRAM_START_ADDR, AR6320V3_IRAM_LEN, "IRAM", "fwdump_rome_v3_iram"},
+ {AR6320V3_AXI_START_ADDR, AR6320V3_AXI_LEN, "AXI" , "fwdump_rome_v3_axi" },
{0, 0, 0, 0}
};
#define INVALID_TARGET_INDEX 0xffff
#define MIN_TARGET_INDEX 0
-#define MAX_TARGET_INDEX 3
+#define MAX_TARGET_INDEX 4
struct ath_target_info {
const char *name;
@@ -157,6 +175,7 @@ static const struct ath_target_info target_info[] = {
{"AR9888_v2", reg_ar9888_v2},
{"AR6320_v1", reg_ar6320_v1},
{"AR6320_v2", reg_ar6320_v2},
+ {"AR6320_v3", reg_ar6320_v3},
};