diff options
| author | Linux Build Service Account <lnxbuild@localhost> | 2014-07-12 02:33:24 -0700 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2014-07-12 02:33:24 -0700 |
| commit | 1a6ec3e5f851e9bebc9b73afcd3c6d274bbcc0f7 (patch) | |
| tree | 6f304316300e61bbf0ed4c0c407c27ac9628b665 | |
| parent | 97e60837cb0bdbba1554ce408561bbd8188c8383 (diff) | |
| parent | 4a98de7e55fe9afb03acd9ddb127aa3f3b411ba3 (diff) | |
Merge "Release 1.0.0.144 QCACLD WLAN Driver"
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 Binary files differindex 1c7b8edb4766..066840f1dee7 100644..100755 --- a/firmware_bin/WCNSS_cfg.dat +++ b/firmware_bin/WCNSS_cfg.dat 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}, }; |
