summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkash Patel <akashp@codeaurora.org>2014-03-17 10:14:58 -0700
committerAkash Patel <akashp@codeaurora.org>2014-03-17 10:15:53 -0700
commite4076c910e6c11bc43447dad596d52864cf00478 (patch)
tree80e4423bf24dd14e27b06afd527f50f5f4b82c0c
parent73b21b76bb3b3ce5a64df0096d871f62f42b68ed (diff)
parent770186f6611a2b94d39c407d2748c2f6302ea2d0 (diff)
Release 1.0.0.63 QCACLD WLAN Driver
Merge remote-tracking branch 'origin/caf/caf-wlan/master' * origin/caf/caf-wlan/master: Cafstaging Release 1.0.0.63 qca-cld: IBSS-RMC TX Flow control enable qcacld:sap: Add scan band preference in INI config qcacld:Memory Leak Fix in HTT qcacld: wma: Fix a missing break qcacld: Fix of memory leak for wma->pGetRssiReq qcacld: Add support to update BI in beacon update indication qcacld: Fix for adding sequence number in management frames qcacld: add QCSAP ioctl setAutoChannel qcacld: hdd: Allow access if we have valid Tspec qca_cld: fix the action frame sub type offset value for Remain-on-Channel CLD-SCAN: Ignore beacon while adding the entry into the scan cache qcacld: Fix of memmory leak in wma_dfs_configure_channel qcacld: Fix issues found by static code analysis wlan: VHT IEs missing in Reassoc Request during roam Change-Id: I5ae0552d3f74d4d686f96362077b626b5ab08a8b
-rw-r--r--CORE/CLD_TXRX/HTT/htt.c41
-rw-r--r--CORE/CLD_TXRX/HTT/htt_h2t.c40
-rw-r--r--CORE/CLD_TXRX/HTT/htt_internal.h8
-rw-r--r--CORE/CLD_TXRX/HTT/htt_types.h1
-rw-r--r--CORE/CLD_TXRX/TLSHIM/tl_shim.c158
-rw-r--r--CORE/CLD_TXRX/TLSHIM/tl_shim.h5
-rw-r--r--CORE/CLD_TXRX/TXRX/ol_tx_send.c15
-rw-r--r--CORE/CLD_TXRX/TXRX/ol_txrx.c26
-rw-r--r--CORE/CLD_TXRX/TXRX/ol_txrx_internal.h7
-rw-r--r--CORE/CLD_TXRX/TXRX/ol_txrx_types.h4
-rw-r--r--CORE/HDD/inc/qc_sap_ioctl.h1
-rw-r--r--CORE/HDD/inc/wlan_hdd_cfg.h11
-rw-r--r--CORE/HDD/inc/wlan_hdd_main.h1
-rw-r--r--CORE/HDD/inc/wlan_hdd_tx_rx.h14
-rw-r--r--CORE/HDD/src/wlan_hdd_assoc.c8
-rw-r--r--CORE/HDD/src/wlan_hdd_cfg.c10
-rw-r--r--CORE/HDD/src/wlan_hdd_hostapd.c15
-rw-r--r--CORE/HDD/src/wlan_hdd_p2p.c2
-rw-r--r--CORE/HDD/src/wlan_hdd_tx_rx.c39
-rw-r--r--CORE/HDD/src/wlan_hdd_wmm.c10
-rw-r--r--CORE/MAC/inc/aniGlobal.h10
-rw-r--r--CORE/MAC/inc/qwlan_version.h4
-rw-r--r--CORE/MAC/src/pe/lim/limScanResultUtils.c12
-rw-r--r--CORE/MAC/src/pe/lim/limSendManagementFrames.c55
-rw-r--r--CORE/SAP/src/sapChSelect.c39
-rw-r--r--CORE/SERVICES/COMMON/ol_txrx_ctrl_api.h14
-rw-r--r--CORE/SERVICES/COMMON/ol_txrx_osif_api.h12
-rw-r--r--CORE/SERVICES/COMMON/wdi_in.h3
-rw-r--r--CORE/SERVICES/WMA/wma.c50
-rw-r--r--CORE/SERVICES/WMI/wmi_unified.c19
-rw-r--r--CORE/SYS/legacy/src/system/src/macInitApi.c5
-rw-r--r--CORE/TL/inc/wlan_qct_tl.h115
-rw-r--r--Kbuild1
33 files changed, 716 insertions, 39 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;
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/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/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/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/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_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/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,
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 &&
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/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
{
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/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
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)
{
diff --git a/CORE/MAC/src/pe/lim/limSendManagementFrames.c b/CORE/MAC/src/pe/lim/limSendManagementFrames.c
index c000ece0653c..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() ***/
@@ -2600,6 +2642,7 @@ limSendReassocReqWithFTIEsMgmtFrame(tpAniSirGlobal pMac,
#endif
tANI_U8 txFlag = 0;
tANI_U8 smeSessionId = 0;
+ tANI_BOOLEAN isVHTEnabled = eANI_BOOLEAN_FALSE;
if (NULL == psessionEntry)
{
@@ -2823,6 +2866,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 ) )
{
diff --git a/CORE/SAP/src/sapChSelect.c b/CORE/SAP/src/sapChSelect.c
index 3d93a4f4165c..49f8d630dfb0 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:
@@ -1914,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++)
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
@@ -90,6 +90,15 @@ 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 <ol_txrx_dbg.h>
diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c
index d835a3df1468..c5378ddd601b 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);
@@ -15480,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 */
@@ -16822,6 +16845,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);
}
@@ -16903,6 +16932,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;
}
@@ -18135,6 +18169,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 +19400,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; idx<wmi_handle->max_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,
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);
}
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)