qcacmn: Add scan related events for TDLS component

Add Scan start and complete events for TDLS component

Change-Id: Ibb452d2823115ec16a7c6e9f88c9ad6cac48930c
CRs-Fixed: 2034220
This commit is contained in:
Kabilan Kannan 2017-03-27 23:42:04 -07:00 • committed by Sandeep Puligilla
commit 8398292c6d
3 changed files with 220 additions and 2 deletions

View file

@ -31,6 +31,11 @@
#include "wlan_policy_mgr_public_struct.h"
#include "wlan_policy_mgr_api.h"
/* Global tdls soc pvt object
* this is useful for some functions which does not receive either vdev or psoc
* objects.
*/
static struct tdls_soc_priv_obj *tdls_soc_global;
QDF_STATUS tdls_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc,
void *arg_list)
@ -56,6 +61,7 @@ QDF_STATUS tdls_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc,
qdf_mem_free(tdls_soc_obj);
}
tdls_soc_global = tdls_soc_obj;
tdls_notice("TDLS obj attach to psoc successfully");
return status;
@ -141,6 +147,8 @@ QDF_STATUS tdls_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev,
{
QDF_STATUS status;
struct tdls_vdev_priv_obj *tdls_vdev_obj;
struct wlan_objmgr_pdev *pdev;
struct tdls_soc_priv_obj *tdls_soc;
tdls_notice("tdls vdev mode %d", wlan_vdev_mlme_get_opmode(vdev));
if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE &&
@ -169,6 +177,23 @@ QDF_STATUS tdls_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev,
if (QDF_IS_STATUS_ERROR(status))
goto out;
tdls_soc = wlan_vdev_get_tdls_soc_obj(vdev);
if (!tdls_soc) {
tdls_err("get soc by vdev failed ");
return QDF_STATUS_E_NOMEM;
}
pdev = wlan_vdev_get_pdev(vdev);
status = ucfg_scan_register_event_handler(pdev,
tdls_scan_complete_event_handler,
tdls_soc);
if (QDF_STATUS_SUCCESS != status) {
tdls_err("scan event register failed ");
return QDF_STATUS_E_FAILURE;
}
tdls_notice("tdls object attach to vdev successfully");
out:
return status;
@ -244,6 +269,9 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg)
case TDLS_CMD_SET_RESPONDER:
tdls_set_responder(msg->bodyptr);
break;
case TDLS_CMD_SCAN_DONE:
tdls_scan_done_callback(msg->bodyptr);
break;
case TDLS_NOTIFY_STA_CONNECTION:
tdls_notify_sta_connect(msg->bodyptr);
break;
@ -257,7 +285,6 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg)
case TDLS_CMD_SESSION_DECREMENT:
tdls_process_policy_mgr_notification(msg->bodyptr);
break;
default:
break;
}
@ -1102,3 +1129,139 @@ release_mode_ref:
return status;
}
/**
* wlan_hdd_tdls_scan_done_callback() - callback for tdls scan done event
* @pAdapter: HDD adapter
*
* Return: Void
*/
void tdls_scan_done_callback(struct tdls_soc_priv_obj *tdls_soc)
{
if (!tdls_soc)
return;
if (TDLS_SUPPORT_DISABLED == tdls_soc->tdls_current_mode) {
tdls_notice("TDLS mode is disabled OR not enabled");
return;
}
/* if tdls was enabled before scan, re-enable tdls mode */
if (TDLS_SUPPORT_IMP_MODE == tdls_soc->tdls_last_mode ||
TDLS_SUPPORT_EXT_CONTROL == tdls_soc->tdls_last_mode ||
TDLS_SUPPORT_EXP_TRIG_ONLY == tdls_soc->tdls_last_mode) {
tdls_notice("revert tdls mode %d",
tdls_soc->tdls_last_mode);
tdls_set_current_mode(tdls_soc, tdls_soc->tdls_last_mode,
false,
TDLS_SET_MODE_SOURCE_SCAN);
}
}
/**
* tdls_post_scan_done_msg() - post scan done message to tdls cmd queue
* @tdls_soc: tdls soc object
*
* Return: QDF_STATUS_SUCCESS or QDF_STATUS_E_NULL_VALUE
*/
static QDF_STATUS tdls_post_scan_done_msg(struct tdls_soc_priv_obj *tdls_soc)
{
struct scheduler_msg msg = {0, };
if (!tdls_soc) {
tdls_err("tdls_soc: %p ", tdls_soc);
return QDF_STATUS_E_NULL_VALUE;
}
msg.bodyptr = tdls_soc;
msg.callback = tdls_process_cmd;
msg.type = TDLS_CMD_SCAN_DONE;
scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg);
return QDF_STATUS_SUCCESS;
}
void tdls_scan_complete_event_handler(struct wlan_objmgr_vdev *vdev,
struct scan_event *event,
void *arg)
{
enum tQDF_ADAPTER_MODE device_mode;
struct tdls_soc_priv_obj *tdls_soc;
if (!vdev || !event || !arg)
return;
if (SCAN_EVENT_TYPE_COMPLETED != event->type)
return;
device_mode = wlan_vdev_mlme_get_opmode(vdev);
if (device_mode != QDF_STA_MODE &&
device_mode != QDF_P2P_CLIENT_MODE)
return;
tdls_soc = (struct tdls_soc_priv_obj *) arg;
tdls_post_scan_done_msg(tdls_soc);
}
QDF_STATUS tdls_scan_callback(struct tdls_soc_priv_obj *tdls_soc)
{
struct tdls_peer *curr_peer;
struct tdls_vdev_priv_obj *tdls_vdev;
struct wlan_objmgr_vdev *vdev;
QDF_STATUS status = QDF_STATUS_SUCCESS;
/* if tdls is not enabled, then continue scan */
if (TDLS_SUPPORT_DISABLED == tdls_soc->tdls_current_mode)
return status;
/* Get the vdev based on vdev operating mode*/
vdev = tdls_get_vdev(tdls_soc->soc, WLAN_TDLS_NB_ID);
if (!vdev)
return status;
tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev);
if (!tdls_vdev)
goto return_success;
curr_peer = tdls_is_progress(tdls_vdev, NULL, 0);
if (NULL != curr_peer) {
if (tdls_soc->scan_reject_count++ >= TDLS_SCAN_REJECT_MAX) {
tdls_notice(QDF_MAC_ADDRESS_STR
". scan rejected %d. force it to idle",
QDF_MAC_ADDR_ARRAY(
curr_peer->peer_mac.bytes),
tdls_soc->scan_reject_count);
tdls_soc->scan_reject_count = 0;
tdls_set_peer_link_status(curr_peer,
TDLS_LINK_IDLE,
TDLS_LINK_UNSPECIFIED);
status = QDF_STATUS_SUCCESS;
} else {
tdls_warn("tdls in progress. scan rejected %d",
tdls_soc->scan_reject_count);
status = QDF_STATUS_E_BUSY;
}
}
return_success:
wlan_objmgr_vdev_release_ref(vdev,
WLAN_TDLS_NB_ID);
return status;
}
void tdls_scan_serialization_comp_info_cb(
union wlan_serialization_rules_info *comp_info)
{
struct tdls_soc_priv_obj *tdls_soc;
QDF_STATUS status;
if (!comp_info)
return;
tdls_soc = tdls_soc_global;
comp_info->scan_info.is_tdls_in_progress = false;
status = tdls_scan_callback(tdls_soc);
if (QDF_STATUS_E_BUSY == status)
comp_info->scan_info.is_tdls_in_progress = true;
}

View file

@ -33,6 +33,7 @@
#include <wlan_objmgr_peer_obj.h>
#include <wlan_tdls_public_structs.h>
#include <scheduler_api.h>
#include "wlan_serialization_api.h"
/* Bit mask flag for tdls_option to FW */
#define ENA_TDLS_OFFCHAN (1 << 0) /* TDLS Off Channel support */
@ -54,6 +55,8 @@
* should not be more than 2000.
*/
#define TDLS_DISCOVERY_TIMEOUT_BEFORE_UPDATE 1000
#define TDLS_SCAN_REJECT_MAX 5
#define tdls_log(level, args...) \
QDF_TRACE(QDF_MODULE_ID_TDLS, level, ## args)
@ -146,6 +149,7 @@ struct tdls_set_state_info {
* @soc: objmgr psoc
* @tdls_current_mode: current tdls mode
* @tdls_last_mode: last tdls mode
* @scan_reject_count: number of times scan rejected due to TDLS
* @tdls_source_bitmap: bit map to set/reset TDLS by different sources
* @tdls_conn_info: this tdls_conn_info can be removed and we can use peer type
* of peer object to get the active tdls peers
@ -182,6 +186,7 @@ struct tdls_soc_priv_obj {
struct wlan_objmgr_psoc *soc;
enum tdls_feature_mode tdls_current_mode;
enum tdls_feature_mode tdls_last_mode;
int scan_reject_count;
unsigned long tdls_source_bitmap;
struct tdls_conn_info tdls_conn_info[WLAN_TDLS_STA_MAX_NUM];
struct tdls_user_config tdls_configs;
@ -619,4 +624,42 @@ struct wlan_objmgr_vdev *tdls_get_vdev(struct wlan_objmgr_psoc *psoc,
QDF_STATUS
tdls_process_policy_mgr_notification(struct wlan_objmgr_psoc *psoc);
/**
* tdls_scan_complete_event_handler() - scan complete event handler for tdls
* @vdev: vdev object
* @event: scan event
* @arg: tdls soc object
*
* Return: None
*/
void tdls_scan_complete_event_handler(struct wlan_objmgr_vdev *vdev,
struct scan_event *event,
void *arg);
/**
* tdls_scan_callback() - callback for TDLS scan operation
* @soc: tdls soc pvt object
*
* Return: QDF_STATUS
*/
QDF_STATUS tdls_scan_callback(struct tdls_soc_priv_obj *tdls_soc);
/**
* wlan_hdd_tdls_scan_done_callback() - callback for tdls scan done event
* @tdls_soc: tdls soc object
*
* Return: Void
*/
void tdls_scan_done_callback(struct tdls_soc_priv_obj *tdls_soc);
/**
* tdls_scan_serialization_comp_info_cb() - callback for scan start
* @comp_info: serialize rules info
*
* Return: negative = caller should stop and return error code immediately
* 1 = caller can continue to scan
*/
void tdls_scan_serialization_comp_info_cb(
union wlan_serialization_rules_info *comp_info);
#endif

View file

@ -30,6 +30,7 @@
#include <wlan_objmgr_global_obj.h>
#include <wlan_objmgr_cmn.h>
#include "wlan_policy_mgr_api.h"
#include "wlan_scan_ucfg_api.h"
QDF_STATUS ucfg_tdls_init(void)
{
@ -134,7 +135,6 @@ static QDF_STATUS tdls_global_init(struct tdls_soc_priv_obj *soc_obj)
else
soc_obj->max_num_tdls_sta = WLAN_TDLS_STA_MAX_NUM;
for (sta_idx = 0; sta_idx < soc_obj->max_num_tdls_sta; sta_idx++) {
soc_obj->tdls_conn_info[sta_idx].sta_id = 0;
soc_obj->tdls_conn_info[sta_idx].session_id = 255;
@ -247,6 +247,18 @@ QDF_STATUS ucfg_tdls_psoc_enable(struct wlan_objmgr_psoc *psoc)
status = tgt_tdls_register_ev_handler(psoc);
if (status != QDF_STATUS_SUCCESS)
return status;
status = wlan_serialization_register_comp_info_cb(psoc,
WLAN_UMAC_COMP_TDLS,
WLAN_SER_CMD_SCAN,
tdls_scan_serialization_comp_info_cb);
if (QDF_STATUS_SUCCESS != status) {
tdls_err("Serialize scan cmd register failed ");
status = QDF_STATUS_E_FAILURE;
}
return status;
}