summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkash Patel <akashp@codeaurora.org>2014-03-25 10:57:30 -0700
committerAkash Patel <akashp@codeaurora.org>2014-03-25 10:59:37 -0700
commit1008beb3e8a18e19490142b4e17ba8bbd09bc6ce (patch)
tree30b5bd4c44f733b9ed6c88b22a2ec77727ce9684
parent3002a2822136ad71a33ac6888d5d974402c5af7a (diff)
parent520dbf1aa53bdae411db47f6a73f4ebd1e421bd2 (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
-rw-r--r--CORE/CLD_TXRX/HTT/htt.h2
-rw-r--r--CORE/CLD_TXRX/HTT/htt_internal.h3
-rw-r--r--CORE/CLD_TXRX/HTT/htt_rx.c154
-rw-r--r--CORE/CLD_TXRX/HTT/htt_types.h7
-rw-r--r--CORE/CLD_TXRX/TXRX/ol_rx.c14
-rw-r--r--CORE/HDD/inc/wlan_hdd_main.h1
-rw-r--r--CORE/HDD/src/wlan_hdd_cfg80211.c5
-rw-r--r--CORE/HDD/src/wlan_hdd_main.c3
-rw-r--r--CORE/HDD/src/wlan_hdd_p2p.c27
-rw-r--r--CORE/MAC/inc/qwlan_version.h4
-rw-r--r--CORE/MAC/src/pe/include/limGlobal.h2
-rw-r--r--CORE/MAC/src/pe/lim/limAssocUtils.c23
-rw-r--r--CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c1
-rw-r--r--CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c6
-rw-r--r--CORE/MAC/src/pe/lim/limScanResultUtils.c70
-rw-r--r--CORE/MAC/src/pe/lim/limScanResultUtils.h1
-rw-r--r--CORE/MAC/src/pe/lim/limUtils.c5
-rw-r--r--CORE/MAC/src/pe/pmm/pmmApi.c96
-rw-r--r--CORE/SERVICES/BMI/ar6320v2_dbg_regtable.h27
-rw-r--r--CORE/SERVICES/WMA/wma.c138
-rw-r--r--CORE/SERVICES/WMA/wma.h5
-rw-r--r--CORE/SME/src/QoS/sme_Qos.c2
-rw-r--r--CORE/SME/src/csr/csrApiRoam.c2
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
{