From 317cd1cea864095e2e56a981ed9005e0ba3aeffc Mon Sep 17 00:00:00 2001 From: Dhanashri Atre Date: Fri, 21 Mar 2014 16:36:22 -0700 Subject: wlan: qcacld: Debug for DMA done bit not set issue Adding the following debug information DMA done bit not set issue: 1. Ensure we are not encountering the rx chaining case 2. Ensure the host index is not getting clobbered 3. Dump contents of the HTT RX IND 4. Add memory barrier to ensure that the done bit is set to 0 5. Mark all the frames with last_msdu bit set to 0 6. Log whether the ring refill timer is ever running 7. Loop till the done bit is set in the RX_IND for some max_num iterations. 8. Invoke API to gather target RAM dumps Change-Id: I8493bc2a06e93edea13db6f77940d09678351167 CRs-Fixed: 628643 --- CORE/CLD_TXRX/HTT/htt.h | 2 + CORE/CLD_TXRX/HTT/htt_internal.h | 3 +- CORE/CLD_TXRX/HTT/htt_rx.c | 154 +++++++++++++++++++++++++++++++++++---- CORE/CLD_TXRX/HTT/htt_types.h | 7 ++ CORE/CLD_TXRX/TXRX/ol_rx.c | 14 ++++ 5 files changed, 163 insertions(+), 17 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_frame, ieee80211_qoscntl */ #include /* ieee80211_rx_status */ +#ifdef DEBUG_DMA_DONE +#include +#include +#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 = -- cgit v1.2.3 From 53fba50222fc0ef96ce0c78c7ac7e04991bbaee3 Mon Sep 17 00:00:00 2001 From: Subramanyam Nalli Date: Sun, 23 Mar 2014 05:46:28 +0530 Subject: qcacld: Increase the maximum number of tspec's supported According to WMMAC WFA cert 5.2.3 test case 24 ADDTS requests needsto send by the STA-DUT with UAPSD enable/disable having differentTID/UP traffic which requries support to maintain 14 uniqueAdd Tspec entries.In our present implementaion we support only 4unique entries.So,increased number of unique entries from 4 to 15. Change-Id: I01576a6b6c5f9ce068b5762e854b7b8d70d0bc8c CRs-Fixed: 637019 --- CORE/MAC/src/pe/include/limGlobal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 -- cgit v1.2.3 From c4837a5476b563d1e0f2cb8772d6cf34c82dd431 Mon Sep 17 00:00:00 2001 From: Subramanyam Nalli Date: Sun, 23 Mar 2014 05:37:14 +0530 Subject: qcacld: SME: Fix to update direction from input addts request Currently, if the direction from the input addts request does notmatch with current direction in driver, direction is hard coded toBidirectional. This fix updates direction from input addts request. Change-Id: I30fa93ce2219535b4c1213bc7049fd6c9eb227d3 CRs-Fixed: 637017 --- CORE/SME/src/QoS/sme_Qos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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' -- cgit v1.2.3 From be70a98b972a13deb5fb568bcd72f1dd10cadf45 Mon Sep 17 00:00:00 2001 From: Nirav Shah Date: Sat, 22 Mar 2014 16:48:37 +0530 Subject: P2P: Fixes race codition for remain_on_chan_ctx Added mutex lock to protect access of remain_on_chan_ctx between MCTread and NL context. Change-Id: Ic63cbc1971e4c5b7429290c5dca1ca8b87624d44 CRs-Fixed: 636944 --- CORE/HDD/inc/wlan_hdd_main.h | 1 + CORE/HDD/src/wlan_hdd_main.c | 3 +++ CORE/HDD/src/wlan_hdd_p2p.c | 27 +++++++++++++++++++++++++-- 3 files changed, 29 insertions(+), 2 deletions(-) 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_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)) || -- cgit v1.2.3 From 763bcf6ec341bf3f9d50ded2c0e31566b1638a80 Mon Sep 17 00:00:00 2001 From: Yuanyuan Liu Date: Fri, 21 Mar 2014 17:53:56 -0700 Subject: qcacld: Run ddr voting in suspend/resume Experimental change that vote for NONE/MEDIUM DDR frequency in suspend/resume in order to avoid DMA race condition. Change-Id: Iefdb874d49ec9b556910e61840583cd7330bbc11 CRs-Fixed: 636955 --- CORE/HDD/src/wlan_hdd_cfg80211.c | 5 +++++ 1 file changed, 5 insertions(+) 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 #include #include +#include #include #include #include @@ -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; -- cgit v1.2.3 From 2bb543af2d477c5006817e6357763a89f09a239a Mon Sep 17 00:00:00 2001 From: "Chandrasekaran, Manishekar" Date: Fri, 21 Mar 2014 11:42:46 +0530 Subject: qcacld: Flush p2p results in LIM cache before starting scan Stale entries exist in LIM cache and these are being passed on to SME. This results in the supplicant choosing invalid parameters from the stale entries to send action packets. This fix will clear only the p2p scan results before scan. Change-Id: Ie50a4b4bdd6ff27940fb4cf81fd531db21289788 CRs-Fixed: 634775 --- CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c | 6 +++ CORE/MAC/src/pe/lim/limScanResultUtils.c | 70 ++++++++++++++++++++++++++ CORE/MAC/src/pe/lim/limScanResultUtils.h | 1 + 3 files changed, 77 insertions(+) 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 *); -- cgit v1.2.3 From f10946bc510375cb230d470e180c27379340f754 Mon Sep 17 00:00:00 2001 From: Kiran Kumar Lokere Date: Wed, 19 Mar 2014 17:48:05 -0700 Subject: Fix the Tx 11b data rate issue on SAP Pass the appropriate network type to FW to pick the data rates corresponding to that network type. Change-Id: Id59347fae2d1e52c0981c4417c090eba9f6008f1 CRs-Fixed: 615756 --- CORE/MAC/src/pe/lim/limAssocUtils.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) 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; -- cgit v1.2.3 From dba22969e279cfd8f8606e7b9932b682f8e86320 Mon Sep 17 00:00:00 2001 From: Rajeev Kumar Date: Sat, 22 Mar 2014 13:40:22 -0700 Subject: qcacld: Fix of double free panic in limProcessSwitchChannelRsp Following is scenario which is leading to crash: 1) WDA_SWITCH_CHANNEL_REQ times out in WMA and wma_vdev_resp_timer() function sends WDA_SWITCH_CHANNEL_RSP to LIM where channel switch context is freed. 2) FW sends channel switch response event to host and WMA function wma_roam_preauth_scan_event_handler() sends WDA_SWITCH_CHANNEL_RSP to LIM and LIM again frees channel switch context leading to double free and panic. Fix is following: 1) If WDA_SWITCH_CHANNEL_REQ times out in WMA then reset preauth chan switch context in wma handle to null after sending channel switch response to LIM such that if FW sends response event then 2nd channel switch reponse is not posted again to LIM. 2) And in limProcessSwitchChannelRsp if session ID is not found then this means channel switch context is already freed so do not free it again. Change-Id: I204a775ff826e7597f42a8f94dbf63db802f58fa CRs-Fixed: 637029 --- CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c | 1 - CORE/SERVICES/WMA/wma.c | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) 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/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index 2b719c830e47..e43e5b648dc4 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -6035,6 +6035,7 @@ 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; -- cgit v1.2.3 From b9ff60c8282ca07a834efaf3a4adf8308b5edc10 Mon Sep 17 00:00:00 2001 From: Bala Shanmugam Kamatchi Date: Sat, 22 Mar 2014 04:04:50 +0530 Subject: qcacld: sme: Set proper PSB value in assoc request Avoid uapsd unmasking on the basis if ACM is enabled so WMM QoS Info field of ASSOC / REASSOC Req carry proper PSB value.Host is now giving priorty to dynamic values over static values of trigger & delivery enabled (PSB) part of ENTER_UAPSD_REQUEST. Change-Id: I16a6688b225ec9bdaab7af87aa83a6218b9a6579 CRs-Fixed: 637020 --- CORE/MAC/src/pe/pmm/pmmApi.c | 96 +++++++++++++++++++++++++++++++++++++------ CORE/SME/src/csr/csrApiRoam.c | 2 - 2 files changed, 83 insertions(+), 15 deletions(-) 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/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 { -- cgit v1.2.3 From 7d4bafd6db38acb6de61113b995a37b30599a89a Mon Sep 17 00:00:00 2001 From: Rajesh Chauhan Date: Wed, 19 Mar 2014 12:09:06 -0700 Subject: qcacld: free ota tx callback for data frame if no ack/nack from FW If FW fails to provide ack/nack for a data frame with OTA Tx completion requirement then ota tx cb remains set in WMA, resulting in failure in Tx of subsequent data frame with OTA Tx Ack requirement. This commit clears that ota tx ack cb, in case there is no ack/nack from FW for 5 or more seconds. Also fixed memory leaks in handling of TDLS commands to FW. Change-Id: Ifc2a8bde4aff17881a7d0cd07402d558a953a4aa CRs-Fixed: 632305 --- CORE/SERVICES/WMA/wma.c | 80 +++++++++++++++++++++++++++++++++++++++++-------- CORE/SERVICES/WMA/wma.h | 5 ++++ 2 files changed, 72 insertions(+), 13 deletions(-) diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index e43e5b648dc4..71122a2f399f 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -13565,6 +13565,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; } @@ -13597,6 +13598,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; @@ -13615,6 +13631,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); @@ -15904,6 +15921,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; } @@ -17973,6 +17993,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__); @@ -17985,9 +18006,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 { /* @@ -18018,6 +18051,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) { @@ -18027,6 +18064,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; } @@ -18973,17 +19011,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); @@ -19014,12 +19055,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, @@ -19036,16 +19080,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); @@ -19102,7 +19149,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 */ @@ -19110,7 +19158,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, @@ -19118,7 +19167,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 @@ -19127,7 +19177,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; -- cgit v1.2.3 From 19a83646f14ddf82fcf17319c327a63999b0768e Mon Sep 17 00:00:00 2001 From: Akash Patel Date: Mon, 24 Mar 2014 12:02:03 -0700 Subject: Corrected copyright issue. In file - CORE/SERVICES/BMI/ar6320v2_dbg_regtable.h Change-Id: I5f5f65a6ba58de800e2ceb54dec070ca652e31f5 --- CORE/SERVICES/BMI/ar6320v2_dbg_regtable.h | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) 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_ -- cgit v1.2.3 From 3f89a01c91e24c7b9ed39645b80e91e5e584a82d Mon Sep 17 00:00:00 2001 From: Akash Patel Date: Mon, 24 Mar 2014 12:09:50 -0700 Subject: Cafstaging Release 1.0.0.70 Cafstaging Release 1.0.0.70 Change-Id: If33dd51dd73ebdeea25ce8db575146a8f7ce463d --- CORE/MAC/inc/qwlan_version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CORE/MAC/inc/qwlan_version.h b/CORE/MAC/inc/qwlan_version.h index 21195c79c49e..ecea34a2c167 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 70 -#define QWLAN_VERSIONSTR "1.0.0.69" +#define QWLAN_VERSIONSTR "1.0.0.70" #ifdef QCA_WIFI_2_0 -- cgit v1.2.3 From 78d0742bdc128399a94c8ef0102e7c767fb87afa Mon Sep 17 00:00:00 2001 From: Rajeev Kumar Date: Mon, 24 Mar 2014 12:00:39 -0700 Subject: qcacld: Fix of memory leka in WMA for DHCP messages Memory allocated for WDA_DHCP_START_IND and WDA_DHCP_STOP_IND in SME is not freed in WMA. Change-Id: I8071c0621caf3b17a66f59ab339b7fbd513b292b CRs-Fixed: 637517 --- CORE/SERVICES/WMA/wma.c | 1 + 1 file changed, 1 insertion(+) diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index 71122a2f399f..390c3456cd18 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -15602,6 +15602,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: -- cgit v1.2.3 From 27b59ecd870b26e60c97c3c9dc6133188b6476ad Mon Sep 17 00:00:00 2001 From: Rajeev Kumar Date: Mon, 24 Mar 2014 12:51:39 -0700 Subject: qcacld: Fix of WMA sending DELETE BSS RSP 2 times to LIM Following is scenario which is leading to crash: 1) WDA_DELETE_BSS_REQ times out in WMA and wma_vdev_resp_timer() function sends WDA_DELETE_BSS_RSP to LIM where delete BSS RSP is processed. 2) FW sends VDEV stop event to host and WMA function wma_vdev_stop_resp_handler sends WDA_DELETE_BSS_RSP to LIM and LIM again process delete BSS response. Fix is following: 1) In vdev stop response timer and vdev stop response event handler 1st check for vdev BSS state and if its in STOPPED state this means this vdev is already deleted and DELETE BDD response is sent to LIM so no need to proceed further. 2) In addition free beacon template memory in vdev stop response timer to avoid memory leak if vdev stop response event is never received from target. Change-Id: I95db0e8fc308ec67388222380714bfcca3936f3e CRs-Fixed: 637536 --- CORE/SERVICES/WMA/wma.c | 56 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 52 insertions(+), 4 deletions(-) diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index 390c3456cd18..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); @@ -6039,7 +6052,25 @@ void wma_vdev_resp_timer(void *data) } 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) { @@ -6051,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; @@ -6069,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; -- cgit v1.2.3 From 89ccc5d562d3ed3deb9d58edfbfdd6ec381865f9 Mon Sep 17 00:00:00 2001 From: Kiran Kumar Lokere Date: Mon, 24 Mar 2014 16:43:27 -0700 Subject: Fix the disconnect event being sent twice to SME. When SME is in disassoc/deauth complete wait state and heartbeat timeout failure happens, then do not send the disconnect indication to SME as the disconnect as already in progress as part of deauth/ disassoc completion. Change-Id: Iac643c18bcde2e9640f08c89675a466ef54f7f3f CRs-Fixed: 636768 --- CORE/MAC/src/pe/lim/limUtils.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) 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.*/ -- cgit v1.2.3 From 520dbf1aa53bdae411db47f6a73f4ebd1e421bd2 Mon Sep 17 00:00:00 2001 From: Akash Patel Date: Mon, 24 Mar 2014 19:43:31 -0700 Subject: Cafstaging Release 1.0.0.71 Cafstaging Release 1.0.0.71 Change-Id: Ia034dc6b119e6f828108853130a5111bc2fae399 --- CORE/MAC/inc/qwlan_version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CORE/MAC/inc/qwlan_version.h b/CORE/MAC/inc/qwlan_version.h index ecea34a2c167..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 70 +#define QWLAN_VERSION_BUILD 71 -#define QWLAN_VERSIONSTR "1.0.0.70" +#define QWLAN_VERSIONSTR "1.0.0.71" #ifdef QCA_WIFI_2_0 -- cgit v1.2.3