diff options
| author | Akash Patel <akashp@codeaurora.org> | 2014-03-25 10:57:30 -0700 |
|---|---|---|
| committer | Akash Patel <akashp@codeaurora.org> | 2014-03-25 10:59:37 -0700 |
| commit | 1008beb3e8a18e19490142b4e17ba8bbd09bc6ce (patch) | |
| tree | 30b5bd4c44f733b9ed6c88b22a2ec77727ce9684 | |
| parent | 3002a2822136ad71a33ac6888d5d974402c5af7a (diff) | |
| parent | 520dbf1aa53bdae411db47f6a73f4ebd1e421bd2 (diff) | |
Release 1.0.0.70 & 1.0.0.71 QCACLD WLAN Driver
Merge remote-tracking branch 'origin/caf/caf-wlan/master'
* origin/caf/caf-wlan/master:
Cafstaging Release 1.0.0.71
Fix the disconnect event being sent twice to SME.
qcacld: Fix of WMA sending DELETE BSS RSP 2 times to LIM
qcacld: Fix of memory leka in WMA for DHCP messages
Cafstaging Release 1.0.0.70
Corrected copyright issue.
qcacld: free ota tx callback for data frame if no ack/nack from FW
qcacld: sme: Set proper PSB value in assoc request
qcacld: Fix of double free panic in limProcessSwitchChannelRsp
Fix the Tx 11b data rate issue on SAP
qcacld: Flush p2p results in LIM cache before starting scan
qcacld: Run ddr voting in suspend/resume
P2P: Fixes race codition for remain_on_chan_ctx
qcacld: SME: Fix to update direction from input addts request
qcacld: Increase the maximum number of tspec's supported
wlan: qcacld: Debug for DMA done bit not set issue
Change-Id: If8164ddc62fd9a73298fbd4c2dfe2cedf8863473
23 files changed, 535 insertions, 63 deletions
diff --git a/CORE/CLD_TXRX/HTT/htt.h b/CORE/CLD_TXRX/HTT/htt.h index 95d09c6c4834..972f25b70085 100644 --- a/CORE/CLD_TXRX/HTT/htt.h +++ b/CORE/CLD_TXRX/HTT/htt.h @@ -3634,4 +3634,6 @@ PREPACK struct htt_tx_frag_desc_bank_cfg_t { #define HTT_TX_CREDIT_SIGN_BIT_POSITIVE 0x0 #define HTT_TX_CREDIT_SIGN_BIT_NEGATIVE 0x1 +#define DEBUG_DMA_DONE + #endif diff --git a/CORE/CLD_TXRX/HTT/htt_internal.h b/CORE/CLD_TXRX/HTT/htt_internal.h index ec76d8c2ebb1..9e528f07329b 100644 --- a/CORE/CLD_TXRX/HTT/htt_internal.h +++ b/CORE/CLD_TXRX/HTT/htt_internal.h @@ -140,6 +140,7 @@ static inline void htt_print_rx_desc(struct htt_host_rx_desc_base *rx_desc) { + adf_os_print("----------------------RX DESC----------------------------\n"); adf_os_print("attention: %#010x\n", (unsigned int)(*(u_int32_t *) &rx_desc->attention)); adf_os_print("frag_info: %#010x\n", @@ -201,7 +202,7 @@ htt_print_rx_desc(struct htt_host_rx_desc_base *rx_desc) (unsigned int)(((u_int32_t *) &rx_desc->ppdu_end)[19]), (unsigned int)(((u_int32_t *) &rx_desc->ppdu_end)[20]), (unsigned int)(((u_int32_t *) &rx_desc->ppdu_end)[21])); - + adf_os_print("---------------------------------------------------------\n"); } diff --git a/CORE/CLD_TXRX/HTT/htt_rx.c b/CORE/CLD_TXRX/HTT/htt_rx.c index 8d1c440c3059..c3154228ca48 100644 --- a/CORE/CLD_TXRX/HTT/htt_rx.c +++ b/CORE/CLD_TXRX/HTT/htt_rx.c @@ -53,6 +53,16 @@ #include <ieee80211_common.h> /* ieee80211_frame, ieee80211_qoscntl */ #include <ieee80211_defines.h> /* ieee80211_rx_status */ +#ifdef DEBUG_DMA_DONE +#include <asm/barrier.h> +#include <wma_api.h> +#endif + +#ifdef DEBUG_DMA_DONE +extern int process_wma_set_command(int sessid, int paramid, + int sval, int vpdev); +#endif + /* AR9888v1 WORKAROUND for EV#112367 */ /* FIX THIS - remove this WAR when the bug is fixed */ #define PEREGRINE_1_0_ZERO_LEN_PHY_ERR_WAR @@ -221,6 +231,9 @@ htt_rx_ring_fill_n(struct htt_pdev_t *pdev, int num) * As long as enough buffers are left in the ring for * another A-MPDU rx, no special recovery is needed. */ +#ifdef DEBUG_DMA_DONE + pdev->rx_ring.dbg_refill_cnt++; +#endif adf_os_timer_start(&pdev->rx_ring.refill_retry_timer, HTT_RX_RING_REFILL_RETRY_TIME_MS); goto fail; @@ -230,6 +243,13 @@ htt_rx_ring_fill_n(struct htt_pdev_t *pdev, int num) rx_desc = htt_rx_desc(rx_netbuf); *(u_int32_t *)&rx_desc->attention = 0; +#ifdef DEBUG_DMA_DONE + *(u_int32_t *)&rx_desc->msdu_end = 1; + + /* To ensure that attention bit is reset and msdu_end is set before + calling dma_map */ + smp_mb(); +#endif /* * Adjust adf_nbuf_data to point to the location in the buffer * where the rx descriptor will be filled in. @@ -604,6 +624,12 @@ htt_rx_netbuf_pop( adf_nbuf_t msdu; HTT_ASSERT1(htt_rx_ring_elems(pdev) != 0); + +#ifdef DEBUG_DMA_DONE + pdev->rx_ring.dbg_ring_idx++; + pdev->rx_ring.dbg_ring_idx &= pdev->rx_ring.size_mask; +#endif + idx = pdev->rx_ring.sw_rd_idx.msdu_payld; msdu = pdev->rx_ring.buf.netbufs_ring[idx]; idx++; @@ -713,6 +739,85 @@ htt_set_checksum_result_hl(adf_nbuf_t msdu, #define htt_set_checksum_result_hl(msdu, rx_desc) /* no-op */ #endif +#ifdef DEBUG_DMA_DONE +void +htt_rx_print_rx_indication( + adf_nbuf_t rx_ind_msg, + htt_pdev_handle pdev) +{ + u_int32_t *msg_word; + int byte_offset; + int mpdu_range, num_mpdu_range; + + msg_word = (u_int32_t *)adf_nbuf_data(rx_ind_msg); + + adf_os_print("------------------HTT RX IND-----------------------------\n"); + adf_os_print("alloc idx paddr %x (*vaddr) %d\n", + pdev->rx_ring.alloc_idx.paddr, + *pdev->rx_ring.alloc_idx.vaddr); + + adf_os_print("sw_rd_idx msdu_payld %d msdu_desc %d\n", + pdev->rx_ring.sw_rd_idx.msdu_payld, + pdev->rx_ring.sw_rd_idx.msdu_desc); + + adf_os_print("dbg_ring_idx %d\n", pdev->rx_ring.dbg_ring_idx); + + adf_os_print("fill_level %d fill_cnt %d\n",pdev->rx_ring.fill_level, + pdev->rx_ring.fill_cnt); + + adf_os_print("initial msdu_payld %d curr mpdu range %d curr mpdu cnt %d\n", + pdev->rx_ring.dbg_initial_msdu_payld, + pdev->rx_ring.dbg_mpdu_range, + pdev->rx_ring.dbg_mpdu_count); + + /* Print the RX_IND contents */ + + adf_os_print("peer id %x RV %x FV %x ext_tid %x msg_type %x\n", + HTT_RX_IND_PEER_ID_GET(*msg_word), + HTT_RX_IND_REL_VALID_GET(*msg_word), + HTT_RX_IND_FLUSH_VALID_GET(*msg_word), + HTT_RX_IND_EXT_TID_GET(*msg_word), + HTT_T2H_MSG_TYPE_GET(*msg_word)); + + adf_os_print("num_mpdu_ranges %x rel_seq_num_end %x rel_seq_num_start %x\n" + " flush_seq_num_end %x flush_seq_num_start %x\n", + HTT_RX_IND_NUM_MPDU_RANGES_GET(*(msg_word + 1)), + HTT_RX_IND_REL_SEQ_NUM_END_GET(*(msg_word + 1)), + HTT_RX_IND_REL_SEQ_NUM_START_GET(*(msg_word + 1)), + HTT_RX_IND_FLUSH_SEQ_NUM_END_GET(*(msg_word + 1)), + HTT_RX_IND_FLUSH_SEQ_NUM_START_GET(*(msg_word + 1))); + + adf_os_print("fw_rx_desc_bytes %x\n", HTT_RX_IND_FW_RX_DESC_BYTES_GET( + *(msg_word + 2 + HTT_RX_PPDU_DESC_SIZE32))); + + /* receive MSDU desc for current frame */ + byte_offset = HTT_ENDIAN_BYTE_IDX_SWAP(HTT_RX_IND_FW_RX_DESC_BYTE_OFFSET + + pdev->rx_ind_msdu_byte_idx); + + adf_os_print("msdu byte idx %x msdu desc %x\n", pdev->rx_ind_msdu_byte_idx, + HTT_RX_IND_FW_RX_DESC_BYTES_GET( + *(msg_word + 2 + HTT_RX_PPDU_DESC_SIZE32))); + + num_mpdu_range = HTT_RX_IND_NUM_MPDU_RANGES_GET(*(msg_word + 1)); + + for (mpdu_range = 0; mpdu_range < num_mpdu_range; mpdu_range++) { + enum htt_rx_status status; + int num_mpdus; + + htt_rx_ind_mpdu_range_info( + pdev, rx_ind_msg, mpdu_range, &status, &num_mpdus); + + adf_os_print("mpdu_range %x status %x num_mpdus %x\n", + pdev->rx_ind_msdu_byte_idx, status, num_mpdus); + } + adf_os_print("---------------------------------------------------------\n"); +} +#endif + +#ifdef DEBUG_DMA_DONE +#define MAX_DONE_BIT_CHECK_ITER 5 +#endif + int htt_rx_amsdu_pop_ll( htt_pdev_handle pdev, @@ -766,37 +871,46 @@ htt_rx_amsdu_pop_ll( * assert for now until we have a way to recover. */ +#ifdef DEBUG_DMA_DONE /* if done bit is not set */ if (adf_os_unlikely(!((*(u_int32_t *) &rx_desc->attention) & RX_ATTENTION_0_MSDU_DONE_MASK))) { - /* invalidate the cache */ - adf_os_print("rx desc done bit not set invalidating cache\n"); + int dbg_iter = MAX_DONE_BIT_CHECK_ITER; + + htt_rx_print_rx_indication(rx_ind_msg, pdev); htt_print_rx_desc(rx_desc); + adf_os_print("done bit still not set retrying...\n"); + + while (dbg_iter && + (!((*(u_int32_t *) &rx_desc->attention) & + RX_ATTENTION_0_MSDU_DONE_MASK))) { + adf_os_mdelay(1); + adf_os_invalidate_range((void *)rx_desc, (void*)((char *)rx_desc + HTT_RX_STD_DESC_RESERVATION)); + dbg_iter--; + } - /* if done bit still not set try waiting for 1 ms and check again */ - if (!((*(u_int32_t *) &rx_desc->attention) & - RX_ATTENTION_0_MSDU_DONE_MASK)) { - - adf_os_print("done bit still not set delay and try again\n"); + /* if the done bit is still not set, ASSERT the target */ + if (adf_os_unlikely(!((*(u_int32_t *) &rx_desc->attention) + & RX_ATTENTION_0_MSDU_DONE_MASK))) + { + htt_rx_print_rx_indication(rx_ind_msg, pdev); htt_print_rx_desc(rx_desc); - adf_os_mdelay(1); - - adf_os_invalidate_range((void *)rx_desc, - (void*)((char *)rx_desc + - HTT_RX_STD_DESC_RESERVATION)); - + process_wma_set_command(0,(int)GEN_PARAM_CRASH_INJECT, + 0, GEN_CMD); + HTT_ASSERT_ALWAYS(0); + } + } +#else HTT_ASSERT_ALWAYS( (*(u_int32_t *) &rx_desc->attention) & RX_ATTENTION_0_MSDU_DONE_MASK); - } - } - +#endif /* * Copy the FW rx descriptor for this MSDU from the rx indication * message into the MSDU's netbuf. @@ -881,6 +995,10 @@ htt_rx_amsdu_pop_ll( msdu = next; msdu_chaining = 1; +#ifdef DEBUG_DMA_DONE + adf_os_print("msdu_chained %d!\n", msdu_chained); +#endif + if (msdu_chained == 0) { /* Trim the last one to the correct size - accounting for * inconsistent HW lengths cuasing length overflows and @@ -1716,6 +1834,10 @@ htt_rx_attach(struct htt_pdev_t *pdev) htt_rx_ring_refill_retry, (void *)pdev); pdev->rx_ring.fill_cnt = 0; +#ifdef DEBUG_DMA_DONE + pdev->rx_ring.dbg_ring_idx = 0; + pdev->rx_ring.dbg_refill_cnt = 0; +#endif htt_rx_ring_fill_n(pdev, pdev->rx_ring.fill_level); htt_rx_amsdu_pop = htt_rx_amsdu_pop_ll; diff --git a/CORE/CLD_TXRX/HTT/htt_types.h b/CORE/CLD_TXRX/HTT/htt_types.h index 81c6aaf9548b..6373b247a17a 100644 --- a/CORE/CLD_TXRX/HTT/htt_types.h +++ b/CORE/CLD_TXRX/HTT/htt_types.h @@ -166,6 +166,13 @@ struct htt_pdev_t { * to replenish Rx ring. */ adf_os_atomic_t refill_ref_cnt; +#ifdef DEBUG_DMA_DONE + u_int32_t dbg_initial_msdu_payld; + u_int32_t dbg_mpdu_range; + u_int32_t dbg_mpdu_count; + u_int32_t dbg_ring_idx; + u_int32_t dbg_refill_cnt; +#endif } rx_ring; int rx_desc_size_hl; long rx_fw_desc_offset; diff --git a/CORE/CLD_TXRX/TXRX/ol_rx.c b/CORE/CLD_TXRX/TXRX/ol_rx.c index 1a4bb7449941..b21d0c5f846f 100644 --- a/CORE/CLD_TXRX/TXRX/ol_rx.c +++ b/CORE/CLD_TXRX/TXRX/ol_rx.c @@ -214,12 +214,21 @@ ol_rx_indication_handler( pdev->htt_pdev, rx_ind_msg, &seq_num_start, &seq_num_end); } +#ifdef DEBUG_DMA_DONE + pdev->htt_pdev->rx_ring.dbg_initial_msdu_payld = + pdev->htt_pdev->rx_ring.sw_rd_idx.msdu_payld; +#endif + for (mpdu_range = 0; mpdu_range < num_mpdu_ranges; mpdu_range++) { enum htt_rx_status status; int i, num_mpdus; adf_nbuf_t head_msdu, tail_msdu, msdu; void *rx_mpdu_desc; +#ifdef DEBUG_DMA_DONE + pdev->htt_pdev->rx_ring.dbg_mpdu_range = mpdu_range; +#endif + htt_rx_ind_mpdu_range_info( pdev->htt_pdev, rx_ind_msg, mpdu_range, &status, &num_mpdus); if ((status == htt_rx_status_ok) && peer) { @@ -246,6 +255,11 @@ ol_rx_indication_handler( * data written by the MAC DMA into memory will be * fetched, rather than garbage from the cache. */ + +#ifdef DEBUG_DMA_DONE + pdev->htt_pdev->rx_ring.dbg_mpdu_count = i; +#endif + msdu_chaining = htt_rx_amsdu_pop( htt_pdev, rx_ind_msg, &head_msdu, &tail_msdu); rx_mpdu_desc = diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h index b44a599848c8..d31d6ab4f767 100644 --- a/CORE/HDD/inc/wlan_hdd_main.h +++ b/CORE/HDD/inc/wlan_hdd_main.h @@ -626,6 +626,7 @@ typedef struct hdd_cfg80211_state_s size_t len; struct sk_buff *skb; hdd_remain_on_chan_ctx_t* remain_on_chan_ctx; + struct mutex remain_on_chan_ctx_lock; eP2PActionFrameState actionFrmState; }hdd_cfg80211_state_t; diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c index fe32ec1c7887..3ac2ebbbb8d4 100644 --- a/CORE/HDD/src/wlan_hdd_cfg80211.c +++ b/CORE/HDD/src/wlan_hdd_cfg80211.c @@ -64,6 +64,7 @@ #include <wlan_hdd_includes.h> #include <net/arp.h> #include <net/cfg80211.h> +#include <net/cnss.h> #include <linux/wireless.h> #include <wlan_hdd_wowl.h> #include <aniGlobal.h> @@ -9927,6 +9928,8 @@ int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy) return 0; } + cnss_request_bus_bandwidth(CNSS_BUS_WIDTH_MEDIUM); + #ifdef QCA_WIFI_2_0 /* Resume MC thread */ complete(&vosSchedContext->ResumeMcEvent); @@ -10095,6 +10098,8 @@ int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy, pHddCtx->isWiphySuspended = TRUE; + cnss_request_bus_bandwidth(CNSS_BUS_WIDTH_NONE); + EXIT(); return 0; diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c index c3e5ef6bae8c..9803ec585c96 100644 --- a/CORE/HDD/src/wlan_hdd_main.c +++ b/CORE/HDD/src/wlan_hdd_main.c @@ -7023,6 +7023,7 @@ hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type, hdd_adapter_list_node_t *pHddAdapterNode = NULL; VOS_STATUS status = VOS_STATUS_E_FAILURE; VOS_STATUS exitbmpsStatus = VOS_STATUS_E_FAILURE; + hdd_cfg80211_state_t *cfgState; hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s iface =%s type = %d\n",__func__,iface_name,session_type); @@ -7198,6 +7199,8 @@ hdd_adapter_t* hdd_open_adapter( hdd_context_t *pHddCtx, tANI_U8 session_type, } } + cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter ); + mutex_init(&cfgState->remain_on_chan_ctx_lock); if( VOS_STATUS_SUCCESS == status ) { diff --git a/CORE/HDD/src/wlan_hdd_p2p.c b/CORE/HDD/src/wlan_hdd_p2p.c index 027d75db90ca..95f2fd2557d7 100644 --- a/CORE/HDD/src/wlan_hdd_p2p.c +++ b/CORE/HDD/src/wlan_hdd_p2p.c @@ -155,7 +155,9 @@ eHalStatus wlan_hdd_remain_on_channel_callback( tHalHandle hHal, void* pCtx, vos_timer_stop(&pRemainChanCtx->hdd_remain_on_chan_timer); vos_timer_destroy(&pRemainChanCtx->hdd_remain_on_chan_timer); + mutex_lock(&cfgState->remain_on_chan_ctx_lock); cfgState->remain_on_chan_ctx = NULL; + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); if( REMAIN_ON_CHANNEL_REQUEST == pRemainChanCtx->rem_on_chan_request) { @@ -415,7 +417,11 @@ static int wlan_hdd_request_remain_on_channel( struct wiphy *wiphy, *cookie = (uintptr_t) pRemainChanCtx; pRemainChanCtx->cookie = *cookie; pRemainChanCtx->rem_on_chan_request = request_type; + + mutex_lock(&cfgState->remain_on_chan_ctx_lock); cfgState->remain_on_chan_ctx = pRemainChanCtx; + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); + cfgState->current_freq = chan->center_freq; pRemainChanCtx->action_pkt_buff.freq = 0; @@ -491,7 +497,10 @@ static int wlan_hdd_request_remain_on_channel( struct wiphy *wiphy, { VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: WLANSAP_RemainOnChannel returned fail", __func__); + + mutex_lock(&cfgState->remain_on_chan_ctx_lock); cfgState->remain_on_chan_ctx = NULL; + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); vos_mem_free (pRemainChanCtx); hdd_allow_suspend(); return -EINVAL; @@ -544,11 +553,13 @@ int wlan_hdd_cfg80211_remain_on_channel( struct wiphy *wiphy, void hdd_remainChanReadyHandler( hdd_adapter_t *pAdapter ) { hdd_cfg80211_state_t *cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter ); - hdd_remain_on_chan_ctx_t* pRemainChanCtx = cfgState->remain_on_chan_ctx; + hdd_remain_on_chan_ctx_t* pRemainChanCtx; VOS_STATUS status; hddLog( LOG1, "Ready on chan ind"); + mutex_lock(&cfgState->remain_on_chan_ctx_lock); + pRemainChanCtx = cfgState->remain_on_chan_ctx; if( pRemainChanCtx != NULL ) { // Removing READY_EVENT_PROPOGATE_TIME from current time which gives @@ -619,6 +630,7 @@ void hdd_remainChanReadyHandler( hdd_adapter_t *pAdapter ) { hddLog( LOGW, "%s: No Pending Remain on channel Request", __func__); } + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); return; } @@ -651,14 +663,17 @@ int wlan_hdd_cfg80211_cancel_remain_on_channel( struct wiphy *wiphy, /* FIXME cancel currently running remain on chan. * Need to check cookie and cancel accordingly */ + mutex_lock(&cfgState->remain_on_chan_ctx_lock); if( (cfgState->remain_on_chan_ctx == NULL) || (cfgState->remain_on_chan_ctx->cookie != cookie) ) { hddLog( LOGE, "%s: No Remain on channel pending with specified cookie value", __func__); + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); return -EINVAL; } + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); /* wait until remain on channel ready event received * for already issued remain on channel request */ @@ -884,6 +899,7 @@ int wlan_hdd_action( struct wiphy *wiphy, struct net_device *dev, // In case of P2P Client mode if we are already // on the same channel then send the frame directly + mutex_lock(&cfgState->remain_on_chan_ctx_lock); if ((type == SIR_MAC_MGMT_FRAME) && (subType == SIR_MAC_MGMT_ACTION) && hdd_p2p_is_action_type_rsp(&buf[WLAN_HDD_PUBLIC_ACTION_FRAME_BODY_OFFSET]) && @@ -900,8 +916,10 @@ int wlan_hdd_action( struct wiphy *wiphy, struct net_device *dev, hddLog( LOGE, "Remain on Channel timer start failed"); } } + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); goto send_frame; } + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); if((cfgState->remain_on_chan_ctx != NULL) && (cfgState->current_freq == chan->center_freq) @@ -968,6 +986,7 @@ int wlan_hdd_action( struct wiphy *wiphy, struct net_device *dev, vos_mem_copy( cfgState->buf, buf, len); + mutex_lock(&cfgState->remain_on_chan_ctx_lock); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) if( cfgState->remain_on_chan_ctx ) { @@ -983,6 +1002,7 @@ int wlan_hdd_action( struct wiphy *wiphy, struct net_device *dev, #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) } #endif + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); } if ( (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) || @@ -1675,7 +1695,6 @@ void hdd_indicateMgmtFrame( hdd_adapter_t *pAdapter, } cfgState = WLAN_HDD_GET_CFG_STATE_PTR( pAdapter ); - pRemainChanCtx = cfgState->remain_on_chan_ctx; if ((type == SIR_MAC_MGMT_FRAME) && (subType == SIR_MAC_MGMT_ACTION)) @@ -1722,6 +1741,8 @@ void hdd_indicateMgmtFrame( hdd_adapter_t *pAdapter, } } #endif + mutex_lock(&cfgState->remain_on_chan_ctx_lock); + pRemainChanCtx = cfgState->remain_on_chan_ctx; if (pRemainChanCtx != NULL) { if(actionFrmType == WLAN_HDD_GO_NEG_REQ || @@ -1763,10 +1784,12 @@ void hdd_indicateMgmtFrame( hdd_adapter_t *pAdapter, hddLog( LOGE,"%s:" "Frames are pending. dropping frame !!!", __func__); } + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); return; } } } + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); if (((actionFrmType == WLAN_HDD_PROV_DIS_RESP) && (cfgState->actionFrmState == HDD_PD_REQ_ACK_PENDING)) || diff --git a/CORE/MAC/inc/qwlan_version.h b/CORE/MAC/inc/qwlan_version.h index 21195c79c49e..0f63f07be249 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 69 +#define QWLAN_VERSION_BUILD 71 -#define QWLAN_VERSIONSTR "1.0.0.69" +#define QWLAN_VERSIONSTR "1.0.0.71" #ifdef QCA_WIFI_2_0 diff --git a/CORE/MAC/src/pe/include/limGlobal.h b/CORE/MAC/src/pe/include/limGlobal.h index d6a6ad0325fa..d01d6a2c4ba2 100644 --- a/CORE/MAC/src/pe/include/limGlobal.h +++ b/CORE/MAC/src/pe/include/limGlobal.h @@ -667,7 +667,7 @@ typedef struct sLimWscIeInfo } tLimWscIeInfo, *tpLimWscIeInfo; // maximum number of tspec's supported -#define LIM_NUM_TSPEC_MAX 4 +#define LIM_NUM_TSPEC_MAX 15 //structure to hold all 11h specific data diff --git a/CORE/MAC/src/pe/lim/limAssocUtils.c b/CORE/MAC/src/pe/lim/limAssocUtils.c index 77ef247b7d3f..499bfc2d2c6a 100644 --- a/CORE/MAC/src/pe/lim/limAssocUtils.c +++ b/CORE/MAC/src/pe/lim/limAssocUtils.c @@ -2313,7 +2313,7 @@ limAddSta( tSirMsgQ msgQ; tSirRetStatus retCode = eSIR_SUCCESS; tSirMacAddr staMac, *pStaAddr; - tANI_U8 i; + tANI_U8 i, nwType11b = 0; tpSirAssocReq pAssocReq; tLimIbssPeerNode *pPeerNode; /* for IBSS mode */ tDot11fIEVHTCaps vht_caps; /* for IBSS mode */ @@ -2656,7 +2656,26 @@ limAddSta( if (pAddStaParams->respReqd) SET_LIM_PROCESS_DEFD_MESGS(pMac, false); - pAddStaParams->nwType = psessionEntry->nwType; + for (i = 0; i < SIR_NUM_11A_RATES; i++) + { + if (sirIsArate(pStaDs->supportedRates.llaRates[i] & 0x7F)) + { + nwType11b = 0; + break; + } + else + { + nwType11b = 1; + } + } + if (nwType11b) + { + pAddStaParams->nwType = eSIR_11B_NW_TYPE; + } + else + { + pAddStaParams->nwType = psessionEntry->nwType; + } msgQ.type = WDA_ADD_STA_REQ; diff --git a/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c b/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c index 7e0bf3e82fcc..8aee29c0fd04 100644 --- a/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c +++ b/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c @@ -3788,7 +3788,6 @@ void limProcessSwitchChannelRsp(tpAniSirGlobal pMac, void *body) if((psessionEntry = peFindSessionBySessionId(pMac, peSessionId))== NULL) { - vos_mem_free(body); limLog(pMac, LOGP, FL("session does not exist for given sessionId")); return; } diff --git a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c index 011624c7be52..31bd56c11ea4 100644 --- a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c +++ b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c @@ -1268,6 +1268,9 @@ __limProcessSmeScanReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) */ if (__limFreshScanReqd(pMac, pScanReq->returnFreshResults)) { + if (pMac->fScanOffload) + limFlushp2pScanResults(pMac); + if (pScanReq->returnFreshResults & SIR_BG_SCAN_PURGE_RESUTLS) { // Discard previously cached scan results @@ -1496,6 +1499,9 @@ __limProcessSmeScanReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) } #endif + if (pMac->fScanOffload) + limFlushp2pScanResults(pMac); + if (pScanReq->returnFreshResults & SIR_BG_SCAN_PURGE_RESUTLS) { // Discard previously cached scan results diff --git a/CORE/MAC/src/pe/lim/limScanResultUtils.c b/CORE/MAC/src/pe/lim/limScanResultUtils.c index bf5c4e68525a..fa381d93e81f 100644 --- a/CORE/MAC/src/pe/lim/limScanResultUtils.c +++ b/CORE/MAC/src/pe/lim/limScanResultUtils.c @@ -1193,7 +1193,77 @@ limDeleteCachedScanResults(tpAniSirGlobal pMac) pMac->lim.gLimSmeScanResultLength = 0; } /****** end limDeleteCachedScanResults() ******/ +/** + * limFlushp2pScanResults() + * + *FUNCTION: + * This function is called before scan to flush the + * the p2p scan entries from LIM + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * NA + * + * @param pMac - Pointer to Global MAC structure + * @return None + */ + +void +limFlushp2pScanResults(tpAniSirGlobal pMac) +{ + tLimScanResultNode *pNode, *pNextNode, *pPrev, *pHead, *pTemp; + tANI_U16 i; + tANI_U8 *pSsidStr; + tSirMacSSid *pSsid; + for (i = 0; i < LIM_MAX_NUM_OF_SCAN_RESULTS; i++) + { + if ((pNode = pMac->lim.gLimCachedScanHashTable[i]) != NULL) + { + pPrev = pNode; + pHead = pNode; + while (pNode) + { + pSsid = (tSirMacSSid *)((tANI_U8 *)&pNode->bssDescription.ieFields + 1); + pSsidStr = pSsid->ssId; + if (vos_mem_compare(pSsidStr, "DIRECT-", 7)) + { + if (pNode == pHead) + { + pTemp = pNode; + pNode = pNode->next; + pMac->lim.gLimSmeScanResultLength -= + (pTemp->bssDescription.length + + sizeof(pTemp->bssDescription.length)); + pPrev = pNode; + pHead = pNode; + vos_mem_free(pTemp); + pMac->lim.gLimCachedScanHashTable[i]= pHead; + } + else + { + pNextNode = pNode->next; + pMac->lim.gLimSmeScanResultLength -= + (pNode->bssDescription.length + + sizeof(pNode->bssDescription.length)); + vos_mem_free(pNode); + pPrev->next = pNextNode; + pNode = pNextNode; + } + } + else + { + pPrev = pNode; + pNode = pNode->next; + } + } + } + } +} /****** end limFlushp2pScanResults() ******/ /** * limReInitScanResults() diff --git a/CORE/MAC/src/pe/lim/limScanResultUtils.h b/CORE/MAC/src/pe/lim/limScanResultUtils.h index 090dc29b9c60..7f04c94a49fc 100644 --- a/CORE/MAC/src/pe/lim/limScanResultUtils.h +++ b/CORE/MAC/src/pe/lim/limScanResultUtils.h @@ -46,6 +46,7 @@ void limInitHashTable(tpAniSirGlobal); eHalStatus limLookupNaddHashEntry(tpAniSirGlobal, tLimScanResultNode *, tANI_U8, tANI_U8); void limDeleteHashEntry(tLimScanResultNode *); +void limFlushp2pScanResults(tpAniSirGlobal); void limDeleteCachedScanResults(tpAniSirGlobal); void limRestorePreScanState(tpAniSirGlobal); void limCopyScanResult(tpAniSirGlobal, tANI_U8 *); diff --git a/CORE/MAC/src/pe/lim/limUtils.c b/CORE/MAC/src/pe/lim/limUtils.c index 78f59a9c74fb..d8c67fa99763 100644 --- a/CORE/MAC/src/pe/lim/limUtils.c +++ b/CORE/MAC/src/pe/lim/limUtils.c @@ -7255,8 +7255,9 @@ void limHandleHeartBeatFailureTimeout(tpAniSirGlobal pMac) #endif if (psessionEntry->limMlmState == eLIM_MLM_LINK_ESTABLISHED_STATE) { - if ((!LIM_IS_CONNECTION_ACTIVE(psessionEntry))&& - (psessionEntry->limSmeState != eLIM_SME_WT_DISASSOC_STATE)) + if ((!LIM_IS_CONNECTION_ACTIVE(psessionEntry)) && + (psessionEntry->limSmeState != eLIM_SME_WT_DISASSOC_STATE) && + (psessionEntry->limSmeState != eLIM_SME_WT_DEAUTH_STATE)) { limLog(pMac, LOGE, FL("Probe_hb_failure: for session:%d " ),psessionEntry->peSessionId); /* AP did not respond to Probe Request. Tear down link with it.*/ diff --git a/CORE/MAC/src/pe/pmm/pmmApi.c b/CORE/MAC/src/pe/pmm/pmmApi.c index 33a8b578a49a..9ad462cba542 100644 --- a/CORE/MAC/src/pe/pmm/pmmApi.c +++ b/CORE/MAC/src/pe/pmm/pmmApi.c @@ -68,6 +68,11 @@ #include "wlan_qct_wda.h" +#define LIM_ADMIT_MASK_FLAG_ACBE 1 +#define LIM_ADMIT_MASK_FLAG_ACBK 2 +#define LIM_ADMIT_MASK_FLAG_ACVI 4 +#define LIM_ADMIT_MASK_FLAG_ACVO 8 + // -------------------------------------------------------------------- /** * pmmInitialize @@ -2562,8 +2567,6 @@ tSirRetStatus pmmUapsdSendChangePwrSaveMsg (tpAniSirGlobal pMac, tANI_U8 mode) { tSirRetStatus retStatus = eSIR_SUCCESS; tpUapsdParams pUapsdParams = NULL; - tANI_U8 uapsdDeliveryMask = 0; - tANI_U8 uapsdTriggerMask = 0; tSirMsgQ msgQ; tpPESession pSessionEntry; tpExitUapsdParams pExitUapsdParams = NULL; @@ -2589,17 +2592,84 @@ tSirRetStatus pmmUapsdSendChangePwrSaveMsg (tpAniSirGlobal pMac, tANI_U8 mode) msgQ.type = WDA_ENTER_UAPSD_REQ; msgQ.bodyptr = pUapsdParams; - uapsdDeliveryMask = (pMac->lim.gUapsdPerAcBitmask | pMac->lim.gUapsdPerAcDeliveryEnableMask); - uapsdTriggerMask = (pMac->lim.gUapsdPerAcBitmask | pMac->lim.gUapsdPerAcTriggerEnableMask); - - pUapsdParams->bkDeliveryEnabled = LIM_UAPSD_GET(ACBK, uapsdDeliveryMask); - pUapsdParams->beDeliveryEnabled = LIM_UAPSD_GET(ACBE, uapsdDeliveryMask); - pUapsdParams->viDeliveryEnabled = LIM_UAPSD_GET(ACVI, uapsdDeliveryMask); - pUapsdParams->voDeliveryEnabled = LIM_UAPSD_GET(ACVO, uapsdDeliveryMask); - pUapsdParams->bkTriggerEnabled = LIM_UAPSD_GET(ACBK, uapsdTriggerMask); - pUapsdParams->beTriggerEnabled = LIM_UAPSD_GET(ACBE, uapsdTriggerMask); - pUapsdParams->viTriggerEnabled = LIM_UAPSD_GET(ACVI, uapsdTriggerMask); - pUapsdParams->voTriggerEnabled = LIM_UAPSD_GET(ACVO, uapsdTriggerMask); + /* + * An AC is delivery enabled AC if the bit for that AC is set into the + * gAcAdmitMask[SIR_MAC_DIRECTION_DLINK],it is not set then we will take Static values. + */ + + if ( pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] & LIM_ADMIT_MASK_FLAG_ACBE) + { + pUapsdParams->beDeliveryEnabled = LIM_UAPSD_GET(ACBE, pMac->lim.gUapsdPerAcDeliveryEnableMask); + } + else + { + pUapsdParams->beDeliveryEnabled = LIM_UAPSD_GET(ACBE, pMac->lim.gUapsdPerAcBitmask); + } + if ( pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] & LIM_ADMIT_MASK_FLAG_ACBK) + { + pUapsdParams->bkDeliveryEnabled = LIM_UAPSD_GET(ACBK, pMac->lim.gUapsdPerAcDeliveryEnableMask); + } + else + { + pUapsdParams->bkDeliveryEnabled = LIM_UAPSD_GET(ACBK, pMac->lim.gUapsdPerAcBitmask); + } + if ( pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] & LIM_ADMIT_MASK_FLAG_ACVI) + { + pUapsdParams->viDeliveryEnabled = LIM_UAPSD_GET(ACVI, pMac->lim.gUapsdPerAcDeliveryEnableMask); + } + else + { + pUapsdParams->viDeliveryEnabled = LIM_UAPSD_GET(ACVI, pMac->lim.gUapsdPerAcBitmask); + } + + if ( pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_DNLINK] & LIM_ADMIT_MASK_FLAG_ACVO) + { + pUapsdParams->voDeliveryEnabled = LIM_UAPSD_GET(ACVO, pMac->lim.gUapsdPerAcDeliveryEnableMask); + } + else + { + pUapsdParams->voDeliveryEnabled = LIM_UAPSD_GET(ACVO, pMac->lim.gUapsdPerAcBitmask); + } + + /* + * An AC is trigger enabled AC if the bit for that AC is set into the + * gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK],it is not set then we will take Static values. + */ + + if ( pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] & LIM_ADMIT_MASK_FLAG_ACBE) + { + pUapsdParams->beTriggerEnabled = LIM_UAPSD_GET(ACBE, pMac->lim.gUapsdPerAcTriggerEnableMask); + } + else + { + pUapsdParams->beTriggerEnabled = LIM_UAPSD_GET(ACBE, pMac->lim.gUapsdPerAcBitmask); + } + if ( pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] & LIM_ADMIT_MASK_FLAG_ACBK) + { + pUapsdParams->bkTriggerEnabled = LIM_UAPSD_GET(ACBK, pMac->lim.gUapsdPerAcTriggerEnableMask); + } + else + { + pUapsdParams->bkTriggerEnabled = LIM_UAPSD_GET(ACBK, pMac->lim.gUapsdPerAcBitmask); + } + if ( pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] & LIM_ADMIT_MASK_FLAG_ACVI) + { + pUapsdParams->viTriggerEnabled = LIM_UAPSD_GET(ACVI, pMac->lim.gUapsdPerAcTriggerEnableMask); + } + else + { + pUapsdParams->viTriggerEnabled = LIM_UAPSD_GET(ACVI, pMac->lim.gUapsdPerAcBitmask); + } + + if ( pMac->lim.gAcAdmitMask[SIR_MAC_DIRECTION_UPLINK] & LIM_ADMIT_MASK_FLAG_ACVO) + { + pUapsdParams->voTriggerEnabled = LIM_UAPSD_GET(ACVO, pMac->lim.gUapsdPerAcTriggerEnableMask); + } + else + { + pUapsdParams->voTriggerEnabled = LIM_UAPSD_GET(ACVO, pMac->lim.gUapsdPerAcBitmask); + } + pUapsdParams->bssIdx = pSessionEntry->bssIdx; PELOGW(pmmLog(pMac, LOGW, diff --git a/CORE/SERVICES/BMI/ar6320v2_dbg_regtable.h b/CORE/SERVICES/BMI/ar6320v2_dbg_regtable.h index c33f0dfacdcd..ba2ab95ebc20 100644 --- a/CORE/SERVICES/BMI/ar6320v2_dbg_regtable.h +++ b/CORE/SERVICES/BMI/ar6320v2_dbg_regtable.h @@ -1,7 +1,28 @@ /* - * Copyright (c) 2014 Qualcomm Atheros, Inc. - * All Rights Reserved. - * Qualcomm Atheros Confidential and Proprietary. + * Copyright (c) 2012,2014 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. */ #ifndef _AR6320V2_DBG_REGTABLE_H_ diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index 2b719c830e47..a2f04a5bf6b3 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -936,6 +936,20 @@ static int wma_vdev_stop_resp_handler(void *handle, u_int8_t *cmd_param_info, #ifndef QCA_WIFI_ISOC struct beacon_info *bcn; #endif + if (resp_event->vdev_id > wma->max_bssid) { + WMA_LOGE("%s: Invalid vdev_id %d", __func__, + resp_event->vdev_id); + return -EINVAL; + } + + iface = &wma->interfaces[resp_event->vdev_id]; + if (WMA_BSS_STATUS_STOPPED == + adf_os_atomic_read(&iface->bss_status)){ + WMA_LOGE("%s: vdev_id %d is already stopped", __func__, + resp_event->vdev_id); + return -EINVAL; + } + peer = ol_txrx_find_peer_by_addr(pdev, params->bssid, &peer_id); if (!peer) WMA_LOGD("%s Failed to find peer %pM", @@ -948,11 +962,9 @@ static int wma_vdev_stop_resp_handler(void *handle, u_int8_t *cmd_param_info, } else { wma->interfaces[resp_event->vdev_id].vdev_up = FALSE; } - iface = &wma->interfaces[resp_event->vdev_id]; ol_txrx_vdev_flush(iface->handle); wdi_in_vdev_unpause(iface->handle); iface->pause_bitmap = 0; - adf_os_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STOPPED); WMA_LOGD("%s: (type %d subtype %d) BSS is stopped", __func__, iface->type, iface->sub_type); #ifndef QCA_WIFI_ISOC @@ -986,6 +998,7 @@ static int wma_vdev_stop_resp_handler(void *handle, u_int8_t *cmd_param_info, WMA_LOGD("%s: scheduling defered deletion", __func__); wma_vdev_detach(wma, iface->del_staself_req, 1); } + adf_os_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STOPPED); } vos_timer_destroy(&req_msg->event_timeout); adf_os_mem_free(req_msg); @@ -6035,10 +6048,29 @@ void wma_vdev_resp_timer(void *data) params->status = VOS_STATUS_E_TIMEOUT; WMA_LOGA("%s: WDA_SWITCH_CHANNEL_REQ timedout", __func__); wma_send_msg(wma, WDA_SWITCH_CHANNEL_RSP, (void *)params, 0); + wma->roam_preauth_chan_context = NULL; } else if (tgt_req->msg_type == WDA_DELETE_BSS_REQ) { tpDeleteBssParams params = (tpDeleteBssParams)tgt_req->user_data; - struct wma_txrx_node *iface = &wma->interfaces[tgt_req->vdev_id]; +#ifndef QCA_WIFI_ISOC + struct beacon_info *bcn; +#endif + struct wma_txrx_node *iface; + + if (tgt_req->vdev_id > wma->max_bssid) { + WMA_LOGE("%s: Invalid vdev_id %d", __func__, + tgt_req->vdev_id); + return; + } + + iface = &wma->interfaces[tgt_req->vdev_id]; + if (WMA_BSS_STATUS_STOPPED == + adf_os_atomic_read(&iface->bss_status)){ + WMA_LOGE("%s: vdev_id %d is already stopped", __func__, + tgt_req->vdev_id); + return; + } + peer = ol_txrx_find_peer_by_addr(pdev, params->bssid, &peer_id); wma_remove_peer(wma, params->bssid, tgt_req->vdev_id, peer); if (wmi_unified_vdev_down_send(wma->wmi_handle, tgt_req->vdev_id) < 0) { @@ -6050,9 +6082,25 @@ void wma_vdev_resp_timer(void *data) ol_txrx_vdev_flush(iface->handle); wdi_in_vdev_unpause(iface->handle); iface->pause_bitmap = 0; - adf_os_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STOPPED); WMA_LOGD("%s: (type %d subtype %d) BSS is stopped", __func__, iface->type, iface->sub_type); + +#ifndef QCA_WIFI_ISOC + bcn = wma->interfaces[tgt_req->vdev_id].beacon; + + if (bcn) { + WMA_LOGD("%s: Freeing beacon struct %p, " + "template memory %p", __func__, + bcn, bcn->buf); + if (bcn->dma_mapped) + adf_nbuf_unmap_single(pdev->osdev, bcn->buf, + ADF_OS_DMA_TO_DEVICE); + adf_nbuf_free(bcn->buf); + vos_mem_free(bcn); + wma->interfaces[tgt_req->vdev_id].beacon = NULL; + } +#endif + #ifdef QCA_IBSS_SUPPORT if (wma_is_vdev_in_ibss_mode(wma, params->sessionId)) { del_sta_param.sessionId = params->sessionId; @@ -6068,6 +6116,7 @@ void wma_vdev_resp_timer(void *data) WMA_LOGD("%s: scheduling defered deletion", __func__); wma_vdev_detach(wma, iface->del_staself_req, 1); } + adf_os_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STOPPED); } else if (tgt_req->msg_type == WDA_DEL_STA_SELF_REQ) { struct wma_txrx_node *iface = (struct wma_txrx_node *)tgt_req->user_data; @@ -13564,6 +13613,7 @@ static void wma_data_tx_ack_work_handler(struct work_struct *ack_work) ack_cb((tpAniSirGlobal)(wma_handle->mac_context), work->status ? 0 : 1); wma_handle->umac_data_ota_ack_cb = NULL; + wma_handle->last_umac_data_nbuf = NULL; adf_os_mem_free(work); wma_handle->ack_work_ctx = NULL; } @@ -13596,6 +13646,21 @@ wma_data_tx_ack_comp_hdlr(void *wma_context, return; } + /* + * if netBuf does not match with pending nbuf then just free the + * netbuf and do not call ack cb + */ + if (wma_handle->last_umac_data_nbuf != netbuf) { + if (wma_handle->umac_data_ota_ack_cb) { + WMA_LOGE("%s: nbuf does not match but umac_data_ota_ack_cb is not null", + __func__); + } else { + WMA_LOGE("%s: nbuf does not match and umac_data_ota_ack_cb is also null", + __func__); + } + goto free_nbuf; + } + if(wma_handle && wma_handle->umac_data_ota_ack_cb) { struct wma_tx_ack_work_ctx *ack_work; @@ -13614,6 +13679,7 @@ wma_data_tx_ack_comp_hdlr(void *wma_context, } } +free_nbuf: /* unmap and freeing the tx buf as txrx is not taking care */ adf_nbuf_unmap_single(pdev->osdev, netbuf, ADF_OS_DMA_TO_DEVICE); adf_nbuf_free(netbuf); @@ -15584,6 +15650,7 @@ VOS_STATUS wma_mc_process_msg(v_VOID_t *vos_context, vos_msg_t *msg) case WDA_DHCP_STOP_IND: wma_process_dhcp_ind(wma_handle, (tAniDHCPInd *)msg->bodyptr); + vos_mem_free(msg->bodyptr); break; case WDA_INIT_THERMAL_INFO_CMD: @@ -15903,6 +15970,9 @@ static VOS_STATUS wma_tx_detach(tp_wma_handle wma_handle) /* Reset Tx Data Frame Ack Cb */ wma_handle->umac_data_ota_ack_cb = NULL; + /* Reset last Tx Data Frame nbuf ptr */ + wma_handle->last_umac_data_nbuf = NULL; + return VOS_STATUS_SUCCESS; } @@ -17972,6 +18042,7 @@ VOS_STATUS WDA_TxPacket(void *wma_context, void *tx_frame, u_int16_t frmLen, struct wma_decap_info_t decap_info; struct ieee80211_frame *wh = (struct ieee80211_frame *)adf_nbuf_data(skb); + v_TIME_t curr_timestamp = vos_timer_get_system_ticks(); if (pdev == NULL) { WMA_LOGE("%s: pdev pointer is not available", __func__); @@ -17984,9 +18055,21 @@ VOS_STATUS WDA_TxPacket(void *wma_context, void *tx_frame, u_int16_t frmLen, * 2) Only one Outstanding Data pending for Ack is allowed */ if (tx_frm_ota_comp_cb) { - if(wma_handle->umac_data_ota_ack_cb) { - WMA_LOGE("Already one Data pending for Ack.Don't Allow"); - return VOS_STATUS_E_FAILURE; + if (wma_handle->umac_data_ota_ack_cb) { + /* + * If last data frame was sent more than 5 seconds + * ago and still we did not receive ack/nack from + * fw then allow Tx of this data frame + */ + if (curr_timestamp >= + wma_handle->last_umac_data_ota_timestamp + 500) { + WMA_LOGE("%s: No Tx Ack for last data frame for more than 5 secs, allow Tx of current data frame", + __func__); + } else { + WMA_LOGE("%s: Already one Data pending for Ack, reject Tx of data frame", + __func__); + return VOS_STATUS_E_FAILURE; + } } } else { /* @@ -18017,6 +18100,10 @@ VOS_STATUS WDA_TxPacket(void *wma_context, void *tx_frame, u_int16_t frmLen, /* Store the Ack Complete Cb */ wma_handle->umac_data_ota_ack_cb = tx_frm_ota_comp_cb; + /* Store the timestamp and nbuf for this data Tx */ + wma_handle->last_umac_data_ota_timestamp = curr_timestamp; + wma_handle->last_umac_data_nbuf = skb; + /* Send the Data frame to TxRx in Non Standard Path */ ret = ol_tx_non_std(txrx_vdev, ol_tx_spec_no_free, skb); if (ret) { @@ -18026,6 +18113,7 @@ VOS_STATUS WDA_TxPacket(void *wma_context, void *tx_frame, u_int16_t frmLen, if (tx_frm_download_comp_cb) tx_frm_download_comp_cb(wma_handle->mac_context, tx_frame, 1); wma_handle->umac_data_ota_ack_cb = NULL; + wma_handle->last_umac_data_nbuf = NULL; return VOS_STATUS_E_FAILURE; } @@ -18972,17 +19060,20 @@ static int wma_update_fw_tdls_state(WMA_HANDLE handle, void *pwmaTdlsparams) t_wma_tdls_mode tdls_mode; t_wma_tdls_params *wma_tdls = (t_wma_tdls_params *)pwmaTdlsparams; u_int16_t len = sizeof(wmi_tdls_set_state_cmd_fixed_param); + int ret = 0; if (!wma_handle || !wma_handle->wmi_handle) { WMA_LOGE("%s: WMA is closed, can not issue fw tdls state cmd", __func__); - return -EINVAL; + ret = -EINVAL; + goto end_fw_tdls_state; } wmi_buf = wmi_buf_alloc(wma_handle->wmi_handle, len); if (!wmi_buf) { WMA_LOGE("%s: wmai_buf_alloc failed", __func__); - return ENOMEM; + ret = ENOMEM; + goto end_fw_tdls_state; } tdls_mode = wma_tdls->tdls_state; cmd = (wmi_tdls_set_state_cmd_fixed_param *)wmi_buf_data(wmi_buf); @@ -19013,12 +19104,15 @@ static int wma_update_fw_tdls_state(WMA_HANDLE handle, void *pwmaTdlsparams) WMI_TDLS_SET_STATE_CMDID)) { WMA_LOGP("%s: failed to send tdls set state command", __func__); adf_nbuf_free(wmi_buf); - return -EIO; + ret = -EIO; + goto end_fw_tdls_state; } WMA_LOGD("%s: vdev_id %d", __func__, wma_tdls->vdev_id); + +end_fw_tdls_state: if (pwmaTdlsparams) vos_mem_free(pwmaTdlsparams); - return 0; + return ret; } static int wma_update_tdls_peer_state(WMA_HANDLE handle, @@ -19035,16 +19129,19 @@ static int wma_update_tdls_peer_state(WMA_HANDLE handle, struct ol_txrx_peer_t *peer; int32_t len = sizeof(wmi_tdls_peer_update_cmd_fixed_param) + sizeof(wmi_tdls_peer_capabilities); + int ret = 0; if (!wma_handle || !wma_handle->wmi_handle) { WMA_LOGE("%s: WMA is closed, can not issue cmd", __func__); - return -EINVAL; + ret = -EINVAL; + goto end_tdls_peer_state; } wmi_buf = wmi_buf_alloc(wma_handle->wmi_handle, len); if (!wmi_buf) { WMA_LOGE("%s: wmi_buf_alloc failed", __func__); - return ENOMEM; + ret = ENOMEM; + goto end_tdls_peer_state; } buf_ptr = (u_int8_t *) wmi_buf_data(wmi_buf); @@ -19101,7 +19198,8 @@ static int wma_update_tdls_peer_state(WMA_HANDLE handle, WMA_LOGE("%s: failed to send tdls peer update state command", __func__); adf_nbuf_free(wmi_buf); - return -EIO; + ret = -EIO; + goto end_tdls_peer_state; } /* in case of teardown, remove peer from fw */ @@ -19109,7 +19207,8 @@ static int wma_update_tdls_peer_state(WMA_HANDLE handle, pdev = vos_get_context(VOS_MODULE_ID_TXRX, wma_handle->vos_context); if (!pdev) { WMA_LOGE("%s: Failed to find pdev", __func__); - return -EIO; + ret = -EIO; + goto end_tdls_peer_state; } peer = ol_txrx_find_peer_by_addr(pdev, peerStateParams->peerMacAddr, @@ -19117,7 +19216,8 @@ static int wma_update_tdls_peer_state(WMA_HANDLE handle, if (!peer) { WMA_LOGE("%s: Failed to get peer handle using peer mac %pM", __func__, peerStateParams->peerMacAddr); - return -EIO; + ret = -EIO; + goto end_tdls_peer_state; } WMA_LOGD("%s: calling wma_remove_peer for peer " MAC_ADDRESS_STR @@ -19126,7 +19226,11 @@ static int wma_update_tdls_peer_state(WMA_HANDLE handle, wma_remove_peer(wma_handle, peer->mac_addr.raw, peerStateParams->vdevId, peer); } - return 0; + +end_tdls_peer_state: + if (peerStateParams) + vos_mem_free(peerStateParams); + return ret; } #endif /* FEATURE_WLAN_TDLS */ diff --git a/CORE/SERVICES/WMA/wma.h b/CORE/SERVICES/WMA/wma.h index 670ffb0fbad2..c89ceb1c022b 100644 --- a/CORE/SERVICES/WMA/wma.h +++ b/CORE/SERVICES/WMA/wma.h @@ -538,6 +538,11 @@ typedef struct { pWDAAckFnTxComp umac_ota_ack_cb[SIR_MAC_MGMT_RESERVED15]; pWDAAckFnTxComp umac_data_ota_ack_cb; + /* timestamp when OTA of last umac data was done */ + v_TIME_t last_umac_data_ota_timestamp; + /* cache nbuf ptr for the last umac data buf */ + adf_nbuf_t last_umac_data_nbuf; + v_BOOL_t needShutdown; #if !defined(QCA_WIFI_ISOC) && !defined(CONFIG_HL_SUPPORT) u_int32_t num_mem_chunks; diff --git a/CORE/SME/src/QoS/sme_Qos.c b/CORE/SME/src/QoS/sme_Qos.c index 42524402d342..c5d8ccbcfdfb 100644 --- a/CORE/SME/src/QoS/sme_Qos.c +++ b/CORE/SME/src/QoS/sme_Qos.c @@ -5719,7 +5719,7 @@ eHalStatus sme_QosAggregateParams( if(pCurrent_Tspec_Info->ts_info.direction != pInput_Tspec_Info->ts_info.direction) { - TspecInfo.ts_info.direction = SME_QOS_WMM_TS_DIR_BOTH; + TspecInfo.ts_info.direction = pInput_Tspec_Info->ts_info.direction; } /*------------------------------------------------------------------------- Max MSDU size : these sizes are `maxed' diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c index 964bf9982f3d..9a471e6486c8 100644 --- a/CORE/SME/src/csr/csrApiRoam.c +++ b/CORE/SME/src/csr/csrApiRoam.c @@ -4360,7 +4360,6 @@ static eCsrJoinState csrRoamJoinNextBss( tpAniSirGlobal pMac, tSmeCmd *pCommand, #ifndef WLAN_MDM_CODE_REDUCTION_OPT acm_mask = sme_QosGetACMMask(pMac, &pScanResult->Result.BssDescriptor, pIesLocal); - pCommand->u.roamCmd.roamProfile.uapsd_mask &= ~(acm_mask); #endif /* WLAN_MDM_CODE_REDUCTION_OPT*/ } else @@ -12855,7 +12854,6 @@ eHalStatus csrSendJoinReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirBssDe #ifndef WLAN_MDM_CODE_REDUCTION_OPT acm_mask = sme_QosGetACMMask(pMac, pBssDescription, pIes); #endif /* WLAN_MDM_CODE_REDUCTION_OPT*/ - uapsd_mask &= ~(acm_mask); } else { |
