From e1be588776a801e97073c25a48feb9dfaf2c0e24 Mon Sep 17 00:00:00 2001 From: Mushtaq A Mujale Date: Fri, 14 Mar 2014 11:52:33 -0700 Subject: wlan: VHT IEs missing in Reassoc Request during roam The routine that sends out the Reassoc Request is modified to look at the VHT information and add the VHT IEs to the frame if appropriate. Change-Id: I39e82c1a2d001ff0ee090f1a2a0c0027598b2471 CRs-Fixed: 630625 --- CORE/MAC/src/pe/lim/limSendManagementFrames.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CORE/MAC/src/pe/lim/limSendManagementFrames.c b/CORE/MAC/src/pe/lim/limSendManagementFrames.c index c000ece0653c..973dc3723199 100644 --- a/CORE/MAC/src/pe/lim/limSendManagementFrames.c +++ b/CORE/MAC/src/pe/lim/limSendManagementFrames.c @@ -2600,6 +2600,7 @@ limSendReassocReqWithFTIEsMgmtFrame(tpAniSirGlobal pMac, #endif tANI_U8 txFlag = 0; tANI_U8 smeSessionId = 0; + tANI_BOOLEAN isVHTEnabled = eANI_BOOLEAN_FALSE; if (NULL == psessionEntry) { @@ -2823,6 +2824,18 @@ limSendReassocReqWithFTIEsMgmtFrame(tpAniSirGlobal pMac, } #endif +#ifdef WLAN_FEATURE_11AC + if ( psessionEntry->vhtCapability && + psessionEntry->vhtCapabilityPresentInBeacon) + { + limLog( pMac, LOG1, FL("Populate VHT IEs in Re-Assoc Request")); + PopulateDot11fVHTCaps( pMac, psessionEntry, &frm.VHTCaps ); + isVHTEnabled = eANI_BOOLEAN_TRUE; + } +#endif + + PopulateDot11fExtCap(pMac, isVHTEnabled, &frm.ExtCap); + nStatus = dot11fGetPackedReAssocRequestSize( pMac, &frm, &nPayload ); if ( DOT11F_FAILED( nStatus ) ) { -- cgit v1.2.3 From 4b01f3182eee70979806ef0734341a48663a3f9a Mon Sep 17 00:00:00 2001 From: Srinivas Girigowda Date: Fri, 14 Mar 2014 11:25:50 -0700 Subject: qcacld: Fix issues found by static code analysis Fix the issues reported by static code analysis tool Change-Id: I3249a946def3d066d8c6832bc3d279f45fd2a88f CRs-Fixed: 631968 --- CORE/SAP/src/sapChSelect.c | 7 +++++++ CORE/SERVICES/WMA/wma.c | 16 +++++++++++++--- CORE/SERVICES/WMI/wmi_unified.c | 19 ++++++++++--------- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/CORE/SAP/src/sapChSelect.c b/CORE/SAP/src/sapChSelect.c index 3d93a4f4165c..49917723a555 100644 --- a/CORE/SAP/src/sapChSelect.c +++ b/CORE/SAP/src/sapChSelect.c @@ -655,6 +655,13 @@ void sapInterferenceRssiCount(tSapSpectChInfo *pSpectCh) tSapSpectChInfo *pExtSpectCh = NULL; v_S31_t rssi; + if (NULL == pSpectCh) + { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: pSpectCh is NULL", __func__); + return; + } + switch(pSpectCh->chNum) { case CHANNEL_1: diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index d835a3df1468..a610d04d54d5 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -18135,6 +18135,11 @@ void wma_target_suspend_acknowledge(void *context) tp_wma_handle wma = vos_get_context(VOS_MODULE_ID_WDA, vos_context); int wow_nack = *((int *)context); + if (NULL == wma) { + WMA_LOGE("%s: wma is NULL", __func__); + return; + } + wma->wow_nack = wow_nack; vos_event_set(&wma->target_suspend); if (wow_nack) @@ -19361,10 +19366,15 @@ void WDA_TxAbort(v_U8_t vdev_id) wma = vos_get_context(VOS_MODULE_ID_WDA, vos_get_global_context(VOS_MODULE_ID_WDA, NULL)); + if (NULL == wma) { + WMA_LOGE("%s: wma is NULL", __func__); + return; + } + iface = &wma->interfaces[vdev_id]; - if (!wma || !iface->handle) { - WMA_LOGE("%s: Failed to get handle wma: %p iface: %p", - __func__, wma, iface->handle); + if (!iface->handle) { + WMA_LOGE("%s: Failed to get iface handle: %p", + __func__, iface->handle); return; } WMA_LOGA("%s: vdevid %d bssid %pM", __func__, vdev_id, iface->bssid); diff --git a/CORE/SERVICES/WMI/wmi_unified.c b/CORE/SERVICES/WMI/wmi_unified.c index 0ee8c9522838..0290a29a1dbd 100644 --- a/CORE/SERVICES/WMI/wmi_unified.c +++ b/CORE/SERVICES/WMI/wmi_unified.c @@ -575,16 +575,17 @@ int wmi_unified_cmd_send(wmi_unified_t wmi_handle, wmi_buf_t buf, int len, /* WMI Event handler register API */ int wmi_unified_get_event_handler_ix(wmi_unified_t wmi_handle, - WMI_EVT_ID event_id) + WMI_EVT_ID event_id) { - u_int32_t idx=0; - for (idx=0; idxmax_event_idx; ++idx) { - if (wmi_handle->event_id[idx] == event_id && - wmi_handle->event_handler[idx] != NULL ) { - return idx; - } - } - return -1; + u_int32_t idx = 0; + for (idx = 0; (idx < wmi_handle->max_event_idx && + idx < WMI_UNIFIED_MAX_EVENT); ++idx) { + if (wmi_handle->event_id[idx] == event_id && + wmi_handle->event_handler[idx] != NULL ) { + return idx; + } + } + return -1; } int wmi_unified_register_event_handler(wmi_unified_t wmi_handle, -- cgit v1.2.3 From 7f144c8e41f2c0ed60268717207d5fc8a8880500 Mon Sep 17 00:00:00 2001 From: Rajeev Kumar Date: Fri, 14 Mar 2014 09:16:54 -0700 Subject: qcacld: Fix of memmory leak in wma_dfs_configure_channel Memory allocated for wma->dfs_ic->ic_curchan in wma_dfs_configure_channel() is not freed in dfs_detach. Change-Id: Ia382bdf8ab9c0b9dbd4f8c2224a556f4dff2729a CRs-Fixed: 631913 --- CORE/SERVICES/WMA/wma.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index a610d04d54d5..ad55c06757e1 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -16822,6 +16822,12 @@ VOS_STATUS wma_wmi_service_close(v_VOID_t *vos_ctx) static void wma_dfs_detach(struct ieee80211com *dfs_ic) { dfs_detach(dfs_ic); + + if (NULL != dfs_ic->ic_curchan) { + OS_FREE(dfs_ic->ic_curchan); + dfs_ic->ic_curchan = NULL; + } + OS_FREE(dfs_ic); } -- cgit v1.2.3 From 1db18d35a7d2bd29a16561ded88c89e6028eccd3 Mon Sep 17 00:00:00 2001 From: Ganesh Kondabattini Date: Fri, 14 Mar 2014 10:39:57 +0530 Subject: CLD-SCAN: Ignore beacon while adding the entry into the scan cache In current design the driver is updating either probe response or beacon frame to cfg80211 as part of scan results even if the driver receives both probe response and beacon frames on scanned channel. If the last received frame is beacon on that channel then driver indicating beacon to cfg80211 as scan result. If the last received frame is probe response on that channel then driver indicating probe response to cfg80211. In cfg80211 , for the existing BSS entry probe responses obtained shall override the previously obtained ie.s without any conditional check but the obtained beacon ie.s shall override the previous ie.s only when these are from the beacons before. This shall result in the supplicant to get the stale probe response though the driver happens to report the updated beacons after the obtained probe response . This results in a failed PBC session by the supplicant for not getting the updated ie. To address this issue, driver indicates only probe response to cfg80211 whennever driver receives both probe response and beacon frames on a particular channel as part of scan. Change-Id: I7831391ddc179943eb1d01b8eeb6782e21a300cf CRs-Fixed: 626691 --- CORE/MAC/src/pe/lim/limScanResultUtils.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CORE/MAC/src/pe/lim/limScanResultUtils.c b/CORE/MAC/src/pe/lim/limScanResultUtils.c index 8be52ddc0999..0042fd505083 100644 --- a/CORE/MAC/src/pe/lim/limScanResultUtils.c +++ b/CORE/MAC/src/pe/lim/limScanResultUtils.c @@ -739,6 +739,18 @@ limLookupNaddHashEntry(tpAniSirGlobal pMac, ptemp->bssDescription.channelId)))) ) { + if (ptemp->bssDescription.fProbeRsp && + !pBssDescr->bssDescription.fProbeRsp) + { + /* If the previously saved frame is probe response + * and the current frame is beacon, then no need + * to update the scan database. Probe response is + * going to have more proper information than beacon + * frame. So it is better to inform the probe + * response frame instead of beacon for proper + * information. */ + return eHAL_STATUS_FAILURE; + } // Found the same BSS description if (action == LIM_HASH_UPDATE) { -- cgit v1.2.3 From 350fb12d61f64e8722cfaeef113f54cb43dfbfb4 Mon Sep 17 00:00:00 2001 From: Ahmad Kholaif Date: Fri, 14 Mar 2014 18:35:37 -0700 Subject: qca_cld: fix the action frame sub type offset value for Remain-on-Channel In hdd_p2p_is_action_type_rsp(), the input buffer is starting from public action type offset, i.e., buf[24]. However, we were double advancing the buffer within the function. As a result, the frame type check within the function was always failing and Remain-On-Channel gets cancelled. This prevents the device from receiving action response frames. Change-Id: If033dc974a33f8be7a684f92f2fc681e1adc27af CRs-fixed: 626368 --- CORE/HDD/inc/wlan_hdd_main.h | 1 + CORE/HDD/src/wlan_hdd_p2p.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h index 9c47f90bb47d..33b3c196c583 100644 --- a/CORE/HDD/inc/wlan_hdd_main.h +++ b/CORE/HDD/inc/wlan_hdd_main.h @@ -178,6 +178,7 @@ #define WLAN_HDD_WFA_P2P_OUI_TYPE 0x09 #define WLAN_HDD_P2P_SOCIAL_CHANNELS 3 #define WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN 1 +#define WLAN_HDD_PUBLIC_ACTION_FRAME_SUB_TYPE_OFFSET 6 #define WLAN_HDD_IS_SOCIAL_CHANNEL(center_freq) \ (((center_freq) == 2412) || ((center_freq) == 2437) || ((center_freq) == 2462)) diff --git a/CORE/HDD/src/wlan_hdd_p2p.c b/CORE/HDD/src/wlan_hdd_p2p.c index a969e6d1763e..061a34806f6e 100644 --- a/CORE/HDD/src/wlan_hdd_p2p.c +++ b/CORE/HDD/src/wlan_hdd_p2p.c @@ -127,7 +127,7 @@ static bool hdd_p2p_is_action_type_rsp( const u8 *buf ) return FALSE; } - actionFrmType = buf[WLAN_HDD_PUBLIC_ACTION_FRAME_TYPE_OFFSET]; + actionFrmType = buf[WLAN_HDD_PUBLIC_ACTION_FRAME_SUB_TYPE_OFFSET]; if ( actionFrmType != WLAN_HDD_INVITATION_REQ && actionFrmType != WLAN_HDD_GO_NEG_REQ && actionFrmType != WLAN_HDD_DEV_DIS_REQ && -- cgit v1.2.3 From f506f9f15960dc83b204610b4f646539ac64cd82 Mon Sep 17 00:00:00 2001 From: Bala Shanmugam Kamatchi Date: Sun, 16 Mar 2014 01:39:07 +0530 Subject: qcacld: hdd: Allow access if we have valid Tspec When we have valid Tspec in VI after reassoc we are downgrading the traffic to BE. While connecting during reassoc check if we have valid Tspec and allow access. Change-Id: I5039193f93ae43058fee936a25982ad66827dd09 CRs-Fixed: 630246 --- CORE/HDD/src/wlan_hdd_wmm.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/CORE/HDD/src/wlan_hdd_wmm.c b/CORE/HDD/src/wlan_hdd_wmm.c index d9ac2c1b4c32..dae24b0fe211 100644 --- a/CORE/HDD/src/wlan_hdd_wmm.c +++ b/CORE/HDD/src/wlan_hdd_wmm.c @@ -1224,8 +1224,10 @@ static eHalStatus hdd_wmm_sme_callback (tHalHandle hHal, pAc->wmmAcAccessAllowed = hdd_wmm_is_access_allowed(pAdapter, pAc); #else // if Tspec only allows downstream traffic then access is not allowed - if (pAc->wmmAcTspecInfo.ts_info.direction == SME_QOS_WMM_TS_DIR_DOWNLINK) + if (pAc->wmmAcTspecValid && + (pAc->wmmAcTspecInfo.ts_info.direction == SME_QOS_WMM_TS_DIR_DOWNLINK)) { pAc->wmmAcAccessAllowed = VOS_FALSE; + } // if ACM bit is not set, allow access if (!(pAc->wmmAcAccessRequired)) @@ -2317,6 +2319,12 @@ VOS_STATUS hdd_wmm_connect( hdd_adapter_t* pAdapter, pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessRequired = VOS_TRUE; pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed = VOS_FALSE; pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessGranted = VOS_FALSE; + //after reassoc if we have valid tspec, allow access + if (pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcTspecValid && + (pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcTspecInfo.ts_info.direction != + SME_QOS_WMM_TS_DIR_DOWNLINK)) { + pAdapter->hddWmmStatus.wmmAcStatus[ac].wmmAcAccessAllowed = VOS_TRUE; + } } else { -- cgit v1.2.3 From cf988e42196e3ff0013f38425debd5ae3e2e588d Mon Sep 17 00:00:00 2001 From: Rajesh Chauhan Date: Sat, 15 Mar 2014 14:31:44 -0700 Subject: qcacld: add QCSAP ioctl setAutoChannel Add QCSAP ioctl setAutoChannel. Change-Id: I7b1ef9e2240c3bc9249a97d0c345811f029e778e CRs-Fixed: 632376 --- CORE/HDD/inc/qc_sap_ioctl.h | 1 + CORE/HDD/src/wlan_hdd_hostapd.c | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/CORE/HDD/inc/qc_sap_ioctl.h b/CORE/HDD/inc/qc_sap_ioctl.h index 7c470ea1a8d4..2c1afe3d639b 100644 --- a/CORE/HDD/inc/qc_sap_ioctl.h +++ b/CORE/HDD/inc/qc_sap_ioctl.h @@ -313,6 +313,7 @@ enum { QCSAP_PARAM_SET_TXRX_FW_STATS=11, QCSAP_PARAM_SET_MCC_CHANNEL_LATENCY = 12, QCSAP_PARAM_SET_MCC_CHANNEL_QUOTA = 13, + QCSAP_PARAM_SET_AUTO_CHANNEL = 14, }; int iw_softap_get_channel_list(struct net_device *dev, diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c index 471eb258aecb..e365bf6992c6 100644 --- a/CORE/HDD/src/wlan_hdd_hostapd.c +++ b/CORE/HDD/src/wlan_hdd_hostapd.c @@ -1165,6 +1165,19 @@ static iw_softap_setparam(struct net_device *dev, WLANSAP_SetMode(pVosContext, set_value); } break; + + case QCSAP_PARAM_SET_AUTO_CHANNEL: + if ((0 != set_value) && (1 != set_value)) + { + hddLog(LOGE, FL("Invalid setAutoChannel value %d"), set_value); + ret = -EINVAL; + } + else + { + (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apAutoChannelSelection = set_value; + } + break; + case QCSAP_PARAM_MAX_ASSOC: if (WNI_CFG_ASSOC_STA_LIMIT_STAMIN > set_value) { @@ -3970,6 +3983,8 @@ static const struct iw_priv_args hostapd_private_args[] = { IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwlandbg" }, { QCSAP_PARAM_AUTO_CHANNEL, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getAutoChannel" }, + { QCSAP_PARAM_SET_AUTO_CHANNEL, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setAutoChannel" }, { QCSAP_PARAM_MODULE_DOWN_IND, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "moduleDownInd" }, { QCSAP_PARAM_CLR_ACL, 0, -- cgit v1.2.3 From 71eef7da5fffa14a671df60446819012ccfc5eb5 Mon Sep 17 00:00:00 2001 From: "Chandrasekaran, Manishekar" Date: Sat, 15 Mar 2014 10:12:22 +0530 Subject: qcacld: Fix for adding sequence number in management frames In the current implementation, the sequence number is zero for management frames. This fix will ensure that non-zero sequence numbers are added to the management frames. Change-Id: I35103f686765ee23aee72eee63f86209be84357a CRs-Fixed: 631221 --- CORE/MAC/inc/aniGlobal.h | 10 +++++++ CORE/MAC/src/pe/lim/limSendManagementFrames.c | 42 +++++++++++++++++++++++++++ CORE/SYS/legacy/src/system/src/macInitApi.c | 5 ++++ 3 files changed, 57 insertions(+) diff --git a/CORE/MAC/inc/aniGlobal.h b/CORE/MAC/inc/aniGlobal.h index 1529b7b4950a..4d38f3e6bc88 100644 --- a/CORE/MAC/inc/aniGlobal.h +++ b/CORE/MAC/inc/aniGlobal.h @@ -142,6 +142,13 @@ typedef struct sAniSirGlobal *tpAniSirGlobal; #define EQUALS_TO_ASCII_VALUE (61) #endif +#ifdef QCA_WIFI_2_0 +#define WLAN_HOST_SEQ_NUM_MIN 2048 +#define WLAN_HOST_SEQ_NUM_MAX 4095 +#define LOW_SEQ_NUM_MASK 0x000F +#define HIGH_SEQ_NUM_MASK 0x0FF0 +#define HIGH_SEQ_NUM_OFFSET 4 +#endif /* QCA_WIFI_2_0 */ // ------------------------------------------------------------------- // Change channel generic scheme @@ -1095,6 +1102,9 @@ typedef struct sAniSirGlobal tANI_U8 lteCoexAntShare; tANI_U8 beacon_offload; tANI_U32 fEnableDebugLog; +#ifdef QCA_WIFI_2_0 + tANI_U16 mgmtSeqNum; +#endif /* QCA_WIFI_2_0 */ } tAniSirGlobal; typedef enum diff --git a/CORE/MAC/src/pe/lim/limSendManagementFrames.c b/CORE/MAC/src/pe/lim/limSendManagementFrames.c index 973dc3723199..9f86e950d4a4 100644 --- a/CORE/MAC/src/pe/lim/limSendManagementFrames.c +++ b/CORE/MAC/src/pe/lim/limSendManagementFrames.c @@ -209,6 +209,38 @@ void limMergeExtCapIEStruct(tDot11fIEExtCap *pDst, } } +#ifdef QCA_WIFI_2_0 +/** + * + * \brief This function is called to add the sequence number to the + * management frames + * + * \param pMac Pointer to Global MAC structure + * + * \param pMacHdr Pointer to MAC management header + * + * The pMacHdr argument points to the MAC management header. The + * sequence number stored in the pMac structure will be incremented + * and updated to the MAC management header. The start sequence + * number is WLAN_HOST_SEQ_NUM_MIN and the end value is + * WLAN_HOST_SEQ_NUM_MAX. After reaching the MAX value, the sequence + * number will roll over. + * + */ +void +limAddMgmtSeqNum (tpAniSirGlobal pMac, tpSirMacMgmtHdr pMacHdr) +{ + if (pMac->mgmtSeqNum >= WLAN_HOST_SEQ_NUM_MAX) { + pMac->mgmtSeqNum = WLAN_HOST_SEQ_NUM_MIN-1; + } + + pMac->mgmtSeqNum++; + + pMacHdr->seqControl.seqNumLo = (pMac->mgmtSeqNum & LOW_SEQ_NUM_MASK); + pMacHdr->seqControl.seqNumHi = + ((pMac->mgmtSeqNum & HIGH_SEQ_NUM_MASK) >> HIGH_SEQ_NUM_OFFSET); +} +#endif /* QCA_WIFI_2_0 */ /** * @@ -264,6 +296,16 @@ tSirRetStatus limPopulateMacHeader( tpAniSirGlobal pMac, vos_mem_copy( (tANI_U8 *) pMacHdr->bssId, (tANI_U8 *) peerAddr, sizeof( tSirMacAddr )); + +#ifdef QCA_WIFI_2_0 + /* Prepare sequence number */ + limAddMgmtSeqNum(pMac, pMacHdr); + limLog(pMac, LOG1,"seqNumLo=%d, seqNumHi=%d, mgmtSeqNum=%d", + pMacHdr->seqControl.seqNumLo, + pMacHdr->seqControl.seqNumHi, + pMac->mgmtSeqNum); +#endif /* QCA_WIFI_2_0 */ + return statusCode; } /*** end limPopulateMacHeader() ***/ diff --git a/CORE/SYS/legacy/src/system/src/macInitApi.c b/CORE/SYS/legacy/src/system/src/macInitApi.c index fcaac7bb7405..9397289fced7 100644 --- a/CORE/SYS/legacy/src/system/src/macInitApi.c +++ b/CORE/SYS/legacy/src/system/src/macInitApi.c @@ -244,6 +244,11 @@ tSirRetStatus macOpen(tHalHandle *pHalHandle, tHddHandle hHdd, tMacOpenParameter pMac->psOffloadEnabled = FALSE; } +#ifdef QCA_WIFI_2_0 + /* FW: 0 to 2047 and Host: 2048 to 4095 */ + pMac->mgmtSeqNum = WLAN_HOST_SEQ_NUM_MIN-1; +#endif /* QCA_WIFI_2_0 */ + return peOpen(pMac, pMacOpenParms); } -- cgit v1.2.3 From ee6d229178a211182090a148f96c932f79ed3512 Mon Sep 17 00:00:00 2001 From: "Chandrasekaran, Manishekar" Date: Fri, 14 Mar 2014 11:06:44 +0530 Subject: qcacld: Add support to update BI in beacon update indication In the current implementation during beacon update, we are updating only 11a coexist parameters. This fix will update the beacon interval in the beacon update. Change-Id: Icf6fb89eb7286d5845dd69735bcca5613f7573fa CRs-Fixed: 631703 --- CORE/SERVICES/WMA/wma.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index ad55c06757e1..6ec4b66fc014 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -7744,6 +7744,23 @@ wma_update_protection_mode(tp_wma_handle wma, u_int8_t vdev_id, WMA_LOGD("Updated protection mode %d to target", prot_mode); } +static void +wma_update_beacon_interval(tp_wma_handle wma, u_int8_t vdev_id, + u_int16_t beaconInterval) +{ + int ret; + + ret = wmi_unified_vdev_set_param_send(wma->wmi_handle, vdev_id, + WMI_VDEV_PARAM_BEACON_INTERVAL, + beaconInterval); + + if (ret) + WMA_LOGE("Failed to update beacon interval"); + else + WMA_LOGE("Updated beacon interval %d for vdev %d", beaconInterval, vdev_id); +} + + /* * Function : wma_process_update_beacon_params * Description : update the beacon parameters to target @@ -7764,6 +7781,11 @@ wma_process_update_beacon_params(tp_wma_handle wma, return; } + if (bcn_params->paramChangeBitmap & PARAM_BCN_INTERVAL_CHANGED) { + wma_update_beacon_interval(wma, bcn_params->smeSessionId, + bcn_params->beaconInterval); + } + if (bcn_params->paramChangeBitmap & PARAM_llBCOEXIST_CHANGED) wma_update_protection_mode(wma, bcn_params->smeSessionId, bcn_params->llbCoexist); -- cgit v1.2.3 From 3def7719359d822272011f466d8f8ed808d6361e Mon Sep 17 00:00:00 2001 From: Rajeev Kumar Date: Fri, 14 Mar 2014 12:39:15 -0700 Subject: qcacld: Fix of memory leak for wma->pGetRssiReq Free memory allocated for wma->pGetRssiReq in wma_close CRs-Fixed: 631477 Change-Id: Ieb8c481f6d2079f6bd3251a28b34b2c9a84bb7d9 --- CORE/SERVICES/WMA/wma.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index 6ec4b66fc014..3ffd51d33a6b 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -16931,6 +16931,11 @@ VOS_STATUS wma_close(v_VOID_t *vos_ctx) wma_handle->dfs_ic = NULL; } + if (NULL != wma_handle->pGetRssiReq) { + adf_os_mem_free(wma_handle->pGetRssiReq); + wma_handle->pGetRssiReq = NULL; + } + WMA_LOGD("%s: Exit", __func__); return VOS_STATUS_SUCCESS; } -- cgit v1.2.3 From 99fbe9fb9c192ee67a6fac25046842a43da806ba Mon Sep 17 00:00:00 2001 From: Prashanth Bhatta Date: Fri, 14 Mar 2014 15:49:45 -0700 Subject: qcacld: wma: Fix a missing break While processing WMA message WDA_MODEM_POWER_STATE_IND, there is a missing break which will lead to double free. Without this change, device is hanging and watch dog bark is observed after loading WLAN driver. Change-Id: Ie12fcb582138c4a2004a6749e3fbd47a565251d3 CRs-fixed: 632144 --- CORE/SERVICES/WMA/wma.c | 1 + 1 file changed, 1 insertion(+) diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index 3ffd51d33a6b..c5378ddd601b 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -15502,6 +15502,7 @@ VOS_STATUS wma_mc_process_msg(v_VOID_t *vos_context, vos_msg_t *msg) wma_notify_modem_power_state(wma_handle, (tSirModemPowerStateInd *)msg->bodyptr); vos_mem_free(msg->bodyptr); + break; default: WMA_LOGD("unknow msg type %x", msg->type); /* Do Nothing? MSG Body should be freed at here */ -- cgit v1.2.3 From 30812d7136d90cbd95a8895425c13ce692881521 Mon Sep 17 00:00:00 2001 From: Ganesh Babu Kumaravel Date: Sat, 15 Mar 2014 12:19:41 +0530 Subject: qcacld:Memory Leak Fix in HTT With ATH_11AC_TXCOMPACT defined for host to target messages send completion won't be called which results in leaking of those memory. So those messages are stored in htt_htc_pkt_misclist after sending to HTC layer which will be freed upon htt_detach. CRs-Fixed: 630814 Change-Id: Ie6660b7f4cea9dbf0c09eb2cbc94377f90490312 --- CORE/CLD_TXRX/HTT/htt.c | 41 ++++++++++++++++++++++++++++++++++++++++ CORE/CLD_TXRX/HTT/htt_h2t.c | 40 +++++++++++++++++++++++++++++++++++---- CORE/CLD_TXRX/HTT/htt_internal.h | 8 ++++++++ CORE/CLD_TXRX/HTT/htt_types.h | 1 + 4 files changed, 86 insertions(+), 4 deletions(-) diff --git a/CORE/CLD_TXRX/HTT/htt.c b/CORE/CLD_TXRX/HTT/htt.c index a6f340661326..003cff20bcc3 100644 --- a/CORE/CLD_TXRX/HTT/htt.c +++ b/CORE/CLD_TXRX/HTT/htt.c @@ -97,6 +97,41 @@ htt_htc_pkt_pool_free(struct htt_pdev_t *pdev) pdev->htt_htc_pkt_freelist = NULL; } +#ifdef ATH_11AC_TXCOMPACT +void +htt_htc_misc_pkt_list_add(struct htt_pdev_t *pdev, struct htt_htc_pkt *pkt) +{ + struct htt_htc_pkt_union *u_pkt = (struct htt_htc_pkt_union *) pkt; + + HTT_TX_MUTEX_ACQUIRE(&pdev->htt_tx_mutex); + if (pdev->htt_htc_pkt_misclist) { + u_pkt->u.next = pdev->htt_htc_pkt_misclist; + pdev->htt_htc_pkt_misclist = u_pkt; + } else { + pdev->htt_htc_pkt_misclist = u_pkt; + } + HTT_TX_MUTEX_RELEASE(&pdev->htt_tx_mutex); +} + +void +htt_htc_misc_pkt_pool_free(struct htt_pdev_t *pdev) +{ + struct htt_htc_pkt_union *pkt, *next; + adf_nbuf_t netbuf; + pkt = pdev->htt_htc_pkt_misclist; + + while (pkt) { + next = pkt->u.next; + netbuf = (adf_nbuf_t)(pkt->u.pkt.htc_pkt.pNetBufContext); + adf_nbuf_unmap(pdev->osdev, netbuf, ADF_OS_DMA_TO_DEVICE); + adf_os_mem_free(netbuf); + adf_os_mem_free(pkt); + pkt = next; + } + pdev->htt_htc_pkt_misclist = NULL; +} +#endif + /*---*/ htt_pdev_handle @@ -123,6 +158,9 @@ htt_attach( adf_os_mem_set(&pdev->stats, 0, sizeof(pdev->stats)); pdev->htt_htc_pkt_freelist = NULL; +#ifdef ATH_11AC_TXCOMPACT + pdev->htt_htc_pkt_misclist = NULL; +#endif /* for efficiency, store a local copy of the is_high_latency flag */ pdev->cfg.is_high_latency = ol_cfg_is_high_latency(pdev->ctrl_pdev); @@ -299,6 +337,9 @@ htt_detach(htt_pdev_handle pdev) htt_rx_detach(pdev); htt_tx_detach(pdev); htt_htc_pkt_pool_free(pdev); +#ifdef ATH_11AC_TXCOMPACT + htt_htc_misc_pkt_pool_free(pdev); +#endif HTT_TX_MUTEX_DESTROY(&pdev->htt_tx_mutex); HTT_TX_NBUF_QUEUE_MUTEX_DESTROY(pdev); adf_os_mem_free(pdev); diff --git a/CORE/CLD_TXRX/HTT/htt_h2t.c b/CORE/CLD_TXRX/HTT/htt_h2t.c index 473c63a2a2db..2e99189272cf 100644 --- a/CORE/CLD_TXRX/HTT/htt_h2t.c +++ b/CORE/CLD_TXRX/HTT/htt_h2t.c @@ -151,8 +151,13 @@ htt_h2t_ver_req_msg(struct htt_pdev_t *pdev) SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg); +#ifdef ATH_11AC_TXCOMPACT + if (HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt) == A_OK) { + htt_htc_misc_pkt_list_add(pdev, pkt); + } +#else HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt); - +#endif return A_OK; } @@ -303,8 +308,13 @@ htt_h2t_rx_ring_cfg_msg_ll(struct htt_pdev_t *pdev) SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg); +#ifdef ATH_11AC_TXCOMPACT + if (HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt) == A_OK) { + htt_htc_misc_pkt_list_add(pdev, pkt); + } +#else HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt); - +#endif return A_OK; } @@ -434,8 +444,13 @@ htt_h2t_rx_ring_cfg_msg_hl(struct htt_pdev_t *pdev) SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg); +#ifdef ATH_11AC_TXCOMPACT + if (HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt) == A_OK) { + htt_htc_misc_pkt_list_add(pdev, pkt); + } +#else HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt); - +#endif return A_OK; } @@ -519,7 +534,13 @@ htt_h2t_dbg_stats_get( SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg); +#ifdef ATH_11AC_TXCOMPACT + if (HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt) == A_OK) { + htt_htc_misc_pkt_list_add(pdev, pkt); + } +#else HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt); +#endif return 0; } @@ -571,8 +592,13 @@ htt_h2t_sync_msg(struct htt_pdev_t *pdev, u_int8_t sync_cnt) SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg); +#ifdef ATH_11AC_TXCOMPACT + if (HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt) == A_OK) { + htt_htc_misc_pkt_list_add(pdev, pkt); + } +#else HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt); - +#endif return A_OK; } @@ -633,6 +659,12 @@ htt_h2t_aggr_cfg_msg(struct htt_pdev_t *pdev, SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg); +#ifdef ATH_11AC_TXCOMPACT + if (HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt) == A_OK) { + htt_htc_misc_pkt_list_add(pdev, pkt); + } +#else HTCSendPkt(pdev->htc_pdev, &pkt->htc_pkt); +#endif return 0; } diff --git a/CORE/CLD_TXRX/HTT/htt_internal.h b/CORE/CLD_TXRX/HTT/htt_internal.h index 3f1ca7bd729f..ec76d8c2ebb1 100644 --- a/CORE/CLD_TXRX/HTT/htt_internal.h +++ b/CORE/CLD_TXRX/HTT/htt_internal.h @@ -383,4 +383,12 @@ htt_htc_pkt_free(struct htt_pdev_t *pdev, struct htt_htc_pkt *pkt); void htt_htc_pkt_pool_free(struct htt_pdev_t *pdev); +#ifdef ATH_11AC_TXCOMPACT +void +htt_htc_misc_pkt_list_add(struct htt_pdev_t *pdev, struct htt_htc_pkt *pkt); + +void +htt_htc_misc_pkt_pool_free(struct htt_pdev_t *pdev); +#endif + #endif /* _HTT_INTERNAL__H_ */ diff --git a/CORE/CLD_TXRX/HTT/htt_types.h b/CORE/CLD_TXRX/HTT/htt_types.h index 2ee69f00c0f3..81c6aaf9548b 100644 --- a/CORE/CLD_TXRX/HTT/htt_types.h +++ b/CORE/CLD_TXRX/HTT/htt_types.h @@ -95,6 +95,7 @@ struct htt_pdev_t { #ifdef ATH_11AC_TXCOMPACT HTT_TX_MUTEX_TYPE txnbufq_mutex; adf_nbuf_queue_t txnbufq; + struct htt_htc_pkt_union *htt_htc_pkt_misclist; #endif struct htt_htc_pkt_union *htt_htc_pkt_freelist; -- cgit v1.2.3 From 6b78c371a7a18e2875a5acd9d04d5cf5df1fdb19 Mon Sep 17 00:00:00 2001 From: Peng Xu Date: Wed, 12 Mar 2014 11:49:41 -0700 Subject: qcacld:sap: Add scan band preference in INI config Add scan band preference parameter in INI config file to enable scanning start from the preferred band during auto channel selection. Change-Id: I59a7b72035ee72baa69f8828a35d9bfcdc274908 CRs-fixed: 627704 --- CORE/HDD/inc/wlan_hdd_cfg.h | 11 +++++++++++ CORE/HDD/src/wlan_hdd_cfg.c | 10 +++++++++- CORE/SAP/src/sapChSelect.c | 32 ++++++++++++++------------------ 3 files changed, 34 insertions(+), 19 deletions(-) diff --git a/CORE/HDD/inc/wlan_hdd_cfg.h b/CORE/HDD/inc/wlan_hdd_cfg.h index 07ea944f6541..90687b187633 100644 --- a/CORE/HDD/inc/wlan_hdd_cfg.h +++ b/CORE/HDD/inc/wlan_hdd_cfg.h @@ -1603,6 +1603,16 @@ typedef enum #define CFG_ONLY_ALLOWED_CHANNELS "gACSAllowedChannels" #define CFG_ONLY_ALLOWED_CHANNELS_DEFAULT "" +/* ACS Scan band preference + * 0 -- No preference + * 1 -- Scan 2.4G first + * 2 -- Scan 5G first +*/ +#define CFG_SAP_SCAN_BAND_PREFERENCE "gAcsScanBandPreference" +#define CFG_SAP_SCAN_BAND_PREFERENCE_MIN (0) +#define CFG_SAP_SCAN_BAND_PREFERENCE_MAX (2) +#define CFG_SAP_SCAN_BAND_PREFERENCE_DEFAULT (0) + /*BMPS Logic * Notes: * 1 - Then Host driver and above layers control the PS mechanism @@ -2733,6 +2743,7 @@ typedef struct v_BOOL_t gEnableOverLapCh; char acsAllowedChnls[CFG_MAX_STR_LEN]; v_BOOL_t fRegChangeDefCountry; + v_U8_t acsScanBandPreference; } hdd_config_t; /*--------------------------------------------------------------------------- Function declarations and documenation diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c index fe9255d8b412..cc7106d07779 100644 --- a/CORE/HDD/src/wlan_hdd_cfg.c +++ b/CORE/HDD/src/wlan_hdd_cfg.c @@ -3187,6 +3187,12 @@ REG_VARIABLE( CFG_REG_CHANGE_DEF_COUNTRY_NAME, WLAN_PARAM_Integer, CFG_REG_CHANGE_DEF_COUNTRY_MIN, CFG_REG_CHANGE_DEF_COUNTRY_MAX), +REG_VARIABLE( CFG_SAP_SCAN_BAND_PREFERENCE, WLAN_PARAM_Integer, + hdd_config_t, acsScanBandPreference, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, + CFG_SAP_SCAN_BAND_PREFERENCE_DEFAULT, + CFG_SAP_SCAN_BAND_PREFERENCE_MIN, + CFG_SAP_SCAN_BAND_PREFERENCE_MAX ), }; /* @@ -3584,6 +3590,7 @@ static void print_hdd_cfg(hdd_context_t *pHddCtx) VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gIPADescSize] Value = [%u] ",pHddCtx->cfg_ini->IpaDescSize); #endif VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gEnableOverLapCh] Value = [%u] ",pHddCtx->cfg_ini->gEnableOverLapCh); + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "Name = [gAcsScanBandPreference] Value = [%u] ",pHddCtx->cfg_ini->acsScanBandPreference); } @@ -5258,7 +5265,8 @@ VOS_STATUS hdd_set_sme_config( hdd_context_t *pHddCtx ) #ifdef QCA_WIFI_2_0 /* Update the p2p listen offload setting */ smeConfig.fP2pListenOffload = pHddCtx->cfg_ini->fP2pListenOffload; - smeConfig.csrConfig.scanBandPreference = eCSR_BAND_ALL; + smeConfig.csrConfig.scanBandPreference = + pHddCtx->cfg_ini->acsScanBandPreference; #endif #ifdef FEATURE_WLAN_SCAN_PNO diff --git a/CORE/SAP/src/sapChSelect.c b/CORE/SAP/src/sapChSelect.c index 49917723a555..49f8d630dfb0 100644 --- a/CORE/SAP/src/sapChSelect.c +++ b/CORE/SAP/src/sapChSelect.c @@ -1921,31 +1921,27 @@ v_U8_t sapSelectChannel(tHalHandle halHandle, ptSapContext pSapCtx, tScanResult sapSortChlWeight(pSpectInfoParams); #ifdef SOFTAP_CHANNEL_RANGE - switch (pSapCtx->scanBandPreference) + if (eCSR_BAND_ALL == pSapCtx->scanBandPreference) { - case eCSR_BAND_ALL: - ccmCfgGetInt( halHandle, WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL, &startChannelNum); - ccmCfgGetInt( halHandle, WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL, &endChannelNum); - ccmCfgGetInt( halHandle, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand); - break; - - case eCSR_BAND_24: + ccmCfgGetInt( halHandle, WNI_CFG_SAP_CHANNEL_SELECT_START_CHANNEL, &startChannelNum); + ccmCfgGetInt( halHandle, WNI_CFG_SAP_CHANNEL_SELECT_END_CHANNEL, &endChannelNum); + ccmCfgGetInt( halHandle, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand); + } + else + { + if (eCSR_BAND_24 == pSapCtx->currentPreferredBand) + { startChannelNum = rfChannels[RF_CHAN_1].channelNum; endChannelNum = rfChannels[RF_CHAN_14].channelNum; operatingBand = eSAP_RF_SUBBAND_2_4_GHZ; - break; - - case eCSR_BAND_5G: + } + else + { startChannelNum = rfChannels[RF_CHAN_36].channelNum; endChannelNum = rfChannels[RF_CHAN_165].channelNum; operatingBand = RF_BAND_5_GHZ; - break; - - default: - VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, - "%s : Invalid scanBandPreference value %d", - __func__, pSapCtx->scanBandPreference); - } + } + } /*Loop till get the best channel in the given range */ for (count=0; count < pSpectInfoParams->numSpectChans ; count++) -- cgit v1.2.3 From 8587f2df82e43fcbfaf5dd66c520107e72d1e57e Mon Sep 17 00:00:00 2001 From: Leo Chang Date: Thu, 13 Mar 2014 14:47:12 -0700 Subject: qca-cld: IBSS-RMC TX Flow control enable IBSS-RMC requirement is packet drop rate should be less than 1%. To achieve this requirement, OS level UDP flow control is needed. WLAN Rome driver is drop based flow control. Then packet drop rate is pretty high. Instead blindly drop packet, back pressuring to OS NET layer is needed. Change-Id: I6066548ff720ea4ac57946956cd61249394a07df CRs-fixed: 611027 --- CORE/CLD_TXRX/TLSHIM/tl_shim.c | 158 ++++++++++++++++++++++++++++++++ CORE/CLD_TXRX/TLSHIM/tl_shim.h | 5 + CORE/CLD_TXRX/TXRX/ol_tx_send.c | 15 +++ CORE/CLD_TXRX/TXRX/ol_txrx.c | 26 ++++++ CORE/CLD_TXRX/TXRX/ol_txrx_internal.h | 7 ++ CORE/CLD_TXRX/TXRX/ol_txrx_types.h | 4 + CORE/HDD/inc/wlan_hdd_tx_rx.h | 14 +++ CORE/HDD/src/wlan_hdd_assoc.c | 8 ++ CORE/HDD/src/wlan_hdd_tx_rx.c | 39 ++++++++ CORE/SERVICES/COMMON/ol_txrx_ctrl_api.h | 14 +++ CORE/SERVICES/COMMON/ol_txrx_osif_api.h | 12 +++ CORE/SERVICES/COMMON/wdi_in.h | 3 + CORE/TL/inc/wlan_qct_tl.h | 115 +++++++++++++++++++++++ Kbuild | 1 + 14 files changed, 421 insertions(+) diff --git a/CORE/CLD_TXRX/TLSHIM/tl_shim.c b/CORE/CLD_TXRX/TLSHIM/tl_shim.c index 0707159b12ec..1c41e725f9a1 100644 --- a/CORE/CLD_TXRX/TLSHIM/tl_shim.c +++ b/CORE/CLD_TXRX/TLSHIM/tl_shim.c @@ -922,6 +922,9 @@ void WLANTL_RegisterVdev(void *vos_ctx, void *vdev) return; } +#ifdef QCA_LL_TX_FLOW_CT + txrx_ops.tx.flow_control_cb = WLANTL_TXFlowControlCb; +#endif /* QCA_LL_TX_FLOW_CT */ txrx_ops.rx.std = tlshim_data_rx_handler; wdi_in_osif_vdev_register(vdev_handle, tl_shim, &txrx_ops); /* TODO: Keep vdev specific tx callback, if needed */ @@ -1634,6 +1637,11 @@ VOS_STATUS WLANTL_Open(void *vos_ctx, WLANTL_ConfigInfoType *tl_cfg) adf_os_spinlock_init(&tl_shim->sta_info[i].stainfo_lock); tl_shim->sta_info[i].flags = 0; INIT_LIST_HEAD(&tl_shim->sta_info[i].cached_bufq); +#ifdef QCA_LL_TX_FLOW_CT + tl_shim->sta_info[i].flowControl = NULL; + tl_shim->sta_info[i].sessionId = 0xFF; + tl_shim->sta_info[i].adpaterCtxt = NULL; +#endif /* QCA_LL_TX_FLOW_CT */ } INIT_WORK(&tl_shim->cache_flush_work, tl_shim_cache_flush_work); @@ -1724,3 +1732,153 @@ void *tl_shim_get_vdev_by_sta_id(void *vos_context, uint8_t sta_id) return peer->vdev; } + +#ifdef QCA_LL_TX_FLOW_CT +/*============================================================================= + FUNCTION WLANTL_GetTxResource + + DESCRIPTION + This function will query WLAN kernel driver TX resource availability. + Per STA/VDEV instance, if TX resource is not available, should back + pressure to OS NET layer. + + DEPENDENCIES + NONE + + PARAMETERS + IN + vos_context : Pointer to VOS global context + sta_id : STA/VDEV instance to query TX resource + + RETURN VALUE + VOS_TRUE : Enough resource available, Not need to PAUSE TX OS Q + VOS_FALSE : TX resource is not enough, stop OS TX Q + + SIDE EFFECTS + +==============================================================================*/ +v_BOOL_t WLANTL_GetTxResource +( + void *vos_context, + uint8_t sta_id +) +{ + struct ol_txrx_peer_t *peer = NULL; + + if (!vos_context) { + return VOS_TRUE; + } + + peer = ol_txrx_peer_find_by_local_id( + ((pVosContextType) vos_context)->pdev_txrx_ctx, + sta_id); + if (!peer) { + return VOS_TRUE; + } + + return (v_BOOL_t)wdi_in_get_tx_resource(peer->vdev); +} + +/*============================================================================= + FUNCTION WLANTL_TXFlowControlCb + + DESCRIPTION + This function will be called bu TX resource management unit. + If TC resource management unit reserved enough resource for TX session, + Call this function to resume OS TX Q. + + PARAMETERS + IN + tlContext : Pointer to TL SHIM context + sessionId : STA/VDEV instance to query TX resource + resume_tx : Resume OS TX Q or not + + RETURN VALUE + NONE + + SIDE EFFECTS + +==============================================================================*/ +void WLANTL_TXFlowControlCb +( + void *tlContext, + v_U8_t sessionId, + v_BOOL_t resume_tx +) +{ + struct txrx_tl_shim_ctx *tl_shim; + v_U8_t sta_loop; + WLANTL_TxFlowControlCBType flow_control_cb = NULL; + void *adpter_ctxt = NULL; + + tl_shim = (struct txrx_tl_shim_ctx *)tlContext; + if (!tl_shim) { + /* Invalid instace */ + return; + } + + for (sta_loop = 0; sta_loop < WLAN_MAX_STA_COUNT; sta_loop++) { + if ((tl_shim->sta_info[sta_loop].sessionId == sessionId) && + (tl_shim->sta_info[sta_loop].flowControl)) + { + flow_control_cb = tl_shim->sta_info[sta_loop].flowControl; + adpter_ctxt = tl_shim->sta_info[sta_loop].adpaterCtxt; + break; + } + } + + if ((flow_control_cb) && (adpter_ctxt)) { + flow_control_cb(adpter_ctxt, resume_tx); + } + return; +} + +/*============================================================================= + FUNCTION WLANTL_RegisterTXFlowControl + + DESCRIPTION + This function will be called by TL client. + Any device want to enable TX flow control, should register Cb function + And needed information into TL SHIM + + PARAMETERS + IN + vos_ctx : Global OS context context + sta_id : STA/VDEV instance index + flowControl : Flow control callback function pointer + sessionId : VDEV ID + adpaterCtxt : VDEV os interface adapter context + + RETURN VALUE + NONE + + SIDE EFFECTS + +==============================================================================*/ +void WLANTL_RegisterTXFlowControl +( + void *vos_ctx, + v_U8_t sta_id, + WLANTL_TxFlowControlCBType flowControl, + v_U8_t sessionId, + void *adpaterCtxt +) +{ + struct txrx_tl_shim_ctx *tl_shim; + struct tlshim_sta_info *sta_info; + + tl_shim = vos_get_context(VOS_MODULE_ID_TL, vos_ctx); + if (!tl_shim) { + TLSHIM_LOGE("tl_shim is NULL"); + return; + } + + sta_info = &tl_shim->sta_info[sta_id]; + sta_info->flowControl = flowControl; + sta_info->sessionId = sessionId; + sta_info->adpaterCtxt = adpaterCtxt; + + return; +} +#endif /* QCA_LL_TX_FLOW_CT */ + diff --git a/CORE/CLD_TXRX/TLSHIM/tl_shim.h b/CORE/CLD_TXRX/TLSHIM/tl_shim.h index 4029179e7743..0530a8f61506 100644 --- a/CORE/CLD_TXRX/TLSHIM/tl_shim.h +++ b/CORE/CLD_TXRX/TLSHIM/tl_shim.h @@ -55,6 +55,11 @@ struct tlshim_sta_info { adf_os_spinlock_t stainfo_lock; struct list_head cached_bufq; unsigned long flags; +#ifdef QCA_LL_TX_FLOW_CT + WLANTL_TxFlowControlCBType flowControl; + v_U8_t sessionId; + void *adpaterCtxt; +#endif /* QCA_LL_TX_FLOW_CT */ }; struct txrx_tl_shim_ctx { diff --git a/CORE/CLD_TXRX/TXRX/ol_tx_send.c b/CORE/CLD_TXRX/TXRX/ol_tx_send.c index 8a879a9373b6..24337792928a 100644 --- a/CORE/CLD_TXRX/TXRX/ol_tx_send.c +++ b/CORE/CLD_TXRX/TXRX/ol_tx_send.c @@ -456,6 +456,7 @@ ol_tx_completion_handler( u_int16_t tx_desc_id; struct ol_tx_desc_t *tx_desc; char *trace_str; + struct ol_txrx_vdev_t *vdev; uint32_t byte_cnt = 0; union ol_tx_desc_list_elem_t *td_array = pdev->tx_desc.array; @@ -516,6 +517,20 @@ ol_tx_completion_handler( } else { OL_TX_TARGET_CREDIT_ADJUST(num_msdus, pdev, NULL); } + +#ifdef QCA_LL_TX_FLOW_CT + adf_os_spin_lock(&pdev->tx_mutex); + TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) + { + if (vdev->os_q_paused && + (pdev->tx_desc.num_free > TXRX_LL_FLOW_CT_FREE_D_HWM)) { + vdev->osif_flow_control_cb(vdev->osif_dev, vdev->vdev_id, A_TRUE); + vdev->os_q_paused = A_FALSE; + } + } + adf_os_spin_unlock(&pdev->tx_mutex); +#endif /* QCA_LL_TX_FLOW_CT */ + /* Do one shot statistics */ TXRX_STATS_UPDATE_TX_STATS(pdev, status, num_msdus, byte_cnt); } diff --git a/CORE/CLD_TXRX/TXRX/ol_txrx.c b/CORE/CLD_TXRX/TXRX/ol_txrx.c index b8dbec773ac7..859cd0f1a685 100644 --- a/CORE/CLD_TXRX/TXRX/ol_txrx.c +++ b/CORE/CLD_TXRX/TXRX/ol_txrx.c @@ -839,6 +839,11 @@ ol_txrx_vdev_attach( ol_tx_vdev_ll_pause_queue_send, vdev); +#ifdef QCA_LL_TX_FLOW_CT + vdev->os_q_paused = A_FALSE; + vdev->osif_flow_control_cb = NULL; +#endif /* QCA_LL_TX_FLOW_CT */ + /* add this vdev into the pdev's list */ TAILQ_INSERT_TAIL(&pdev->vdev_list, vdev, vdev_list_elem); @@ -870,6 +875,9 @@ void ol_txrx_osif_vdev_register(ol_txrx_vdev_handle vdev, } else { txrx_ops->tx.std = vdev->tx = OL_TX_LL; txrx_ops->tx.non_std = ol_tx_non_std_ll; +#ifdef QCA_LL_TX_FLOW_CT + vdev->osif_flow_control_cb = txrx_ops->tx.flow_control_cb; +#endif /* QCA_LL_TX_FLOW_CT */ } } @@ -1971,3 +1979,21 @@ ol_vdev_rx_set_intrabss_fwd( vdev->disable_intrabss_fwd = val; } +#ifdef QCA_LL_TX_FLOW_CT +a_bool_t +ol_txrx_get_tx_resource( + ol_txrx_vdev_handle vdev +) +{ + adf_os_spin_lock_bh(&vdev->pdev->tx_mutex); + if ((vdev->pdev->tx_desc.num_free) < + TXRX_LL_FLOW_CT_FREE_D_LWM) { + /* Not enough free resource, stop TX OS Q */ + vdev->os_q_paused = A_TRUE; + adf_os_spin_unlock_bh(&vdev->pdev->tx_mutex); + return A_FALSE; + } + adf_os_spin_unlock_bh(&vdev->pdev->tx_mutex); + return A_TRUE; +} +#endif /* QCA_LL_TX_FLOW_CT */ diff --git a/CORE/CLD_TXRX/TXRX/ol_txrx_internal.h b/CORE/CLD_TXRX/TXRX/ol_txrx_internal.h index 6b8a6f6b85fa..43894a50fece 100644 --- a/CORE/CLD_TXRX/TXRX/ol_txrx_internal.h +++ b/CORE/CLD_TXRX/TXRX/ol_txrx_internal.h @@ -667,4 +667,11 @@ do { #define QCA_SUPPORT_TXRX_VDEV_LL_TXQ #endif +#ifdef QCA_LL_TX_FLOW_CT +#define TXRX_LL_FLOW_CT_FREE_Q_LWM 100 +#define TXRX_LL_FLOW_CT_FREE_Q_HWM 300 +#define TXRX_LL_FLOW_CT_FREE_D_LWM 500 +#define TXRX_LL_FLOW_CT_FREE_D_HWM 550 +#endif /* QCA_LL_TX_FLOW_CT */ + #endif /* _OL_TXRX_INTERNAL__H_ */ diff --git a/CORE/CLD_TXRX/TXRX/ol_txrx_types.h b/CORE/CLD_TXRX/TXRX/ol_txrx_types.h index 6dd6cddc42c0..66cf4a31576e 100644 --- a/CORE/CLD_TXRX/TXRX/ol_txrx_types.h +++ b/CORE/CLD_TXRX/TXRX/ol_txrx_types.h @@ -754,6 +754,10 @@ struct ol_txrx_vdev_t { adf_os_timer_t timer; } ll_pause; a_bool_t disable_intrabss_fwd; +#ifdef QCA_LL_TX_FLOW_CT + a_bool_t os_q_paused; + ol_txrx_tx_fc_fp osif_flow_control_cb; +#endif /* QCA_LL_TX_FLOW_CT */ }; struct ol_rx_reorder_array_elem_t { diff --git a/CORE/HDD/inc/wlan_hdd_tx_rx.h b/CORE/HDD/inc/wlan_hdd_tx_rx.h index 050fa972fa81..96377948a27f 100644 --- a/CORE/HDD/inc/wlan_hdd_tx_rx.h +++ b/CORE/HDD/inc/wlan_hdd_tx_rx.h @@ -309,4 +309,18 @@ void hdd_flush_ibss_tx_queues( hdd_adapter_t *pAdapter, v_U8_t STAId); ========================================================================*/ void hdd_wmm_acquire_access_required(hdd_adapter_t *pAdapter, WLANTL_ACEnumType acType); + +#ifdef QCA_LL_TX_FLOW_CT +/**============================================================================ + @brief hdd_tx_resume_cb() - Resume OS TX Q. + Q was stopped due to WLAN TX path low resource condition + + @param adapter_context : [in] pointer to vdev apdapter + @param tx_resume : [in] TX Q resume trigger + + @return : NONE + ===========================================================================*/ +void hdd_tx_resume_cb(void *adapter_context, + v_U8_t tx_resume); +#endif /* QCA_LL_TX_FLOW_CT */ #endif // end #if !defined( WLAN_HDD_TX_RX_H ) diff --git a/CORE/HDD/src/wlan_hdd_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c index 62748ac31302..353da498816e 100644 --- a/CORE/HDD/src/wlan_hdd_assoc.c +++ b/CORE/HDD/src/wlan_hdd_assoc.c @@ -1122,6 +1122,14 @@ static VOS_STATUS hdd_roamRegisterSTA( hdd_adapter_t *pAdapter, return vosStatus; } +#ifdef QCA_LL_TX_FLOW_CT + WLANTL_RegisterTXFlowControl(pHddCtx->pvosContext, + staDesc.ucSTAId, + hdd_tx_resume_cb, + pAdapter->sessionId, + (void *)pAdapter); +#endif /* QCA_LL_TX_FLOW_CT */ + if ( cfg_param->dynSplitscan && ( VOS_TIMER_STATE_RUNNING != vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr))) diff --git a/CORE/HDD/src/wlan_hdd_tx_rx.c b/CORE/HDD/src/wlan_hdd_tx_rx.c index d2ae468b6221..7633775a4cbc 100644 --- a/CORE/HDD/src/wlan_hdd_tx_rx.c +++ b/CORE/HDD/src/wlan_hdd_tx_rx.c @@ -809,6 +809,36 @@ int hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } #else +#ifdef QCA_LL_TX_FLOW_CT +/**============================================================================ + @brief hdd_tx_resume_cb() - Resume OS TX Q. + Q was stopped due to WLAN TX path low resource condition + + @param adapter_context : [in] pointer to vdev apdapter + @param tx_resume : [in] TX Q resume trigger + + @return : NONE + ===========================================================================*/ +void hdd_tx_resume_cb(void *adapter_context, + v_U8_t tx_resume) +{ + hdd_adapter_t *pAdapter = (hdd_adapter_t *)adapter_context; + + if (!pAdapter) + { + /* INVALID ARG */ + return; + } + + /* Resume TX */ + if (VOS_TRUE == tx_resume) + { + netif_tx_wake_all_queues(pAdapter->dev); + } + return; +} +#endif /* QCA_LL_TX_FLOW_CT */ + /**============================================================================ @brief hdd_hard_start_xmit() - Function registered with the Linux OS for transmitting packets. This version of the function directly passes the packet @@ -867,6 +897,15 @@ int hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) kfree_skb(skb); return NETDEV_TX_OK; } +#ifdef QCA_LL_TX_FLOW_CT + if(VOS_FALSE == WLANTL_GetTxResource((WLAN_HDD_GET_CTX(pAdapter))->pvosContext, + STAId)) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG, + "%s: Out of TX resource, stop Q", __func__); + netif_tx_stop_all_queues(dev); + } +#endif /* QCA_LL_TX_FLOW_CT */ } else { diff --git a/CORE/SERVICES/COMMON/ol_txrx_ctrl_api.h b/CORE/SERVICES/COMMON/ol_txrx_ctrl_api.h index 4ec903979b67..22ada2a448b9 100644 --- a/CORE/SERVICES/COMMON/ol_txrx_ctrl_api.h +++ b/CORE/SERVICES/COMMON/ol_txrx_ctrl_api.h @@ -997,4 +997,18 @@ static inline void ol_tx_throttle_init_period(struct ol_txrx_pdev_t *pdev, void ol_vdev_rx_set_intrabss_fwd(ol_txrx_vdev_handle vdev, a_bool_t val); +#ifdef QCA_LL_TX_FLOW_CT +/** + * @brief Query TX resource availability by OS IF + * @details + * OS IF will query TX resource status to decide back pressuring or not + * + * @param vdev - the virtual device + */ +a_bool_t +ol_txrx_get_tx_resource( + ol_txrx_vdev_handle vdev +); +#endif /* QCA_LL_TX_FLOW_CT */ + #endif /* _OL_TXRX_CTRL_API__H_ */ diff --git a/CORE/SERVICES/COMMON/ol_txrx_osif_api.h b/CORE/SERVICES/COMMON/ol_txrx_osif_api.h index 43e3c2130601..5e7c102cacee 100644 --- a/CORE/SERVICES/COMMON/ol_txrx_osif_api.h +++ b/CORE/SERVICES/COMMON/ol_txrx_osif_api.h @@ -89,6 +89,15 @@ typedef void (*ol_txrx_rx_fp)(void *osif_dev, u_int16_t peer_id, typedef void (*ol_txrx_rx_fp)(void *osif_dev, adf_nbuf_t msdus); #endif /* OSIF_NEED_RX_PEER_ID */ +/** + * @typedef ol_txrx_tx_fc_fp + * @brief tx flow control notification function from txrx to OS shim + * @param osif_dev - the virtual device's OS shim object + * @param vdev_id - virtual device id + * @param tx_resume - tx os q should be resumed or not + */ +typedef void (*ol_txrx_tx_fc_fp)(void *osif_dev, u_int8_t vdev_id, a_bool_t tx_resume); + /** * @typedef ol_txrx_rx_fp * @brief receive function to hand batches of data frames from txrx to OS shim @@ -99,6 +108,9 @@ struct ol_txrx_osif_ops { struct { ol_txrx_tx_fp std; ol_txrx_tx_non_std_fp non_std; +#ifdef QCA_LL_TX_FLOW_CT + ol_txrx_tx_fc_fp flow_control_cb; +#endif /* QCA_LL_TX_FLOW_CT */ } tx; /* rx function pointers - specified by OS shim, stored by txrx */ diff --git a/CORE/SERVICES/COMMON/wdi_in.h b/CORE/SERVICES/COMMON/wdi_in.h index 7f7f0c807787..b015b24828b0 100644 --- a/CORE/SERVICES/COMMON/wdi_in.h +++ b/CORE/SERVICES/COMMON/wdi_in.h @@ -1222,6 +1222,9 @@ ol_tx_queue_log_display(ol_txrx_pdev_handle pdev); #define wdi_in_peer_state_update ol_txrx_peer_state_update #define wdi_in_peer_keyinstalled_state_update ol_txrx_peer_keyinstalled_state_update #define wdi_in_vdev_rx_fwd_disabled ol_vdev_rx_set_intrabss_fwd +#ifdef QCA_LL_TX_FLOW_CT +#define wdi_in_get_tx_resource ol_txrx_get_tx_resource +#endif /* QCA_LL_TX_FLOW_CT */ #include diff --git a/CORE/TL/inc/wlan_qct_tl.h b/CORE/TL/inc/wlan_qct_tl.h index a2944c554c2d..a23ba91ca460 100644 --- a/CORE/TL/inc/wlan_qct_tl.h +++ b/CORE/TL/inc/wlan_qct_tl.h @@ -630,6 +630,29 @@ typedef VOS_STATUS (*WLANTL_STARxCBType)( v_PVOID_t pvosGCtx, typedef VOS_STATUS (*WLANTL_STARxCBType)(v_PVOID_t pvosGCtx, adf_nbuf_t pDataBuff, v_U8_t ucSTAId); + +#ifdef QCA_LL_TX_FLOW_CT +/*---------------------------------------------------------------------------- + + DESCRIPTION + Type of the TX Flow Control callback registered with TL. + + TL will call this to notify the client when TX resource condition + is chnaged + + PARAMETERS + + IN + adapterCtxt: pointer to device apapter context + resume_tx: Ressume OS TX Q + + RETURN VALUE + NONE + +----------------------------------------------------------------------------*/ +typedef void (*WLANTL_TxFlowControlCBType)(void *adapterCtxt, + v_BOOL_t resume_tx); +#endif /* QCA_LL_TX_FLOW_CT */ #endif /* QCA_WIFI_2_0 */ /*---------------------------------------------------------------------------- @@ -2993,4 +3016,96 @@ WLANTL_TLDebugMessage } #endif /* QCA_WIFI_2_0 */ + +#ifdef QCA_WIFI_2_0 +#ifdef QCA_LL_TX_FLOW_CT +/*============================================================================= + FUNCTION WLANTL_GetTxResource + + DESCRIPTION + This function will query WLAN kernel driver TX resource availability. + Per STA/VDEV instance, if TX resource is not available, should back + pressure to OS NET layer. + + DEPENDENCIES + NONE + + PARAMETERS + IN + vos_context : Pointer to VOS global context + sta_id : STA/VDEV instance to query TX resource + + RETURN VALUE + VOS_TRUE : Enough resource available, Not need to PAUSE TX OS Q + VOS_FALSE : TX resource is not enough, stop OS TX Q + + SIDE EFFECTS + +==============================================================================*/ +v_BOOL_t WLANTL_GetTxResource +( + void *vos_context, + uint8_t sta_id +); + +/*============================================================================= + FUNCTION WLANTL_TXFlowControlCb + + DESCRIPTION + This function will be called by TX resource management unit. + If TC resource management unit reserved enough resource for TX session, + Call this function to resume OS TX Q. + + PARAMETERS + IN + tlContext : Pointer to TL SHIM context + sessionId : STA/VDEV instance to query TX resource + resume_tx : Resume OS TX Q or not + + RETURN VALUE + NONE + + SIDE EFFECTS + +==============================================================================*/ +void WLANTL_TXFlowControlCb +( + void *tlContext, + v_U8_t sessionId, + v_BOOL_t resume_tx +); + +/*============================================================================= + FUNCTION WLANTL_RegisterTXFlowControl + + DESCRIPTION + This function will be called by TL client. + Any device want to enable TX flow control, should register Cb function + And needed information into TL SHIM + + PARAMETERS + IN + vos_ctx : Global OS context context + sta_id : STA/VDEV instance index + flowControl : Flow control callback function pointer + sessionId : VDEV ID + adpaterCtxt : VDEV os interface adapter context + + RETURN VALUE + NONE + + SIDE EFFECTS + +==============================================================================*/ +void WLANTL_RegisterTXFlowControl +( + void *vos_ctx, + v_U8_t sta_id, + WLANTL_TxFlowControlCBType flowControl, + v_U8_t sessionId, + void *adpaterCtxt +); +#endif /* QCA_LL_TX_FLOW_CT */ +#endif /* QCA_WIFI_2_0 */ + #endif /* #ifndef WLAN_QCT_WLANTL_H */ diff --git a/Kbuild b/Kbuild index 8095ebc86a2d..74de600c1a90 100644 --- a/Kbuild +++ b/Kbuild @@ -880,6 +880,7 @@ CDEFINES += -DWLANTL_DEBUG else CDEFINES += -DOSIF_NEED_RX_PEER_ID \ -DQCA_SUPPORT_TXRX_LOCAL_PEER_ID +CDEFINES += -DQCA_LL_TX_FLOW_CT endif ifeq ($(CONFIG_QCA_WIFI_2_0), 1) -- cgit v1.2.3 From 770186f6611a2b94d39c407d2748c2f6302ea2d0 Mon Sep 17 00:00:00 2001 From: Akash Patel Date: Sat, 15 Mar 2014 22:19:35 -0700 Subject: Cafstaging Release 1.0.0.63 Cafstaging Release 1.0.0.63 Change-Id: Ia2c26cabb5984eae446621ad8ba556af266db7ff --- CORE/MAC/inc/qwlan_version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CORE/MAC/inc/qwlan_version.h b/CORE/MAC/inc/qwlan_version.h index 69dd21b6c149..b4a82fa4eefa 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 62 +#define QWLAN_VERSION_BUILD 63 -#define QWLAN_VERSIONSTR "1.0.0.62" +#define QWLAN_VERSIONSTR "1.0.0.63" #ifdef QCA_WIFI_2_0 -- cgit v1.2.3