summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2018-07-02 03:57:31 -0700
committerLinux Build Service Account <lnxbuild@localhost>2018-07-02 03:57:31 -0700
commit27910c51e3f68e7a90a9262ed01ee0ed0aaa82d2 (patch)
tree13c5e3896cb648f02f2321a0d7a059e318ecd51d
parent571578139c1d395361fe17692d1971549b7a6bb4 (diff)
parenta6d6253be0619cdd2329e2c9a2d2753c3ae83c93 (diff)
Merge a6d6253be0619cdd2329e2c9a2d2753c3ae83c93 on remote branch
Change-Id: Ic84455b4045d3bcf1a1df00f535df41f36377bb2
-rw-r--r--dp/inc/cdp_txrx_cmn.h13
-rw-r--r--hif/src/ce/ce_main.c2
-rw-r--r--hif/src/ce/ce_tasklet.c18
-rw-r--r--hif/src/ce/ce_tasklet.h3
-rw-r--r--htc/htc.c2
-rw-r--r--htc/htc_api.h26
-rw-r--r--htc/htc_internal.h2
-rw-r--r--htc/htc_recv.c8
-rw-r--r--htc/htc_send.c33
-rw-r--r--qdf/inc/qdf_idr.h82
-rw-r--r--qdf/inc/qdf_types.h11
-rw-r--r--qdf/linux/src/i_qdf_idr.h42
-rw-r--r--qdf/linux/src/qdf_idr.c142
-rw-r--r--wmi/inc/wmi_unified_param.h4
-rw-r--r--wmi/src/wmi_unified.c1
-rw-r--r--wmi/src/wmi_unified_tlv.c4
16 files changed, 355 insertions, 38 deletions
diff --git a/dp/inc/cdp_txrx_cmn.h b/dp/inc/cdp_txrx_cmn.h
index cbb5d4c2bb20..a8c202da9c02 100644
--- a/dp/inc/cdp_txrx_cmn.h
+++ b/dp/inc/cdp_txrx_cmn.h
@@ -145,9 +145,19 @@ enum connectivity_stats_pkt_status {
* ol_txrx_tx_fp - top-level transmit function
* @data_vdev - handle to the virtual device object
* @msdu_list - list of network buffers
+ * @notify_tx_comp - tx completion to be notified
*/
typedef qdf_nbuf_t (*ol_txrx_tx_fp)(ol_txrx_vdev_handle data_vdev,
- qdf_nbuf_t msdu_list);
+ qdf_nbuf_t msdu_list,
+ bool notify_tx_comp);
+/**
+ * ol_txrx_completion_fp - top-level transmit function
+ * for tx completion
+ * @skb: skb data
+ * @osif_dev: the virtual device's OS shim object
+ */
+typedef void (*ol_txrx_completion_fp)(struct sk_buff *skb,
+ void *osif_dev);
/**
* ol_txrx_tx_flow_control_fp - tx flow control notification
* function from txrx to OS shim
@@ -264,6 +274,7 @@ struct ol_txrx_ops {
/* tx function pointers - specified by txrx, stored by OS shim */
struct {
ol_txrx_tx_fp tx;
+ ol_txrx_completion_fp tx_comp;
} tx;
/* rx function pointers - specified by OS shim, stored by txrx */
diff --git a/hif/src/ce/ce_main.c b/hif/src/ce/ce_main.c
index 6fbd121cd1ac..458fff0afb8b 100644
--- a/hif/src/ce/ce_main.c
+++ b/hif/src/ce/ce_main.c
@@ -2306,6 +2306,7 @@ void hif_unconfig_ce(struct hif_softc *hif_sc)
int pipe_num;
struct HIF_CE_pipe_info *pipe_info;
struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(hif_sc);
+ struct hif_opaque_softc *hif_hdl = GET_HIF_OPAQUE_HDL(hif_sc);
for (pipe_num = 0; pipe_num < hif_sc->ce_count; pipe_num++) {
pipe_info = &hif_state->pipe_info[pipe_num];
@@ -2318,6 +2319,7 @@ void hif_unconfig_ce(struct hif_softc *hif_sc)
qdf_spinlock_destroy(&pipe_info->recv_bufs_needed_lock);
}
}
+ deinit_tasklet_workers(hif_hdl);
if (hif_sc->athdiag_procfs_inited) {
athdiag_procfs_remove();
hif_sc->athdiag_procfs_inited = false;
diff --git a/hif/src/ce/ce_tasklet.c b/hif/src/ce/ce_tasklet.c
index 625bbc776d0c..462b43495843 100644
--- a/hif/src/ce/ce_tasklet.c
+++ b/hif/src/ce/ce_tasklet.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2018 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -111,6 +111,22 @@ void init_tasklet_workers(struct hif_opaque_softc *scn)
work_initialized = true;
}
+/**
+ * deinit_tasklet_workers() - deinit_tasklet_workers
+ * @scn: HIF Context
+ *
+ * Return: N/A
+ */
+void deinit_tasklet_workers(struct hif_opaque_softc *scn)
+{
+ u32 id;
+
+ for (id = 0; id < CE_ID_MAX; id++)
+ cancel_work_sync(&tasklet_workers[id].work);
+
+ work_initialized = false;
+}
+
#ifdef CONFIG_SLUB_DEBUG_ON
/**
* ce_schedule_tasklet() - schedule ce tasklet
diff --git a/hif/src/ce/ce_tasklet.h b/hif/src/ce/ce_tasklet.h
index 93287ae6cfc2..05da16872781 100644
--- a/hif/src/ce/ce_tasklet.h
+++ b/hif/src/ce/ce_tasklet.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2016,2018 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -20,6 +20,7 @@
#define __CE_TASKLET_H__
#include "ce_main.h"
void init_tasklet_workers(struct hif_opaque_softc *scn);
+void deinit_tasklet_workers(struct hif_opaque_softc *scn);
void ce_tasklet_init(struct HIF_CE_state *hif_ce_state, uint32_t mask);
void ce_tasklet_kill(struct hif_softc *scn);
int hif_drain_tasklets(struct hif_softc *scn);
diff --git a/htc/htc.c b/htc/htc.c
index 178c530913d5..ef4ce830853d 100644
--- a/htc/htc.c
+++ b/htc/htc.c
@@ -179,6 +179,8 @@ static void htc_cleanup(HTC_TARGET *target)
}
#endif
+ htc_flush_endpoint_txlookupQ(target);
+
qdf_spinlock_destroy(&target->HTCLock);
qdf_spinlock_destroy(&target->HTCRxLock);
qdf_spinlock_destroy(&target->HTCTxLock);
diff --git a/htc/htc_api.h b/htc/htc_api.h
index c129f4295d0c..7376731779bc 100644
--- a/htc/htc_api.h
+++ b/htc/htc_api.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2014, 2016-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, 2016-2018 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -443,18 +443,6 @@ QDF_STATUS htc_wait_target(HTC_HANDLE HTCHandle);
QDF_STATUS htc_start(HTC_HANDLE HTCHandle);
/**
- * htc_add_receive_pkt - Add receive packet to HTC
- * @HTCHandle - HTC handle
- * @pPacket - HTC receive packet to add
- *
- * User must supply HTC packets for capturing incoming HTC frames.
- * The caller must initialize each HTC packet using the
- * SET_HTC_PACKET_INFO_RX_REFILL() macro.
- * Return: A_OK on success
- */
-A_STATUS htc_add_receive_pkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket);
-
-/**
* htc_connect_service - Connect to an HTC service
* @HTCHandle - HTC handle
* @pReq - connection details
@@ -696,18 +684,6 @@ struct ol_ath_htc_stats *ieee80211_ioctl_get_htc_stats(HTC_HANDLE
*/
int htc_get_tx_queue_depth(HTC_HANDLE *htc_handle, HTC_ENDPOINT_ID endpoint_id);
-#ifdef HIF_USB
-#define HTCReturnReceivePkt(target, p, osbuf) \
- do { \
- A_NETBUF_FREE(osbuf); \
- if (p->Status == A_CLONE) { \
- qdf_mem_free(p); \
- } \
- } while (0)
-#else
-#define HTCReturnReceivePkt(target, p, osbuf) htc_add_receive_pkt(target, p)
-#endif
-
#ifdef WLAN_FEATURE_FASTPATH
void htc_ctrl_msg_cmpl(HTC_HANDLE htc_pdev, HTC_ENDPOINT_ID htc_ep_id);
diff --git a/htc/htc_internal.h b/htc/htc_internal.h
index 35f8af1bc38d..a5473e0e5324 100644
--- a/htc/htc_internal.h
+++ b/htc/htc_internal.h
@@ -295,6 +295,8 @@ void free_htc_packet_container(HTC_TARGET *target, HTC_PACKET *pPacket);
void htc_flush_rx_hold_queue(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint);
void htc_flush_endpoint_tx(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint,
HTC_TX_TAG Tag);
+void htc_flush_endpoint_txlookupQ(HTC_TARGET *target);
+
void htc_recv_init(HTC_TARGET *target);
QDF_STATUS htc_wait_recv_ctrl_message(HTC_TARGET *target);
void htc_free_control_tx_packet(HTC_TARGET *target, HTC_PACKET *pPacket);
diff --git a/htc/htc_recv.c b/htc/htc_recv.c
index e76dea089b8d..bc6bf711d46f 100644
--- a/htc/htc_recv.c
+++ b/htc/htc_recv.c
@@ -566,14 +566,6 @@ A_STATUS htc_add_receive_pkt_multiple(HTC_HANDLE HTCHandle,
return status;
}
-A_STATUS htc_add_receive_pkt(HTC_HANDLE HTCHandle, HTC_PACKET *pPacket)
-{
- HTC_PACKET_QUEUE queue;
-
- INIT_HTC_PACKET_QUEUE_AND_ADD(&queue, pPacket);
- return htc_add_receive_pkt_multiple(HTCHandle, &queue);
-}
-
void htc_flush_rx_hold_queue(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint)
{
HTC_PACKET *pPacket;
diff --git a/htc/htc_send.c b/htc/htc_send.c
index dffc74a736ea..826a38ba4664 100644
--- a/htc/htc_send.c
+++ b/htc/htc_send.c
@@ -607,7 +607,14 @@ static QDF_STATUS htc_issue_packets(HTC_TARGET *target,
pHtcHdr = (HTC_FRAME_HDR *)
qdf_nbuf_get_frag_vaddr(netbuf, 0);
- AR_DEBUG_ASSERT(pHtcHdr);
+ if (qdf_unlikely(!pHtcHdr)) {
+ AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+ ("%s Invalid pHtcHdr\n",
+ __func__));
+ AR_DEBUG_ASSERT(pHtcHdr);
+ status = QDF_STATUS_E_FAILURE;
+ break;
+ }
HTC_WRITE32(pHtcHdr,
SM(payloadLen,
@@ -2082,6 +2089,30 @@ void htc_flush_endpoint_tx(HTC_TARGET *target, HTC_ENDPOINT *pEndpoint,
UNLOCK_HTC_TX(target);
}
+/* flush endpoint TX Lookup queue */
+void htc_flush_endpoint_txlookupQ(HTC_TARGET *target)
+{
+ int i;
+ HTC_PACKET *pPacket;
+ HTC_ENDPOINT *pEndpoint;
+
+ for (i = 0; i < ENDPOINT_MAX; i++) {
+ pEndpoint = &target->endpoint[i];
+
+ if (!pEndpoint && pEndpoint->service_id == 0)
+ continue;
+
+ while (HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxLookupQueue)) {
+ pPacket = htc_packet_dequeue(&pEndpoint->TxLookupQueue);
+
+ if (pPacket) {
+ pPacket->Status = QDF_STATUS_E_CANCELED;
+ send_packet_completion(target, pPacket);
+ }
+ }
+ }
+}
+
/* HTC API to flush an endpoint's TX queue*/
void htc_flush_endpoint(HTC_HANDLE HTCHandle, HTC_ENDPOINT_ID Endpoint,
HTC_TX_TAG Tag)
diff --git a/qdf/inc/qdf_idr.h b/qdf/inc/qdf_idr.h
new file mode 100644
index 000000000000..7ad63aca898e
--- /dev/null
+++ b/qdf/inc/qdf_idr.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ *
+ * 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.
+ */
+
+/**
+ * DOC: qdf_idr(ID Allocation)
+ * QCA driver framework (QDF) ID allocation APIs
+ */
+
+#if !defined(__QDF_IDR_H)
+#define __QDF_IDR_H
+
+/* Include Files */
+#include <qdf_types.h>
+#include <qdf_status.h>
+#include <i_qdf_idr.h>
+
+/**
+ * qdf_idr - platform idr object
+ */
+typedef __qdf_idr qdf_idr;
+
+/**
+ * qdf_idr_create() - idr initialization function
+ * @idp: pointer to qdf idr
+ *
+ * Return: QDF status
+ */
+QDF_STATUS qdf_idr_create(qdf_idr *idp);
+
+/**
+ * qdf_idr_destroy() - idr deinitialization function
+ * @idp: pointer to qdf idr
+ *
+ * Return: QDF status
+ */
+QDF_STATUS qdf_idr_destroy(qdf_idr *idp);
+
+/**
+ * qdf_idr_alloc() - Allocates an unused ID
+ * @idp: pointer to qdf idr
+ * @ptr: pointer to be associated with the new ID
+ * @id: pointer to return new ID
+ *
+ * Return: QDF status
+ */
+QDF_STATUS qdf_idr_alloc(qdf_idr *idp, void *ptr, int32_t *id);
+
+/**
+ * qdf_idr_remove() - Removes this ID from the IDR.
+ * @idp: pointer to qdf idr
+ * @id: ID to be remove
+ *
+ * Return: QDF status
+ */
+QDF_STATUS qdf_idr_remove(qdf_idr *idp, int32_t id);
+
+/**
+ * qdf_idr_find() - find the user pointer from the IDR by id.
+ * @idp: pointer to qdf idr
+ * @id: ID to be remove
+ * @ptr: pointer to return user pointer for given ID
+ *
+ * Return: QDF status
+ */
+QDF_STATUS qdf_idr_find(qdf_idr *idp, int32_t id, void **ptr);
+
+#endif /* __QDF_IDR_H */
diff --git a/qdf/inc/qdf_types.h b/qdf/inc/qdf_types.h
index cb6b2d337393..616b9bcf05de 100644
--- a/qdf/inc/qdf_types.h
+++ b/qdf/inc/qdf_types.h
@@ -469,6 +469,15 @@ void qdf_vtrace_msg(QDF_MODULE_ID module, QDF_TRACE_LEVEL level,
* restart of SAP
* @QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL: Switch using fav channel(s)
* without SAP restart
+ * @QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION:**Not In Use**
+ * Force switch without SAP restart. MCC is allowed only in below exception
+ * cases:
+ * Exception Case-1: When STA is operating on DFS channel.
+ * Exception Case-2: When STA is operating on LTE-CoEx channel.
+ * Exception Case-3: When STA is operating on AP disabled channel.
+ * @QDF_MCC_TO_SCC_WITH_PREFERRED_BAND: Force SCC only in user preferred band.
+ * Allow MCC if STA is operating or comes up on other than user preferred band.
+ *
* @QDF_MCC_TO_SCC_SWITCH_MAX: max switch
*/
typedef enum {
@@ -477,6 +486,8 @@ typedef enum {
QDF_MCC_TO_SCC_SWITCH_FORCE,
QDF_MCC_TO_SCC_SWITCH_FORCE_WITHOUT_DISCONNECTION,
QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL,
+ QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION,
+ QDF_MCC_TO_SCC_WITH_PREFERRED_BAND,
QDF_MCC_TO_SCC_SWITCH_MAX
} tQDF_MCC_TO_SCC_SWITCH_MODE;
#endif
diff --git a/qdf/linux/src/i_qdf_idr.h b/qdf/linux/src/i_qdf_idr.h
new file mode 100644
index 000000000000..57b56c031104
--- /dev/null
+++ b/qdf/linux/src/i_qdf_idr.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ *
+ * 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.
+ */
+
+/**
+ * DOC: i_qdf_idr.h (ID Allocation)
+ * Linux-specific definitions for QDF ID Allocation API's
+ */
+
+#if !defined(__I_QDF_IDR_H)
+#define __I_QDF_IDR_H
+
+#include <linux/idr.h>
+#include <qdf_lock.h>
+
+/**
+ * struct __qdf_idr_s
+ * @lock: qdf spinlock
+ * @idr: idr handler
+ */
+struct __qdf_idr_s {
+ qdf_spinlock_t lock;
+ struct idr idr;
+};
+
+typedef struct __qdf_idr_s __qdf_idr;
+
+#endif /* __I_QDF_IDR_H */
diff --git a/qdf/linux/src/qdf_idr.c b/qdf/linux/src/qdf_idr.c
new file mode 100644
index 000000000000..e6c2b7f34341
--- /dev/null
+++ b/qdf/linux/src/qdf_idr.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ *
+ * 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.
+ */
+
+/**
+ * DOC: qdf_idr
+ * This file provides the ability to map an ID to a pointer
+ */
+
+/* Include files */
+#include <qdf_idr.h>
+#include <qdf_module.h>
+
+#define QDF_IDR_START 0x100
+#define QDF_IDR_END 0
+
+static int qdf_idr_gpf_flag(void)
+{
+ if (in_interrupt() || irqs_disabled() || in_atomic())
+ return GFP_ATOMIC;
+
+ return GFP_KERNEL;
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0)
+/**
+ * __qdf_idr_alloc() - Allocates an unused ID
+ * @idp: pointer to qdf idr
+ * @ptr: pointer to be associated with the new ID
+ * @start: the minimum ID
+ * @end: the maximum ID
+ *
+ * Return: new ID
+ */
+static inline int32_t
+__qdf_idr_alloc(qdf_idr *idp, void *ptr, int32_t start, int32_t end)
+{
+ int32_t id = 0;
+
+ idr_get_new(&idp->idr, ptr, &id);
+
+ return id;
+}
+#else
+static inline int32_t
+__qdf_idr_alloc(qdf_idr *idp, void *ptr, int32_t start, int32_t end)
+{
+ return idr_alloc(&idp->idr, ptr, start, end, qdf_idr_gpf_flag());
+}
+#endif
+
+QDF_STATUS qdf_idr_create(qdf_idr *idp)
+{
+ if (!idp)
+ return QDF_STATUS_E_INVAL;
+
+ qdf_spinlock_create(&idp->lock);
+
+ idr_init(&idp->idr);
+
+ return QDF_STATUS_SUCCESS;
+}
+
+qdf_export_symbol(qdf_idr_create);
+
+QDF_STATUS qdf_idr_destroy(qdf_idr *idp)
+{
+ if (!idp)
+ return QDF_STATUS_E_INVAL;
+
+ qdf_spinlock_destroy(&idp->lock);
+ idr_destroy(&idp->idr);
+
+ return QDF_STATUS_SUCCESS;
+}
+
+qdf_export_symbol(qdf_idr_destroy);
+
+QDF_STATUS qdf_idr_alloc(qdf_idr *idp, void *ptr, int32_t *id)
+{
+ int local_id;
+
+ if (!idp || !ptr)
+ return QDF_STATUS_E_INVAL;
+
+ qdf_spinlock_acquire(&idp->lock);
+ local_id = __qdf_idr_alloc(idp, ptr, QDF_IDR_START, QDF_IDR_END);
+ qdf_spinlock_release(&idp->lock);
+ if (local_id < QDF_IDR_START)
+ return QDF_STATUS_E_FAILURE;
+
+ *id = local_id;
+
+ return QDF_STATUS_SUCCESS;
+}
+
+qdf_export_symbol(qdf_idr_alloc);
+
+QDF_STATUS qdf_idr_remove(qdf_idr *idp, int32_t id)
+{
+ if (!idp || id < QDF_IDR_START)
+ return QDF_STATUS_E_INVAL;
+
+ qdf_spinlock_acquire(&idp->lock);
+ idr_remove(&idp->idr, id);
+ qdf_spinlock_release(&idp->lock);
+
+ return QDF_STATUS_SUCCESS;
+}
+
+qdf_export_symbol(qdf_idr_remove);
+
+QDF_STATUS qdf_idr_find(qdf_idr *idp, int32_t id, void **ptr)
+{
+ if (!ptr || (id < QDF_IDR_START))
+ return QDF_STATUS_E_INVAL;
+
+ qdf_spinlock_acquire(&idp->lock);
+ *ptr = idr_find(&idp->idr, id);
+ qdf_spinlock_release(&idp->lock);
+ if (!ptr)
+ return QDF_STATUS_E_INVAL;
+ else
+ return QDF_STATUS_SUCCESS;
+}
+
+qdf_export_symbol(qdf_idr_find);
+
diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h
index eba5979d6980..f3e0c86382b4 100644
--- a/wmi/inc/wmi_unified_param.h
+++ b/wmi/inc/wmi_unified_param.h
@@ -788,6 +788,8 @@ struct beacon_tmpl_params {
* struct beacon_params - beacon cmd parameter
* @vdev_id: vdev id
* @tim_ie_offset: tim ie offset
+ * @csa_count_offset: Offset of Switch count field in CSA IE
+ * @ecsa_count_offset: Offset of Switch count field in ECSA IE
* @tmpl_len: beacon template length
* @tmpl_len_aligned: beacon template alignment
* @frm: beacon template parameter
@@ -795,6 +797,8 @@ struct beacon_tmpl_params {
struct beacon_params {
uint8_t vdev_id;
uint32_t tim_ie_offset;
+ uint32_t csa_count_offset;
+ uint32_t ecsa_count_offset;
uint32_t tmpl_len;
uint32_t tmpl_len_aligned;
uint8_t *frm;
diff --git a/wmi/src/wmi_unified.c b/wmi/src/wmi_unified.c
index b774a782f577..d9f128dbba10 100644
--- a/wmi/src/wmi_unified.c
+++ b/wmi/src/wmi_unified.c
@@ -1322,6 +1322,7 @@ QDF_STATUS wmi_unified_cmd_send(wmi_unified_t wmi_handle, wmi_buf_t buf,
return QDF_STATUS_E_NOMEM;
}
+ qdf_mem_zero(qdf_nbuf_data(buf), sizeof(WMI_CMD_HDR));
WMI_SET_FIELD(qdf_nbuf_data(buf), WMI_CMD_HDR, COMMANDID, cmd_id);
qdf_atomic_inc(&wmi_handle->pending_cmds);
diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c
index a21df99f057c..11f0d412e47c 100644
--- a/wmi/src/wmi_unified_tlv.c
+++ b/wmi/src/wmi_unified_tlv.c
@@ -1301,6 +1301,8 @@ QDF_STATUS send_beacon_send_cmd_tlv(wmi_unified_t wmi_handle,
WMITLV_GET_STRUCT_TLVLEN(wmi_bcn_tmpl_cmd_fixed_param));
cmd->vdev_id = param->vdev_id;
cmd->tim_ie_offset = param->tim_ie_offset;
+ cmd->csa_switch_count_offset = param->csa_count_offset;
+ cmd->ext_csa_switch_count_offset = param->ecsa_count_offset;
cmd->buf_len = param->tmpl_len;
buf_ptr += sizeof(wmi_bcn_tmpl_cmd_fixed_param);
@@ -9485,7 +9487,7 @@ QDF_STATUS send_stats_ext_req_cmd_tlv(wmi_unified_t wmi_handle,
QDF_STATUS ret;
wmi_req_stats_ext_cmd_fixed_param *cmd;
wmi_buf_t buf;
- uint16_t len;
+ size_t len;
uint8_t *buf_ptr;
len = sizeof(*cmd) + WMI_TLV_HDR_SIZE + preq->request_data_len;