Merge "qca-wifi: Updating CFR's DBR handler API"
diff --git a/dp/inc/dp_rate_stats.h b/dp/inc/dp_rate_stats.h
new file mode 100644
index 0000000..c9bd589
--- /dev/null
+++ b/dp/inc/dp_rate_stats.h
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+/**
+ * @file: dp_rate_stats.h
+ * @brief: Define peer rate statistics related objects and APIs
+ */
+
+#ifndef _DP_RATE_STATS_
+#define _DP_RATE_STATS_
+
+#include <cdp_txrx_handle.h>
+#include <qdf_nbuf.h>
+#include <wdi_event_api.h>
+
+#ifdef QCA_SUPPORT_RDK_STATS
+
+#include <qdf_util.h>
+#include <cdp_txrx_cmn_struct.h>
+#include <cdp_txrx_cmn.h>
+#include <dp_ratetable.h>
+#include <dp_rate_stats_pub.h>
+
+#define RATE_STATS_LOCK_CREATE(lock) qdf_spinlock_create(lock)
+#define RATE_STATS_LOCK_DESTROY(lock) qdf_spinlock_destroy(lock)
+#define RATE_STATS_LOCK_ACQUIRE(lock) qdf_spin_lock_bh(lock)
+#define RATE_STATS_LOCK_RELEASE(lock) qdf_spin_unlock_bh(lock)
+
+struct cdp_pdev;
+
+/**
+ * struct wlan_peer_tx_rate_stats - peer tx rate statistics
+ * @stats: array containing tx rate stats
+ * @cur_rix: rate index updated last in list
+ * @lock: lock protecting list
+ * @sojourn: sojourn statistics
+ */
+struct wlan_peer_tx_rate_stats {
+ struct wlan_tx_rate_stats stats[WLANSTATS_CACHE_SIZE];
+ struct wlan_tx_sojourn_stats sojourn;
+ uint32_t cur_rix;
+ uint8_t cur_cache_idx;
+ qdf_spinlock_t lock;
+};
+
+/**
+ * struct wlan_peer_rx_rate_stats - Peer Rx rate statistics
+ * @stats: array containing rx rate stats
+ * @cur_rix: rate index updated last in list
+ * @lock: lock protecting list
+ */
+struct wlan_peer_rx_rate_stats {
+ struct wlan_rx_rate_stats stats[WLANSTATS_CACHE_SIZE];
+ uint32_t cur_rix;
+ uint32_t cur_cache_idx;
+ qdf_spinlock_t lock;
+};
+
+/**
+ * struct wlan_peer_rate_stats - Peer rate statistics ctx
+ * @tx: tx rate statistics
+ * @rx: rx rate statistics
+ * @mac_addr: peer MAC address
+ * @peer_cookie: cookie for unique session of peer
+ * @pdev: dp pdev
+ */
+struct wlan_peer_rate_stats_ctx {
+ struct wlan_peer_tx_rate_stats tx;
+ struct wlan_peer_rx_rate_stats rx;
+ uint8_t mac_addr[WLAN_MAC_ADDR_LEN];
+ uint64_t peer_cookie;
+ struct cdp_pdev *pdev;
+};
+
+/**
+ * struct wlan_soc_rate_stats_ctx - rate stats context at soc level
+ * @soc: Opaque soc handle
+ * @txs_cache_flush: tx stats flush count
+ * @rxs_cache_flush: rx stats flush count
+ * @txs_last_idx_cache_hit: cache hit for rate index received as last rate index
+ * @txs_cache_hit: tx stats cache hit for rate index received from cache db
+ * @rxs_last_idx_cache_hit: cache hit for rate index received as last rate index
+ * @rxs_cache_hit: cache hit for rate index received from cache database
+ * @txs_cache_miss: rate index recevied is not in cache database
+ * @rxs_cache_miss: rate index recevied is not in cache database
+ */
+struct wlan_soc_rate_stats_ctx {
+ struct cdp_soc_t *soc;
+ uint32_t txs_cache_flush;
+ uint32_t rxs_cache_flush;
+ uint32_t txs_last_idx_cache_hit;
+ uint32_t txs_cache_hit;
+ uint32_t rxs_last_idx_cache_hit;
+ uint32_t rxs_cache_hit;
+ uint32_t txs_cache_miss;
+ uint32_t rxs_cache_miss;
+};
+
+/**
+ * wlan_peer_update_rate_stats ()- WDI handler to update rate stats
+ * @ctx: soc level stats context
+ * @event: WDI event enum
+ * @stats: buffer containing cdp_peer_tx_rate_stats_intf or
+ * cdp_peer_rx_rate_stats_intf
+ * @peer_id: peer id
+ * @type: enum wlan_rate_stats_type
+ */
+
+void wlan_peer_update_rate_stats(void *ctx,
+ enum WDI_EVENT event,
+ void *stats, uint16_t peer_id,
+ uint32_t type);
+
+/**
+ * wlan_cfg80211_flush_rate_stats ()- os_if layer handler to
+ * flush rate statistics
+ * @pdev: Ctrl pdev
+ * @event: WDI event enum
+ * @ptr: Stats buffer
+ * @peer_id: peer id
+ * @status: status
+ */
+void wlan_cfg80211_flush_rate_stats(void *ctrl_pdev, enum WDI_EVENT event,
+ void *ptr, uint16_t peer_id,
+ uint32_t status);
+
+/**
+ * wlan_peer_create_event_handler ()- peer create event handler
+ * to initialize statistics objects
+ * @pdev: Ctrl pdev
+ * @event: WDI event enum
+ * @peer_mac: Peer MAC address
+ * @buf: Stats buffer
+ * @peer_id: peer id
+ * @status: status
+ */
+void wlan_peer_create_event_handler(void *pdev, enum WDI_EVENT event,
+ void *buf, uint16_t peer_id,
+ uint32_t status);
+
+/**
+ * wlan_peer_destroy_event_handler ()- peer destroy event handler
+ * to deinitilize statistics objects
+ * @pdev: Ctrl pdev
+ * @event: WDI event enum
+ * @peer_mac: Peer MAC address
+ * @buf: Stats buffer
+ * @peer_id: peer id
+ * @status: status
+ */
+void wlan_peer_destroy_event_handler(void *pdev, enum WDI_EVENT event,
+ void *buf, uint16_t peer_id,
+ uint32_t status);
+
+/**
+ * wlan_peer_rate_stats_flush_req ()- stats flush request event handler
+ * This flushes statistics to user space entity
+ * @pdev: Ctrl pdev
+ * @event: WDI event enum
+ * @buf: Stats buffer
+ * @peer_id: peer id
+ * @status: status
+ */
+void wlan_peer_rate_stats_flush_req(void *pdev, enum WDI_EVENT event,
+ void *buf, uint16_t peer_id,
+ uint32_t status);
+
+#else
+static inline void
+wlan_peer_update_rate_stats(void *pdev, enum WDI_EVENT event,
+ void *stats, uint16_t peer_id,
+ uint32_t type)
+{
+}
+
+static inline void
+wlan_cfg80211_flush_rate_stats(void *ctrl_pdev, enum WDI_EVENT event,
+ void *ptr, uint16_t peer_id,
+ uint32_t status)
+{
+}
+
+static inline void
+wlan_peer_create_event_handler(void *pdev, enum WDI_EVENT event,
+ void *buf, uint16_t peer_id,
+ uint32_t type)
+{
+}
+
+static inline void
+wlan_peer_destroy_event_handler(void *pdev, enum WDI_EVENT event,
+ void *buf, uint16_t peer_id,
+ uint32_t type)
+{
+}
+
+static inline void
+wlan_peer_rate_stats_flush_req(void *pdev,
+ enum WDI_EVENT event,
+ void *buf, uint16_t peer_id,
+ uint32_t type)
+{
+}
+#endif /* QCA_SUPPORT_RDK_STATS */
+#endif /* _DP_RATE_STATS_ */
diff --git a/dp/inc/dp_rate_stats_pub.h b/dp/inc/dp_rate_stats_pub.h
new file mode 100644
index 0000000..b46708e
--- /dev/null
+++ b/dp/inc/dp_rate_stats_pub.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+/**
+ * @file: dp_rate_stats_pub.h
+ * @breief: Define peer rate statistics related objects and APIs
+ * accessed required for user space tools
+ */
+
+#ifndef _DP_RATE_STATS_UAPI_
+#define _DP_RATE_STATS_UAPI_
+
+#define WLANSTATS_CACHE_SIZE 10
+#define MAX_RSSI_ANT 4
+#define MAX_RSSI_HT 4
+#define WLAN_DATA_TID_MAX 8
+#define WLAN_MAC_ADDR_LEN 6
+#define WLANSTATS_RSSI_OFFSET 8
+#define WLANSTATS_RSSI_MASK 0xff
+#define WLANSTATS_RSSI_MAX 0x80
+
+#ifndef __KERNEL__
+#define qdf_ewma_tx_lag int
+#define qdf_ewma_rx_rssi int
+#else
+#include <cdp_txrx_cmn_struct.h>
+QDF_DECLARE_EWMA(rx_rssi, 1024, 8)
+#endif
+
+/**
+ * enum cdp_peer_rate_stats_cmd -
+ * used by app to get specific stats
+ */
+enum wlan_peer_rate_stats_cmd {
+ DP_PEER_RX_RATE_STATS,
+ DP_PEER_TX_RATE_STATS,
+ DP_PEER_SOJOURN_STATS,
+};
+
+/** struct wlan_tx_rate_stats - Tx packet rate info
+ * @rix: Rate index derived from nss, mcs, preamble, ht, sgi
+ * @rate: Data rate in kbps
+ * @mpdu_success: success mpdus count
+ * @mpdu_attempts: attempt mpdus count
+ * @num_ppdus: ppdu count
+ */
+struct wlan_tx_rate_stats {
+ uint32_t rix;
+ uint32_t rate;
+ uint32_t mpdu_success;
+ uint32_t mpdu_attempts;
+ uint32_t num_ppdus;
+};
+
+/** struct wlan_rx_rate_stats - Rx rate packet info
+ * @rix: Rate index derived from nss, mcs, preamble, ht, sgi
+ * @rate: Data rate in kbps
+ * @num_bytes: num of bytes
+ * @num_msdus: num of msdus
+ * @num_mpdus: num of mpdus
+ * @num_ppdus: num of ppdus
+ * @num_retries: num of retries
+ * @num_sgi: num of short guard interval
+ */
+struct wlan_rx_rate_stats {
+ uint32_t rix;
+ uint32_t rate;
+ uint32_t num_bytes;
+ uint32_t num_msdus;
+ uint32_t num_mpdus;
+ uint32_t num_ppdus;
+ uint32_t num_retries;
+ uint32_t num_sgi;
+ qdf_ewma_rx_rssi avg_rssi;
+ qdf_ewma_rx_rssi avg_rssi_ant[MAX_RSSI_ANT][MAX_RSSI_HT];
+};
+
+/*
+ * struct wlan_tx_sojourn_stats - Tx sojourn stats
+ * @ppdu_seq_id: ppdu_seq_id from tx completion
+ * @avg_sojourn_msdu: average sojourn msdu time
+ * @sum_sojourn_msdu: sum sojourn msdu time
+ * @num_msdu: number of msdus per ppdu
+ * @cookie: cookie to be used by upper layer
+ */
+struct wlan_tx_sojourn_stats {
+ uint32_t ppdu_seq_id;
+ qdf_ewma_tx_lag avg_sojourn_msdu[WLAN_DATA_TID_MAX];
+ uint32_t sum_sojourn_msdu[WLAN_DATA_TID_MAX];
+ uint32_t num_msdus[WLAN_DATA_TID_MAX];
+ void *cookie;
+};
+
+/**
+ * struct wlan_peer_rate_stats_intf - Interface structure to
+ * flush stats to user spave entity
+ * @stats: statistics buffer
+ * @buf_len: buffer len
+ * @peer_mac: peer mac address
+ * @stats_type: statistics type
+ * @cookie: peer cookie
+ */
+struct wlan_peer_rate_stats_intf {
+ void *stats;
+ uint32_t buf_len;
+ uint8_t peer_mac[WLAN_MAC_ADDR_LEN];
+ uint8_t stats_type;
+ uint64_t cookie;
+};
+#endif /* _DP_RATE_STATS_UAPI_ */
diff --git a/dp/src/dp_rate_stats.c b/dp/src/dp_rate_stats.c
new file mode 100644
index 0000000..50c1017
--- /dev/null
+++ b/dp/src/dp_rate_stats.c
@@ -0,0 +1,410 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+/**
+ * @file: dp_rate_stats.c
+ * @breief: Core peer rate statistics processing module
+ */
+
+#include "dp_rate_stats.h"
+#include "dp_rate_stats_pub.h"
+
+#ifdef QCA_SUPPORT_RDK_STATS
+
+static void
+wlan_peer_flush_rx_rate_stats(struct wlan_soc_rate_stats_ctx *soc_stats_ctx,
+ struct wlan_peer_rate_stats_ctx *stats_ctx)
+{
+ struct wlan_peer_rate_stats_intf buf;
+ struct wlan_peer_rx_rate_stats *rx_stats;
+
+ if (!soc_stats_ctx)
+ return;
+ rx_stats = &stats_ctx->rx;
+
+ buf.stats = (struct wlan_rx_rate_stats *)rx_stats->stats;
+ buf.buf_len = WLANSTATS_CACHE_SIZE * sizeof(struct wlan_rx_rate_stats);
+ buf.stats_type = DP_PEER_RX_RATE_STATS;
+ buf.cookie = stats_ctx->peer_cookie;
+ qdf_mem_copy(buf.peer_mac, stats_ctx->mac_addr, WLAN_MAC_ADDR_LEN);
+ cdp_peer_flush_rate_stats(soc_stats_ctx->soc,
+ stats_ctx->pdev, &buf);
+
+ soc_stats_ctx->rxs_cache_flush++;
+ qdf_info("rxs_cache_flush: %d", soc_stats_ctx->rxs_cache_flush);
+
+ qdf_mem_zero(rx_stats->stats, WLANSTATS_CACHE_SIZE *
+ sizeof(struct wlan_rx_rate_stats));
+}
+
+static void
+wlan_peer_flush_tx_rate_stats(struct wlan_soc_rate_stats_ctx *soc_stats_ctx,
+ struct wlan_peer_rate_stats_ctx *stats_ctx)
+{
+ struct wlan_peer_rate_stats_intf buf;
+ struct wlan_peer_tx_rate_stats *tx_stats;
+
+ if (!soc_stats_ctx)
+ return;
+
+ tx_stats = &stats_ctx->tx;
+ buf.stats = (struct wlan_tx_rate_stats *)tx_stats->stats;
+ buf.buf_len = (WLANSTATS_CACHE_SIZE * sizeof(struct wlan_tx_rate_stats)
+ + sizeof(struct wlan_tx_sojourn_stats));
+ buf.stats_type = DP_PEER_TX_RATE_STATS;
+ buf.cookie = stats_ctx->peer_cookie;
+ qdf_mem_copy(buf.peer_mac, stats_ctx->mac_addr, WLAN_MAC_ADDR_LEN);
+ cdp_peer_flush_rate_stats(soc_stats_ctx->soc,
+ stats_ctx->pdev, &buf);
+
+ soc_stats_ctx->txs_cache_flush++;
+ qdf_info("txs_cache_flush: %d", soc_stats_ctx->txs_cache_flush);
+
+ qdf_mem_zero(tx_stats->stats, WLANSTATS_CACHE_SIZE *
+ sizeof(struct wlan_tx_rate_stats) +
+ sizeof(struct wlan_tx_sojourn_stats));
+}
+
+static void
+wlan_peer_flush_rate_stats(struct wlan_soc_rate_stats_ctx *soc_stats_ctx,
+ struct wlan_peer_rate_stats_ctx *stats_ctx)
+{
+ struct wlan_peer_tx_rate_stats *tx_stats;
+ struct wlan_peer_rx_rate_stats *rx_stats;
+
+ tx_stats = &stats_ctx->tx;
+ rx_stats = &stats_ctx->rx;
+
+ RATE_STATS_LOCK_ACQUIRE(&tx_stats->lock);
+ wlan_peer_flush_tx_rate_stats(soc_stats_ctx, stats_ctx);
+ RATE_STATS_LOCK_RELEASE(&tx_stats->lock);
+
+ RATE_STATS_LOCK_ACQUIRE(&rx_stats->lock);
+ wlan_peer_flush_rx_rate_stats(soc_stats_ctx, stats_ctx);
+ RATE_STATS_LOCK_RELEASE(&rx_stats->lock);
+}
+
+void wlan_peer_rate_stats_flush_req(void *ctx, enum WDI_EVENT event,
+ void *buf, uint16_t peer_id,
+ uint32_t type)
+{
+ if (buf)
+ wlan_peer_flush_rate_stats(ctx, buf);
+}
+
+static inline void
+__wlan_peer_update_rx_rate_stats(struct wlan_rx_rate_stats *__rx_stats,
+ struct cdp_rx_indication_ppdu *cdp_rx_ppdu)
+{
+ uint8_t ant, ht;
+
+ __rx_stats->rix = cdp_rx_ppdu->rix;
+ __rx_stats->rate = cdp_rx_ppdu->rx_ratekbps;
+ __rx_stats->num_bytes += cdp_rx_ppdu->num_bytes;
+ __rx_stats->num_msdus += cdp_rx_ppdu->num_msdu;
+ __rx_stats->num_mpdus += cdp_rx_ppdu->num_mpdu;
+ __rx_stats->num_retries += cdp_rx_ppdu->retries;
+ __rx_stats->num_ppdus += 1;
+
+ if (cdp_rx_ppdu->u.gi)
+ __rx_stats->num_sgi++;
+
+ qdf_ewma_rx_rssi_add(&__rx_stats->avg_rssi, cdp_rx_ppdu->rssi);
+
+ for (ant = 0; ant < MAX_RSSI_ANT; ant++) {
+ for (ht = 0; ht < MAX_RSSI_HT; ht++)
+ qdf_ewma_rx_rssi_add(&__rx_stats->avg_rssi_ant[ant][ht],
+ cdp_rx_ppdu->rssi_chain[ant][ht]);
+ }
+}
+
+static void
+wlan_peer_update_rx_rate_stats(struct wlan_soc_rate_stats_ctx *soc_stats_ctx,
+ struct cdp_rx_indication_ppdu *cdp_rx_ppdu)
+{
+ struct wlan_peer_rate_stats_ctx *stats_ctx;
+ struct wlan_peer_rx_rate_stats *rx_stats;
+ struct wlan_rx_rate_stats *__rx_stats;
+ uint8_t cache_idx;
+ bool idx_match = false;
+
+ stats_ctx = (struct wlan_peer_rate_stats_ctx *)cdp_rx_ppdu->cookie;
+
+ if (qdf_unlikely(!stats_ctx)) {
+ qdf_warn("peer rate stats ctx is NULL, return");
+ qdf_warn("peer_mac: " QDF_MAC_ADDR_STR,
+ QDF_MAC_ADDR_ARRAY(cdp_rx_ppdu->mac_addr));
+ return;
+ }
+
+ rx_stats = &stats_ctx->rx;
+
+ if (qdf_unlikely(cdp_rx_ppdu->rix > DP_RATE_TABLE_SIZE)) {
+ qdf_warn("Invalid rate index, return");
+ return;
+ }
+
+ RATE_STATS_LOCK_ACQUIRE(&rx_stats->lock);
+ if (qdf_likely(rx_stats->cur_rix == cdp_rx_ppdu->rix)) {
+ __rx_stats = &rx_stats->stats[rx_stats->cur_cache_idx];
+ __wlan_peer_update_rx_rate_stats(__rx_stats,
+ cdp_rx_ppdu);
+
+ soc_stats_ctx->rxs_last_idx_cache_hit++;
+ goto done;
+ }
+
+ /* check if cache is available */
+ for (cache_idx = 0; cache_idx < WLANSTATS_CACHE_SIZE; cache_idx++) {
+ __rx_stats = &rx_stats->stats[cache_idx];
+ if (!__rx_stats->rix || (__rx_stats->rix == cdp_rx_ppdu->rix)) {
+ idx_match = true;
+ break;
+ }
+ }
+ /* if index matches or found empty index, update stats to that
+ * cache index else flush cache and update stats to cache index zero
+ */
+ if (idx_match) {
+ __wlan_peer_update_rx_rate_stats(__rx_stats,
+ cdp_rx_ppdu);
+ rx_stats->cur_rix = cdp_rx_ppdu->rix;
+ rx_stats->cur_cache_idx = cache_idx;
+ soc_stats_ctx->rxs_cache_hit++;
+ goto done;
+ } else {
+ wlan_peer_flush_rx_rate_stats(soc_stats_ctx, stats_ctx);
+ __rx_stats = &rx_stats->stats[0];
+ __wlan_peer_update_rx_rate_stats(__rx_stats,
+ cdp_rx_ppdu);
+ rx_stats->cur_rix = cdp_rx_ppdu->rix;
+ rx_stats->cur_cache_idx = 0;
+ soc_stats_ctx->rxs_cache_miss++;
+ }
+done:
+ RATE_STATS_LOCK_RELEASE(&rx_stats->lock);
+}
+
+static inline void
+__wlan_peer_update_tx_rate_stats(struct wlan_tx_rate_stats *__tx_stats,
+ struct cdp_tx_completion_ppdu_user *ppdu_user)
+{
+ uint8_t num_ppdus;
+ uint8_t mpdu_attempts;
+ uint8_t mpdu_success;
+
+ num_ppdus = ppdu_user->long_retries + 1;
+ mpdu_attempts = num_ppdus * ppdu_user->mpdu_tried_ucast;
+ mpdu_success = ppdu_user->mpdu_tried_ucast - ppdu_user->mpdu_failed;
+
+ __tx_stats->rix = ppdu_user->rix;
+ __tx_stats->rate = ppdu_user->tx_rate;
+ __tx_stats->num_ppdus += num_ppdus;
+ __tx_stats->mpdu_attempts += mpdu_attempts;
+ __tx_stats->mpdu_success += mpdu_success;
+}
+
+static void
+wlan_peer_update_tx_rate_stats(struct wlan_soc_rate_stats_ctx *soc_stats_ctx,
+ struct cdp_tx_completion_ppdu *cdp_tx_ppdu)
+{
+ struct cdp_tx_completion_ppdu_user *ppdu_user;
+ struct wlan_peer_rate_stats_ctx *stats_ctx;
+ struct wlan_peer_tx_rate_stats *tx_stats;
+ struct wlan_tx_rate_stats *__tx_stats;
+ uint8_t cache_idx;
+ uint8_t user_idx;
+ bool idx_match = false;
+
+ for (user_idx = 0; user_idx < cdp_tx_ppdu->num_users; user_idx++) {
+ ppdu_user = &cdp_tx_ppdu->user[user_idx];
+ stats_ctx = (struct wlan_peer_rate_stats_ctx *)
+ ppdu_user->cookie;
+
+ if (qdf_unlikely(!stats_ctx)) {
+ qdf_warn("peer rate stats ctx is NULL, return");
+ qdf_warn("peer_mac: " QDF_MAC_ADDR_STR,
+ QDF_MAC_ADDR_ARRAY(ppdu_user->mac_addr));
+ return;
+ }
+
+ tx_stats = &stats_ctx->tx;
+ RATE_STATS_LOCK_ACQUIRE(&tx_stats->lock);
+
+ if (qdf_unlikely(ppdu_user->rix > DP_RATE_TABLE_SIZE)) {
+ qdf_warn("Invalid rate index, continue.");
+ RATE_STATS_LOCK_RELEASE(&tx_stats->lock);
+ continue;
+ }
+ if (qdf_likely(tx_stats->cur_rix == ppdu_user->rix)) {
+ __tx_stats = &tx_stats->stats[tx_stats->cur_cache_idx];
+ __wlan_peer_update_tx_rate_stats(__tx_stats, ppdu_user);
+ soc_stats_ctx->txs_last_idx_cache_hit++;
+ RATE_STATS_LOCK_RELEASE(&tx_stats->lock);
+ continue;
+ }
+
+ /* check if cache is available */
+ for (cache_idx = 0; cache_idx < WLANSTATS_CACHE_SIZE;
+ cache_idx++) {
+ __tx_stats = &tx_stats->stats[cache_idx];
+ if (!__tx_stats->rix ||
+ (__tx_stats->rix == ppdu_user->rix)) {
+ idx_match = true;
+ break;
+ }
+ }
+ /* if index matches or found empty index,
+ * update stats to that cache index
+ * else flush cache and update stats to cache index zero
+ */
+ if (idx_match) {
+ soc_stats_ctx->txs_cache_hit++;
+
+ __wlan_peer_update_tx_rate_stats(__tx_stats,
+ ppdu_user);
+ tx_stats->cur_rix = ppdu_user->rix;
+ tx_stats->cur_cache_idx = cache_idx;
+ } else {
+ soc_stats_ctx->txs_cache_miss++;
+
+ wlan_peer_flush_tx_rate_stats(soc_stats_ctx, stats_ctx);
+ __tx_stats = &tx_stats->stats[0];
+ __wlan_peer_update_tx_rate_stats(__tx_stats,
+ ppdu_user);
+ tx_stats->cur_rix = ppdu_user->rix;
+ tx_stats->cur_cache_idx = 0;
+ }
+ RATE_STATS_LOCK_RELEASE(&tx_stats->lock);
+ }
+}
+
+static void
+wlan_peer_update_sojourn_stats(void *ctx,
+ struct cdp_tx_sojourn_stats *sojourn_stats)
+{
+ struct wlan_peer_rate_stats_ctx *stats_ctx;
+ struct wlan_peer_tx_rate_stats *tx_stats;
+ uint8_t tid;
+
+ stats_ctx = (struct wlan_peer_rate_stats_ctx *)sojourn_stats->cookie;
+
+ if (qdf_unlikely(!stats_ctx)) {
+ qdf_warn("peer rate stats ctx is NULL, return");
+ return;
+ }
+
+ tx_stats = &stats_ctx->tx;
+
+ RATE_STATS_LOCK_ACQUIRE(&tx_stats->lock);
+ for (tid = 0; tid < CDP_DATA_TID_MAX; tid++) {
+ tx_stats->sojourn.avg_sojourn_msdu[tid] =
+ sojourn_stats->avg_sojourn_msdu[tid];
+
+ tx_stats->sojourn.sum_sojourn_msdu[tid] +=
+ sojourn_stats->sum_sojourn_msdu[tid];
+
+ tx_stats->sojourn.num_msdus[tid] +=
+ sojourn_stats->num_msdus[tid];
+ }
+ RATE_STATS_LOCK_RELEASE(&tx_stats->lock);
+}
+
+void wlan_peer_update_rate_stats(void *ctx,
+ enum WDI_EVENT event,
+ void *buf, uint16_t peer_id,
+ uint32_t stats_type)
+{
+ struct wlan_soc_rate_stats_ctx *soc_stats_ctx;
+ struct cdp_tx_completion_ppdu *cdp_tx_ppdu;
+ struct cdp_rx_indication_ppdu *cdp_rx_ppdu;
+ struct cdp_tx_sojourn_stats *sojourn_stats;
+ qdf_nbuf_t nbuf;
+
+ if (qdf_unlikely(!buf))
+ return;
+
+ if (qdf_unlikely(!ctx))
+ return;
+
+ soc_stats_ctx = ctx;
+ nbuf = buf;
+
+ switch (event) {
+ case WDI_EVENT_TX_PPDU_DESC:
+ cdp_tx_ppdu = (struct cdp_tx_completion_ppdu *)
+ qdf_nbuf_data(nbuf);
+ wlan_peer_update_tx_rate_stats(soc_stats_ctx, cdp_tx_ppdu);
+ break;
+ case WDI_EVENT_RX_PPDU_DESC:
+ cdp_rx_ppdu = (struct cdp_rx_indication_ppdu *)
+ qdf_nbuf_data(nbuf);
+ wlan_peer_update_rx_rate_stats(soc_stats_ctx, cdp_rx_ppdu);
+ break;
+ case WDI_EVENT_TX_SOJOURN_STAT:
+ sojourn_stats = (struct cdp_tx_sojourn_stats *)
+ qdf_nbuf_data(nbuf);
+ wlan_peer_update_sojourn_stats(soc_stats_ctx, sojourn_stats);
+ break;
+ default:
+ qdf_err("Err, Invalid type");
+ }
+}
+
+void wlan_peer_create_event_handler(void *pdev, enum WDI_EVENT event,
+ void *buf, uint16_t peer_id,
+ uint32_t type)
+{
+ struct cdp_peer_cookie *peer_info;
+ struct wlan_peer_rate_stats_ctx *stats;
+
+ peer_info = (struct cdp_peer_cookie *)buf;
+ stats = qdf_mem_malloc(sizeof(*stats));
+ if (!stats) {
+ qdf_err("malloc failed, returning NULL");
+ return;
+ }
+ qdf_mem_zero(stats, sizeof(*stats));
+ RATE_STATS_LOCK_CREATE(&stats->tx.lock);
+ RATE_STATS_LOCK_CREATE(&stats->rx.lock);
+ qdf_mem_copy(stats->mac_addr, peer_info->mac_addr, QDF_MAC_ADDR_SIZE);
+ stats->peer_cookie = peer_info->cookie;
+ stats->pdev = pdev;
+
+ peer_info->ctx = (void *)stats;
+}
+
+void wlan_peer_destroy_event_handler(void *ctx, enum WDI_EVENT event,
+ void *buf, uint16_t peer_id,
+ uint32_t type)
+{
+ struct cdp_peer_cookie *peer_info;
+ struct wlan_peer_rate_stats_ctx *stats;
+
+ peer_info = (struct cdp_peer_cookie *)buf;
+ stats = (struct wlan_peer_rate_stats_ctx *)peer_info->ctx;
+
+ if (stats) {
+ wlan_peer_flush_rate_stats(ctx, stats);
+ RATE_STATS_LOCK_DESTROY(&stats->tx.lock);
+ RATE_STATS_LOCK_DESTROY(&stats->rx.lock);
+ qdf_mem_free(stats);
+ qdf_info("DEBUG DEiniitialized rate stats");
+ }
+}
+#endif
diff --git a/qal/inc/qal_notifier.h b/qal/inc/qal_notifier.h
new file mode 100644
index 0000000..0a538a3
--- /dev/null
+++ b/qal/inc/qal_notifier.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2019 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: qal_notifier (QAL notifier)
+ * QCA driver framework for OS notifier handlers
+ */
+
+#ifndef __QAL_NOTIFIER_H
+#define __QAL_NOTIFIER_H
+
+#include "qdf_types.h"
+
+typedef QDF_STATUS (*qal_panic_notifier)(void *data);
+
+/**
+ *
+ * qal_register_panic_notifier() - register to panic notifier chain
+ *
+ * To be called once, globally.
+ *
+ * Return: None
+ */
+QDF_STATUS qal_register_panic_notifier(qal_panic_notifier cb);
+
+/**
+ * qal_unregister_panic_notifier() - unregister linux panic notifier chain
+ *
+ * To be called once, globally.
+ *
+ * Return: None
+ */
+QDF_STATUS qal_unregister_panic_notifier(void);
+
+#endif /* __QAL_NOTIFIER_H */
diff --git a/qal/linux/src/qal_devcfg.c b/qal/linux/src/qal_devcfg.c
new file mode 100644
index 0000000..cf9aec4
--- /dev/null
+++ b/qal/linux/src/qal_devcfg.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2019 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: qal_devcfg
+ * This file provides OS dependent device config related APIs
+ */
+
+#include "qdf_debugfs.h"
+#include "qdf_mem.h"
+#include "qdf_types.h"
+#include "qdf_nbuf.h"
+#include "qdf_module.h"
+#include "qal_devcfg.h"
+#include <net/cfg80211.h>
+
+QDF_STATUS
+qal_devcfg_send_response(qdf_nbuf_t cfgbuf)
+{
+ int ret;
+
+ if (!cfgbuf)
+ return QDF_STATUS_E_INVAL;
+
+ ret = cfg80211_vendor_cmd_reply(cfgbuf);
+
+ return qdf_status_from_os_return(ret);
+}
+
+qdf_export_symbol(qal_devcfg_send_response);
diff --git a/qal/linux/src/qal_notifier.c b/qal/linux/src/qal_notifier.c
new file mode 100644
index 0000000..c0a6746
--- /dev/null
+++ b/qal/linux/src/qal_notifier.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+#include "qal_notifier.h"
+#include "qdf_module.h"
+#include "qdf_trace.h"
+
+static struct notifier_block qal_panic_nb;
+
+static qal_panic_notifier qal_panic_cb;
+
+static int qal_panic_notifier_handler(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ qal_panic_cb(data);
+ return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS qal_register_panic_notifier(qal_panic_notifier cb)
+{
+ QDF_ASSERT(!qal_panic_cb);
+ if (qal_panic_cb) {
+ qdf_err("Panic notifier already registered");
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ qal_panic_cb = cb;
+
+ qal_panic_nb.notifier_call = qal_panic_notifier_handler;
+ atomic_notifier_chain_register(&panic_notifier_list,
+ &qal_panic_nb);
+
+ return QDF_STATUS_SUCCESS;
+}
+
+qdf_export_symbol(qal_register_panic_notifier);
+
+QDF_STATUS qal_unregister_panic_notifier(void)
+{
+ atomic_notifier_chain_unregister(&panic_notifier_list,
+ &qal_panic_nb);
+
+ return QDF_STATUS_SUCCESS;
+}
+
+qdf_export_symbol(qal_unregister_panic_notifier);
diff --git a/qal/linux/src/qal_vbus_dev.c b/qal/linux/src/qal_vbus_dev.c
new file mode 100644
index 0000000..4b56b25
--- /dev/null
+++ b/qal/linux/src/qal_vbus_dev.c
@@ -0,0 +1,273 @@
+/*
+ * Copyright (c) 2019 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: qal_vbus_dev
+ * This file provides OS dependent virtual bus device related APIs
+ */
+
+#include "qdf_util.h"
+#include "qal_vbus_dev.h"
+#include "qdf_module.h"
+#include <linux/of_gpio.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
+#include <linux/reset.h>
+#endif
+
+QDF_STATUS
+qal_vbus_get_iorsc(int devnum, uint32_t flag, char *devname)
+{
+ int ret;
+
+ if (!devname)
+ return QDF_STATUS_E_INVAL;
+
+ ret = gpio_request_one(devnum, flag, devname);
+
+ return qdf_status_from_os_return(ret);
+}
+
+qdf_export_symbol(qal_vbus_get_iorsc);
+
+QDF_STATUS
+qal_vbus_release_iorsc(int devnum)
+{
+ if (devnum <= 0)
+ return QDF_STATUS_E_INVAL;
+
+ gpio_free(devnum);
+
+ return QDF_STATUS_SUCCESS;
+}
+
+qdf_export_symbol(qal_vbus_release_iorsc);
+
+QDF_STATUS
+qal_vbus_enable_devclk(struct qdf_dev_clk *clk)
+{
+ int ret;
+
+ if (!clk)
+ return QDF_STATUS_E_INVAL;
+
+ ret = clk_prepare_enable((struct clk *)clk);
+
+ return qdf_status_from_os_return(ret);
+}
+
+qdf_export_symbol(qal_vbus_enable_devclk);
+
+QDF_STATUS
+qal_vbus_disable_devclk(struct qdf_dev_clk *clk)
+{
+ if (!clk)
+ return QDF_STATUS_E_INVAL;
+
+ clk_disable_unprepare((struct clk *)clk);
+
+ return QDF_STATUS_SUCCESS;
+}
+
+qdf_export_symbol(qal_vbus_disable_devclk);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)
+QDF_STATUS
+qal_vbus_get_dev_rstctl(struct qdf_pfm_hndl *pfhndl, const char *state,
+ struct qdf_vbus_rstctl **rstctl)
+{
+ struct reset_control *rsctl;
+
+ if (!pfhndl || !state)
+ return QDF_STATUS_E_INVAL;
+
+ rsctl = reset_control_get_optional_exclusive((struct device *)pfhndl,
+ state);
+
+ if (!rsctl)
+ return QDF_STATUS_E_FAILURE;
+
+ *rstctl = (struct qdf_vbus_rstctl *)rsctl;
+
+ return QDF_STATUS_SUCCESS;
+}
+#else
+QDF_STATUS
+qal_vbus_get_dev_rstctl(struct qdf_pfm_hndl *pfhndl, const char *state,
+ struct qdf_vbus_rstctl **rstctl)
+{
+ struct reset_control *rsctl;
+
+ if (!pfhndl || !state)
+ return QDF_STATUS_E_INVAL;
+
+ rsctl = reset_control_get_optional((struct device *)pfhndl,
+ state);
+
+ if (!rsctl)
+ return QDF_STATUS_E_FAILURE;
+
+ *rstctl = (struct qdf_vbus_rstctl *)rsctl;
+
+ return QDF_STATUS_SUCCESS;
+}
+#endif
+#else
+QDF_STATUS
+qal_vbus_get_dev_rstctl(struct qdf_pfm_hndl *pfhndl, const char *state,
+ struct qdf_vbus_rstctl **rstctl)
+{
+ if (!pfhndl || !state)
+ return QDF_STATUS_E_INVAL;
+ *rstctl = NULL;
+
+ return QDF_STATUS_SUCCESS;
+}
+#endif
+
+qdf_export_symbol(qal_vbus_get_dev_rstctl);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
+QDF_STATUS
+qal_vbus_release_dev_rstctl(struct qdf_pfm_hndl *pfhndl,
+ struct qdf_vbus_rstctl *rstctl)
+{
+ if (!pfhndl || !rstctl)
+ return QDF_STATUS_E_INVAL;
+
+ reset_control_put((struct reset_control *)rstctl);
+
+ return QDF_STATUS_SUCCESS;
+}
+#else
+QDF_STATUS
+qal_release_dev_rstctl(struct qdf_pfm_hndl *pfhndl,
+ struct qdf_vbus_rstctl *rstctl)
+{
+ if (!pfhndl || !rstctl)
+ return QDF_STATUS_E_INVAL;
+
+ return QDF_STATUS_E_FAILURE;
+}
+#endif
+
+qdf_export_symbol(qal_vbus_release_dev_rstctl);
+
+QDF_STATUS
+qal_vbus_activate_dev_rstctl(struct qdf_pfm_hndl *pfhndl,
+ struct qdf_vbus_rstctl *rstctl)
+{
+ int ret;
+
+ if (!pfhndl || !rstctl)
+ return QDF_STATUS_E_INVAL;
+
+ ret = reset_control_assert((struct reset_control *)rstctl);
+
+ return qdf_status_from_os_return(ret);
+}
+
+qdf_export_symbol(qal_vbus_activate_dev_rstctl);
+
+QDF_STATUS
+qal_vbus_deactivate_dev_rstctl(struct qdf_pfm_hndl *pfhndl,
+ struct qdf_vbus_rstctl *rstctl)
+{
+ int ret;
+
+ if (!pfhndl || !rstctl)
+ return QDF_STATUS_E_INVAL;
+
+ ret = reset_control_deassert((struct reset_control *)rstctl);
+
+ return qdf_status_from_os_return(ret);
+}
+
+qdf_export_symbol(qal_vbus_deactivate_dev_rstctl);
+
+QDF_STATUS
+qal_vbus_get_resource(struct qdf_pfm_hndl *pfhndl,
+ struct qdf_vbus_resource **rsc,
+ uint32_t restype, uint32_t residx)
+{
+ struct resource *rsrc;
+
+ if (!pfhndl)
+ return QDF_STATUS_E_INVAL;
+
+ rsrc = platform_get_resource((struct platform_device *)pfhndl,
+ restype, residx);
+ if (!rsrc)
+ return QDF_STATUS_E_FAILURE;
+
+ *rsc = (struct qdf_vbus_resource *)rsrc;
+
+ return QDF_STATUS_SUCCESS;
+}
+
+qdf_export_symbol(qal_vbus_get_resource);
+
+QDF_STATUS
+qal_vbus_get_irq(struct qdf_pfm_hndl *pfhndl, const char *str, int *irq)
+{
+ int inum;
+
+ if (!pfhndl || !str)
+ return QDF_STATUS_E_INVAL;
+
+ inum = platform_get_irq_byname((struct platform_device *)pfhndl, str);
+
+ if (inum < 0)
+ return QDF_STATUS_E_FAULT;
+
+ *irq = inum;
+
+ return QDF_STATUS_SUCCESS;
+}
+
+qdf_export_symbol(qal_vbus_get_irq);
+
+QDF_STATUS
+qal_vbus_register_driver(struct qdf_pfm_drv *pfdev)
+{
+ int ret;
+
+ if (!pfdev)
+ return QDF_STATUS_E_INVAL;
+
+ ret = platform_driver_register((struct platform_driver *)pfdev);
+
+ return qdf_status_from_os_return(ret);
+}
+
+qdf_export_symbol(qal_vbus_register_driver);
+
+QDF_STATUS
+qal_vbus_deregister_driver(struct qdf_pfm_drv *pfdev)
+{
+ if (!pfdev)
+ return QDF_STATUS_E_INVAL;
+
+ platform_driver_unregister((struct platform_driver *)pfdev);
+
+ return QDF_STATUS_SUCCESS;
+}
+
+qdf_export_symbol(qal_vbus_deregister_driver);
diff --git a/target_if/cfr/src/target_if_cfr_8074v2.c b/target_if/cfr/src/target_if_cfr_8074v2.c
index 90c145b..f0eb26c 100644
--- a/target_if/cfr/src/target_if_cfr_8074v2.c
+++ b/target_if/cfr/src/target_if_cfr_8074v2.c
@@ -426,7 +426,8 @@
header->chip_type = CFR_CAPTURE_RADIO_HKV2;
header->pltform_type = CFR_PLATFORM_TYPE_ARM;
header->Reserved = 0;
- header->u.meta_v1.status = tx_evt_param.status;
+ header->u.meta_v1.status = (tx_evt_param.status &
+ PEER_CFR_CAPTURE_EVT_STATUS_MASK)?0:1;
header->u.meta_v1.channel_bw = tx_evt_param.bandwidth;
header->u.meta_v1.phy_mode = tx_evt_param.phy_mode;
header->u.meta_v1.prim20_chan = tx_evt_param.primary_20mhz_chan;
diff --git a/tools/linux/peerstats.c b/tools/linux/peerstats.c
new file mode 100644
index 0000000..adb2bcb
--- /dev/null
+++ b/tools/linux/peerstats.c
@@ -0,0 +1,365 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+/**
+ * file: peer rate statitistics application
+ * This file provides framework to display peer rate statistics
+ */
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <qcatools_lib.h>
+#include <dp_rate_stats_pub.h>
+
+#ifndef min
+#define min(x, y) ((x) < (y) ? (x) : (y))
+#else
+#error confilicting defs of min
+#endif
+
+#define DP_PEER_STATS_PRINT(fmt, ...) \
+ do { \
+ printf(fmt, ##__VA_ARGS__); \
+ printf("\n"); \
+ } while (0)
+
+char interface[IFNAMSIZ];
+
+static void dp_peer_rx_rate_stats_print(uint8_t *peer_mac,
+ uint64_t peer_cookie,
+ void *buffer,
+ uint32_t buffer_len)
+{
+ int i = 0;
+ struct wlan_rx_rate_stats *rx_stats;
+
+ rx_stats = (struct wlan_rx_rate_stats *)buffer;
+ DP_PEER_STATS_PRINT("\n......................................");
+ DP_PEER_STATS_PRINT("......................................");
+ DP_PEER_STATS_PRINT("PEER %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n",
+ peer_mac[0],
+ peer_mac[1],
+ peer_mac[2],
+ peer_mac[3],
+ peer_mac[4],
+ peer_mac[5]);
+ DP_PEER_STATS_PRINT("\tpeer cookie: %016llx\n",
+ peer_cookie);
+ DP_PEER_STATS_PRINT("\n..............................................");
+ DP_PEER_STATS_PRINT("................................");
+ DP_PEER_STATS_PRINT("................................................");
+ DP_PEER_STATS_PRINT(".................................\n");
+ DP_PEER_STATS_PRINT("\tRx statistics:");
+ DP_PEER_STATS_PRINT(" %10s | %10s | %10s | %10s | %10s | %10s",
+ "rate",
+ "rix",
+ "bytes",
+ "msdus",
+ "mpdus",
+ "ppdus");
+ DP_PEER_STATS_PRINT("\t\t%10s | %10s | %10s | %10s | %10s | %10s |",
+ "retries",
+ "rssi",
+ "rssi 1 p20",
+ "rssi 1 e20",
+ "rssi 1 e40",
+ "rssi 1 e80");
+ DP_PEER_STATS_PRINT(" | %10s | | %10s | %10s | %10s | %10s | %10s",
+ "rssi 2 p20",
+ "rssi 2 e20",
+ "rssi 2 e40",
+ "rssi 2 e80",
+ "rssi 3 p20",
+ "rssi 3 e20");
+ DP_PEER_STATS_PRINT(" | %10s | %10s | %10s | %10s | %10s | %10s\n\n\n",
+ "rssi 3 e40",
+ "rssi 3 e80",
+ "rssi 4 p20",
+ "rssi 4 e20",
+ "rssi 4 e40",
+ "rssi 4 e80");
+
+ for (i = 0; i < WLANSTATS_CACHE_SIZE; i++) {
+ DP_PEER_STATS_PRINT("\t\t%10u | %10u | %10u | %10u | %10u |",
+ rx_stats->rate,
+ rx_stats->rix,
+ rx_stats->num_bytes,
+ rx_stats->num_msdus,
+ rx_stats->num_mpdus
+ );
+ DP_PEER_STATS_PRINT(" %10u | %10u | %10u | %10u | %10u |",
+ rx_stats->num_ppdus,
+ rx_stats->num_retries,
+ rx_stats->num_sgi,
+ rx_stats->avg_rssi,
+ rx_stats->avg_rssi_ant[0][0]);
+ DP_PEER_STATS_PRINT(" %10u | %10u | %10u | %10u | %10u |",
+ rx_stats->avg_rssi_ant[0][1],
+ rx_stats->avg_rssi_ant[0][2],
+ rx_stats->avg_rssi_ant[0][3],
+ rx_stats->avg_rssi_ant[1][0],
+ rx_stats->avg_rssi_ant[1][1]);
+ DP_PEER_STATS_PRINT(" %10u | %10u | %10u | %10u | %10u |",
+ rx_stats->avg_rssi_ant[1][2],
+ rx_stats->avg_rssi_ant[1][3],
+ rx_stats->avg_rssi_ant[2][0],
+ rx_stats->avg_rssi_ant[2][1],
+ rx_stats->avg_rssi_ant[2][2]);
+ DP_PEER_STATS_PRINT(" %10u | %10u | %10u | %10u | %10u\n\n\n",
+ rx_stats->avg_rssi_ant[2][3],
+ rx_stats->avg_rssi_ant[3][0],
+ rx_stats->avg_rssi_ant[3][1],
+ rx_stats->avg_rssi_ant[3][2],
+ rx_stats->avg_rssi_ant[3][3]);
+ rx_stats = rx_stats + 1;
+ }
+}
+
+static void
+dp_peer_tx_sojourn_stats_print(uint8_t *peer_mac,
+ uint64_t peer_cookie,
+ struct wlan_tx_sojourn_stats *sojourn_stats)
+{
+ uint8_t tid;
+
+ DP_PEER_STATS_PRINT("\n..........................................");
+ DP_PEER_STATS_PRINT("....................................");
+ DP_PEER_STATS_PRINT("....................................");
+ DP_PEER_STATS_PRINT(".........................................\n");
+ DP_PEER_STATS_PRINT("PEER%02hhx:%02hhx:%02hhx:%02hhx%02hhx:%02hhx\n",
+ peer_mac[0],
+ peer_mac[1],
+ peer_mac[2],
+ peer_mac[3],
+ peer_mac[4],
+ peer_mac[5]);
+ DP_PEER_STATS_PRINT("\tPEER Cookie: %016llx\n",
+ peer_cookie);
+ DP_PEER_STATS_PRINT("\n...........................................");
+ DP_PEER_STATS_PRINT("...................................");
+ DP_PEER_STATS_PRINT("..................................");
+ DP_PEER_STATS_PRINT("............................................");
+ DP_PEER_STATS_PRINT("\n\tSojourn statistics:\n");
+ DP_PEER_STATS_PRINT("\t\t%10s %10s %20s %20s\n",
+ "tid",
+ "ave",
+ "sum",
+ "num");
+
+ for (tid = 0; tid < WLAN_DATA_TID_MAX; tid++) {
+ /* change sum_sojourn_msdu data type to u64 */
+ DP_PEER_STATS_PRINT("\t\t%10d %10u %20u %20u\n",
+ tid,
+ sojourn_stats->avg_sojourn_msdu[tid],
+ sojourn_stats->sum_sojourn_msdu[tid],
+ sojourn_stats->num_msdus[tid]);
+ }
+ DP_PEER_STATS_PRINT("\n...........................................");
+ DP_PEER_STATS_PRINT("...................................");
+ DP_PEER_STATS_PRINT("...................................");
+ DP_PEER_STATS_PRINT("...........................................\n");
+}
+
+static void dp_peer_tx_rate_stats_print(uint8_t *peer_mac,
+ uint64_t peer_cookie,
+ void *buffer,
+ uint32_t buffer_len)
+{
+ int i = 0;
+ struct wlan_tx_rate_stats *tx_stats;
+ struct wlan_tx_sojourn_stats *sojourn_stats;
+
+ if (buffer_len < (WLANSTATS_CACHE_SIZE *
+ sizeof(struct wlan_tx_rate_stats))
+ + sizeof(struct wlan_tx_sojourn_stats)) {
+ DP_PEER_STATS_PRINT("invalid buffer len, return");
+ return;
+ }
+ tx_stats = (struct wlan_tx_rate_stats *)buffer;
+ DP_PEER_STATS_PRINT("\n...........................................");
+ DP_PEER_STATS_PRINT("...................................");
+ DP_PEER_STATS_PRINT("...................................");
+ DP_PEER_STATS_PRINT("...........................................\n");
+ DP_PEER_STATS_PRINT("PEER%02hhx:%02hhx:%02hhx:%02hhx%02hhx:%02hhx\n\n",
+ peer_mac[0],
+ peer_mac[1],
+ peer_mac[2],
+ peer_mac[3],
+ peer_mac[4],
+ peer_mac[5]);
+ DP_PEER_STATS_PRINT("\tPEER Cookie: %016llx",
+ peer_cookie);
+ DP_PEER_STATS_PRINT("\n...........................................");
+ DP_PEER_STATS_PRINT("...................................");
+ DP_PEER_STATS_PRINT("...................................");
+ DP_PEER_STATS_PRINT("...........................................\n");
+ DP_PEER_STATS_PRINT("\tTx statistics:\n");
+ DP_PEER_STATS_PRINT("\t\t%10s | %10s | %10s | %10s | %10s",
+ "rate",
+ "rix",
+ "attempts",
+ "success",
+ "ppdus");
+ for (i = 0; i < WLANSTATS_CACHE_SIZE; i++) {
+ DP_PEER_STATS_PRINT("\t\t%10u | %10u | %10u | %10u | %10u\n",
+ tx_stats->rate,
+ tx_stats->rix,
+ tx_stats->mpdu_attempts,
+ tx_stats->mpdu_success,
+ tx_stats->num_ppdus);
+ tx_stats = tx_stats + 1;
+ }
+
+ sojourn_stats = buffer + (WLANSTATS_CACHE_SIZE *
+ sizeof(struct wlan_tx_rate_stats));
+ dp_peer_tx_sojourn_stats_print(peer_mac, peer_cookie, sojourn_stats);
+
+ return;
+}
+
+static void dp_peer_stats_handler(uint32_t cache_type,
+ uint8_t *peer_mac,
+ uint64_t peer_cookie,
+ void *buffer,
+ uint32_t buffer_len)
+{
+ switch (cache_type) {
+ case DP_PEER_RX_RATE_STATS:
+ dp_peer_rx_rate_stats_print(peer_mac, peer_cookie,
+ buffer, buffer_len);
+ break;
+ case DP_PEER_TX_RATE_STATS:
+ dp_peer_tx_rate_stats_print(peer_mac, peer_cookie,
+ buffer, buffer_len);
+ break;
+ }
+}
+
+static void
+dp_peer_stats_event_callback(char *ifname,
+ uint32_t cmdid,
+ uint8_t *data,
+ size_t len)
+{
+ struct nlattr *tb_array[QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_MAX + 1];
+ struct nlattr *tb;
+ void *buffer = NULL;
+ uint32_t buffer_len = 0;
+ uint8_t *peer_mac;
+ uint32_t cache_type;
+ uint64_t peer_cookie;
+
+ if (cmdid != QCA_NL80211_VENDOR_SUBCMD_PEER_STATS_CACHE_FLUSH) {
+ /* ignore anyother events*/
+ return;
+ }
+
+ if (strncmp(interface, ifname, sizeof(interface)) != 0) {
+ /* ignore events for other interfaces*/
+ return;
+ }
+
+ if (nla_parse(tb_array, QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_MAX,
+ (struct nlattr *)data, len, NULL)) {
+ printf("INVALID EVENT\n");
+ return;
+ }
+
+ tb = tb_array[QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_TYPE];
+ if (!tb) {
+ printf("#############%s:%d\n", __func__, __LINE__);
+ return;
+ }
+ cache_type = nla_get_u32(tb);
+
+ tb = tb_array[QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_PEER_MAC];
+ if (!tb) {
+ printf("#############%s:%d\n", __func__, __LINE__);
+ return;
+ }
+ peer_mac = (uint8_t *)nla_data(tb);
+
+ tb = tb_array[QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_DATA];
+ if (tb) {
+ buffer = (void *)nla_data(tb);
+ buffer_len = nla_len(tb);
+ }
+
+ tb = tb_array[QCA_WLAN_VENDOR_ATTR_PEER_STATS_CACHE_PEER_COOKIE];
+ if (!tb) {
+ printf("#############%s:%d\n", __func__, __LINE__);
+ return;
+ }
+ peer_cookie = nla_get_u64(tb);
+ if (!buffer) {
+ printf("#############%s:%d\n", __func__, __LINE__);
+ return;
+ }
+
+ dp_peer_stats_handler(cache_type, peer_mac, peer_cookie,
+ buffer, buffer_len);
+}
+
+int main(int argc, char *argv[])
+{
+ int err = 0;
+ wifi_cfg80211_context cfg80211_ctxt;
+ char *ifname;
+ int num_msecs = 0;
+ int status = 0;
+
+ if (argc < 2) {
+ fprintf(stderr, "Invalid commands args\n");
+ return -EIO;
+ }
+
+ /* Reset the cfg80211 context to 0 if the application does not pass
+ * custom private event and command sockets. In this case, the default
+ * port is used for netlink communication.
+ */
+ memset(&cfg80211_ctxt, 0, sizeof(wifi_cfg80211_context));
+
+ ifname = argv[1];
+ memcpy(interface, ifname, sizeof(interface));
+ cfg80211_ctxt.event_callback = dp_peer_stats_event_callback;
+
+ err = wifi_init_nl80211(&cfg80211_ctxt);
+ if (err) {
+ fprintf(stderr, "unable to create NL socket\n");
+ return -EIO;
+ }
+
+ /* Starting event thread to listen for responses*/
+ if (wifi_nl80211_start_event_thread(&cfg80211_ctxt)) {
+ fprintf(stderr, "Unable to setup nl80211 event thread\n");
+ status = -EIO;
+ goto cleanup;
+ }
+
+ while (true) {
+ /*sleep for 1 ms*/
+ usleep(1000);
+ num_msecs++;
+ }
+
+ wifi_destroy_nl80211(&cfg80211_ctxt);
+ return 0;
+
+cleanup:
+ wifi_destroy_nl80211(&cfg80211_ctxt);
+ return status;
+}
diff --git a/umac/dfs/core/src/misc/dfs_zero_cac.c b/umac/dfs/core/src/misc/dfs_zero_cac.c
index 9488f9e..25442b6 100644
--- a/umac/dfs/core/src/misc/dfs_zero_cac.c
+++ b/umac/dfs/core/src/misc/dfs_zero_cac.c
@@ -95,6 +95,8 @@
#include "wlan_dfs_utils_api.h"
#include "dfs_internal.h"
#include "dfs_etsi_precac.h"
+#include "target_if.h"
+#include "wlan_dfs_init_deinit_api.h"
void dfs_zero_cac_reset(struct wlan_dfs *dfs)
{
@@ -102,7 +104,6 @@
dfs_get_override_precac_timeout(dfs,
&(dfs->dfs_precac_timeout_override));
- qdf_timer_sync_cancel(&dfs->dfs_precac_timer);
dfs->dfs_precac_primary_freq = 0;
dfs->dfs_precac_secondary_freq = 0;
@@ -120,9 +121,9 @@
PRECAC_LIST_UNLOCK(dfs);
}
-void dfs_zero_cac_timer_detach(struct wlan_dfs *dfs)
+void dfs_zero_cac_timer_detach(struct dfs_soc_priv_obj *dfs_soc_obj)
{
- qdf_timer_free(&dfs->dfs_precac_timer);
+ qdf_timer_free(&dfs_soc_obj->dfs_precac_timer);
}
int dfs_override_precac_timeout(struct wlan_dfs *dfs, int precac_timeout)
@@ -265,30 +266,115 @@
return ret_val;
}
+#ifdef QCA_SUPPORT_AGILE_DFS
+void dfs_find_pdev_for_agile_precac(struct wlan_objmgr_pdev *pdev,
+ uint8_t *cur_precac_dfs_index)
+{
+ struct wlan_dfs *dfs;
+ struct dfs_soc_priv_obj *dfs_soc_obj;
+ struct wlan_objmgr_psoc *psoc;
+
+ dfs = wlan_pdev_get_dfs_obj(pdev);
+ psoc = wlan_pdev_get_psoc(pdev);
+
+ dfs_soc_obj = dfs->dfs_soc_obj;
+
+ *cur_precac_dfs_index =
+ (dfs_soc_obj->cur_precac_dfs_index + 1) % dfs_soc_obj->num_dfs_privs;
+}
+
+void dfs_prepare_agile_precac_chan(struct wlan_dfs *dfs)
+{
+ struct wlan_objmgr_psoc *psoc;
+ struct wlan_objmgr_pdev *pdev;
+ struct wlan_dfs *temp_dfs;
+ struct dfs_soc_priv_obj *dfs_soc_obj;
+ struct wlan_lmac_if_dfs_tx_ops *dfs_tx_ops;
+ uint8_t ch_freq = 0;
+ uint8_t cur_dfs_idx = 0;
+ int i;
+
+ psoc = wlan_pdev_get_psoc(dfs->dfs_pdev_obj);
+ dfs_soc_obj = dfs->dfs_soc_obj;
+
+ dfs_tx_ops = wlan_psoc_get_dfs_txops(psoc);
+
+ pdev = dfs->dfs_pdev_obj;
+
+ for (i = 0; i < dfs_soc_obj->num_dfs_privs; i++) {
+ dfs_find_pdev_for_agile_precac(pdev, &cur_dfs_idx);
+ dfs_soc_obj->cur_precac_dfs_index = cur_dfs_idx;
+ temp_dfs = dfs_soc_obj->dfs_priv[cur_dfs_idx].dfs;
+ pdev = temp_dfs->dfs_pdev_obj;
+ if (!dfs_soc_obj->dfs_priv[cur_dfs_idx].agile_precac_active)
+ continue;
+
+ dfs_find_vht80_chan_for_agile_precac(temp_dfs,
+ &ch_freq,
+ temp_dfs->dfs_curchan->dfs_ch_vhtop_ch_freq_seg1,
+ temp_dfs->dfs_curchan->dfs_ch_vhtop_ch_freq_seg2);
+
+ if (!ch_freq) {
+ qdf_info(" %s : %d No preCAC required channels left in current pdev: %pK",
+ __func__, __LINE__, pdev);
+ continue;
+ } else {
+ break;
+ }
+ }
+
+ if (ch_freq) {
+ qdf_info("%s : %d ADFS channel set request sent for pdev: %pK ch_freq: %d",
+ __func__, __LINE__, pdev, ch_freq);
+ if (dfs_tx_ops && dfs_tx_ops->dfs_agile_ch_cfg_cmd)
+ dfs_tx_ops->dfs_agile_ch_cfg_cmd(pdev, &ch_freq);
+ else
+ dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
+ "dfs_tx_ops=%pK", dfs_tx_ops);
+ } else {
+ qdf_info("No channels in preCAC required list");
+ }
+}
+#endif
+
#define VHT80_IEEE_FREQ_OFFSET 6
void dfs_mark_precac_dfs(struct wlan_dfs *dfs,
- uint8_t is_radar_found_on_secondary_seg)
+ uint8_t is_radar_found_on_secondary_seg, uint8_t detector_id)
{
struct dfs_precac_entry *precac_entry = NULL, *tmp_precac_entry = NULL;
uint8_t found = 0;
+ struct wlan_objmgr_psoc *psoc;
+ struct dfs_soc_priv_obj *dfs_soc_obj;
- dfs_debug(dfs, WLAN_DEBUG_DFS,
- "is_radar_found_on_secondary_seg = %u secondary_freq = %u primary_freq = %u",
- is_radar_found_on_secondary_seg,
- dfs->dfs_precac_secondary_freq,
- dfs->dfs_precac_primary_freq);
+ psoc = wlan_pdev_get_psoc(dfs->dfs_pdev_obj);
+ dfs_soc_obj = dfs->dfs_soc_obj;
- /*
- * Even if radar found on primary, we need to move the channel from
- * precac-required-list and precac-done-list to precac-nol-list.
- */
- PRECAC_LIST_LOCK(dfs);
- if (!TAILQ_EMPTY(&dfs->dfs_precac_required_list)) {
- TAILQ_FOREACH_SAFE(precac_entry,
- &dfs->dfs_precac_required_list,
- pe_list,
- tmp_precac_entry) {
+ if (is_radar_found_on_secondary_seg) {
+ dfs_debug(dfs, WLAN_DEBUG_DFS,
+ "is_radar_found_on_secondary_seg = %u secondary_freq = %u primary_freq = %u",
+ is_radar_found_on_secondary_seg,
+ dfs->dfs_precac_secondary_freq,
+ dfs->dfs_precac_primary_freq);
+ } else {
+ dfs->dfs_precac_secondary_freq = dfs->dfs_agile_precac_freq;
+ dfs_debug(dfs, WLAN_DEBUG_DFS,
+ "agile_precac_freq = %u ",
+ dfs->dfs_agile_precac_freq);
+ }
+
+ if (detector_id != AGILE_DETECTOR_ID) {
+ /*
+ * Even if radar found on primary, we need to move
+ * the channel from precac-required-list and precac-done-list
+ * to precac-nol-list.
+ */
+ PRECAC_LIST_LOCK(dfs);
+ if (!TAILQ_EMPTY(&dfs->dfs_precac_required_list)) {
+ TAILQ_FOREACH_SAFE(precac_entry,
+ &dfs->dfs_precac_required_list,
+ pe_list,
+ tmp_precac_entry) {
/*
* If on primary then use IS_WITHIN_RANGE else use
* equality directly.
@@ -300,52 +386,110 @@
precac_entry->vht80_freq,
VHT80_IEEE_FREQ_OFFSET)) {
TAILQ_REMOVE(&dfs->dfs_precac_required_list,
- precac_entry, pe_list);
+ precac_entry, pe_list);
dfs_debug(dfs, WLAN_DEBUG_DFS,
- "removing the freq = %u from required list and adding to NOL list",
- precac_entry->vht80_freq);
+ "removing the freq = %u from required list and adding to NOL list",
+ precac_entry->vht80_freq);
TAILQ_INSERT_TAIL(&dfs->dfs_precac_nol_list,
- precac_entry, pe_list);
+ precac_entry, pe_list);
qdf_timer_mod(&precac_entry->precac_nol_timer,
- dfs_get_nol_timeout(dfs)*1000);
+ dfs_get_nol_timeout(dfs) * 1000);
found = 1;
break;
+ }
}
}
- }
- /* If not found in precac-required-list remove from precac-done-list */
- if (!found && !TAILQ_EMPTY(&dfs->dfs_precac_done_list)) {
- TAILQ_FOREACH_SAFE(precac_entry,
- &dfs->dfs_precac_done_list,
- pe_list,
- tmp_precac_entry) {
- /*
- * If on primary then use IS_WITHIN_RANGE else use
- * equality directly.
- */
- if (is_radar_found_on_secondary_seg ?
+ /*
+ * If not found in precac-required-list
+ * remove from precac-done-list
+ */
+ if (!found && !TAILQ_EMPTY(&dfs->dfs_precac_done_list)) {
+ TAILQ_FOREACH_SAFE(precac_entry,
+ &dfs->dfs_precac_done_list,
+ pe_list,
+ tmp_precac_entry) {
+ /*
+ * If on primary then use IS_WITHIN_RANGE
+ * else use equality directly.
+ */
+ if (is_radar_found_on_secondary_seg ?
(dfs->dfs_precac_secondary_freq ==
precac_entry->vht80_freq) :
IS_WITHIN_RANGE(
dfs->dfs_curchan->dfs_ch_ieee,
precac_entry->vht80_freq, 6)) {
- TAILQ_REMOVE(&dfs->dfs_precac_done_list,
- precac_entry, pe_list);
+ TAILQ_REMOVE(&dfs->dfs_precac_done_list,
+ precac_entry, pe_list);
- dfs_debug(dfs, WLAN_DEBUG_DFS,
- "removing the the freq = %u from done list and adding to NOL list",
- precac_entry->vht80_freq);
- TAILQ_INSERT_TAIL(&dfs->dfs_precac_nol_list,
+ dfs_debug(dfs, WLAN_DEBUG_DFS,
+ "removing the freq = %u from done list and adding to NOL list",
+ precac_entry->vht80_freq);
+ TAILQ_INSERT_TAIL(
+ &dfs->dfs_precac_nol_list,
precac_entry, pe_list);
- qdf_timer_mod(&precac_entry->precac_nol_timer,
- dfs_get_nol_timeout(dfs)*1000);
- break;
+ qdf_timer_mod(
+ &precac_entry->precac_nol_timer,
+ dfs_get_nol_timeout(dfs) * 1000);
+ break;
+ }
}
}
+ PRECAC_LIST_UNLOCK(dfs);
+ } else {
+ PRECAC_LIST_LOCK(dfs);
+ if (!TAILQ_EMPTY(&dfs->dfs_precac_required_list)) {
+ TAILQ_FOREACH_SAFE(precac_entry,
+ &dfs->dfs_precac_required_list,
+ pe_list,
+ tmp_precac_entry) {
+ if (dfs->dfs_precac_secondary_freq ==
+ precac_entry->vht80_freq) {
+ TAILQ_REMOVE(&dfs->dfs_precac_required_list,
+ precac_entry, pe_list);
+
+ dfs_debug(dfs, WLAN_DEBUG_DFS,
+ "removing the freq = %u from required list and adding to NOL list",
+ precac_entry->vht80_freq);
+ TAILQ_INSERT_TAIL(&dfs->dfs_precac_nol_list,
+ precac_entry, pe_list);
+ qdf_timer_mod(&precac_entry->precac_nol_timer,
+ dfs_get_nol_timeout(dfs) * 1000);
+ found = 1;
+ break;
+ }
+ }
+ }
+
+ /* If not found in precac-required-list
+ * remove from precac-done-list
+ */
+ if (!found && !TAILQ_EMPTY(&dfs->dfs_precac_done_list)) {
+ TAILQ_FOREACH_SAFE(precac_entry,
+ &dfs->dfs_precac_done_list,
+ pe_list,
+ tmp_precac_entry) {
+ if (dfs->dfs_precac_secondary_freq ==
+ precac_entry->vht80_freq) {
+ TAILQ_REMOVE(&dfs->dfs_precac_done_list,
+ precac_entry, pe_list);
+
+ dfs_debug(dfs, WLAN_DEBUG_DFS,
+ "removing the the freq = %u from done list and adding to NOL list",
+ precac_entry->vht80_freq);
+ TAILQ_INSERT_TAIL(
+ &dfs->dfs_precac_nol_list,
+ precac_entry, pe_list);
+ qdf_timer_mod(
+ &precac_entry->precac_nol_timer,
+ dfs_get_nol_timeout(dfs) * 1000);
+ break;
+ }
+ }
+ }
+ PRECAC_LIST_UNLOCK(dfs);
}
- PRECAC_LIST_UNLOCK(dfs);
/* TO BE DONE xxx:- Need to lock the channel change */
/*
@@ -353,10 +497,10 @@
* channel change will happen after RANDOM channel selection anyway.
*/
- if (dfs->dfs_precac_timer_running) {
+ if (dfs_soc_obj->dfs_precac_timer_running) {
/* Cancel the PreCAC timer */
- qdf_timer_stop(&dfs->dfs_precac_timer);
- dfs->dfs_precac_timer_running = 0;
+ qdf_timer_stop(&dfs_soc_obj->dfs_precac_timer);
+ dfs_soc_obj->dfs_precac_timer_running = 0;
/*
* Change the channel
@@ -368,19 +512,57 @@
if (dfs_is_ap_cac_timer_running(dfs)) {
dfs->dfs_defer_precac_channel_change = 1;
dfs_debug(dfs, WLAN_DEBUG_DFS,
- "Primary CAC is running, defer the channel change"
- );
+ "Primary CAC is running, defer the channel change"
+ );
} else {
dfs_mlme_channel_change_by_precac(
dfs->dfs_pdev_obj);
}
+ } else {
+ dfs_debug(dfs, WLAN_DEBUG_DFS,
+ "PreCAC timer interrupted due to RADAR, Sending Agile channel set command"
+ );
+ dfs_prepare_agile_precac_chan(dfs);
}
}
}
+#ifdef QCA_SUPPORT_AGILE_DFS
+void dfs_process_ocac_complete(struct wlan_objmgr_pdev *pdev,
+ uint32_t ocac_status,
+ uint32_t center_freq)
+{
+ struct wlan_dfs *dfs = NULL;
+
+ dfs = wlan_pdev_get_dfs_obj(pdev);
+
+ /* STOP TIMER irrespective of status */
+ utils_dfs_cancel_precac_timer(pdev);
+ if (ocac_status == OCAC_RESET) {
+ dfs_debug(NULL, WLAN_DEBUG_DFS_ALWAYS,
+ "PreCAC timer reset, Sending Agile chan set command");
+ dfs_prepare_agile_precac_chan(dfs);
+ } else if (ocac_status == OCAC_CANCEL) {
+ dfs_debug(NULL, WLAN_DEBUG_DFS_ALWAYS,
+ "PreCAC timer abort, agile precac stopped");
+ } else if (ocac_status == OCAC_SUCCESS) {
+ dfs_debug(NULL, WLAN_DEBUG_DFS_ALWAYS,
+ "PreCAC timer Completed for agile freq: %d",
+ center_freq);
+ /*
+ * TRIGGER agile precac timer with 0sec timeout
+ * with ocac_status 0 for old pdev
+ */
+ dfs_start_agile_precac_timer(dfs, center_freq, ocac_status);
+ } else {
+ dfs_debug(NULL, WLAN_DEBUG_DFS_ALWAYS, "Error Unknown");
+ }
+}
+#endif
+
bool dfs_is_precac_timer_running(struct wlan_dfs *dfs)
{
- return dfs->dfs_precac_timer_running ? true : false;
+ return dfs->dfs_soc_obj->dfs_precac_timer_running ? true : false;
}
#define VHT80_IEEE_FREQ_OFFSET 6
@@ -498,59 +680,102 @@
{
struct dfs_precac_entry *precac_entry, *tmp_precac_entry;
struct wlan_dfs *dfs = NULL;
+ struct dfs_soc_priv_obj *dfs_soc_obj = NULL;
+ uint32_t current_time;
- OS_GET_TIMER_ARG(dfs, struct wlan_dfs *);
- dfs->dfs_precac_timer_running = 0;
+ OS_GET_TIMER_ARG(dfs_soc_obj, struct dfs_soc_priv_obj *);
- /*
- * Remove the HVT80 freq from the precac-required-list and add it to the
- * precac-done-list
- */
+ dfs = dfs_soc_obj->dfs_priv[dfs_soc_obj->cur_precac_dfs_index].dfs;
+ dfs_soc_obj->dfs_precac_timer_running = 0;
- PRECAC_LIST_LOCK(dfs);
- if (!TAILQ_EMPTY(&dfs->dfs_precac_required_list)) {
- TAILQ_FOREACH_SAFE(precac_entry,
- &dfs->dfs_precac_required_list,
- pe_list,
- tmp_precac_entry) {
- if (dfs->dfs_precac_secondary_freq ==
- precac_entry->vht80_freq) {
+ if (!dfs->dfs_agile_precac_enable) {
+ /*
+ * Remove the HT80 freq from the precac-required-list
+ * and add it to the precac-done-list
+ */
+
+ PRECAC_LIST_LOCK(dfs);
+ if (!TAILQ_EMPTY(&dfs->dfs_precac_required_list)) {
+ TAILQ_FOREACH_SAFE(precac_entry,
+ &dfs->dfs_precac_required_list,
+ pe_list,
+ tmp_precac_entry) {
+ if (dfs->dfs_precac_secondary_freq !=
+ precac_entry->vht80_freq)
+ continue;
+
TAILQ_REMOVE(&dfs->dfs_precac_required_list,
- precac_entry, pe_list);
+ precac_entry, pe_list);
dfs_debug(dfs, WLAN_DEBUG_DFS,
- "removing the the freq = %u from required list and adding to done list",
- precac_entry->vht80_freq);
+ "removing the the freq = %u from required list and adding to done list",
+ precac_entry->vht80_freq);
TAILQ_INSERT_TAIL(&dfs->dfs_precac_done_list,
- precac_entry, pe_list);
+ precac_entry, pe_list);
break;
}
}
- }
- PRECAC_LIST_UNLOCK(dfs);
+ PRECAC_LIST_UNLOCK(dfs);
- dfs_debug(dfs, WLAN_DEBUG_DFS,
- "Pre-cac expired, Precac Secondary chan %u curr time %d",
- dfs->dfs_precac_secondary_freq,
- (qdf_system_ticks_to_msecs(qdf_system_ticks()) / 1000));
- /*
- * Do vdev restart so that we can change the secondary VHT80 channel.
- */
- dfs_precac_check_home_chan_change(dfs);
+ current_time = qdf_system_ticks_to_msecs(qdf_system_ticks());
+ dfs_debug(dfs, WLAN_DEBUG_DFS,
+ "Pre-cac expired, Precac Secondary chan %u curr time %d",
+ dfs->dfs_precac_secondary_freq,
+ (current_time) / 1000);
+ /*
+ * Do vdev restart so that we can change
+ * the secondary VHT80 channel.
+ */
+ dfs_precac_check_home_chan_change(dfs);
+ } else {
+ current_time = qdf_system_ticks_to_msecs(qdf_system_ticks());
+ dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
+ "Pre-cac expired, Agile Precac chan %u curr time %d",
+ dfs->dfs_agile_precac_freq,
+ current_time / 1000);
+ if (dfs_soc_obj->ocac_status == OCAC_SUCCESS) {
+ dfs_soc_obj->ocac_status = OCAC_RESET;
+ PRECAC_LIST_LOCK(dfs);
+ if (!TAILQ_EMPTY(
+ &dfs->dfs_precac_required_list)) {
+ TAILQ_FOREACH_SAFE(
+ precac_entry,
+ &dfs->dfs_precac_required_list,
+ pe_list,
+ tmp_precac_entry) {
+ if (dfs->dfs_agile_precac_freq !=
+ precac_entry->vht80_freq)
+ continue;
+
+ TAILQ_REMOVE(
+ &dfs->dfs_precac_required_list,
+ precac_entry, pe_list);
+ dfs_info(dfs, WLAN_DEBUG_DFS,
+ "removing the freq = %u from required list and adding to done list",
+ precac_entry->vht80_freq);
+ TAILQ_INSERT_TAIL(
+ &dfs->dfs_precac_done_list,
+ precac_entry, pe_list);
+ break;
+ }
+ }
+ PRECAC_LIST_UNLOCK(dfs);
+ }
+ dfs_prepare_agile_precac_chan(dfs);
+ }
}
-void dfs_zero_cac_timer_init(struct wlan_dfs *dfs)
+void dfs_zero_cac_timer_init(struct dfs_soc_priv_obj *dfs_soc_obj)
{
- qdf_timer_init(NULL,
- &(dfs->dfs_precac_timer),
- dfs_precac_timeout,
- (void *) dfs,
- QDF_TIMER_TYPE_WAKE_APPS);
+ dfs_soc_obj->precac_state_started = false;
+ qdf_timer_init(NULL, &dfs_soc_obj->dfs_precac_timer,
+ dfs_precac_timeout,
+ (void *)dfs_soc_obj,
+ QDF_TIMER_TYPE_WAKE_APPS);
}
void dfs_zero_cac_attach(struct wlan_dfs *dfs)
{
dfs->dfs_precac_timeout_override = -1;
- dfs_zero_cac_timer_init(dfs);
PRECAC_LIST_LOCK_CREATE(dfs);
}
@@ -573,16 +798,24 @@
/* Move the channel from precac-NOL to precac-required-list */
TAILQ_REMOVE(&dfs->dfs_precac_nol_list, precac_entry, pe_list);
dfs_debug(dfs, WLAN_DEBUG_DFS,
- "removing the the freq = %u from PreCAC NOL-list and adding Precac-required list",
- precac_entry->vht80_freq);
- TAILQ_INSERT_TAIL(&dfs->dfs_precac_required_list, precac_entry,
- pe_list);
+ "removing the the freq = %u from PreCAC NOL-list and adding Precac-required list",
+ precac_entry->vht80_freq);
+ TAILQ_INSERT_TAIL(&dfs->dfs_precac_required_list,
+ precac_entry,
+ pe_list);
}
PRECAC_LIST_UNLOCK(dfs);
- /* TO BE DONE xxx : Need to lock the channel change */
- /* Do a channel change */
- dfs_mlme_channel_change_by_precac(dfs->dfs_pdev_obj);
+ if (!dfs->dfs_agile_precac_enable) {
+ /* TO BE DONE xxx : Need to lock the channel change */
+ /* Do a channel change */
+ dfs_mlme_channel_change_by_precac(dfs->dfs_pdev_obj);
+ } else {
+ dfs_debug(dfs, WLAN_DEBUG_DFS,
+ "Precac NOL timeout, sending agile channel set command"
+ );
+ dfs_prepare_agile_precac_chan(dfs);
+ }
}
void dfs_init_precac_list(struct wlan_dfs *dfs)
@@ -719,6 +952,26 @@
}
+#if defined(QCA_SUPPORT_AGILE_DFS) || defined(ATH_SUPPORT_ZERO_CAC_DFS)
+void dfs_agile_soc_obj_init(struct wlan_dfs *dfs,
+ struct wlan_objmgr_psoc *psoc)
+{
+ struct dfs_soc_priv_obj *dfs_soc_obj;
+
+ dfs_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
+ WLAN_UMAC_COMP_DFS);
+ dfs->dfs_psoc_idx = dfs_soc_obj->num_dfs_privs;
+ dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
+ "dfs->dfs_psoc_idx: %d ", dfs->dfs_psoc_idx);
+ dfs_soc_obj->dfs_priv[dfs_soc_obj->num_dfs_privs].dfs = dfs;
+ dfs_soc_obj->num_dfs_privs++;
+ dfs->dfs_soc_obj = dfs_soc_obj;
+
+ dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs_soc_obj->num_dfs_privs: %d ",
+ dfs_soc_obj->num_dfs_privs);
+}
+#endif
+
void dfs_zero_cac_detach(struct wlan_dfs *dfs)
{
dfs_deinit_precac_list(dfs);
@@ -731,13 +984,15 @@
struct dfs_precac_entry *precac_entry;
uint8_t ieee_freq = 0;
- dfs_debug(dfs, WLAN_DEBUG_DFS, "exclude_ieee_freq = %u",
+ dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "exclude_ieee_freq = %u",
exclude_ieee_freq);
PRECAC_LIST_LOCK(dfs);
if (!TAILQ_EMPTY(&dfs->dfs_precac_required_list)) {
TAILQ_FOREACH(precac_entry, &dfs->dfs_precac_required_list,
pe_list) {
+ dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
+ "freq: %d ", precac_entry->vht80_freq);
if (precac_entry->vht80_freq != exclude_ieee_freq) {
ieee_freq = precac_entry->vht80_freq;
break;
@@ -745,27 +1000,75 @@
}
}
PRECAC_LIST_UNLOCK(dfs);
- dfs_debug(dfs, WLAN_DEBUG_DFS, "ieee_freq = %u", ieee_freq);
+ dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "ieee_freq = %u", ieee_freq);
return ieee_freq;
}
void dfs_cancel_precac_timer(struct wlan_dfs *dfs)
{
- qdf_timer_stop(&dfs->dfs_precac_timer);
- dfs->dfs_precac_timer_running = 0;
+ struct dfs_soc_priv_obj *dfs_soc_obj;
+
+ dfs_soc_obj = dfs->dfs_soc_obj;
+ qdf_timer_stop(&dfs_soc_obj->dfs_precac_timer);
+ dfs_soc_obj->dfs_precac_timer_running = 0;
}
-void dfs_start_precac_timer(struct wlan_dfs *dfs, uint8_t precac_chan)
+#ifdef QCA_SUPPORT_AGILE_DFS
+void dfs_start_agile_precac_timer(struct wlan_dfs *dfs, uint8_t precac_chan,
+ uint8_t ocac_status)
+{
+ struct dfs_channel *ichan, lc;
+ uint8_t first_primary_dfs_ch_ieee;
+ int agile_cac_timeout;
+ struct dfs_soc_priv_obj *dfs_soc_obj;
+
+ dfs_soc_obj = dfs->dfs_soc_obj;
+ dfs_soc_obj->dfs_precac_timer_running = 1;
+
+ first_primary_dfs_ch_ieee = precac_chan - VHT80_IEEE_FREQ_OFFSET;
+ ichan = &lc;
+ dfs_mlme_find_dot11_channel(dfs->dfs_pdev_obj,
+ first_primary_dfs_ch_ieee, 0,
+ WLAN_PHYMODE_11AC_VHT80,
+ &ichan->dfs_ch_freq,
+ &ichan->dfs_ch_flags,
+ &ichan->dfs_ch_flagext,
+ &ichan->dfs_ch_ieee,
+ &ichan->dfs_ch_vhtop_ch_freq_seg1,
+ &ichan->dfs_ch_vhtop_ch_freq_seg2);
+ agile_cac_timeout = (dfs->dfs_precac_timeout_override != -1) ?
+ dfs->dfs_precac_timeout_override :
+ dfs_mlme_get_cac_timeout(dfs->dfs_pdev_obj,
+ ichan->dfs_ch_freq,
+ ichan->dfs_ch_vhtop_ch_freq_seg2,
+ ichan->dfs_ch_flags);
+ if (ocac_status == OCAC_SUCCESS) {
+ dfs_soc_obj->ocac_status = OCAC_SUCCESS;
+ agile_cac_timeout = 0;
+ }
+
+ dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
+ "precactimeout = %d", (agile_cac_timeout) * 1000);
+ qdf_timer_mod(&dfs_soc_obj->dfs_precac_timer,
+ (agile_cac_timeout) * 1000);
+}
+#endif
+
+void dfs_start_precac_timer(struct wlan_dfs *dfs,
+ uint8_t precac_chan)
{
struct dfs_channel *ichan, lc;
uint8_t first_primary_dfs_ch_ieee;
int primary_cac_timeout;
int secondary_cac_timeout;
int precac_timeout;
+ struct dfs_soc_priv_obj *dfs_soc_obj;
+ dfs_soc_obj = dfs->dfs_soc_obj;
+ dfs = dfs_soc_obj->dfs_priv[dfs_soc_obj->cur_precac_dfs_index].dfs;
#define EXTRA_TIME_IN_SEC 5
- dfs->dfs_precac_timer_running = 1;
+ dfs_soc_obj->dfs_precac_timer_running = 1;
/*
* Get the first primary ieee chan in the HT80 band and find the channel
@@ -823,7 +1126,7 @@
dfs_debug(dfs, WLAN_DEBUG_DFS,
"precactimeout = %d", (precac_timeout)*1000);
- qdf_timer_mod(&dfs->dfs_precac_timer, (precac_timeout) * 1000);
+ qdf_timer_mod(&dfs_soc_obj->dfs_precac_timer, (precac_timeout) * 1000);
}
void dfs_print_precaclists(struct wlan_dfs *dfs)
@@ -1072,6 +1375,39 @@
}
#endif
+#ifdef QCA_SUPPORT_AGILE_DFS
+void dfs_find_vht80_chan_for_agile_precac(struct wlan_dfs *dfs,
+ uint8_t *ch_freq,
+ uint8_t ch_freq_seg1,
+ uint8_t ch_freq_seg2)
+{
+ uint8_t ieee_freq;
+
+ dfs->dfs_soc_obj->ocac_status = OCAC_RESET;
+ ieee_freq = dfs_get_freq_from_precac_required_list(
+ dfs,
+ ch_freq_seg1);
+ dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
+ "ieee_freq: %d ch_freq_seg1: %d , ch_freq_seg2 : %d ",
+ ieee_freq, ch_freq_seg1, ch_freq_seg2);
+ if (ieee_freq == ch_freq_seg2 && ieee_freq != 0)
+ ieee_freq = dfs_get_freq_from_precac_required_list(
+ dfs,
+ ch_freq_seg2);
+ if (ieee_freq) {
+ dfs->dfs_agile_precac_freq = ieee_freq;
+ /* Start the pre_cac_timer */
+ dfs_start_agile_precac_timer(dfs,
+ dfs->dfs_agile_precac_freq,
+ dfs->dfs_soc_obj->ocac_status);
+ } else {
+ dfs->dfs_agile_precac_freq = 0;
+ }
+
+ *ch_freq = dfs->dfs_agile_precac_freq;
+}
+#endif
+
void dfs_find_vht80_chan_for_precac(struct wlan_dfs *dfs,
uint32_t chan_mode,
uint8_t ch_freq_seg1,
@@ -1089,7 +1425,7 @@
dfs_debug(dfs, WLAN_DEBUG_DFS,
"precac_secondary_freq = %u precac_running = %u",
dfs->dfs_precac_secondary_freq,
- dfs->dfs_precac_timer_running);
+ dfs->dfs_soc_obj->dfs_precac_timer_running);
/*
* If Pre-CAC is enabled then find a center frequency for
@@ -1103,7 +1439,7 @@
* channel. If precac timer is not running then try to
* find a new channel from precac-required-list.
*/
- if (dfs->dfs_precac_timer_running) {
+ if (dfs->dfs_soc_obj->dfs_precac_timer_running) {
/*
* Primary and secondary VHT80 cannot be the
* same. Therefore exclude the primary
@@ -1191,41 +1527,137 @@
struct wlan_objmgr_psoc *psoc;
struct wlan_lmac_if_target_tx_ops *tx_ops;
uint32_t target_type;
+ struct target_psoc_info *tgt_hdl;
+ struct tgt_info *info;
psoc = wlan_pdev_get_psoc(dfs->dfs_pdev_obj);
if (!psoc) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "psoc is NULL");
dfs->dfs_precac_enable = 0;
+ dfs->dfs_agile_precac_enable = 0;
return;
}
tx_ops = &psoc->soc_cb.tx_ops.target_tx_ops;
target_type = lmac_get_target_type(dfs->dfs_pdev_obj);
+ tgt_hdl = (struct target_psoc_info *)wlan_psoc_get_tgt_if_handle(psoc);
+ if (!tgt_hdl) {
+ dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "target_psoc_info is null");
+ return;
+ }
+
+ info = (struct tgt_info *)(&tgt_hdl->info);
+
+ if (!info) {
+ dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "tgt_info is null");
+ return;
+ }
+
/*
* If
* 1) The chip is CASCADE,
- * 3) The user has enabled Pre-CAC and
- * 4) The regdomain the ETSI,
+ * 2) The user has enabled Pre-CAC and
+ * 3) The regdomain the ETSI,
* then enable preCAC.
+ *
+ * OR
+ *
+ * If
+ * 1) The chip has agile_capability enabled
+ * 2) The user has enabled Pre-CAC and
+ * 3) The regdomain the ETSI,
+ * then enable Agile preCAC.
*/
+
if ((1 == value) && tx_ops->tgt_is_tgt_type_qca9984(target_type) &&
(utils_get_dfsdomain(dfs->dfs_pdev_obj) == DFS_ETSI_DOMAIN)) {
dfs->dfs_precac_enable = value;
+ } else if ((1 == value) && (info->wlan_res_cfg.agile_capability == 1) &&
+ (utils_get_dfsdomain(dfs->dfs_pdev_obj) == DFS_ETSI_DOMAIN)) {
+ dfs->dfs_agile_precac_enable = value;
} else {
+ dfs->dfs_agile_precac_enable = 0;
dfs->dfs_precac_enable = 0;
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "preCAC disabled");
}
+
if (dfs_is_precac_timer_running(dfs)) {
dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
"Precac flag changed. Cancel the precac timer");
dfs_cancel_precac_timer(dfs);
+ dfs->dfs_soc_obj->precac_state_started = 0;
}
}
+#ifdef QCA_SUPPORT_AGILE_DFS
+void dfs_agile_precac_start(struct wlan_dfs *dfs)
+{
+ uint8_t agile_freq = 0;
+ uint8_t ocac_status = 0;
+ struct dfs_soc_priv_obj *dfs_soc_obj;
+ uint8_t cur_dfs_idx;
+
+ dfs_soc_obj = dfs->dfs_soc_obj;
+ /*
+ * Initiate first call to start preCAC here, for agile_freq as 0,
+ * and ocac_status as 0
+ */
+
+ qdf_info("%s : %d agile_precac_started: %d",
+ __func__, __LINE__,
+ dfs_soc_obj->precac_state_started);
+
+ if (!dfs_soc_obj->precac_state_started)
+ dfs_soc_obj->cur_precac_dfs_index = dfs->dfs_psoc_idx;
+
+ cur_dfs_idx = dfs_soc_obj->cur_precac_dfs_index;
+ dfs_soc_obj->dfs_priv[cur_dfs_idx].agile_precac_active = true;
+ dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS,
+ " setting true to cur_precac_dfs_index = %d, dfs: %pK",
+ dfs_soc_obj->cur_precac_dfs_index,
+ dfs->dfs_soc_obj->dfs_priv[cur_dfs_idx].dfs);
+
+ if (!dfs->dfs_soc_obj->precac_state_started) {
+ qdf_info("%s : %d Initiated agile precac",
+ __func__, __LINE__);
+ dfs->dfs_soc_obj->precac_state_started = true;
+ dfs_start_agile_precac_timer(dfs,
+ agile_freq,
+ ocac_status);
+ }
+}
+#endif
+
uint32_t dfs_get_precac_enable(struct wlan_dfs *dfs)
{
- return dfs->dfs_precac_enable;
+ struct wlan_objmgr_psoc *psoc;
+ struct target_psoc_info *tgt_hdl;
+ uint32_t retval = 0;
+ struct tgt_info *info;
+
+ psoc = wlan_pdev_get_psoc(dfs->dfs_pdev_obj);
+ if (!psoc) {
+ dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "psoc is NULL");
+ dfs->dfs_agile_precac_enable = 0;
+ retval = 0;
+ }
+
+ tgt_hdl = (struct target_psoc_info *)wlan_psoc_get_tgt_if_handle(psoc);
+
+ info = (struct tgt_info *)(&tgt_hdl->info);
+ if (!tgt_hdl) {
+ dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "target_psoc_info is null");
+ dfs->dfs_agile_precac_enable = 0;
+ retval = 0;
+ }
+
+ if (info->wlan_res_cfg.agile_capability == 0)
+ retval = dfs->dfs_precac_enable;
+ else
+ retval = dfs->dfs_agile_precac_enable;
+
+ return retval;
}
#ifdef WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT
diff --git a/umac/mlme/vdev_mgr/core/src/vdev_mlme_sm_actions.c b/umac/mlme/vdev_mgr/core/src/vdev_mlme_sm_actions.c
index 79e01d0..1b840a4 100644
--- a/umac/mlme/vdev_mgr/core/src/vdev_mlme_sm_actions.c
+++ b/umac/mlme/vdev_mgr/core/src/vdev_mlme_sm_actions.c
@@ -217,15 +217,13 @@
if ((!pdev_mlme->restart_pend_vdev_bmap[0] &&
!pdev_mlme->restart_pend_vdev_bmap[1]) &&
(!pdev_mlme->restart_send_vdev_bmap[0] &&
- !pdev_mlme->restart_send_vdev_bmap[1]))
+ !pdev_mlme->restart_send_vdev_bmap[1])) {
wlan_pdev_mlme_op_clear
(pdev,
WLAN_PDEV_OP_RESTART_INPROGRESS);
wlan_pdev_mlme_op_clear(pdev,
WLAN_PDEV_OP_MBSSID_RESTART);
-
- } else {
- status = QDF_STATUS_SUCCESS;
+ }
}
qdf_spin_unlock_bh(&pdev_mlme->vdev_restart_lock);
diff --git a/wmi/inc/wmi_unified_ap_api.h b/wmi/inc/wmi_unified_ap_api.h
index edf3d01..aa552b9 100644
--- a/wmi/inc/wmi_unified_ap_api.h
+++ b/wmi/inc/wmi_unified_ap_api.h
@@ -56,7 +56,7 @@
struct peer_update_wds_entry_params *param);
QDF_STATUS wmi_unified_vdev_set_neighbour_rx_cmd_send(void *wmi_hdl,
- uint8_t macaddr[IEEE80211_ADDR_LEN],
+ uint8_t macaddr[QDF_MAC_ADDR_SIZE],
struct set_neighbour_rx_params *param);
QDF_STATUS wmi_unified_vdev_config_ratemask_cmd_send(void *wmi_hdl,
@@ -192,7 +192,7 @@
#endif /* WLAN_SUPPORT_FILS */
QDF_STATUS wmi_unified_set_qboost_param_cmd_send(void *wmi_hdl,
- uint8_t macaddr[IEEE80211_ADDR_LEN],
+ uint8_t macaddr[QDF_MAC_ADDR_SIZE],
struct set_qboost_params *param);
QDF_STATUS wmi_unified_gpio_config_cmd_send(void *wmi_hdl,
diff --git a/wmi/inc/wmi_unified_smart_ant_api.h b/wmi/inc/wmi_unified_smart_ant_api.h
index 325d4fd..37636ba 100644
--- a/wmi/inc/wmi_unified_smart_ant_api.h
+++ b/wmi/inc/wmi_unified_smart_ant_api.h
@@ -31,15 +31,15 @@
struct smart_ant_rx_ant_params *param);
QDF_STATUS wmi_unified_smart_ant_set_tx_ant_cmd_send(void *wmi_hdl,
- uint8_t macaddr[IEEE80211_ADDR_LEN],
+ uint8_t macaddr[QDF_MAC_ADDR_SIZE],
struct smart_ant_tx_ant_params *param);
QDF_STATUS wmi_unified_smart_ant_set_training_info_cmd_send(void *wmi_hdl,
- uint8_t macaddr[IEEE80211_ADDR_LEN],
+ uint8_t macaddr[QDF_MAC_ADDR_SIZE],
struct smart_ant_training_info_params *param);
QDF_STATUS wmi_unified_smart_ant_node_config_cmd_send(void *wmi_hdl,
- uint8_t macaddr[IEEE80211_ADDR_LEN],
+ uint8_t macaddr[QDF_MAC_ADDR_SIZE],
struct smart_ant_node_config_params *param);
QDF_STATUS wmi_unified_set_ant_switch_tbl_cmd_send(void *wmi_hdl,
diff --git a/wmi/src/wmi_unified_ap_api.c b/wmi/src/wmi_unified_ap_api.c
index e51d4e2..6476b3a 100644
--- a/wmi/src/wmi_unified_ap_api.c
+++ b/wmi/src/wmi_unified_ap_api.c
@@ -199,7 +199,7 @@
* @return QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
*/
QDF_STATUS wmi_unified_vdev_set_neighbour_rx_cmd_send(void *wmi_hdl,
- uint8_t macaddr[IEEE80211_ADDR_LEN],
+ uint8_t macaddr[QDF_MAC_ADDR_SIZE],
struct set_neighbour_rx_params *param)
{
wmi_unified_t wmi = (wmi_unified_t) wmi_hdl;
@@ -878,7 +878,7 @@
* @return QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
*/
QDF_STATUS wmi_unified_set_qboost_param_cmd_send(void *wmi_hdl,
- uint8_t macaddr[IEEE80211_ADDR_LEN],
+ uint8_t macaddr[QDF_MAC_ADDR_SIZE],
struct set_qboost_params *param)
{
wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
diff --git a/wmi/src/wmi_unified_ap_tlv.c b/wmi/src/wmi_unified_ap_tlv.c
index d11c703..3330ca4 100644
--- a/wmi/src/wmi_unified_ap_tlv.c
+++ b/wmi/src/wmi_unified_ap_tlv.c
@@ -596,7 +596,7 @@
* @return QDF_STATUS_SUCCESS on success and -ve on failure.
*/
static QDF_STATUS send_vdev_set_neighbour_rx_cmd_tlv(wmi_unified_t wmi_handle,
- uint8_t macaddr[IEEE80211_ADDR_LEN],
+ uint8_t macaddr[QDF_MAC_ADDR_SIZE],
struct set_neighbour_rx_params *param)
{
wmi_vdev_filter_nrp_config_cmd_fixed_param *cmd;
@@ -2015,7 +2015,7 @@
*/
static QDF_STATUS
send_set_qboost_param_cmd_tlv(wmi_unified_t wmi_handle,
- uint8_t macaddr[IEEE80211_ADDR_LEN],
+ uint8_t macaddr[QDF_MAC_ADDR_SIZE],
struct set_qboost_params *param)
{
WMI_QBOOST_CFG_CMD_fixed_param *cmd;
diff --git a/wmi/src/wmi_unified_non_tlv.c b/wmi/src/wmi_unified_non_tlv.c
index b14e0d9..4a469f1 100644
--- a/wmi/src/wmi_unified_non_tlv.c
+++ b/wmi/src/wmi_unified_non_tlv.c
@@ -44,7 +44,7 @@
* Return: 0 for success or error code
*/
static QDF_STATUS send_vdev_create_cmd_non_tlv(wmi_unified_t wmi_handle,
- uint8_t macaddr[IEEE80211_ADDR_LEN],
+ uint8_t macaddr[QDF_MAC_ADDR_SIZE],
struct vdev_create_params *param)
{
wmi_vdev_create_cmd *cmd;
@@ -270,7 +270,7 @@
* Return: 0 for success or error code
*/
static QDF_STATUS send_vdev_set_neighbour_rx_cmd_non_tlv(wmi_unified_t wmi_handle,
- uint8_t macaddr[IEEE80211_ADDR_LEN],
+ uint8_t macaddr[QDF_MAC_ADDR_SIZE],
struct set_neighbour_rx_params *param)
{
wmi_vdev_filter_nrp_config_cmd *cmd;
@@ -502,7 +502,7 @@
* Return: 0 for success or error code
*/
static QDF_STATUS send_peer_flush_tids_cmd_non_tlv(wmi_unified_t wmi_handle,
- uint8_t peer_addr[IEEE80211_ADDR_LEN],
+ uint8_t peer_addr[QDF_MAC_ADDR_SIZE],
struct peer_flush_params *param)
{
wmi_peer_flush_tids_cmd *cmd;
@@ -532,7 +532,7 @@
*/
static QDF_STATUS send_peer_delete_cmd_non_tlv(wmi_unified_t wmi_handle,
uint8_t
- peer_addr[IEEE80211_ADDR_LEN],
+ peer_addr[QDF_MAC_ADDR_SIZE],
uint8_t vdev_id)
{
wmi_peer_delete_cmd *cmd;
@@ -616,7 +616,7 @@
* Return: 0 for success or error code
*/
static QDF_STATUS send_peer_param_cmd_non_tlv(wmi_unified_t wmi_handle,
- uint8_t peer_addr[IEEE80211_ADDR_LEN],
+ uint8_t peer_addr[QDF_MAC_ADDR_SIZE],
struct peer_set_params *param)
{
wmi_peer_set_param_cmd *cmd;
@@ -651,7 +651,7 @@
* Return: 0 for success or error code
*/
static QDF_STATUS send_vdev_up_cmd_non_tlv(wmi_unified_t wmi_handle,
- uint8_t bssid[IEEE80211_ADDR_LEN],
+ uint8_t bssid[QDF_MAC_ADDR_SIZE],
struct vdev_up_params *param)
{
wmi_vdev_up_cmd *cmd;
@@ -835,7 +835,7 @@
{
wmi_peer_add_wds_entry_cmd *cmd;
wmi_buf_t buf;
- uint8_t null_macaddr[IEEE80211_ADDR_LEN];
+ uint8_t null_macaddr[QDF_MAC_ADDR_SIZE];
int len = sizeof(wmi_peer_add_wds_entry_cmd);
buf = wmi_buf_alloc(wmi_handle, len);
@@ -843,7 +843,7 @@
WMI_LOGE("%s: wmi_buf_alloc failed", __func__);
return QDF_STATUS_E_NOMEM;
}
- qdf_mem_zero(null_macaddr, IEEE80211_ADDR_LEN);
+ qdf_mem_zero(null_macaddr, QDF_MAC_ADDR_SIZE);
cmd = (wmi_peer_add_wds_entry_cmd *)wmi_buf_data(buf);
WMI_CHAR_ARRAY_TO_MAC_ADDR(param->bridge_addr, &cmd->wds_macaddr);
WMI_CHAR_ARRAY_TO_MAC_ADDR(null_macaddr, &cmd->peer_macaddr);
@@ -1115,7 +1115,8 @@
int len = sizeof(wmi_pdev_set_param_cmd);
if ((param->param_id < wmi_pdev_param_max) &&
- (wmi_handle->pdev_param[param->param_id]
+ wmi_handle->soc->pdev_param &&
+ (wmi_handle->soc->pdev_param[param->param_id]
!= WMI_UNAVAILABLE_PARAM)) {
buf = wmi_buf_alloc(wmi_handle, len);
@@ -1124,7 +1125,7 @@
return QDF_STATUS_E_FAILURE;
}
cmd = (wmi_pdev_set_param_cmd *)wmi_buf_data(buf);
- cmd->param_id = wmi_handle->pdev_param[param->param_id];
+ cmd->param_id = wmi_handle->soc->pdev_param[param->param_id];
cmd->param_value = param->param_value;
return wmi_unified_cmd_send(wmi_handle, buf, len,
WMI_PDEV_SET_PARAM_CMDID);
@@ -1521,7 +1522,8 @@
int len = sizeof(wmi_vdev_set_param_cmd);
if ((param->param_id < wmi_vdev_param_max) &&
- (wmi_handle->vdev_param[param->param_id] !=
+ wmi_handle->soc->vdev_param &&
+ (wmi_handle->soc->vdev_param[param->param_id] !=
WMI_UNAVAILABLE_PARAM)) {
buf = wmi_buf_alloc(wmi_handle, len);
@@ -1535,7 +1537,7 @@
#else
cmd->vdev_id = param->if_id;
#endif
- cmd->param_id = wmi_handle->vdev_param[param->param_id];
+ cmd->param_id = wmi_handle->soc->vdev_param[param->param_id];
cmd->param_value = param->param_value;
return wmi_unified_cmd_send(wmi_handle, buf, len,
WMI_VDEV_SET_PARAM_CMDID);
@@ -1608,7 +1610,7 @@
* @return QDF_STATUS_SUCCESS on success and -ve on failure.
*/
static QDF_STATUS send_stats_request_cmd_non_tlv(wmi_unified_t wmi_handle,
- uint8_t macaddr[IEEE80211_ADDR_LEN],
+ uint8_t macaddr[QDF_MAC_ADDR_SIZE],
struct stats_request_params *param)
{
wmi_buf_t buf;
@@ -2606,7 +2608,7 @@
* @return QDF_STATUS_SUCCESS on success and -ve on failure.
*/
static QDF_STATUS send_smart_ant_set_tx_ant_cmd_non_tlv(wmi_unified_t wmi_handle,
- uint8_t macaddr[IEEE80211_ADDR_LEN],
+ uint8_t macaddr[QDF_MAC_ADDR_SIZE],
struct smart_ant_tx_ant_params *param)
{
wmi_peer_sant_set_tx_antenna_cmd *cmd;
@@ -2656,7 +2658,7 @@
*/
static QDF_STATUS send_smart_ant_set_training_info_cmd_non_tlv(
wmi_unified_t wmi_handle,
- uint8_t macaddr[IEEE80211_ADDR_LEN],
+ uint8_t macaddr[QDF_MAC_ADDR_SIZE],
struct smart_ant_training_info_params *param)
{
wmi_peer_sant_set_train_antenna_cmd *cmd;
@@ -2709,7 +2711,7 @@
* @return QDF_STATUS_SUCCESS on success and -ve on failure.
*/
static QDF_STATUS send_smart_ant_set_node_config_cmd_non_tlv(wmi_unified_t wmi_handle,
- uint8_t macaddr[IEEE80211_ADDR_LEN],
+ uint8_t macaddr[QDF_MAC_ADDR_SIZE],
struct smart_ant_node_config_params *param)
{
wmi_peer_sant_set_node_config_ops_cmd *cmd;
@@ -3252,7 +3254,7 @@
*/
static QDF_STATUS
send_addba_clearresponse_cmd_non_tlv(wmi_unified_t wmi_handle,
- uint8_t macaddr[IEEE80211_ADDR_LEN],
+ uint8_t macaddr[QDF_MAC_ADDR_SIZE],
struct addba_clearresponse_params *param)
{
wmi_addba_clear_resp_cmd *cmd;
@@ -3282,7 +3284,7 @@
*/
static QDF_STATUS
send_addba_send_cmd_non_tlv(wmi_unified_t wmi_handle,
- uint8_t macaddr[IEEE80211_ADDR_LEN],
+ uint8_t macaddr[QDF_MAC_ADDR_SIZE],
struct addba_send_params *param)
{
wmi_addba_send_cmd *cmd;
@@ -3314,7 +3316,7 @@
*/
static QDF_STATUS
send_delba_send_cmd_non_tlv(wmi_unified_t wmi_handle,
- uint8_t macaddr[IEEE80211_ADDR_LEN],
+ uint8_t macaddr[QDF_MAC_ADDR_SIZE],
struct delba_send_params *param)
{
wmi_delba_send_cmd *cmd;
@@ -3348,7 +3350,7 @@
*/
static QDF_STATUS
send_addba_setresponse_cmd_non_tlv(wmi_unified_t wmi_handle,
- uint8_t macaddr[IEEE80211_ADDR_LEN],
+ uint8_t macaddr[QDF_MAC_ADDR_SIZE],
struct addba_setresponse_params *param)
{
wmi_addba_setresponse_cmd *cmd;
@@ -3381,7 +3383,7 @@
*/
static QDF_STATUS
send_singleamsdu_cmd_non_tlv(wmi_unified_t wmi_handle,
- uint8_t macaddr[IEEE80211_ADDR_LEN],
+ uint8_t macaddr[QDF_MAC_ADDR_SIZE],
struct singleamsdu_params *param)
{
wmi_send_singleamsdu_cmd *cmd;
@@ -3413,7 +3415,7 @@
*/
static QDF_STATUS
send_set_qboost_param_cmd_non_tlv(wmi_unified_t wmi_handle,
- uint8_t macaddr[IEEE80211_ADDR_LEN],
+ uint8_t macaddr[QDF_MAC_ADDR_SIZE],
struct set_qboost_params *param)
{
@@ -5278,7 +5280,7 @@
WMI_SET_CHANNEL_FLAG(w_chan, WMI_CHAN_FLAG_DFS);
WMI_CHAR_ARRAY_TO_MAC_ADDR(((uint8_t *)peer), &body->dest_mac);
- qdf_mem_set(spoof, IEEE80211_ADDR_LEN, 0);
+ qdf_mem_set(spoof, QDF_MAC_ADDR_SIZE, 0);
WMI_CHAR_ARRAY_TO_MAC_ADDR(((uint8_t *)param->spoof_mac_addr),
&body->spoof_bssid);
@@ -5379,7 +5381,7 @@
/* Convert num_vaps to octets:
6*Num_of_vap + 1 (Max BSSID Indicator field) */
param->colocated_bss[1] =
- (param->colocated_bss[1]*IEEE80211_ADDR_LEN)+1;
+ (param->colocated_bss[1]*QDF_MAC_ADDR_SIZE)+1;
colocated_bss_len = param->colocated_bss[1]+2;
qdf_mem_copy(rtt_req->colocated_bssids_info,
param->colocated_bss,
@@ -10069,8 +10071,10 @@
wmi_handle->soc->svc_ids = &svc_ids[0];
populate_non_tlv_service(wmi_handle->services);
populate_non_tlv_events_id(wmi_handle->wmi_events);
- populate_pdev_param_non_tlv(wmi_handle->pdev_param);
- populate_vdev_param_non_tlv(wmi_handle->vdev_param);
+ if (wmi_handle->soc->pdev_param)
+ populate_pdev_param_non_tlv(wmi_handle->soc->pdev_param);
+ if (wmi_handle->soc->vdev_param)
+ populate_vdev_param_non_tlv(wmi_handle->soc->vdev_param);
#ifdef WMI_INTERFACE_EVENT_LOGGING
wmi_handle->soc->buf_offset_command = 0;
diff --git a/wmi/src/wmi_unified_smart_ant_api.c b/wmi/src/wmi_unified_smart_ant_api.c
index 5319b1b..99e13de 100644
--- a/wmi/src/wmi_unified_smart_ant_api.c
+++ b/wmi/src/wmi_unified_smart_ant_api.c
@@ -84,7 +84,7 @@
* @return QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
*/
QDF_STATUS wmi_unified_smart_ant_set_tx_ant_cmd_send(void *wmi_hdl,
- uint8_t macaddr[IEEE80211_ADDR_LEN],
+ uint8_t macaddr[QDF_MAC_ADDR_SIZE],
struct smart_ant_tx_ant_params *param)
{
wmi_unified_t wmi = (wmi_unified_t) wmi_hdl;
@@ -104,7 +104,7 @@
* @return QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
*/
QDF_STATUS wmi_unified_smart_ant_set_training_info_cmd_send(void *wmi_hdl,
- uint8_t macaddr[IEEE80211_ADDR_LEN],
+ uint8_t macaddr[QDF_MAC_ADDR_SIZE],
struct smart_ant_training_info_params *param)
{
wmi_unified_t wmi = (wmi_unified_t) wmi_hdl;
@@ -125,7 +125,7 @@
* @return QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
*/
QDF_STATUS wmi_unified_smart_ant_node_config_cmd_send(void *wmi_hdl,
- uint8_t macaddr[IEEE80211_ADDR_LEN],
+ uint8_t macaddr[QDF_MAC_ADDR_SIZE],
struct smart_ant_node_config_params *param)
{
wmi_unified_t wmi = (wmi_unified_t) wmi_hdl;
diff --git a/wmi/src/wmi_unified_smart_ant_tlv.c b/wmi/src/wmi_unified_smart_ant_tlv.c
index 4487947..33a792f 100644
--- a/wmi/src/wmi_unified_smart_ant_tlv.c
+++ b/wmi/src/wmi_unified_smart_ant_tlv.c
@@ -186,7 +186,7 @@
* @return QDF_STATUS_SUCCESS on success and -ve on failure.
*/
static QDF_STATUS send_smart_ant_set_tx_ant_cmd_tlv(wmi_unified_t wmi_handle,
- uint8_t macaddr[IEEE80211_ADDR_LEN],
+ uint8_t macaddr[QDF_MAC_ADDR_SIZE],
struct smart_ant_tx_ant_params *param)
{
wmi_peer_smart_ant_set_tx_antenna_cmd_fixed_param *cmd;
@@ -319,7 +319,7 @@
*/
static QDF_STATUS send_smart_ant_set_training_info_cmd_tlv(
wmi_unified_t wmi_handle,
- uint8_t macaddr[IEEE80211_ADDR_LEN],
+ uint8_t macaddr[QDF_MAC_ADDR_SIZE],
struct smart_ant_training_info_params *param)
{
wmi_peer_smart_ant_set_train_antenna_cmd_fixed_param *cmd;
@@ -402,7 +402,7 @@
*/
static QDF_STATUS send_smart_ant_set_node_config_cmd_tlv(
wmi_unified_t wmi_handle,
- uint8_t macaddr[IEEE80211_ADDR_LEN],
+ uint8_t macaddr[QDF_MAC_ADDR_SIZE],
struct smart_ant_node_config_params *param)
{
wmi_peer_smart_ant_set_node_config_ops_cmd_fixed_param *cmd;