qcacld-3.0: Enable monitor mode based on VDEV SM

Enable monitor mode based on VDEV SM

Change-Id: I3ed95a7d741b802a67432bc8d8bcab05fe1b51d5
CRs-Fixed: 2457147
This commit is contained in:
Jinwei Chen 2019-06-14 11:04:47 +08:00 • committed by nshrivas
commit 8cb25b3042
9 changed files with 375 additions and 27 deletions

View file

@ -27,6 +27,7 @@
static struct vdev_mlme_ops sta_mlme_ops;
static struct vdev_mlme_ops ap_mlme_ops;
static struct vdev_mlme_ops mon_mlme_ops;
static struct mlme_ext_ops ext_ops;
bool mlme_is_vdev_in_beaconning_mode(enum QDF_OPMODE vdev_opmode)
@ -74,6 +75,8 @@ QDF_STATUS mlme_register_vdev_mgr_ops(struct vdev_mlme_obj *vdev_mlme)
if (mlme_is_vdev_in_beaconning_mode(vdev->vdev_mlme.vdev_opmode))
vdev_mlme->ops = &ap_mlme_ops;
else if (vdev->vdev_mlme.vdev_opmode == QDF_MONITOR_MODE)
vdev_mlme->ops = &mon_mlme_ops;
else
vdev_mlme->ops = &sta_mlme_ops;
@ -468,6 +471,7 @@ static QDF_STATUS vdevmgr_mlme_vdev_down_send(struct vdev_mlme_obj *vdev_mlme,
vdev_mlme->vdev->vdev_objmgr.vdev_id);
return wma_ap_mlme_vdev_down_send(vdev_mlme, data_len, data);
}
/**
* vdevmgr_notify_down_complete() - callback to indicate vdev down is completed
* @vdev_mlme: vdev mlme object
@ -844,6 +848,119 @@ static QDF_STATUS ap_vdev_dfs_cac_timer_stop(struct vdev_mlme_obj *vdev_mlme,
return QDF_STATUS_SUCCESS;
}
/**
* mon_mlme_vdev_start_restart_send () - send vdev start/restart req
* @vdev_mlme: vdev mlme object
* @data_len: event data length
* @data: event data
*
* This function is called to initiate actions of VDEV start/restart
*
* Return: QDF_STATUS
*/
static QDF_STATUS mon_mlme_vdev_start_restart_send(
struct vdev_mlme_obj *vdev_mlme,
uint16_t data_len, void *data)
{
mlme_legacy_debug("vdev id = %d",
vdev_mlme->vdev->vdev_objmgr.vdev_id);
return lim_mon_mlme_vdev_start_send(vdev_mlme, data_len, data);
}
/**
* mon_start_continue () - vdev start rsp calback
* @vdev_mlme: vdev mlme object
* @data_len: event data length
* @data: event data
*
* This function is called to handle the VDEV START/RESTART calback
*
* Return: QDF_STATUS
*/
static QDF_STATUS mon_mlme_start_continue(struct vdev_mlme_obj *vdev_mlme,
uint16_t data_len, void *data)
{
mlme_legacy_debug("vdev id = %d",
vdev_mlme->vdev->vdev_objmgr.vdev_id);
return wma_mon_mlme_vdev_start_continue(vdev_mlme, data_len, data);
}
/**
* mon_mlme_vdev_up_send() - callback to send vdev up
* @vdev_mlme: vdev mlme object
* @data_len: event data length
* @data: event data
*
* This function is called to send vdev up req
*
* Return: QDF_STATUS
*/
static QDF_STATUS mon_mlme_vdev_up_send(struct vdev_mlme_obj *vdev_mlme,
uint16_t data_len, void *data)
{
mlme_legacy_debug("vdev id = %d",
vdev_mlme->vdev->vdev_objmgr.vdev_id);
return wma_mon_mlme_vdev_up_send(vdev_mlme, data_len, data);
}
/**
* mon_mlme_vdev_disconnect_peers() - callback to disconnect all connected peers
* @vdev_mlme: vdev mlme object
* @data_len: event data length
* @data: event data
*
* montior mode no connected peers, only do VDEV state transition.
*
* Return: QDF_STATUS
*/
static QDF_STATUS mon_mlme_vdev_disconnect_peers(
struct vdev_mlme_obj *vdev_mlme,
uint16_t data_len, void *data)
{
mlme_legacy_debug("vdev id = %d",
vdev_mlme->vdev->vdev_objmgr.vdev_id);
return wlan_vdev_mlme_sm_deliver_evt(
vdev_mlme->vdev,
WLAN_VDEV_SM_EV_DISCONNECT_COMPLETE,
0, NULL);
}
/**
* mon_mlme_vdev_stop_send() - callback to send stop vdev request
* @vdev_mlme: vdev mlme object
* @data_len: event data length
* @data: event data
*
* This function is called to send stop vdev request
*
* Return: QDF_STATUS
*/
static QDF_STATUS mon_mlme_vdev_stop_send(struct vdev_mlme_obj *vdev_mlme,
uint16_t data_len, void *data)
{
mlme_legacy_debug("vdev id = %d",
vdev_mlme->vdev->vdev_objmgr.vdev_id);
return wma_mon_mlme_vdev_stop_send(vdev_mlme, data_len, data);
}
/**
* mon_mlme_vdev_down_send() - callback to send vdev down req
* @vdev_mlme: vdev mlme object
* @data_len: event data length
* @data: event data
*
* This function is called to send vdev down req
*
* Return: QDF_STATUS
*/
static QDF_STATUS mon_mlme_vdev_down_send(struct vdev_mlme_obj *vdev_mlme,
uint16_t data_len, void *data)
{
mlme_legacy_debug("vdev id = %d",
vdev_mlme->vdev->vdev_objmgr.vdev_id);
return wma_mon_mlme_vdev_down_send(vdev_mlme, data_len, data);
}
/**
* struct sta_mlme_ops - VDEV MLME operation callbacks strucutre for sta
* @mlme_vdev_start_send: callback to initiate actions of VDEV
@ -934,6 +1051,16 @@ static struct vdev_mlme_ops ap_mlme_ops = {
.mlme_vdev_is_newchan_no_cac = ap_mlme_vdev_is_newchan_no_cac,
};
static struct vdev_mlme_ops mon_mlme_ops = {
.mlme_vdev_start_send = mon_mlme_vdev_start_restart_send,
.mlme_vdev_restart_send = mon_mlme_vdev_start_restart_send,
.mlme_vdev_start_continue = mon_mlme_start_continue,
.mlme_vdev_up_send = mon_mlme_vdev_up_send,
.mlme_vdev_disconnect_peers = mon_mlme_vdev_disconnect_peers,
.mlme_vdev_stop_send = mon_mlme_vdev_stop_send,
.mlme_vdev_down_send = mon_mlme_vdev_down_send,
};
/**
* struct mlme_ext_ops - VDEV MLME legacy global callbacks structure
* @mlme_vdev_ext_hdl_create: callback to invoke creation of legacy

View file

@ -5810,7 +5810,7 @@ static struct cdp_me_ops ol_ops_me = {
};
static struct cdp_mon_ops ol_ops_mon = {
/* EMPTY FOR MCL */
.txrx_monitor_record_channel = ol_htt_mon_note_chan,
};
static struct cdp_host_stats_ops ol_ops_host_stats = {

View file

@ -4996,11 +4996,36 @@ static void lim_process_sme_start_beacon_req(struct mac_context *mac, uint32_t *
}
}
static void lim_mon_change_channel(
struct mac_context *mac_ctx,
struct pe_session *session_entry)
{
if (wlan_vdev_mlme_get_state(session_entry->vdev) == WLAN_VDEV_S_INIT)
wlan_vdev_mlme_sm_deliver_evt(session_entry->vdev,
WLAN_VDEV_SM_EV_START,
sizeof(*session_entry),
session_entry);
else if (wlan_vdev_mlme_get_state(session_entry->vdev) ==
WLAN_VDEV_S_UP) {
mlme_set_chan_switch_in_progress(session_entry->vdev, true);
wlan_vdev_mlme_sm_deliver_evt(session_entry->vdev,
WLAN_VDEV_SM_EV_FW_VDEV_RESTART,
sizeof(*session_entry),
session_entry);
} else {
pe_err("Invalid vdev state to change channel");
}
}
static void lim_change_channel(
struct mac_context *mac_ctx,
struct pe_session *session_entry)
{
if (session_entry->bssType == eSIR_MONITOR_MODE)
return lim_mon_change_channel(mac_ctx, session_entry);
mlme_set_chan_switch_in_progress(session_entry->vdev, true);
if (wlan_vdev_mlme_get_state(session_entry->vdev) ==
WLAN_VDEV_S_DFS_CAC_WAIT)
wlan_vdev_mlme_sm_deliver_evt(session_entry->vdev,

View file

@ -8097,6 +8097,35 @@ QDF_STATUS lim_ap_mlme_vdev_start_req_failed(struct vdev_mlme_obj *vdev_mlme,
return QDF_STATUS_SUCCESS;
}
QDF_STATUS lim_mon_mlme_vdev_start_send(struct vdev_mlme_obj *vdev_mlme,
uint16_t data_len, void *data)
{
struct mac_context *mac_ctx;
struct pe_session *session = (struct pe_session *)data;
if (!data) {
pe_err("data is NULL");
return QDF_STATUS_E_INVAL;
}
mac_ctx = session->mac_ctx;
if (!mac_ctx) {
pe_err("mac_ctx is NULL");
return QDF_STATUS_E_INVAL;
}
lim_set_channel(mac_ctx, session->currentOperChannel,
session->ch_center_freq_seg0,
session->ch_center_freq_seg1,
session->ch_width,
session->maxTxPower,
session->peSessionId,
session->cac_duration_ms,
session->dfs_regdomain);
return QDF_STATUS_SUCCESS;
}
void lim_send_start_bss_confirm(struct mac_context *mac_ctx,
tLimMlmStartCnf *start_cnf)
{

View file

@ -1682,6 +1682,20 @@ QDF_STATUS lim_ap_mlme_vdev_restart_send(struct vdev_mlme_obj *vdev_mlme,
QDF_STATUS lim_ap_mlme_vdev_start_req_failed(struct vdev_mlme_obj *vdev_mlme,
uint16_t data_len, void *data);
/**
* lim_mon_mlme_vdev_start_send() - Invokes VDEV start operation
* @vdev_mlme_obj: VDEV MLME comp object
* @data_len: data size
* @data: event data
*
* API invokes VDEV start operation
*
* Return: SUCCESS on successful completion of start operation
* FAILURE, if it fails due to any
*/
QDF_STATUS lim_mon_mlme_vdev_start_send(struct vdev_mlme_obj *vdev_mlme,
uint16_t data_len, void *event);
#ifdef CRYPTO_SET_KEY_CONVERGED
static inline bool lim_is_set_key_req_converged(void)
{

View file

@ -452,7 +452,7 @@ bool wma_get_hidden_ssid_restart_in_progress(struct wma_txrx_node *iface);
bool wma_get_channel_switch_in_progress(struct wma_txrx_node *iface);
/**
* wma_sta_mlme_vdev_start_continue - VDEV start response handling
* wma_sta_mlme_vdev_start_continue() - VDEV start response handling
* @vdev_mlme_obj: VDEV MLME comp object
* @data_len: data size
* @data: event data
@ -466,7 +466,7 @@ QDF_STATUS wma_sta_mlme_vdev_start_continue(struct vdev_mlme_obj *vdev_mlme,
uint16_t data_len, void *data);
/**
* wma_sta_mlme_vdev_roam_notify - VDEV roam notify handling
* wma_sta_mlme_vdev_roam_notify() - VDEV roam notify handling
* @vdev_mlme_obj: VDEV MLME comp object
* @data_len: data size
* @data: event data
@ -480,7 +480,7 @@ QDF_STATUS wma_sta_mlme_vdev_roam_notify(struct vdev_mlme_obj *vdev_mlme,
uint16_t data_len, void *data);
/**
* wma_ap_mlme_vdev_start_continue - VDEV start response handling
* wma_ap_mlme_vdev_start_continue() - VDEV start response handling
* @vdev_mlme_obj: VDEV MLME comp object
* @data_len: data size
* @data: event data
@ -494,7 +494,7 @@ QDF_STATUS wma_ap_mlme_vdev_start_continue(struct vdev_mlme_obj *vdev_mlme,
uint16_t data_len, void *data);
/**
* wma_sta_vdev_up_send - Send VDEV UP command
* wma_sta_vdev_up_send() - Send VDEV UP command
* @vdev_mlme_obj: VDEV MLME comp object
* @data_len: data size
* @data: event data
@ -508,7 +508,7 @@ QDF_STATUS wma_sta_vdev_up_send(struct vdev_mlme_obj *vdev_mlme,
uint16_t data_len, void *data);
/**
* wma_mlme_vdev_stop_continue - VDEV stop response handling
* wma_mlme_vdev_stop_continue() - VDEV stop response handling
* @vdev_mlme_obj: VDEV MLME comp object
* @data_len: data size
* @data: event data
@ -522,7 +522,7 @@ QDF_STATUS wma_mlme_vdev_stop_continue(struct vdev_mlme_obj *vdev_mlme,
uint16_t data_len, void *data);
/**
* wma_ap_mlme_vdev_down_send - VDEV down operation
* wma_ap_mlme_vdev_down_send() - VDEV down operation
* @vdev_mlme_obj: VDEV MLME comp object
* @data_len: data size
* @data: event data
@ -536,7 +536,7 @@ QDF_STATUS wma_ap_mlme_vdev_down_send(struct vdev_mlme_obj *vdev_mlme,
uint16_t data_len, void *data);
/**
* wma_mlme_vdev_notify_down_complete - VDEV init state transition
* wma_mlme_vdev_notify_down_complete() - VDEV init state transition
* notification
* @vdev_mlme_obj: VDEV MLME comp object
* @data_len: data size
@ -552,7 +552,7 @@ wma_mlme_vdev_notify_down_complete(struct vdev_mlme_obj *vdev_mlme,
uint16_t data_len, void *data);
/**
* wma_ap_mlme_vdev_stop_start_send - handle vdev stop during start req
* wma_ap_mlme_vdev_stop_start_send() - handle vdev stop during start req
* @vdev_mlme_obj: VDEV MLME comp object
* @type: restart req or start req
* @data_len: data size
@ -567,7 +567,7 @@ QDF_STATUS wma_ap_mlme_vdev_stop_start_send(struct vdev_mlme_obj *vdev_mlme,
uint16_t data_len, void *data);
/**
* wma_sta_mlme_vdev_down_send - VDEV down operation
* wma_sta_mlme_vdev_down_send() - VDEV down operation
* @vdev_mlme_obj: VDEV MLME comp object
* @data_len: data size
* @data: event data
@ -580,6 +580,62 @@ QDF_STATUS wma_ap_mlme_vdev_stop_start_send(struct vdev_mlme_obj *vdev_mlme,
QDF_STATUS wma_sta_mlme_vdev_down_send(struct vdev_mlme_obj *vdev_mlme,
uint16_t data_len, void *data);
/**
* wma_mon_mlme_vdev_start_continue() - VDEV start response handling
* @vdev_mlme_obj: VDEV MLME comp object
* @data_len: data size
* @data: event data
*
* API invokes VDEV start response actions
*
* Return: SUCCESS on successful completion of start response operation
* FAILURE, if it fails due to any
*/
QDF_STATUS wma_mon_mlme_vdev_start_continue(struct vdev_mlme_obj *vdev_mlme,
uint16_t data_len, void *data);
/**
* wma_mon_mlme_vdev_up_send() - Send VDEV UP command
* @vdev_mlme_obj: VDEV MLME comp object
* @data_len: data size
* @data: event data
*
* API invokes VDEV UP Command
*
* Return: SUCCESS on successful completion of start response operation
* FAILURE, if it fails due to any
*/
QDF_STATUS wma_mon_mlme_vdev_up_send(struct vdev_mlme_obj *vdev_mlme,
uint16_t data_len, void *data);
/**
* wma_mon_mlme_vdev_stop_send() - VDEV stop operation
* @vdev_mlme_obj: VDEV MLME comp object
* @data_len: data size
* @data: event data
*
* API invokes VDEV stop operation
*
* Return: SUCCESS on successful completion of VDEV stop operation
* FAILURE, if it fails due to any
*/
QDF_STATUS wma_mon_mlme_vdev_stop_send(struct vdev_mlme_obj *vdev_mlme,
uint16_t data_len, void *data);
/**
* wma_mon_mlme_vdev_down_send() - VDEV down operation
* @vdev_mlme_obj: VDEV MLME comp object
* @data_len: data size
* @data: event data
*
* API invokes VDEV down operation
*
* Return: SUCCESS on successful completion of VDEV down operation
* FAILURE, if it fails due to any
*/
QDF_STATUS wma_mon_mlme_vdev_down_send(struct vdev_mlme_obj *vdev_mlme,
uint16_t data_len, void *data);
#ifdef FEATURE_WLM_STATS
/**
* typedef wma_wlm_stats_cb() - Callback function for WLM stats

View file

@ -735,14 +735,13 @@ wma_release_vdev_ref(struct wma_txrx_node *iface)
static void wma_handle_monitor_mode_vdev_detach(tp_wma_handle wma,
uint8_t vdev_id)
{
if (wma_send_vdev_stop_to_fw(wma, vdev_id)) {
WMA_LOGE("%s: %d Failed to send vdev stop", __func__, __LINE__);
wma_remove_vdev_req(wma, vdev_id,
WMA_TARGET_REQ_TYPE_VDEV_STOP);
}
struct wma_txrx_node *iface;
if (wma_send_vdev_down_to_fw(wma, vdev_id) != QDF_STATUS_SUCCESS)
WMA_LOGE("Failed to send vdev down cmd: vdev %d", vdev_id);
iface = &wma->interfaces[vdev_id];
wlan_vdev_mlme_sm_deliver_evt(iface->vdev,
WLAN_VDEV_SM_EV_DOWN,
0, NULL);
iface->vdev_active = false;
}
static QDF_STATUS wma_handle_vdev_detach(tp_wma_handle wma_handle,
@ -1037,8 +1036,10 @@ QDF_STATUS wma_vdev_detach(tp_wma_handle wma_handle,
pdel_sta_self_req_param, generateRsp);
}
if (QDF_IS_STATUS_SUCCESS(status))
if (QDF_IS_STATUS_SUCCESS(status) &&
iface->type != WMI_VDEV_TYPE_MONITOR)
iface->vdev_active = false;
return status;
send_fail_rsp:
@ -2636,6 +2637,7 @@ wma_handle_vdev_stop_rsp(tp_wma_handle wma,
struct wma_txrx_node *iface;
iface = &wma->interfaces[resp_event->vdev_id];
return wlan_vdev_mlme_sm_deliver_evt(iface->vdev,
WLAN_VDEV_SM_EV_STOP_RESP,
sizeof(*resp_event), resp_event);

View file

@ -76,6 +76,7 @@
#include "wlan_mlme_api.h"
#include <wlan_mlme_main.h>
#include <wlan_crypto_global_api.h>
#include <cdp_txrx_mon.h>
#ifdef FEATURE_WLAN_EXTSCAN
#define WMA_EXTSCAN_CYCLE_WAKE_LOCK_DURATION WAKELOCK_DURATION_RECOMMENDED
@ -3517,12 +3518,6 @@ void wma_set_channel(tp_wma_handle wma, tpSwitchChannelParams params)
}
}
if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam() &&
wma_is_vdev_up(vdev_id)) {
WMA_LOGD("%s: setting channel switch to true for vdev_id:%d",
__func__, req.vdev_id);
}
msg = wma_fill_vdev_req(wma, req.vdev_id, WMA_CHNL_SWITCH_REQ,
WMA_TARGET_REQ_TYPE_VDEV_START, params,
WMA_VDEV_START_REQUEST_TIMEOUT);
@ -3543,9 +3538,12 @@ void wma_set_channel(tp_wma_handle wma, tpSwitchChannelParams params)
goto send_resp;
}
/* This is temporary, should be removed */
if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam())
ol_htt_mon_note_chan(pdev, req.chan);
/*
* Record monitor mode channel here in case HW
* indicate RX PPDU TLV with invalid channel number.
*/
if (intr[vdev_id].type == WMI_VDEV_TYPE_MONITOR)
cdp_record_monitor_chan_num(soc, pdev, req.chan);
return;
send_resp:

View file

@ -5064,6 +5064,103 @@ QDF_STATUS wma_ap_mlme_vdev_stop_start_send(struct vdev_mlme_obj *vdev_mlme,
return wma_vdev_send_start_resp(wma, bss_params);
}
QDF_STATUS wma_mon_mlme_vdev_start_continue(struct vdev_mlme_obj *vdev_mlme,
uint16_t data_len, void *data)
{
if (mlme_is_chan_switch_in_progress(vdev_mlme->vdev))
mlme_set_chan_switch_in_progress(vdev_mlme->vdev, false);
wlan_vdev_mlme_sm_deliver_evt(vdev_mlme->vdev,
WLAN_VDEV_SM_EV_START_SUCCESS,
data_len,
data);
return QDF_STATUS_SUCCESS;
}
QDF_STATUS wma_mon_mlme_vdev_up_send(struct vdev_mlme_obj *vdev_mlme,
uint16_t data_len, void *data)
{
struct vdev_up_params param;
uint8_t vdev_id;
tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
QDF_STATUS status;
struct wma_txrx_node *iface;
if (!wma) {
WMA_LOGE("%s wma handle is NULL", __func__);
return QDF_STATUS_E_INVAL;
}
vdev_id = wlan_vdev_get_id(vdev_mlme->vdev);
param.vdev_id = vdev_id;
iface = &wma->interfaces[vdev_id];
status = wma_send_vdev_up_to_fw(wma, &param, iface->bssid);
if (QDF_IS_STATUS_ERROR(status))
WMA_LOGE("%s: Failed to send vdev up cmd: vdev %d bssid %pM",
__func__, vdev_id, iface->bssid);
wma_send_msg_high_priority(wma, WMA_SWITCH_CHANNEL_RSP,
data, 0);
return status;
}
QDF_STATUS wma_mon_mlme_vdev_stop_send(struct vdev_mlme_obj *vdev_mlme,
uint16_t data_len, void *data)
{
uint8_t vdev_id;
tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
QDF_STATUS status;
if (!wma) {
WMA_LOGE("%s wma handle is NULL", __func__);
return QDF_STATUS_E_INVAL;
}
vdev_id = wlan_vdev_get_id(vdev_mlme->vdev);
status = wma_send_vdev_stop_to_fw(wma, vdev_id);
if (QDF_IS_STATUS_ERROR(status))
WMA_LOGE("%s: Failed to send vdev stop cmd: vdev %d",
__func__, vdev_id);
wlan_vdev_mlme_sm_deliver_evt(vdev_mlme->vdev,
WLAN_VDEV_SM_EV_MLME_DOWN_REQ,
0,
NULL);
return status;
}
QDF_STATUS wma_mon_mlme_vdev_down_send(struct vdev_mlme_obj *vdev_mlme,
uint16_t data_len, void *data)
{
uint8_t vdev_id;
tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
QDF_STATUS status;
if (!wma) {
WMA_LOGE("%s wma handle is NULL", __func__);
return QDF_STATUS_E_INVAL;
}
vdev_id = wlan_vdev_get_id(vdev_mlme->vdev);
status = wma_send_vdev_down_to_fw(wma, vdev_id);
if (QDF_IS_STATUS_ERROR(status))
WMA_LOGE("%s: Failed to send vdev down cmd: vdev %d",
__func__, vdev_id);
wlan_vdev_mlme_sm_deliver_evt(vdev_mlme->vdev,
WLAN_VDEV_SM_EV_DOWN_COMPLETE,
0,
NULL);
return status;
}
#ifdef FEATURE_WLM_STATS
int wma_wlm_stats_req(int vdev_id, uint32_t bitmask, uint32_t max_size,
wma_wlm_stats_cb cb, void *cookie)