diff options
| author | Akash Patel <akashp@codeaurora.org> | 2014-03-17 10:14:58 -0700 |
|---|---|---|
| committer | Akash Patel <akashp@codeaurora.org> | 2014-03-17 10:15:53 -0700 |
| commit | e4076c910e6c11bc43447dad596d52864cf00478 (patch) | |
| tree | 80e4423bf24dd14e27b06afd527f50f5f4b82c0c | |
| parent | 73b21b76bb3b3ce5a64df0096d871f62f42b68ed (diff) | |
| parent | 770186f6611a2b94d39c407d2748c2f6302ea2d0 (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
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 */ @@ -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) |
