Merge 233121e3a7 on remote branch

Change-Id: I6568da680ee1e7b041d453d551964c6d52ee1cc2
This commit is contained in:
Linux Build Service Account 2021-11-24 05:56:50 -08:00
commit 470247dffe
30 changed files with 721 additions and 600 deletions

View file

@ -2730,4 +2730,33 @@ cdp_drain_txrx(ol_txrx_soc_handle soc)
return soc->ops->cmn_drv_ops->txrx_drain(soc);
}
#ifdef WLAN_FEATURE_PKT_CAPTURE_V2
/**
* cdp_set_pkt_capture_mode() - set pkt capture mode in dp ctx
* @soc: opaque soc handle
* @val: value to be set
*/
static inline void
cdp_set_pkt_capture_mode(ol_txrx_soc_handle soc, bool val)
{
if (!soc || !soc->ops) {
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
"%s: Invalid Instance", __func__);
QDF_BUG(0);
return;
}
if (!soc->ops->cmn_drv_ops ||
!soc->ops->cmn_drv_ops->set_pkt_capture_mode)
return;
soc->ops->cmn_drv_ops->set_pkt_capture_mode(soc, val);
}
#else
static inline void
cdp_set_pkt_capture_mode(ol_txrx_soc_handle soc, bool val)
{
}
#endif
#endif /* _CDP_TXRX_CMN_H_ */

View file

@ -578,6 +578,9 @@ struct cdp_cmn_ops {
ol_osif_peer_handle osif_peer);
#endif /* QCA_SUPPORT_WDS_EXTENDED */
void (*txrx_drain)(ol_txrx_soc_handle soc);
#ifdef WLAN_FEATURE_PKT_CAPTURE_V2
void (*set_pkt_capture_mode)(struct cdp_soc_t *soc, bool val);
#endif
};
struct cdp_ctrl_ops {

View file

@ -1024,6 +1024,8 @@ struct cdp_tx_stats {
uint32_t num_ppdu_cookie_valid;
uint32_t no_ack_count[QDF_PROTO_SUBTYPE_MAX];
struct cdp_pkt_info tx_success_twt;
/* mpdu retry count in case of successful transmission */
uint32_t mpdu_success_with_retries;
};
/* struct cdp_rx_stats - rx Level Stats

View file

@ -871,6 +871,8 @@ static inline void dp_update_vdev_stats(struct dp_soc *soc,
tgtobj->tx.dropped.fw_reason3 +=
srcobj->stats.tx.dropped.fw_reason3;
tgtobj->tx.dropped.age_out += srcobj->stats.tx.dropped.age_out;
tgtobj->tx.mpdu_success_with_retries +=
srcobj->stats.tx.mpdu_success_with_retries;
tgtobj->rx.err.mic_err += srcobj->stats.rx.err.mic_err;
if (srcobj->stats.rx.rssi != 0)
tgtobj->rx.rssi = srcobj->stats.rx.rssi;

View file

@ -10495,27 +10495,27 @@ static void dp_display_srng_info(struct cdp_soc_t *soc_hdl)
dp_info("SRNG HP-TP data:");
for (i = 0; i < soc->num_tcl_data_rings; i++) {
hal_get_sw_hptp(hal_soc, soc->tcl_data_ring[i].hal_srng,
&hp, &tp);
&tp, &hp);
dp_info("TCL DATA ring[%d]: hp=0x%x, tp=0x%x", i, hp, tp);
hal_get_sw_hptp(hal_soc, soc->tx_comp_ring[i].hal_srng,
&hp, &tp);
&tp, &hp);
dp_info("TX comp ring[%d]: hp=0x%x, tp=0x%x", i, hp, tp);
}
for (i = 0; i < soc->num_reo_dest_rings; i++) {
hal_get_sw_hptp(hal_soc, soc->reo_dest_ring[i].hal_srng,
&hp, &tp);
&tp, &hp);
dp_info("REO DST ring[%d]: hp=0x%x, tp=0x%x", i, hp, tp);
}
hal_get_sw_hptp(hal_soc, soc->reo_exception_ring.hal_srng, &hp, &tp);
hal_get_sw_hptp(hal_soc, soc->reo_exception_ring.hal_srng, &tp, &hp);
dp_info("REO exception ring: hp=0x%x, tp=0x%x", hp, tp);
hal_get_sw_hptp(hal_soc, soc->rx_rel_ring.hal_srng, &hp, &tp);
hal_get_sw_hptp(hal_soc, soc->rx_rel_ring.hal_srng, &tp, &hp);
dp_info("WBM RX release ring: hp=0x%x, tp=0x%x", hp, tp);
hal_get_sw_hptp(hal_soc, soc->wbm_desc_rel_ring.hal_srng, &hp, &tp);
hal_get_sw_hptp(hal_soc, soc->wbm_desc_rel_ring.hal_srng, &tp, &hp);
dp_info("WBM desc release ring: hp=0x%x, tp=0x%x", hp, tp);
}
@ -11294,6 +11294,16 @@ static void dp_drain_txrx(struct cdp_soc_t *soc_handle)
}
#endif
#ifdef WLAN_FEATURE_PKT_CAPTURE_V2
static void
dp_set_pkt_capture_mode(struct cdp_soc_t *soc_handle, bool val)
{
struct dp_soc *soc = (struct dp_soc *)soc_handle;
soc->wlan_cfg_ctx->pkt_capture_mode = val;
}
#endif
static struct cdp_cmn_ops dp_ops_cmn = {
.txrx_soc_attach_target = dp_soc_attach_target_wifi3,
.txrx_vdev_attach = dp_vdev_attach_wifi3,
@ -11396,6 +11406,9 @@ static struct cdp_cmn_ops dp_ops_cmn = {
#if defined(FEATURE_RUNTIME_PM) || defined(DP_POWER_SAVE)
.txrx_drain = dp_drain_txrx,
#endif
#ifdef WLAN_FEATURE_PKT_CAPTURE_V2
.set_pkt_capture_mode = dp_set_pkt_capture_mode,
#endif
};
static struct cdp_ctrl_ops dp_ops_ctrl = {

View file

@ -1411,27 +1411,6 @@ qdf_nbuf_t dp_rx_mon_restitch_mpdu(struct dp_soc *soc, uint32_t mac_id,
}
#endif
#ifdef DP_MON_RSSI_IN_DBM
/*
* dp_rx_mon_rssi_convert(): convert rssi_comb from unit dBm to dB
* to match with radiotap further conversion requirement
* @rx_status: monitor mode rx status pointer
*
* Return: none
*/
static inline
void dp_rx_mon_rssi_convert(struct mon_rx_status *rx_status)
{
rx_status->rssi_comb = rx_status->rssi_comb -
rx_status->chan_noise_floor;
}
#else
static inline
void dp_rx_mon_rssi_convert(struct mon_rx_status *rx_status)
{
}
#endif
/*
* dp_rx_mon_deliver(): function to deliver packets to stack
* @soc: DP soc
@ -1469,8 +1448,6 @@ QDF_STATUS dp_rx_mon_deliver(struct dp_soc *soc, uint32_t mac_id,
pdev->ppdu_info.rx_status.device_id = soc->device_id;
pdev->ppdu_info.rx_status.chan_noise_floor =
pdev->chan_noise_floor;
/* convert rssi_comb from dBm to positive dB value */
dp_rx_mon_rssi_convert(&pdev->ppdu_info.rx_status);
dp_handle_tx_capture(soc, pdev, mon_mpdu);

View file

@ -58,6 +58,8 @@
/* invalid peer id for reinject*/
#define DP_INVALID_PEER 0XFFFE
#define DP_RETRY_COUNT 7
/*mapping between hal encrypt type and cdp_sec_type*/
#define MAX_CDP_SEC_TYPE 12
static const uint8_t sec_type_map[MAX_CDP_SEC_TYPE] = {
@ -4113,12 +4115,15 @@ dp_tx_update_peer_stats(struct dp_tx_desc_s *tx_desc,
DP_STATS_INCC(peer, tx.stbc, 1, ts->stbc);
DP_STATS_INCC(peer, tx.ldpc, 1, ts->ldpc);
DP_STATS_INCC(peer, tx.retries, 1, ts->transmit_cnt > 1);
#if defined(FEATURE_PERPKT_INFO) && WDI_EVENT_ENABLE
dp_wdi_event_handler(WDI_EVENT_UPDATE_DP_STATS, pdev->soc,
&peer->stats, ts->peer_id,
UPDATE_PEER_STATS, pdev->pdev_id);
#endif
if (ts->first_msdu)
DP_STATS_INCC(peer, tx.mpdu_success_with_retries,
qdf_do_div(ts->transmit_cnt, DP_RETRY_COUNT),
ts->transmit_cnt > DP_RETRY_COUNT);
}
#ifdef QCA_LL_TX_FLOW_CONTROL_V2

View file

@ -455,8 +455,7 @@ static inline void hal_srng_write_address_32_mb(struct hal_soc *hal_soc,
{
qdf_iowrite32(addr, value);
}
#elif defined(FEATURE_HAL_DELAYED_REG_WRITE) || \
defined(FEATURE_HAL_DELAYED_REG_WRITE_V2)
#elif defined(FEATURE_HAL_DELAYED_REG_WRITE)
static inline void hal_srng_write_address_32_mb(struct hal_soc *hal_soc,
struct hal_srng *srng,
void __iomem *addr,
@ -778,8 +777,7 @@ static inline void hal_write32_mb_confirm_retry(struct hal_soc *hal_soc,
}
#endif /* GENERIC_SHADOW_REGISTER_ACCESS_ENABLE */
#if defined(FEATURE_HAL_DELAYED_REG_WRITE) || \
defined(FEATURE_HAL_DELAYED_REG_WRITE_V2)
#if defined(FEATURE_HAL_DELAYED_REG_WRITE)
/**
* hal_dump_reg_write_srng_stats() - dump SRNG reg write stats
* @hal_soc: HAL soc handle

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2016-2021 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
@ -25,8 +25,7 @@
#include "qdf_mem.h"
#include "qdf_nbuf.h"
#include "pld_common.h"
#if defined(FEATURE_HAL_DELAYED_REG_WRITE) || \
defined(FEATURE_HAL_DELAYED_REG_WRITE_V2)
#if defined(FEATURE_HAL_DELAYED_REG_WRITE)
#include "qdf_defer.h"
#include "qdf_timer.h"
#endif
@ -259,8 +258,7 @@ typedef struct hal_ring_handle *hal_ring_handle_t;
*/
#define HAL_SRNG_FLUSH_EVENT BIT(0)
#if defined(FEATURE_HAL_DELAYED_REG_WRITE) || \
defined(FEATURE_HAL_DELAYED_REG_WRITE_V2)
#if defined(FEATURE_HAL_DELAYED_REG_WRITE)
/**
* struct hal_reg_write_q_elem - delayed register write queue element
@ -339,21 +337,6 @@ struct hal_reg_write_soc_stats {
uint32_t sched_delay[REG_WRITE_SCHED_DELAY_HIST_MAX];
uint32_t dequeue_delay;
};
#ifdef FEATURE_HAL_DELAYED_REG_WRITE_V2
struct hal_reg_write_tcl_stats {
uint32_t wq_delayed;
uint32_t wq_direct;
uint32_t timer_enq;
uint32_t timer_direct;
uint32_t enq_timer_set;
uint32_t direct_timer_set;
uint32_t timer_reset;
qdf_time_t enq_time;
qdf_time_t deq_time;
uint32_t sched_delay[REG_WRITE_SCHED_DELAY_HIST_MAX];
};
#endif
#endif
/* Common SRNG ring structure for source and destination rings */
@ -476,10 +459,7 @@ struct hal_srng {
/* last ring desc entry cleared */
uint32_t last_desc_cleared;
#endif
#if defined(FEATURE_HAL_DELAYED_REG_WRITE) || \
defined(FEATURE_HAL_DELAYED_REG_WRITE_V2)
/* Previous hp/tp (based on ring dir) value written to the reg */
uint32_t last_reg_wr_val;
#if defined(FEATURE_HAL_DELAYED_REG_WRITE)
/* flag to indicate whether srng is already queued for delayed write */
uint8_t reg_write_in_progress;
/* last dequeue elem time stamp */
@ -718,8 +698,7 @@ struct hal_hw_txrx_ops {
*/
struct hal_soc_stats {
uint32_t reg_write_fail;
#if defined(FEATURE_HAL_DELAYED_REG_WRITE) || \
defined(FEATURE_HAL_DELAYED_REG_WRITE_V2)
#if defined(FEATURE_HAL_DELAYED_REG_WRITE)
struct hal_reg_write_soc_stats wstats;
#endif
#ifdef GENERIC_SHADOW_REGISTER_ACCESS_ENABLE
@ -835,20 +814,6 @@ struct hal_soc {
/* read index used by worker thread to dequeue/write registers */
uint32_t read_idx;
#endif /*FEATURE_HAL_DELAYED_REG_WRITE */
#ifdef FEATURE_HAL_DELAYED_REG_WRITE_V2
/* delayed work for TCL reg write to be queued into workqueue */
qdf_work_t tcl_reg_write_work;
/* workqueue for TCL delayed register writes */
qdf_workqueue_t *tcl_reg_write_wq;
/* flag denotes whether TCL delayed write work is active */
qdf_atomic_t tcl_work_active;
/* flag indiactes TCL write happening from direct context */
bool tcl_direct;
/* timer to handle the pending TCL reg writes */
qdf_timer_t tcl_reg_write_timer;
/* stats related to TCL reg write */
struct hal_reg_write_tcl_stats tcl_stats;
#endif /* FEATURE_HAL_DELAYED_REG_WRITE_V2 */
qdf_atomic_t active_work_cnt;
#ifdef GENERIC_SHADOW_REGISTER_ACCESS_ENABLE
struct shadow_reg_config
@ -857,8 +822,7 @@ struct hal_soc {
#endif
};
#if defined(FEATURE_HAL_DELAYED_REG_WRITE) || \
defined(FEATURE_HAL_DELAYED_REG_WRITE_V2)
#if defined(FEATURE_HAL_DELAYED_REG_WRITE)
/**
* hal_delayed_reg_write() - delayed regiter write
* @hal_soc: HAL soc handle

View file

@ -446,8 +446,7 @@ uint32_t hal_get_target_type(hal_soc_handle_t hal_soc_hdl)
qdf_export_symbol(hal_get_target_type);
#if defined(FEATURE_HAL_DELAYED_REG_WRITE) || \
defined(FEATURE_HAL_DELAYED_REG_WRITE_V2)
#if defined(FEATURE_HAL_DELAYED_REG_WRITE)
/**
* hal_is_reg_write_tput_level_high() - throughput level for delayed reg writes
* @hal: hal_soc pointer
@ -501,41 +500,6 @@ void hal_dump_reg_write_srng_stats(hal_soc_handle_t hal_soc_hdl)
hal_fill_reg_write_srng_stats(srng, buf, sizeof(buf)));
}
#ifdef FEATURE_HAL_DELAYED_REG_WRITE_V2
/**
* hal_dump_tcl_stats() - dump the TCL reg write stats
* @hal: hal_soc pointer
*
* Return: None
*/
static inline void hal_dump_tcl_stats(struct hal_soc *hal)
{
struct hal_srng *srng = hal_get_srng(hal, HAL_SRNG_SW2TCL1);
uint32_t *hist = hal->tcl_stats.sched_delay;
char buf[HAL_REG_WRITE_SRNG_STATS_LEN];
hal_debug("TCL: %s sched-delay hist %u %u %u %u",
hal_fill_reg_write_srng_stats(srng, buf, sizeof(buf)),
hist[REG_WRITE_SCHED_DELAY_SUB_100us],
hist[REG_WRITE_SCHED_DELAY_SUB_1000us],
hist[REG_WRITE_SCHED_DELAY_SUB_5000us],
hist[REG_WRITE_SCHED_DELAY_GT_5000us]);
hal_debug("wq_dly %u wq_dir %u tim_enq %u tim_dir %u enq_tim_cnt %u dir_tim_cnt %u rst_tim_cnt %u",
hal->tcl_stats.wq_delayed,
hal->tcl_stats.wq_direct,
hal->tcl_stats.timer_enq,
hal->tcl_stats.timer_direct,
hal->tcl_stats.enq_timer_set,
hal->tcl_stats.direct_timer_set,
hal->tcl_stats.timer_reset);
}
#else
static inline void hal_dump_tcl_stats(struct hal_soc *hal)
{
}
#endif
void hal_dump_reg_write_stats(hal_soc_handle_t hal_soc_hdl)
{
uint32_t *hist;
@ -553,8 +517,6 @@ void hal_dump_reg_write_stats(hal_soc_handle_t hal_soc_hdl)
hist[REG_WRITE_SCHED_DELAY_SUB_1000us],
hist[REG_WRITE_SCHED_DELAY_SUB_5000us],
hist[REG_WRITE_SCHED_DELAY_GT_5000us]);
hal_dump_tcl_stats(hal);
}
int hal_get_reg_write_pending_work(void *hal_soc)
@ -577,46 +539,6 @@ int hal_get_reg_write_pending_work(void *hal_soc)
#define HAL_REG_WRITE_QUEUE_LEN 32
#endif
#ifdef FEATURE_HAL_DELAYED_REG_WRITE_V2
/**
* hal_process_reg_write_q_elem() - process a regiter write queue element
* @hal: hal_soc pointer
* @q_elem: pointer to hal regiter write queue element
*
* Return: The value which was written to the address
*/
static uint32_t
hal_process_reg_write_q_elem(struct hal_soc *hal,
struct hal_reg_write_q_elem *q_elem)
{
struct hal_srng *srng = q_elem->srng;
uint32_t write_val;
SRNG_LOCK(&srng->lock);
srng->reg_write_in_progress = false;
srng->wstats.dequeues++;
if (srng->ring_dir == HAL_SRNG_SRC_RING) {
write_val = srng->u.src_ring.hp;
q_elem->dequeue_val = write_val;
q_elem->valid = 0;
SRNG_UNLOCK(&srng->lock);
hal_write_address_32_mb(hal,
srng->u.src_ring.hp_addr,
write_val, false);
} else {
write_val = srng->u.dst_ring.tp;
q_elem->dequeue_val = write_val;
q_elem->valid = 0;
SRNG_UNLOCK(&srng->lock);
hal_write_address_32_mb(hal,
srng->u.dst_ring.tp_addr,
write_val, false);
}
return write_val;
}
#else
/**
* hal_process_reg_write_q_elem() - process a regiter write queue element
* @hal: hal_soc pointer
@ -656,7 +578,6 @@ hal_process_reg_write_q_elem(struct hal_soc *hal,
return write_val;
}
#endif
/**
* hal_reg_write_fill_sched_delay_hist() - fill reg write delay histogram in hal
@ -818,8 +739,8 @@ static void hal_reg_write_work(void *arg)
static void __hal_flush_reg_write_work(struct hal_soc *hal)
{
qdf_cancel_work(&hal->reg_write_work);
qdf_flush_work(&hal->reg_write_work);
qdf_disable_work(&hal->reg_write_work);
}
void hal_flush_reg_write_work(hal_soc_handle_t hal_handle)
@ -962,383 +883,6 @@ static inline void hal_delayed_reg_write_deinit(struct hal_soc *hal)
}
#endif
#ifdef FEATURE_HAL_DELAYED_REG_WRITE_V2
#ifdef MEMORY_DEBUG
/**
* hal_reg_write_get_timestamp() - Function to get the timestamp
*
* Return: return present simestamp
*/
static inline qdf_time_t hal_del_reg_write_get_ts(void)
{
return qdf_get_log_timestamp();
}
/**
* hal_del_reg_write_ts_usecs() - Convert the timestamp to micro secs
* @ts: timestamp value to be converted
*
* Return: return the timestamp in micro secs
*/
static inline qdf_time_t hal_del_reg_write_ts_usecs(qdf_time_t ts)
{
return qdf_log_timestamp_to_usecs(ts);
}
/**
* hal_tcl_write_fill_sched_delay_hist() - fill TCL reg write delay histogram
* @hal: hal_soc pointer
* @delay: delay in us
*
* Return: None
*/
static inline void hal_tcl_write_fill_sched_delay_hist(struct hal_soc *hal)
{
uint32_t *hist;
uint32_t delay_us;
hal->tcl_stats.deq_time = hal_del_reg_write_get_ts();
delay_us = hal_del_reg_write_ts_usecs(hal->tcl_stats.deq_time -
hal->tcl_stats.enq_time);
hist = hal->tcl_stats.sched_delay;
if (delay_us < 100)
hist[REG_WRITE_SCHED_DELAY_SUB_100us]++;
else if (delay_us < 1000)
hist[REG_WRITE_SCHED_DELAY_SUB_1000us]++;
else if (delay_us < 5000)
hist[REG_WRITE_SCHED_DELAY_SUB_5000us]++;
else
hist[REG_WRITE_SCHED_DELAY_GT_5000us]++;
}
#else
static inline qdf_time_t hal_del_reg_write_get_ts(void)
{
return 0;
}
static inline qdf_time_t hal_del_reg_write_ts_usecs(qdf_time_t ts)
{
return 0;
}
static inline void hal_tcl_write_fill_sched_delay_hist(struct hal_soc *hal)
{
}
#endif
/**
* hal_tcl_reg_write_work() - Worker to process delayed SW2TCL1 writes
* @arg: hal_soc pointer
*
* Return: None
*/
static void hal_tcl_reg_write_work(void *arg)
{
struct hal_soc *hal = arg;
struct hal_srng *srng = hal_get_srng(hal, HAL_SRNG_SW2TCL1);
SRNG_LOCK(&srng->lock);
srng->wstats.dequeues++;
hal_tcl_write_fill_sched_delay_hist(hal);
/*
* During the tranition of low to high tput scenario, reg write moves
* from delayed to direct write context, there is a little chance that
* worker thread gets scheduled later than direct context write which
* already wrote the latest HP value. This check can catch that case
* and avoid the repetitive writing of the same HP value.
*/
if (srng->last_reg_wr_val != srng->u.src_ring.hp) {
srng->last_reg_wr_val = srng->u.src_ring.hp;
if (hal->tcl_direct) {
/*
* TCL reg writes have been moved to direct context and
* the assumption is that PCIe bus stays in Active state
* during high tput, hence its fine to write the HP
* while the SRNG_LOCK is being held.
*/
hal->tcl_stats.wq_direct++;
hal_write_address_32_mb(hal, srng->u.src_ring.hp_addr,
srng->last_reg_wr_val, false);
srng->reg_write_in_progress = false;
SRNG_UNLOCK(&srng->lock);
} else {
/*
* TCL reg write to happen in delayed context,
* write operation might take time due to possibility of
* PCIe bus stays in low power state during low tput,
* Hence release the SRNG_LOCK before writing.
*/
hal->tcl_stats.wq_delayed++;
srng->reg_write_in_progress = false;
SRNG_UNLOCK(&srng->lock);
hal_write_address_32_mb(hal, srng->u.src_ring.hp_addr,
srng->last_reg_wr_val, false);
}
} else {
srng->reg_write_in_progress = false;
SRNG_UNLOCK(&srng->lock);
}
/*
* Decrement active_work_cnt to make sure that hif_try_complete_tasks
* will wait. This will avoid race condition between delayed register
* worker and bus suspend (system suspend or runtime suspend).
*
* The following decrement should be done at the end!
*/
qdf_atomic_dec(&hal->active_work_cnt);
qdf_atomic_set(&hal->tcl_work_active, false);
}
static void __hal_flush_tcl_reg_write_work(struct hal_soc *hal)
{
qdf_cancel_work(&hal->tcl_reg_write_work);
}
/**
* hal_tcl_reg_write_enqueue() - enqueue TCL register writes into kworker
* @hal_soc: hal_soc pointer
* @srng: srng pointer
* @addr: iomem address of regiter
* @value: value to be written to iomem address
*
* This function executes from within the SRNG LOCK
*
* Return: None
*/
static void hal_tcl_reg_write_enqueue(struct hal_soc *hal_soc,
struct hal_srng *srng,
void __iomem *addr,
uint32_t value)
{
hal_soc->tcl_stats.enq_time = hal_del_reg_write_get_ts();
if (qdf_queue_work(hal_soc->qdf_dev, hal_soc->tcl_reg_write_wq,
&hal_soc->tcl_reg_write_work)) {
srng->reg_write_in_progress = true;
qdf_atomic_inc(&hal_soc->active_work_cnt);
qdf_atomic_set(&hal_soc->tcl_work_active, true);
srng->wstats.enqueues++;
} else {
hal_soc->tcl_stats.enq_timer_set++;
qdf_timer_mod(&hal_soc->tcl_reg_write_timer, 1);
}
}
/**
* hal_tcl_reg_write_timer() - timer handler to take care of pending TCL writes
* @arg: srng handle
*
* This function handles the pending TCL reg writes missed due to the previous
* scheduled worker running.
*
* Return: None
*/
static void hal_tcl_reg_write_timer(void *arg)
{
hal_ring_handle_t srng_hdl = arg;
struct hal_srng *srng;
struct hal_soc *hal;
srng = (struct hal_srng *)srng_hdl;
hal = srng->hal_soc;
if (hif_pm_runtime_get(hal->hif_handle, RTPM_ID_DW_TX_HW_ENQUEUE,
true)) {
hal_srng_set_event(srng_hdl, HAL_SRNG_FLUSH_EVENT);
hal_srng_inc_flush_cnt(srng_hdl);
goto fail;
}
SRNG_LOCK(&srng->lock);
if (hal->tcl_direct) {
/*
* Due to the previous scheduled worker still running,
* direct reg write cannot be performed, so posted the
* pending writes to timer context.
*/
if (srng->last_reg_wr_val != srng->u.src_ring.hp) {
srng->last_reg_wr_val = srng->u.src_ring.hp;
srng->wstats.direct++;
hal->tcl_stats.timer_direct++;
hal_write_address_32_mb(hal, srng->u.src_ring.hp_addr,
srng->last_reg_wr_val, false);
}
} else {
/*
* Due to the previous scheduled worker still running,
* queue_work from delayed context would fail,
* so retry from timer context.
*/
if (qdf_queue_work(hal->qdf_dev, hal->tcl_reg_write_wq,
&hal->tcl_reg_write_work)) {
srng->reg_write_in_progress = true;
qdf_atomic_inc(&hal->active_work_cnt);
qdf_atomic_set(&hal->tcl_work_active, true);
srng->wstats.enqueues++;
hal->tcl_stats.timer_enq++;
} else {
if (srng->last_reg_wr_val != srng->u.src_ring.hp) {
hal->tcl_stats.timer_reset++;
qdf_timer_mod(&hal->tcl_reg_write_timer, 1);
}
}
}
SRNG_UNLOCK(&srng->lock);
hif_pm_runtime_put(hal->hif_handle, RTPM_ID_DW_TX_HW_ENQUEUE);
fail:
return;
}
/**
* hal_delayed_tcl_reg_write_init() - Initialization for delayed TCL reg writes
* @hal_soc: hal_soc pointer
*
* Initialize main data structures to process TCL register writes in a delayed
* workqueue.
*
* Return: QDF_STATUS_SUCCESS on success else a QDF error.
*/
static QDF_STATUS hal_delayed_tcl_reg_write_init(struct hal_soc *hal)
{
struct hal_srng *srng = hal_get_srng(hal, HAL_SRNG_SW2TCL1);
QDF_STATUS status;
hal->tcl_reg_write_wq =
qdf_alloc_high_prior_ordered_workqueue("hal_tcl_reg_write_wq");
if (!hal->tcl_reg_write_wq) {
hal_err("hal_tcl_reg_write_wq alloc failed");
return QDF_STATUS_E_NOMEM;
}
status = qdf_create_work(0, &hal->tcl_reg_write_work,
hal_tcl_reg_write_work, hal);
if (status != QDF_STATUS_SUCCESS) {
hal_err("tcl_reg_write_work create failed");
goto fail;
}
status = qdf_timer_init(hal->qdf_dev, &hal->tcl_reg_write_timer,
hal_tcl_reg_write_timer, (void *)srng,
QDF_TIMER_TYPE_WAKE_APPS);
if (status != QDF_STATUS_SUCCESS) {
hal_err("tcl_reg_write_timer init failed");
goto fail;
}
qdf_atomic_init(&hal->tcl_work_active);
return QDF_STATUS_SUCCESS;
fail:
qdf_destroy_workqueue(0, hal->tcl_reg_write_wq);
return status;
}
/**
* hal_delayed_tcl_reg_write_deinit() - De-Initialize delayed TCL reg writes
* @hal_soc: hal_soc pointer
*
* De-initialize main data structures to process TCL register writes in a
* delayed workqueue.
*
* Return: None
*/
static void hal_delayed_tcl_reg_write_deinit(struct hal_soc *hal)
{
qdf_timer_stop(&hal->tcl_reg_write_timer);
qdf_timer_free(&hal->tcl_reg_write_timer);
__hal_flush_tcl_reg_write_work(hal);
qdf_flush_workqueue(0, hal->tcl_reg_write_wq);
qdf_destroy_workqueue(0, hal->tcl_reg_write_wq);
}
#else
static inline QDF_STATUS hal_delayed_tcl_reg_write_init(struct hal_soc *hal)
{
return QDF_STATUS_SUCCESS;
}
static inline void hal_delayed_tcl_reg_write_deinit(struct hal_soc *hal)
{
}
#endif
#ifdef FEATURE_HAL_DELAYED_REG_WRITE_V2
#ifdef FEATURE_HAL_DELAYED_REG_WRITE
static inline void hal_reg_write_enqueue_v2(struct hal_soc *hal_soc,
struct hal_srng *srng,
void __iomem *addr,
uint32_t value)
{
hal_reg_write_enqueue(hal_soc, srng, addr, value);
}
#else
static inline void hal_reg_write_enqueue_v2(struct hal_soc *hal_soc,
struct hal_srng *srng,
void __iomem *addr,
uint32_t value)
{
qdf_atomic_inc(&hal_soc->stats.wstats.direct);
srng->wstats.direct++;
hal_write_address_32_mb(hal_soc, addr, value, false);
}
#endif
void hal_delayed_reg_write(struct hal_soc *hal_soc,
struct hal_srng *srng,
void __iomem *addr,
uint32_t value)
{
switch (srng->ring_type) {
case TCL_DATA:
if (hal_is_reg_write_tput_level_high(hal_soc)) {
hal_soc->tcl_direct = true;
if (srng->reg_write_in_progress ||
!qdf_atomic_read(&hal_soc->tcl_work_active)) {
/*
* Now the delayed work have either completed
* the writing or not even scheduled and would
* be blocked by SRNG_LOCK, hence it is fine to
* do direct write here.
*/
srng->last_reg_wr_val = srng->u.src_ring.hp;
srng->wstats.direct++;
hal_write_address_32_mb(hal_soc, addr,
srng->last_reg_wr_val,
false);
} else {
hal_soc->tcl_stats.direct_timer_set++;
qdf_timer_mod(&hal_soc->tcl_reg_write_timer, 1);
}
} else {
hal_soc->tcl_direct = false;
if (srng->reg_write_in_progress) {
srng->wstats.coalesces++;
} else {
hal_tcl_reg_write_enqueue(hal_soc, srng,
addr, value);
}
}
break;
case CE_SRC:
case CE_DST:
case CE_DST_STATUS:
hal_reg_write_enqueue_v2(hal_soc, srng, addr, value);
break;
default:
qdf_atomic_inc(&hal_soc->stats.wstats.direct);
srng->wstats.direct++;
hal_write_address_32_mb(hal_soc, addr, value, false);
break;
}
}
#else
#ifdef FEATURE_HAL_DELAYED_REG_WRITE
#ifdef QCA_WIFI_QCA6750
void hal_delayed_reg_write(struct hal_soc *hal_soc,
@ -1398,7 +942,6 @@ void hal_delayed_reg_write(struct hal_soc *hal_soc,
}
#endif
#endif
#endif
/**
* hal_attach - Initialize HAL layer
@ -1470,7 +1013,6 @@ void *hal_attach(struct hif_opaque_softc *hif_handle, qdf_device_t qdf_dev)
qdf_atomic_init(&hal->active_work_cnt);
hal_delayed_reg_write_init(hal);
hal_delayed_tcl_reg_write_init(hal);
return (void *)hal;
@ -1521,7 +1063,6 @@ extern void hal_detach(void *hal_soc)
struct hal_soc *hal = (struct hal_soc *)hal_soc;
hal_delayed_reg_write_deinit(hal);
hal_delayed_tcl_reg_write_deinit(hal);
qdf_mem_free_consistent(hal->qdf_dev, hal->qdf_dev->dev,
sizeof(*(hal->shadow_rdptr_mem_vaddr)) * HAL_SRNG_ID_MAX,

View file

@ -2073,7 +2073,11 @@ struct hal_hw_srng_config hw_srng_table_6490[] = {
},
{ /* WBM2SW_RELEASE */
.start_ring_id = HAL_SRNG_WBM2SW0_RELEASE,
#ifdef CONFIG_PLD_PCIE_FW_SIM
.max_rings = 5,
#else
.max_rings = 4,
#endif
.entry_size = sizeof(struct wbm_release_ring) >> 2,
.lmac_ring = FALSE,
.ring_dir = HAL_SRNG_DST_RING,

View file

@ -327,6 +327,8 @@ struct hif_opaque_softc {
* @HIF_EVENT_BH_SCHED: NAPI POLL scheduled event
* @HIF_EVENT_SRNG_ACCESS_START: hal ring access start event
* @HIF_EVENT_SRNG_ACCESS_END: hal ring access end event
* @HIF_EVENT_BH_COMPLETE: NAPI POLL completion event
* @HIF_EVENT_BH_FORCE_BREAK: NAPI POLL force break event
*/
enum hif_event_type {
HIF_EVENT_IRQ_TRIGGER,
@ -335,6 +337,8 @@ enum hif_event_type {
HIF_EVENT_BH_SCHED,
HIF_EVENT_SRNG_ACCESS_START,
HIF_EVENT_SRNG_ACCESS_END,
HIF_EVENT_BH_COMPLETE,
HIF_EVENT_BH_FORCE_BREAK,
/* Do check hif_hist_skip_event_record when adding new events */
};
@ -360,7 +364,7 @@ enum hif_system_pm_state {
/* HIF_EVENT_HIST_MAX should always be power of 2 */
#define HIF_EVENT_HIST_MAX 512
#define HIF_NUM_INT_CONTEXTS HIF_MAX_GROUP
#define HIF_EVENT_HIST_ENABLE_MASK 0x3F
#define HIF_EVENT_HIST_ENABLE_MASK 0xFF
static inline uint64_t hif_get_log_timestamp(void)
{

View file

@ -96,7 +96,7 @@ hif_hist_skip_event_record(struct hif_event_history *hist_ev,
HIF_EVENT_HIST_MAX)) {
last_irq_rec =
&hist_ev->event[hist_ev->misc.last_irq_index];
last_irq_rec->timestamp = qdf_get_log_timestamp();
last_irq_rec->timestamp = hif_get_log_timestamp();
last_irq_rec->cpu_id = qdf_get_cpu();
last_irq_rec->hp++;
last_irq_rec->tp = last_irq_rec->timestamp -
@ -106,7 +106,7 @@ hif_hist_skip_event_record(struct hif_event_history *hist_ev,
break;
case HIF_EVENT_BH_SCHED:
if (rec->type == HIF_EVENT_BH_SCHED) {
rec->timestamp = qdf_get_log_timestamp();
rec->timestamp = hif_get_log_timestamp();
rec->cpu_id = qdf_get_cpu();
return true;
}
@ -119,6 +119,11 @@ hif_hist_skip_event_record(struct hif_event_history *hist_ev,
if (rec->type != HIF_EVENT_SRNG_ACCESS_START)
return true;
break;
case HIF_EVENT_BH_COMPLETE:
case HIF_EVENT_BH_FORCE_BREAK:
if (rec->type != HIF_EVENT_SRNG_ACCESS_END)
return true;
break;
default:
break;
}
@ -623,6 +628,8 @@ static int hif_exec_poll(struct napi_struct *napi, int budget)
actual_dones = work_done;
if (!hif_ext_group->force_break && work_done < normalized_budget) {
hif_record_event(hif_ext_group->hif, hif_ext_group->grp_id,
0, 0, 0, HIF_EVENT_BH_COMPLETE);
napi_complete(napi);
qdf_atomic_dec(&scn->active_grp_tasklet_cnt);
hif_ext_group->irq_enable(hif_ext_group);
@ -630,6 +637,8 @@ static int hif_exec_poll(struct napi_struct *napi, int budget)
} else {
/* if the ext_group supports time based yield, claim full work
* done anyways */
hif_record_event(hif_ext_group->hif, hif_ext_group->grp_id,
0, 0, 0, HIF_EVENT_BH_FORCE_BREAK);
work_done = normalized_budget;
}

View file

@ -475,6 +475,36 @@
* configurations, concurrency combinations, etc. The attributes used
* with this command are defined in
* enum qca_wlan_vendor_attr_usable_channels.
*
* @QCA_NL80211_VENDOR_SUBCMD_SET_MONITOR_MODE: This vendor subcommand is used
* to set packet monitor mode that aims to send the specified set of TX and
* RX frames on the current client interface to an active monitor interface.
* If this Monitor mode is set, the driver will send the configured frames,
* from the interface on which the command is issued, to an active monitor
* interface. The attributes used with this command are defined in
* enum qca_wlan_vendor_attr_set_monitor_mode.
*
* Though the monitor mode is configured for the respective data/mgmt/ctrl
* frames, it is up to the respective WLAN driver/firmware/hardware designs
* to consider the possibility of sending these frames over the monitor
* interface. For example, the control frames are handled with in the
* hardware and thus passing such frames over the monitor interface is left
* to the respective designs.
*
* Also, this monitor mode is governed to behave accordingly in
* suspend/resume states. If the firmware handles any of such frames
* in suspend state without waking up the host and if the monitor mode
* is configured to notify all such frames, then the firmware is expected
* to resume the host and forward the respective frames to the monitor
* interface. Please note that such a request to get the frames over the
* monitor interface will have a definite power implications.
*
* @QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS: This vendor subcommand is used both
* as a request to set the driver/firmware with the parameters to trigger
* the roaming events, and also used by the driver/firmware to pass on the
* various roam events to userspace.
* Applicable only for the STA mode. The attributes used with this command
* are defined in enum qca_wlan_vendor_attr_roam_events.
*/
enum qca_nl80211_vendor_subcmds {
@ -708,6 +738,8 @@ enum qca_nl80211_vendor_subcmds {
QCA_NL80211_VENDOR_SUBCMD_MBSSID_TX_VDEV_STATUS = 196,
QCA_NL80211_VENDOR_SUBCMD_CONCURRENT_MULTI_STA_POLICY = 197,
QCA_NL80211_VENDOR_SUBCMD_USABLE_CHANNELS = 198,
QCA_NL80211_VENDOR_SUBCMD_SET_MONITOR_MODE = 202,
QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS = 203,
};
enum qca_wlan_vendor_tos {
@ -11014,4 +11046,270 @@ enum qca_wlan_vendor_attr_usable_channels {
QCA_WLAN_VENDOR_ATTR_USABLE_CHANNELS_AFTER_LAST - 1,
};
/**
* qca_wlan_vendor_monitor_data_frame_type - Represent the various
* data types to be sent over the monitor interface.
*/
enum qca_wlan_vendor_monitor_data_frame_type {
QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ALL = BIT(0),
/* valid only if QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ALL is
not set */
QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ARP = BIT(1),
QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_DHCPV4 = BIT(2),
QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_DHCPV6 = BIT(3),
QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_EAPOL = BIT(4),
QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_DNSV4 = BIT(5),
QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_DNSV6 = BIT(6),
QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_SYN = BIT(7),
QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_SYNACK = BIT(8),
QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_FIN = BIT(9),
QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_FINACK = BIT(10),
QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_ACK = BIT(11),
QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_TCP_RST = BIT(12),
QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ICMPV4 = BIT(13),
QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_ICMPV6 = BIT(14),
QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_RTP = BIT(15),
QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_TYPE_SIP = BIT(16),
QCA_WLAN_VENDOR_MONITOR_DATA_FRAME_QOS_NULL = BIT(17),
};
/**
* qca_wlan_vendor_monitor_mgmt_frame_type - Represent the various
* mgmt types to be sent over the monitor interface.
* @QCA_WLAN_VENDOR_MONITOR_MGMT_FRAME_TYPE_ALL: All the MGMT Frames.
* @QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_NO_BEACON: All the MGMT Frames
* except the Beacons. Valid only in the Connect state.
* @QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_BEACON: Only the connected
* BSSID Beacons. Valid only in the Connect state.
* @QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_SCAN_BEACON: Represents
* the Beacons obtained during the scan (off channel and connected channel)
* when in connected state.
*/
enum qca_wlan_vendor_monitor_mgmt_frame_type {
QCA_WLAN_VENDOR_MONITOR_MGMT_FRAME_TYPE_ALL = BIT(0),
/* valid only if QCA_WLAN_VENDOR_MONITOR_MGMT_FRAME_TYPE_ALL is not set */
QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_NO_BEACON = BIT(1),
QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_BEACON = BIT(2),
QCA_WLAN_VENDOR_MONITOR_MGMT_CONNECT_SCAN_BEACON = BIT(3),
};
/**
* qca_wlan_vendor_monitor_ctrl_frame_type - Represent the various
* ctrl types to be sent over the monitor interface.
* @QCA_WLAN_VENDOR_MONITOR_CTRL_FRAME_TYPE_ALL: All the ctrl Frames.
* @QCA_WLAN_VENDOR_MONITOR_CTRL_TRIGGER_FRAME: Trigger Frame.
*/
enum qca_wlan_vendor_monitor_ctrl_frame_type {
QCA_WLAN_VENDOR_MONITOR_CTRL_FRAME_TYPE_ALL = BIT(0),
/* valid only if QCA_WLAN_VENDOR_MONITOR_CTRL_FRAME_TYPE_ALL is not set */
QCA_WLAN_VENDOR_MONITOR_CTRL_TRIGGER_FRAME = BIT(1),
};
/**
* enum qca_wlan_vendor_attr_set_monitor_mode - Used by the
* vendor command QCA_NL80211_VENDOR_SUBCMD_SET_MONITOR_MODE to set the
* monitor mode.
*
* @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_DATA_TX_FRAME_TYPE: u32 attribute,
* Represents the tx data packet type to be monitored (u32). These data packets
* are represented by enum qca_wlan_vendor_monitor_data_frame_type.
*
* @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_DATA_RX_FRAME_TYPE: u32 attribute,
* Represents the tx data packet type to be monitored (u32). These data packets
* are represented by enum qca_wlan_vendor_monitor_data_frame_type.
*
* @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MGMT_TX_FRAME_TYPE: u32 attribute,
* Represents the tx data packet type to be monitored (u32). These mgmt packets
* are represented by enum qca_wlan_vendor_monitor_mgmt_frame_type.
*
* @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MGMT_RX_FRAME_TYPE: u32 attribute,
* Represents the tx data packet type to be monitored (u32). These mgmt packets
* are represented by enum qca_wlan_vendor_monitor_mgmt_frame_type.
*
* @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CTRL_TX_FRAME_TYPE: u32 attribute,
* Represents the tx data packet type to be monitored (u32). These ctrl packets
* are represented by enum qca_wlan_vendor_monitor_ctrl_frame_type.
*
* @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CTRL_RX_FRAME_TYPE: u32 attribute,
* Represents the tx data packet type to be monitored (u32). These ctrl packets
* are represented by enum qca_wlan_vendor_monitor_ctrl_frame_type.
*
* @QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CONNECTED_BEACON_INTERVAL:
* u32 attribute, An interval only for the connected beacon interval, which
* expects that the connected BSSID's beacons shall be sent on the monitor
* interface only on this specific interval.
*/
enum qca_wlan_vendor_attr_set_monitor_mode {
QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_INVALID = 0,
QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_DATA_TX_FRAME_TYPE = 1,
QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_DATA_RX_FRAME_TYPE = 2,
QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MGMT_TX_FRAME_TYPE = 3,
QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MGMT_RX_FRAME_TYPE = 4,
QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CTRL_TX_FRAME_TYPE = 5,
QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CTRL_RX_FRAME_TYPE = 6,
QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_CONNECTED_BEACON_INTERVAL = 7,
/* keep last */
QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_AFTER_LAST,
QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_MAX =
QCA_WLAN_VENDOR_ATTR_SET_MONITOR_MODE_AFTER_LAST - 1,
};
/**
* enum qca_wlan_vendor_roam_scan_state - Roam scan state flags.
* Bits will be set to 1 if the corresponding state is enabled.
*
* @QCA_VENDOR_WLAN_ROAM_SCAN_STATE_START: Scan Start.
* @QCA_VENDOR_WLAN_ROAM_SCAN_STATE_END: Scan end.
*/
enum qca_wlan_vendor_roam_scan_state {
QCA_WLAN_VENDOR_ROAM_SCAN_STATE_START = BIT(0),
QCA_WLAN_VENDOR_ROAM_SCAN_STATE_END = BIT(1),
};
/**
* enum qca_wlan_vendor_roam_event_type - Roam event type flags.
* Bits will be set to 1 if the corresponding event is notified.
*
* @QCA_WLAN_VENDOR_ROAM_EVENT_TRIGGER_REASON: Represents that the roam event
* carries the trigger reason. When set, it is expected that the roam event
* carries the respective reason via the attribute
* QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TRIGGER_REASON. This event also carries
* the BSSID, RSSI, frequency info of the AP to which the roam is attempted.
*
* @QCA_WLAN_VENDOR_ROAM_EVENT_FAIL_REASON: Represents that the roam event
* carries the roam fail reason. When set, it is expected that the roam event
* carries the respective reason via the attribute
* QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_FAIL_REASON. This event also carries the
* BSSID, RSSI, frequency info of the AP to which the roam was attempted.
*
* @QCA_WLAN_VENDOR_ROAM_EVENT_INVOKE_FAIL_REASON: Represents that the roam
* event carries the roam invoke fail reason. When set, it is expected that
* the roam event carries the respective reason via the attribute
* QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_INVOKE_FAIL_REASON.
*
* @QCA_WLAN_VENDOR_ROAM_EVENT_SCAN_STATE: Represents that the roam event
* carries the roam scan state. When set, it is expected that the roam event
* carries the respective scan state via the attribute
* QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_STATE and the corresponding
* frequency info via QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_FREQ_LIST.
*/
enum qca_wlan_vendor_roam_event_type {
QCA_WLAN_VENDOR_ROAM_EVENT_TRIGGER_REASON = BIT(0),
QCA_WLAN_VENDOR_ROAM_EVENT_FAIL_REASON = BIT(1),
QCA_WLAN_VENDOR_ROAM_EVENT_INVOKE_FAIL_REASON = BIT(2),
QCA_WLAN_VENDOR_ROAM_EVENT_ROAM_SCAN_STATE = BIT(3),
};
/**
* enum qca_wlan_vendor_attr_roam_events_candidate_info: Roam candidate info.
* Referred by QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO.
*
* @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_BSSID: 6-byte MAC address
* representing the BSSID of the AP to which the Roam is attempted.
*
* @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_RSSI: Signed 32-bit value
* in dBm, signifying the RSSI of the candidate BSSID to which the Roaming is
* attempted.
*
* @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_FREQ: u32, Frequency in MHz
* on which the roam is attempted.
*
* @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_FAIL_REASON: u32, used in
* STA mode only. This represents the roam fail reason for the last failed
* roaming attempt by the firmware for the specific BSSID. Different roam
* failure reason codes are specified in enum qca_vendor_roam_fail_reasons.
*/
enum qca_wlan_vendor_attr_roam_events_candidate_info {
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_INVALID = 0,
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_BSSID = 1,
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_RSSI = 2,
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_FREQ = 3,
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_FAIL_REASON = 4,
/* keep last */
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_AFTER_LAST,
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_MAX =
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO_AFTER_LAST - 1,
};
/**
* enum qca_wlan_vendor_attr_roam_events - Used by the
* vendor command QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS to either configure the
* roam events to the driver or notify these events from the driver.
*
* @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CONFIGURE: u8 attribute. Configures the
* driver/firmware to enable/disable the notification of roam events. It's a
* mandatory attribute and used only in the request from the userspace to the
* host driver. 1-Enable, 0-Disable.
* If the roaming is totally offloaded to the firmware, this request when
* enabled shall mandate the firmware to notify all the relevant roam events
* represented by the below attributes. If the host is in the suspend mode,
* the behavior of the firmware to notify these events is guided by
* QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_DEVICE_STATE, and if the request is to get
* these events in the suspend state, the firmware is expected to wake up the
* host before the respective events are notified. Please note that such a
* request to get the events in the suspend state will have a definite power
* implication.
*
* @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_SUSPEND_STATE: flag attribute. Represents
* that the roam events need to be notified in the suspend state too. By
* default, these roam events are notified in the resume state. With this flag,
* the roam events are notified in both resume and suspend states.
* This attribute is used in the request from the userspace to the host driver.
*
* @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TYPE: u32, used in STA mode only.
* Represents the different roam event types, signified by the enum
* qca_wlan_vendor_roam_event_type.
* Each bit of this attribute represents the different roam even types reported
* through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS.
* This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS.
*
* @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TRIGGER_REASON: u32, used in STA
* mode only. This represents the roam trigger reason for the last roaming
* attempted by the firmware. Each bit of this attribute represents the
* different roam trigger reason code which are defined in enum
* qca_vendor_roam_triggers.
* This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS.
*
* @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_INVOKE_FAIL_REASON: u32, used in
* STA mode only. This represents the roam invoke fail reason for the last
* failed roam invoke. Different roam invoke failure reason codes
* are specified in enum qca_vendor_roam_invoke_fail_reasons.
*
* @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO: Array of candidates info
* for which the roam is attempted. Each entry is a nested attribute defined
* by enum qca_wlan_vendor_attr_roam_events_candidate_info.
* This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS.
*
* @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_STATE: u8 attribute. Represents
* the scan state on which the roam events need to be notified. The values for
* this attribute are referred from enum qca_wlan_vendor_roam_scan_state.
* This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS.
*
* @QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_FREQ_LIST: Nested attribute of
* u32 values. List of frequencies in MHz considered for a roam scan.
* This is sent as an event through QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS.
*/
enum qca_wlan_vendor_attr_roam_events {
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_INVALID = 0,
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CONFIGURE = 1,
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_SUSPEND_STATE = 2,
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TYPE = 3,
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_TRIGGER_REASON = 4,
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_INVOKE_FAIL_REASON = 5,
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_CANDIDATE_INFO = 6,
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_STATE = 7,
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_ROAM_SCAN_FREQ_LIST = 8,
/* keep last */
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_AFTER_LAST,
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_MAX =
QCA_WLAN_VENDOR_ATTR_ROAM_EVENTS_AFTER_LAST - 1,
};
#endif

View file

@ -238,6 +238,9 @@ enum qca_nl80211_vendor_subcmds_index {
#ifdef WLAN_CFR_ENABLE
QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG_INDEX,
#endif
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS_INDEX,
#endif
};
#if !defined(SUPPORT_WDEV_CFG80211_VENDOR_EVENT_ALLOC) && \

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2018 The Linux Foundation. All rights reserved.
* Copyright (c) 2014-2018, 2021 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
@ -41,8 +41,36 @@ typedef __qdf_event_t qdf_event_t;
QDF_STATUS qdf_event_create(qdf_event_t *event);
/**
* qdf_event_set() - sets a QDF event for single waiting threads
* @event: The event to set to the signalled state
*
* The state of the specified event is set to signalled by calling
* qdf_event_set().
*
* Single thread waiting on the event as a result of a qdf_event_wait() will
* be unblocked and available to be scheduled for execution when the event
* is signaled by a call to qdf_event_set().
*
* Return: QDF status
*/
QDF_STATUS qdf_event_set(qdf_event_t *event);
/**
* qdf_event_set_all() - sets a QDF event for all waiting threads
* @event: The event to set to the signalled state
*
* The state of the specified event is set to signalled by calling
* qdf_event_set_all().
*
* Any threads waiting on the event as a result of a qdf_event_wait() will
* be unblocked and available to be scheduled for execution when the event
* is signaled by a call to qdf_event_set().
*
* Return: QDF status
*/
QDF_STATUS qdf_event_set_all(qdf_event_t *event);
QDF_STATUS qdf_event_reset(qdf_event_t *event);
QDF_STATUS qdf_event_destroy(qdf_event_t *event);

View file

@ -2952,6 +2952,32 @@ bool qdf_nbuf_data_is_dns_response(qdf_nbuf_t buf)
return __qdf_nbuf_data_is_dns_response(qdf_nbuf_data(buf));
}
/**
* qdf_nbuf_data_is_tcp_fin() - check if skb data is a tcp fin
* @buf: buffer
*
* Return: true if packet is tcp fin packet.
* false otherwise.
*/
static inline
bool qdf_nbuf_data_is_tcp_fin(qdf_nbuf_t buf)
{
return __qdf_nbuf_data_is_tcp_fin(qdf_nbuf_data(buf));
}
/**
* qdf_nbuf_data_is_tcp_fin_ack() - check if skb data is a tcp fin ack
* @buf: buffer
*
* Return: true if packet is tcp fin ack packet.
* false otherwise.
*/
static inline
bool qdf_nbuf_data_is_tcp_fin_ack(qdf_nbuf_t buf)
{
return __qdf_nbuf_data_is_tcp_fin_ack(qdf_nbuf_data(buf));
}
/**
* qdf_nbuf_data_is_tcp_syn() - check if skb data is a tcp syn
* @buf: buffer
@ -2978,6 +3004,19 @@ bool qdf_nbuf_data_is_tcp_syn_ack(qdf_nbuf_t buf)
return __qdf_nbuf_data_is_tcp_syn_ack(qdf_nbuf_data(buf));
}
/**
* qdf_nbuf_data_is_tcp_rst() - check if skb data is a tcp rst
* @buf: buffer
*
* Return: true if packet is tcp rst packet.
* false otherwise.
*/
static inline
bool qdf_nbuf_data_is_tcp_rst(qdf_nbuf_t buf)
{
return __qdf_nbuf_data_is_tcp_rst(qdf_nbuf_data(buf));
}
/**
* qdf_nbuf_data_is_tcp_ack() - check if skb data is a tcp ack
* @buf: buffer

View file

@ -73,6 +73,11 @@ typedef struct sk_buff_head __qdf_nbuf_queue_head_t;
/* mark the first packet after wow wakeup */
#define QDF_MARK_FIRST_WAKEUP_PACKET 0x80000000
/* TCP Related MASK */
#define QDF_NBUF_PKT_TCPOP_FIN 0x01
#define QDF_NBUF_PKT_TCPOP_FIN_ACK 0x11
#define QDF_NBUF_PKT_TCPOP_RST 0x04
/*
* Make sure that qdf_dma_addr_t in the cb block is always 64 bit aligned
*/
@ -836,8 +841,11 @@ uint32_t __qdf_nbuf_get_arp_tgt_ip(uint8_t *data);
uint8_t *__qdf_nbuf_get_dns_domain_name(uint8_t *data, uint32_t len);
bool __qdf_nbuf_data_is_dns_query(uint8_t *data);
bool __qdf_nbuf_data_is_dns_response(uint8_t *data);
bool __qdf_nbuf_data_is_tcp_fin(uint8_t *data);
bool __qdf_nbuf_data_is_tcp_fin_ack(uint8_t *data);
bool __qdf_nbuf_data_is_tcp_syn(uint8_t *data);
bool __qdf_nbuf_data_is_tcp_syn_ack(uint8_t *data);
bool __qdf_nbuf_data_is_tcp_rst(uint8_t *data);
bool __qdf_nbuf_data_is_tcp_ack(uint8_t *data);
uint16_t __qdf_nbuf_data_get_tcp_src_port(uint8_t *data);
uint16_t __qdf_nbuf_data_get_tcp_dst_port(uint8_t *data);

View file

@ -77,19 +77,6 @@ QDF_STATUS qdf_event_create(qdf_event_t *event)
}
qdf_export_symbol(qdf_event_create);
/**
* qdf_event_set() - sets a QDF event
* @event: The event to set to the signalled state
*
* The state of the specified event is set to signalled by calling
* qdf_event_set().
*
* Any threads waiting on the event as a result of a qdf_event_wait() will
* be unblocked and available to be scheduled for execution when the event
* is signaled by a call to qdf_event_set().
*
* Return: QDF status
*/
QDF_STATUS qdf_event_set(qdf_event_t *event)
{
QDF_BUG(event);
@ -106,8 +93,28 @@ QDF_STATUS qdf_event_set(qdf_event_t *event)
return QDF_STATUS_SUCCESS;
}
qdf_export_symbol(qdf_event_set);
QDF_STATUS qdf_event_set_all(qdf_event_t *event)
{
QDF_BUG(event);
if (!event)
return QDF_STATUS_E_FAULT;
/* ensure event is initialized */
QDF_BUG(event->cookie == LINUX_EVENT_COOKIE);
if (event->cookie != LINUX_EVENT_COOKIE)
return QDF_STATUS_E_INVAL;
event->done = true;
complete_all(&event->complete);
return QDF_STATUS_SUCCESS;
}
qdf_export_symbol(qdf_event_set_all);
/**
* qdf_event_reset() - resets a QDF event
* @event: The event to set to the NOT signalled state

View file

@ -1725,6 +1725,50 @@ bool __qdf_nbuf_data_is_dns_response(uint8_t *data)
return false;
}
/**
* __qdf_nbuf_data_is_tcp_fin() - check if skb data is a tcp fin
* @data: Pointer to network data buffer
*
* This api is to check if the packet is tcp fin.
*
* Return: true if packet is tcp fin packet.
* false otherwise.
*/
bool __qdf_nbuf_data_is_tcp_fin(uint8_t *data)
{
uint8_t op_code;
op_code = (uint8_t)(*(uint8_t *)(data +
QDF_NBUF_PKT_TCP_OPCODE_OFFSET));
if (op_code == QDF_NBUF_PKT_TCPOP_FIN)
return true;
return false;
}
/**
* __qdf_nbuf_data_is_tcp_fin_ack() - check if skb data is a tcp fin ack
* @data: Pointer to network data buffer
*
* This api is to check if the tcp packet is fin ack.
*
* Return: true if packet is tcp fin ack packet.
* false otherwise.
*/
bool __qdf_nbuf_data_is_tcp_fin_ack(uint8_t *data)
{
uint8_t op_code;
op_code = (uint8_t)(*(uint8_t *)(data +
QDF_NBUF_PKT_TCP_OPCODE_OFFSET));
if (op_code == QDF_NBUF_PKT_TCPOP_FIN_ACK)
return true;
return false;
}
/**
* __qdf_nbuf_data_is_tcp_syn() - check if skb data is a tcp syn
* @data: Pointer to network data buffer
@ -1767,6 +1811,28 @@ bool __qdf_nbuf_data_is_tcp_syn_ack(uint8_t *data)
return false;
}
/**
* __qdf_nbuf_data_is_tcp_rst() - check if skb data is a tcp rst
* @data: Pointer to network data buffer
*
* This api is to check if the tcp packet is rst.
*
* Return: true if packet is tcp rst packet.
* false otherwise.
*/
bool __qdf_nbuf_data_is_tcp_rst(uint8_t *data)
{
uint8_t op_code;
op_code = (uint8_t)(*(uint8_t *)(data +
QDF_NBUF_PKT_TCP_OPCODE_OFFSET));
if (op_code == QDF_NBUF_PKT_TCPOP_RST)
return true;
return false;
}
/**
* __qdf_nbuf_data_is_tcp_ack() - check if skb data is a tcp ack
* @data: Pointer to network data buffer
@ -4438,6 +4504,14 @@ static unsigned int qdf_nbuf_update_radiotap_ampdu_flags(
return rtap_len;
}
#ifdef DP_MON_RSSI_IN_DBM
#define QDF_MON_STATUS_GET_RSSI_IN_DBM(rx_status) \
(rx_status->rssi_comb)
#else
#define QDF_MON_STATUS_GET_RSSI_IN_DBM(rx_status) \
(rx_status->rssi_comb + rx_status->chan_noise_floor)
#endif
/**
* qdf_nbuf_update_radiotap() - Update radiotap header from rx_status
* @rx_status: Pointer to rx_status.
@ -4513,7 +4587,7 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
* rssi_comb is int dB, need to convert it to dBm.
* normalize value to noise floor of -96 dBm
*/
rtap_buf[rtap_len] = rx_status->rssi_comb + rx_status->chan_noise_floor;
rtap_buf[rtap_len] = QDF_MON_STATUS_GET_RSSI_IN_DBM(rx_status);
rtap_len += 1;
/* RX signal noise floor */

View file

@ -1732,6 +1732,10 @@ void target_if_spectral_process_phyerr(
}
p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral);
if (!p_sops->spectral_process_phyerr) {
spectral_err("null spectral_process_phyerr");
return;
}
p_sops->spectral_process_phyerr(spectral, data, datalen,
p_rfqual, p_chaninfo,
tsf64, acs_stats);

View file

@ -370,7 +370,8 @@ QDF_STATUS wlan_crypto_set_pmksa(struct wlan_crypto_params *crypto_params,
return QDF_STATUS_E_INVAL;
}
crypto_params->pmksa[first_available_slot] = pmksa;
crypto_debug("PMKSA: Added the PMKSA entry at index=%d", i);
crypto_debug("PMKSA: Added the PMKSA entry at index=%d",
first_available_slot);
return QDF_STATUS_SUCCESS;
}
@ -379,7 +380,7 @@ static
QDF_STATUS wlan_crypto_del_pmksa(struct wlan_crypto_params *crypto_params,
struct wlan_crypto_pmksa *pmksa)
{
uint8_t i, j;
uint8_t i, j, valid_entries_in_table = 0;
bool match_found = false;
u8 del_pmk[MAX_PMK_LEN] = {0};
@ -387,7 +388,12 @@ QDF_STATUS wlan_crypto_del_pmksa(struct wlan_crypto_params *crypto_params,
for (i = 0; i < WLAN_CRYPTO_MAX_PMKID; i++) {
if (!crypto_params->pmksa[i])
continue;
if (qdf_is_macaddr_equal(&pmksa->bssid,
valid_entries_in_table++;
if (!pmksa->ssid_len &&
!qdf_is_macaddr_zero(&pmksa->bssid) &&
qdf_is_macaddr_equal(&pmksa->bssid,
&crypto_params->pmksa[i]->bssid)) {
match_found = true;
} else if (pmksa->ssid_len &&
@ -435,7 +441,8 @@ QDF_STATUS wlan_crypto_del_pmksa(struct wlan_crypto_params *crypto_params,
}
if (i == WLAN_CRYPTO_MAX_PMKID && !match_found)
crypto_debug("No such pmksa entry exists");
crypto_debug("No such pmksa entry exists: valid entries:%d",
valid_entries_in_table);
return QDF_STATUS_SUCCESS;
}
@ -453,6 +460,8 @@ QDF_STATUS wlan_crypto_pmksa_flush(struct wlan_crypto_params *crypto_params)
crypto_params->pmksa[i] = NULL;
}
crypto_debug("Flushed the pmksa table");
return QDF_STATUS_SUCCESS;
}
@ -607,16 +616,19 @@ wlan_crypto_get_peer_pmksa(struct wlan_objmgr_vdev *vdev,
for (i = 0; i < WLAN_CRYPTO_MAX_PMKID; i++) {
if (!crypto_params->pmksa[i])
continue;
if (qdf_is_macaddr_equal(&pmksa->bssid,
&crypto_params->pmksa[i]->bssid)) {
if (pmksa->ssid_len &&
!qdf_mem_cmp(pmksa->ssid,
crypto_params->pmksa[i]->ssid,
pmksa->ssid_len) &&
!qdf_mem_cmp(pmksa->cache_id,
crypto_params->pmksa[i]->cache_id,
WLAN_CACHE_ID_LEN)) {
return crypto_params->pmksa[i];
} else if (pmksa->ssid_len &&
!qdf_mem_cmp(pmksa->ssid,
crypto_params->pmksa[i]->ssid,
pmksa->ssid_len) &&
!qdf_mem_cmp(pmksa->cache_id,
crypto_params->pmksa[i]->cache_id,
WLAN_CACHE_ID_LEN)){
} else if (!pmksa->ssid_len &&
!qdf_is_macaddr_zero(&pmksa->bssid) &&
qdf_is_macaddr_equal(&pmksa->bssid,
&crypto_params->pmksa[i]->bssid)) {
return crypto_params->pmksa[i];
}
}

View file

@ -37,9 +37,13 @@
* change.
* @psoc: Pointer to global psoc structure.
* @pdev: Pointer to global pdev structure.
* @ch_avoid_ind: if chan avoid indicated
* @avoid_info: chan avoid info if @ch_avoid_ind is true
*/
static void reg_call_chan_change_cbks(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_pdev *pdev)
struct wlan_objmgr_pdev *pdev,
bool ch_avoid_ind,
struct avoid_freq_ind_data *avoid_info)
{
struct chan_change_cbk_entry *cbk_list;
struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
@ -70,21 +74,9 @@ static void reg_call_chan_change_cbks(struct wlan_objmgr_psoc *psoc,
NUM_CHANNELS *
sizeof(struct regulatory_channel));
if (psoc_priv_obj->ch_avoid_ind) {
avoid_freq_ind = qdf_mem_malloc(sizeof(*avoid_freq_ind));
if (!avoid_freq_ind)
goto skip_ch_avoid_ind;
if (ch_avoid_ind)
avoid_freq_ind = avoid_info;
qdf_mem_copy(&avoid_freq_ind->freq_list,
&psoc_priv_obj->avoid_freq_list,
sizeof(struct ch_avoid_ind_type));
qdf_mem_copy(&avoid_freq_ind->chan_list,
&psoc_priv_obj->unsafe_chan_list,
sizeof(struct unsafe_ch_list));
psoc_priv_obj->ch_avoid_ind = false;
}
skip_ch_avoid_ind:
cbk_list = psoc_priv_obj->cbk_list;
for (ctr = 0; ctr < REG_MAX_CHAN_CHANGE_CBKS; ctr++) {
@ -98,8 +90,6 @@ skip_ch_avoid_ind:
cbk_list[ctr].arg);
}
qdf_mem_free(cur_chan_list);
if (avoid_freq_ind)
qdf_mem_free(avoid_freq_ind);
}
/**
@ -111,10 +101,28 @@ static void reg_alloc_and_fill_payload(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_pdev *pdev,
struct reg_sched_payload **payload)
{
struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
psoc_priv_obj = reg_get_psoc_obj(psoc);
if (!psoc_priv_obj) {
reg_err("reg psoc private obj is NULL");
*payload = NULL;
return;
}
*payload = qdf_mem_malloc(sizeof(**payload));
if (*payload) {
(*payload)->psoc = psoc;
(*payload)->pdev = pdev;
(*payload)->ch_avoid_ind = !!psoc_priv_obj->ch_avoid_ind;
qdf_mem_copy(&(*payload)->avoid_info.freq_list,
&psoc_priv_obj->avoid_freq_list,
sizeof(psoc_priv_obj->avoid_freq_list));
qdf_mem_copy(&(*payload)->avoid_info.chan_list,
&psoc_priv_obj->unsafe_chan_list,
sizeof(psoc_priv_obj->unsafe_chan_list));
psoc_priv_obj->ch_avoid_ind = false;
}
}
@ -146,7 +154,8 @@ static QDF_STATUS reg_sched_chan_change_cbks_sb(struct scheduler_msg *msg)
struct wlan_objmgr_psoc *psoc = load->psoc;
struct wlan_objmgr_pdev *pdev = load->pdev;
reg_call_chan_change_cbks(psoc, pdev);
reg_call_chan_change_cbks(psoc, pdev, load->ch_avoid_ind,
&load->avoid_info);
wlan_objmgr_pdev_release_ref(pdev, WLAN_REGULATORY_SB_ID);
wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_SB_ID);
@ -183,7 +192,8 @@ static QDF_STATUS reg_sched_chan_change_cbks_nb(struct scheduler_msg *msg)
struct wlan_objmgr_psoc *psoc = load->psoc;
struct wlan_objmgr_pdev *pdev = load->pdev;
reg_call_chan_change_cbks(psoc, pdev);
reg_call_chan_change_cbks(psoc, pdev, load->ch_avoid_ind,
&load->avoid_info);
wlan_objmgr_pdev_release_ref(pdev, WLAN_REGULATORY_NB_ID);
wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_NB_ID);

View file

@ -1203,16 +1203,6 @@ struct reg_freq_range {
uint32_t high_freq;
};
/**
* struct reg_sched_payload
* @psoc: psoc ptr
* @pdev: pdev ptr
*/
struct reg_sched_payload {
struct wlan_objmgr_psoc *psoc;
struct wlan_objmgr_pdev *pdev;
};
/**
* enum direction
* @NORTHBOUND: northbound
@ -1359,6 +1349,20 @@ struct avoid_freq_ind_data {
struct unsafe_ch_list chan_list;
};
/**
* struct reg_sched_payload
* @psoc: psoc ptr
* @pdev: pdev ptr
* @ch_avoid_ind: if avoidance event indicated
* @avoid_info: chan avoid info if @ch_avoid_ind is true
*/
struct reg_sched_payload {
struct wlan_objmgr_psoc *psoc;
struct wlan_objmgr_pdev *pdev;
bool ch_avoid_ind;
struct avoid_freq_ind_data avoid_info;
};
#define FIVEG_STARTING_FREQ 5000
#define TWOG_STARTING_FREQ 2407
#define TWOG_CHAN_14_IN_MHZ 2484

View file

@ -859,6 +859,26 @@ QDF_STATUS
wmi_unified_vdev_set_param_send(wmi_unified_t wmi_handle,
struct vdev_set_params *param);
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
/**
* wmi_unified_roam_set_param_send() - WMI roam set parameter function
* @wmi_handle: handle to WMI.
* @roam_param: pointer to hold roam set parameter
*
* Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
*/
QDF_STATUS
wmi_unified_roam_set_param_send(wmi_unified_t wmi_handle,
struct vdev_set_params *roam_param);
#else
static inline QDF_STATUS
wmi_unified_roam_set_param_send(wmi_unified_t wmi_handle,
struct vdev_set_params *roam_param)
{
return QDF_STATUS_SUCCESS;
}
#endif
/**
* wmi_unified_sifs_trigger_send() - WMI vdev sifs trigger parameter function
* @wmi_handle: handle to WMI.

View file

@ -7887,12 +7887,14 @@ struct wmi_roam_scan_data {
* @status: 0 - Roaming is success ; 1 - Roaming failed ;
* 2 - No roam
* @fail_reason: One of WMI_ROAM_FAIL_REASON_ID
* @fail_bssid: BSSID of the last attempted roam failed AP
*/
struct wmi_roam_result {
bool present;
uint32_t timestamp;
uint32_t status;
uint32_t fail_reason;
struct qdf_mac_addr fail_bssid;
};
/**

View file

@ -1015,6 +1015,9 @@ QDF_STATUS (*send_pdev_set_pcl_cmd)(wmi_unified_t wmi_handle,
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
QDF_STATUS (*send_vdev_set_pcl_cmd)(wmi_unified_t wmi_handle,
struct set_pcl_cmd_params *params);
QDF_STATUS (*send_roam_set_param_cmd)(wmi_unified_t wmi_handle,
struct vdev_set_params *roam_param);
#endif
#ifdef WLAN_POLICY_MGR_ENABLE

View file

@ -399,6 +399,19 @@ wmi_unified_vdev_set_param_send(wmi_unified_t wmi_handle,
return QDF_STATUS_E_FAILURE;
}
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
QDF_STATUS
wmi_unified_roam_set_param_send(wmi_unified_t wmi_handle,
struct vdev_set_params *roam_param)
{
if (wmi_handle->ops->send_roam_set_param_cmd)
return wmi_handle->ops->send_roam_set_param_cmd(wmi_handle,
roam_param);
return QDF_STATUS_E_FAILURE;
}
#endif
QDF_STATUS wmi_unified_sifs_trigger_send(wmi_unified_t wmi_handle,
struct sifs_trigger_param *param)
{

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2013-2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2013-2021 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
@ -693,7 +693,7 @@ static QDF_STATUS extract_ndp_initiator_rsp_tlv(wmi_unified_t wmi_handle,
return QDF_STATUS_SUCCESS;
}
#define MAX_NAN_MSG_LEN 200
#define MAX_NAN_MSG_LEN 400
static QDF_STATUS extract_nan_msg_tlv(uint8_t *data,
struct nan_dump_msg *msg)

View file

@ -14263,6 +14263,7 @@ extract_roam_result_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf,
dst->status = src_data->roam_status;
dst->timestamp = src_data->timestamp;
dst->fail_reason = src_data->roam_fail_reason;
WMI_MAC_ADDR_TO_CHAR_ARRAY(&src_data->bssid, dst->fail_bssid.bytes);
return QDF_STATUS_SUCCESS;
}
@ -14328,6 +14329,47 @@ extract_roam_11kv_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf,
return QDF_STATUS_SUCCESS;
}
/**
* send_roam_set_param_cmd_tlv() - WMI roam set parameter function
* @wmi_handle : handle to WMI.
* @roam_param : pointer to hold roam set parameter
*
* Return: 0 on success and -ve on failure.
*/
static QDF_STATUS
send_roam_set_param_cmd_tlv(wmi_unified_t wmi_handle,
struct vdev_set_params *roam_param)
{
QDF_STATUS ret;
wmi_roam_set_param_cmd_fixed_param *cmd;
wmi_buf_t buf;
uint16_t len = sizeof(*cmd);
buf = wmi_buf_alloc(wmi_handle, len);
if (!buf)
return QDF_STATUS_E_NOMEM;
cmd = (wmi_roam_set_param_cmd_fixed_param *)wmi_buf_data(buf);
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_roam_set_param_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN
(wmi_roam_set_param_cmd_fixed_param));
cmd->vdev_id = roam_param->vdev_id;
cmd->param_id = roam_param->param_id;
cmd->param_value = roam_param->param_value;
wmi_debug("Setting vdev %d roam_param = %x, value = %u",
cmd->vdev_id, cmd->param_id, cmd->param_value);
wmi_mtrace(WMI_ROAM_SET_PARAM_CMDID, cmd->vdev_id, 0);
ret = wmi_unified_cmd_send(wmi_handle, buf, len,
WMI_ROAM_SET_PARAM_CMDID);
if (QDF_IS_STATUS_ERROR(ret)) {
wmi_err("Failed to send roam set param command, ret = %d", ret);
wmi_buf_free(buf);
}
return ret;
}
#else
static inline QDF_STATUS
extract_roam_trigger_stats_tlv(wmi_unified_t wmi_handle, void *evt_buf,
@ -15039,6 +15081,9 @@ struct wmi_ops tlv_ops = {
.extract_pdev_csa_switch_count_status =
extract_pdev_csa_switch_count_status_tlv,
.send_set_tpc_power_cmd = send_set_tpc_power_cmd_tlv,
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
.send_roam_set_param_cmd = send_roam_set_param_cmd_tlv,
#endif /* WLAN_FEATURE_ROAM_OFFLOAD */
};
/**