qcacmn: Add TDLS off channel changes for TDLS UMAC

Add TDLS offchannel and related osif changes in TDLS
UMAC component.

Change-Id: Ic562709eb8a6361322860c4f7333633a7894af99
CRs-Fixed: 2034220
This commit is contained in:
Kabilan Kannan 2017-04-17 21:53:42 -07:00 • committed by Sandeep Puligilla
commit 7e189c3436
13 changed files with 662 additions and 6 deletions

View file

@ -43,7 +43,7 @@ static uint16_t tdls_get_connected_peer(struct tdls_soc_priv_obj *soc_obj)
*
* Return: None.
*/
static void tdls_decrement_peer_count(struct tdls_soc_priv_obj *soc_obj)
void tdls_decrement_peer_count(struct tdls_soc_priv_obj *soc_obj)
{
if (soc_obj->connected_peer_count)
soc_obj->connected_peer_count--;

View file

@ -365,4 +365,14 @@ int tdls_validate_mgmt_request(struct tdls_validate_action_req *tdls_validate);
*/
int tdls_set_responder(struct tdls_set_responder_req *set_req);
/**
* tdls_decrement_peer_count() - decrement connected TDLS peer counter
* @soc_obj: TDLS soc object
*
* Used in scheduler thread context, no lock needed.
*
* Return: None.
*/
void tdls_decrement_peer_count(struct tdls_soc_priv_obj *soc_obj);
#endif

View file

@ -25,6 +25,7 @@
#include "wlan_tdls_main.h"
#include "wlan_tdls_peer.h"
#include "wlan_tdls_ct.h"
#include "wlan_tdls_cmds_process.h"
bool tdls_is_vdev_connected(struct wlan_objmgr_vdev *vdev)
{
@ -936,3 +937,386 @@ void tdls_ct_handler(void *user_data)
WLAN_TDLS_NB_ID);
}
/**
* tdls_set_tdls_offchannel() - set tdls off-channel number
* @tdls_soc: tdls soc object
* @offchanmode: tdls off-channel number
*
* This function sets tdls off-channel number
*
* Return: 0 on success; negative errno otherwise
*/
static
int tdls_set_tdls_offchannel(struct tdls_soc_priv_obj *tdls_soc,
int offchannel)
{
uint32_t tdls_feature_flags;
tdls_feature_flags = tdls_soc->tdls_configs.tdls_feature_flags;
if (TDLS_IS_OFF_CHANNEL_ENABLED(tdls_feature_flags) &&
(TDLS_SUPPORT_EXP_TRIG_ONLY == tdls_soc->tdls_current_mode ||
TDLS_SUPPORT_IMP_MODE == tdls_soc->tdls_current_mode ||
TDLS_SUPPORT_EXT_CONTROL == tdls_soc->tdls_current_mode)) {
if (offchannel < TDLS_PREFERRED_OFF_CHANNEL_NUM_MIN ||
offchannel > TDLS_PREFERRED_OFF_CHANNEL_NUM_MAX) {
tdls_err("Invalid tdls off channel %u", offchannel);
return -EINVAL;
}
} else {
tdls_err("Either TDLS or TDLS Off-channel is not enabled");
return -ENOTSUPP;
}
tdls_notice("change tdls off channel from %d to %d",
tdls_soc->tdls_off_channel, offchannel);
tdls_soc->tdls_off_channel = offchannel;
return 0;
}
/**
* tdls_set_tdls_secoffchanneloffset() - set secondary tdls off-channel offset
* @tdls_soc: tdls soc object
* @offchanmode: tdls off-channel offset
*
* This function sets 2nd tdls off-channel offset
*
* Return: 0 on success; negative errno otherwise
*/
static
int tdls_set_tdls_secoffchanneloffset(struct tdls_soc_priv_obj *tdls_soc,
int offchanoffset)
{
uint32_t tdls_feature_flags;
tdls_feature_flags = tdls_soc->tdls_configs.tdls_feature_flags;
if (!TDLS_IS_OFF_CHANNEL_ENABLED(tdls_feature_flags) ||
TDLS_SUPPORT_SUSPENDED >= tdls_soc->tdls_current_mode) {
tdls_err("Either TDLS or TDLS Off-channel is not enabled");
return -ENOTSUPP;
}
tdls_soc->tdls_channel_offset = 0;
switch (offchanoffset) {
case TDLS_SEC_OFFCHAN_OFFSET_0:
tdls_soc->tdls_channel_offset = (1 << BW_20_OFFSET_BIT);
break;
case TDLS_SEC_OFFCHAN_OFFSET_40PLUS:
case TDLS_SEC_OFFCHAN_OFFSET_40MINUS:
tdls_soc->tdls_channel_offset = (1 << BW_40_OFFSET_BIT);
break;
case TDLS_SEC_OFFCHAN_OFFSET_80:
tdls_soc->tdls_channel_offset = (1 << BW_80_OFFSET_BIT);
break;
case TDLS_SEC_OFFCHAN_OFFSET_160:
tdls_soc->tdls_channel_offset = (1 << BW_160_OFFSET_BIT);
break;
default:
tdls_err("Invalid tdls secondary off channel offset %d",
offchanoffset);
return -EINVAL;
} /* end switch */
tdls_notice("change tdls secondary off channel offset to 0x%x",
tdls_soc->tdls_channel_offset);
return 0;
}
/**
* tdls_set_tdls_offchannelmode() - set tdls off-channel mode
* @adapter: Pointer to the HDD adapter
* @offchanmode: tdls off-channel mode
*
* This function sets tdls off-channel mode
*
* Return: 0 on success; negative errno otherwise
*/
static
int tdls_set_tdls_offchannelmode(struct wlan_objmgr_vdev *vdev,
int offchanmode)
{
struct tdls_peer *conn_peer = NULL;
struct tdls_channel_switch_params chan_switch_params;
QDF_STATUS status = QDF_STATUS_E_FAILURE;
int ret_value = 0;
struct tdls_vdev_priv_obj *tdls_vdev;
struct tdls_soc_priv_obj *tdls_soc;
uint32_t tdls_feature_flags;
status = tdls_get_vdev_objects(vdev, &tdls_vdev, &tdls_soc);
if (status != QDF_STATUS_SUCCESS)
return -EINVAL;
if (offchanmode < ENABLE_CHANSWITCH ||
offchanmode > DISABLE_CHANSWITCH) {
tdls_err("Invalid tdls off channel mode %d", offchanmode);
return -EINVAL;
}
if (tdls_is_vdev_connected(vdev)) {
tdls_err("tdls off channel req in not associated state %d",
offchanmode);
return -EPERM;
}
tdls_feature_flags = tdls_soc->tdls_configs.tdls_feature_flags;
if (!TDLS_IS_OFF_CHANNEL_ENABLED(tdls_feature_flags) ||
TDLS_SUPPORT_SUSPENDED >= tdls_soc->tdls_current_mode) {
tdls_err("Either TDLS or TDLS Off-channel is not enabled");
return -ENOTSUPP;
}
conn_peer = tdls_find_first_connected_peer(tdls_vdev);
if (NULL == conn_peer) {
tdls_err("No TDLS Connected Peer");
return -EPERM;
}
tdls_notice("TDLS Channel Switch in swmode=%d tdls_off_channel %d offchanoffset %d",
offchanmode, tdls_soc->tdls_off_channel,
tdls_soc->tdls_channel_offset);
switch (offchanmode) {
case ENABLE_CHANSWITCH:
if (tdls_soc->tdls_off_channel &&
tdls_soc->tdls_channel_offset) {
chan_switch_params.tdls_off_ch =
tdls_soc->tdls_off_channel;
chan_switch_params.tdls_off_ch_bw_offset =
tdls_soc->tdls_channel_offset;
chan_switch_params.oper_class =
tdls_find_opclass(tdls_soc->soc,
chan_switch_params.tdls_off_ch,
chan_switch_params.tdls_off_ch_bw_offset);
} else {
tdls_err("TDLS off-channel parameters are not set yet!!!");
return -EINVAL;
}
break;
case DISABLE_CHANSWITCH:
chan_switch_params.tdls_off_ch = 0;
chan_switch_params.tdls_off_ch_bw_offset = 0;
chan_switch_params.oper_class = 0;
break;
default:
tdls_err("Incorrect Parameters mode: %d tdls_off_channel: %d offchanoffset: %d",
offchanmode, tdls_soc->tdls_off_channel,
tdls_soc->tdls_channel_offset);
return -EINVAL;
} /* end switch */
chan_switch_params.vdev_id = tdls_vdev->session_id;
chan_switch_params.tdls_sw_mode = offchanmode;
chan_switch_params.is_responder =
conn_peer->is_responder;
qdf_mem_copy(&chan_switch_params.peer_mac_addr,
&conn_peer->peer_mac.bytes,
QDF_MAC_ADDR_SIZE);
tdls_notice("Peer " QDF_MAC_ADDRESS_STR " vdevId: %d, off channel: %d, offset: %d, mode: %d, is_responder: %d",
QDF_MAC_ADDR_ARRAY(chan_switch_params.peer_mac_addr),
chan_switch_params.vdev_id,
chan_switch_params.tdls_off_ch,
chan_switch_params.tdls_off_ch_bw_offset,
chan_switch_params.tdls_sw_mode,
chan_switch_params.is_responder);
status = tdls_set_offchan_mode(tdls_soc->soc,
&chan_switch_params);
if (status != QDF_STATUS_SUCCESS) {
tdls_err("Failed to send channel switch request to wmi");
return -EINVAL;
}
tdls_soc->tdls_fw_off_chan_mode = offchanmode;
if (ENABLE_CHANSWITCH == offchanmode) {
conn_peer = tdls_find_first_connected_peer(tdls_vdev);
if (NULL == conn_peer) {
tdls_err("No TDLS Connected Peer");
return -EPERM;
}
conn_peer->pref_off_chan_num =
chan_switch_params.tdls_off_ch;
conn_peer->op_class_for_pref_off_chan =
chan_switch_params.oper_class;
}
return ret_value;
}
/**
* tdls_delete_all_tdls_peers(): send request to delete tdls peers
* @vdev: vdev object
* @tdls_soc: tdls soc object
*
* This function sends request to lim to delete tdls peers
*
* Return: QDF_STATUS
*/
static
QDF_STATUS tdls_delete_all_tdls_peers(struct wlan_objmgr_vdev *vdev,
struct tdls_soc_priv_obj *tdls_soc)
{
struct wlan_objmgr_peer *peer;
struct tdls_del_all_tdls_peers *del_msg;
struct scheduler_msg msg;
QDF_STATUS status;
del_msg = qdf_mem_malloc(sizeof(*del_msg));
if (NULL == del_msg) {
tdls_err("memory alloc failed");
return QDF_STATUS_E_FAILURE;
}
qdf_mem_zero(del_msg, sizeof(*del_msg));
peer = wlan_vdev_get_bsspeer(vdev);
if (QDF_STATUS_SUCCESS != wlan_objmgr_peer_try_get_ref(peer,
WLAN_TDLS_SB_ID)) {
return QDF_STATUS_E_FAILURE;
}
qdf_mem_copy(del_msg->bssid.bytes,
wlan_peer_get_macaddr(peer), QDF_MAC_ADDR_SIZE);
del_msg->msg_type = tdls_soc->tdls_del_all_peers;
del_msg->msg_len = (uint16_t) sizeof(*del_msg);
/* Send the request to PE. */
qdf_mem_zero(&msg, sizeof(msg));
tdls_debug("sending delete all peers req to PE ");
msg.type = del_msg->msg_type;
msg.bodyptr = del_msg;
status = scheduler_post_msg(QDF_MODULE_ID_PE, &msg);
wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_SB_ID);
return status;
}
void tdls_disable_offchan_and_teardown_links(
struct wlan_objmgr_vdev *vdev)
{
uint16_t connected_tdls_peers = 0;
uint8_t staidx;
struct tdls_peer *curr_peer = NULL;
struct tdls_vdev_priv_obj *tdls_vdev;
struct tdls_soc_priv_obj *tdls_soc;
QDF_STATUS status;
status = tdls_get_vdev_objects(vdev, &tdls_vdev, &tdls_soc);
if (QDF_STATUS_SUCCESS != status) {
tdls_err("tdls objects are NULL ");
return;
}
if (TDLS_SUPPORT_SUSPENDED >= tdls_soc->tdls_current_mode) {
tdls_notice("TDLS mode %d is disabled OR not suspended now",
tdls_soc->tdls_current_mode);
return;
}
connected_tdls_peers = tdls_soc->connected_peer_count;
if (!connected_tdls_peers) {
tdls_notice("No TDLS connected peers to delete");
return;
}
/* TDLS is not supported in case of concurrency.
* Disable TDLS Offchannel in FW to avoid more
* than two concurrent channels and generate TDLS
* teardown indication to supplicant.
* Below function Finds the first connected peer and
* disables TDLS offchannel for that peer.
* FW enables TDLS offchannel only when there is
* one TDLS peer. When there are more than one TDLS peer,
* there will not be TDLS offchannel in FW.
* So to avoid sending multiple request to FW, for now,
* just invoke offchannel mode functions only once
*/
tdls_set_tdls_offchannel(tdls_soc,
tdls_soc->tdls_configs.tdls_pre_off_chan_num);
tdls_set_tdls_secoffchanneloffset(tdls_soc,
TDLS_SEC_OFFCHAN_OFFSET_40PLUS);
tdls_set_tdls_offchannelmode(vdev, DISABLE_CHANSWITCH);
/* Send Msg to PE for deleting all the TDLS peers */
tdls_delete_all_tdls_peers(vdev, tdls_soc);
for (staidx = 0; staidx < tdls_soc->max_num_tdls_sta;
staidx++) {
if (!tdls_soc->tdls_conn_info[staidx].sta_id)
continue;
curr_peer = tdls_find_all_peer(tdls_soc,
tdls_soc->tdls_conn_info[staidx].peer_mac.bytes);
if (!curr_peer)
continue;
tdls_notice("indicate TDLS teardown (staId %d)",
curr_peer->sta_id);
/* Indicate teardown to supplicant */
tdls_indicate_teardown(tdls_vdev,
curr_peer,
TDLS_TEARDOWN_PEER_UNSPEC_REASON);
/*
* Del Sta happened already as part of tdls_delete_all_tdls_peers
* Hence clear tdls vdev data structure.
*/
tdls_reset_peer(tdls_vdev, curr_peer->peer_mac.bytes);
if (tdls_soc->tdls_dereg_tl_peer)
tdls_soc->tdls_dereg_tl_peer(
tdls_soc->tdls_tl_peer_data,
wlan_vdev_get_id(vdev),
curr_peer->sta_id);
tdls_decrement_peer_count(tdls_soc);
tdls_soc->tdls_conn_info[staidx].sta_id = 0;
tdls_soc->tdls_conn_info[staidx].session_id = 255;
qdf_mem_zero(&tdls_soc->tdls_conn_info[staidx].peer_mac,
sizeof(struct qdf_mac_addr));
}
}
void tdls_teardown_connections(struct wlan_objmgr_vdev *vdev)
{
struct tdls_osif_indication indication;
struct tdls_soc_priv_obj *tdls_soc;
struct wlan_objmgr_vdev *tdls_vdev_obj;
if (!vdev) {
QDF_ASSERT(0);
return;
}
tdls_soc = wlan_vdev_get_tdls_soc_obj(vdev);
if (!tdls_soc)
return;
/* Get the tdls specific vdev and clear the links */
tdls_vdev_obj = tdls_get_vdev(tdls_soc->soc, WLAN_TDLS_SB_ID);
if (tdls_vdev_obj) {
tdls_disable_offchan_and_teardown_links(tdls_vdev_obj);
wlan_objmgr_vdev_release_ref(tdls_vdev_obj, WLAN_TDLS_SB_ID);
}
indication.vdev = vdev;
if (tdls_soc->tdls_event_cb)
tdls_soc->tdls_event_cb(tdls_soc->tdls_evt_cb_data,
TDLS_EVENT_TEARDOWN_LINKS_DONE,
&indication);
}

View file

@ -31,6 +31,10 @@
*/
#define TDLS_DISCOVERY_TIMEOUT_ERE_UPDATE 1000
#define TDLS_PREFERRED_OFF_CHANNEL_NUM_MIN 1
#define TDLS_PREFERRED_OFF_CHANNEL_NUM_MAX 165
#define TDLS_PREFERRED_OFF_CHANNEL_NUM_DEFAULT 36
/**
* tdls_is_vdev_connected() - check the vdev is connected to ap
* @vdev: vdev object manager
@ -172,4 +176,22 @@ bool tdls_is_vdev_connected(struct wlan_objmgr_vdev *vdev);
*/
bool tdls_is_vdev_authenticated(struct wlan_objmgr_vdev *vdev);
/**
* tdls_teardown_connections() -teardown and delete all the tdls peers
* @vdev: vdev oobject
*
* Return: true or false
*/
void tdls_teardown_connections(struct wlan_objmgr_vdev *vdev);
/**
* tdls_disable_offchan_and_teardown_links - Disable offchannel
* and teardown TDLS links
* @tdls_soc : tdls soc object
*
* Return: None
*/
void tdls_disable_offchan_and_teardown_links(
struct wlan_objmgr_vdev *vdev);
#endif

View file

@ -287,6 +287,9 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg)
case TDLS_CMD_SESSION_DECREMENT:
tdls_process_policy_mgr_notification(msg->bodyptr);
break;
case TDLS_CMD_TEARDOWN_LINKS:
tdls_teardown_connections(msg->bodyptr);
break;
default:
break;
}
@ -468,6 +471,20 @@ static void tdls_state_param_setting_dump(struct tdls_info *info)
}
QDF_STATUS tdls_set_offchan_mode(struct wlan_objmgr_psoc *psoc,
struct tdls_channel_switch_params *param)
{
QDF_STATUS status;
/* wmi_unified_set_tdls_offchan_mode_cmd() will be called directly */
status = tgt_tdls_set_offchan_mode(psoc, param);
if (!QDF_IS_STATUS_SUCCESS(status))
status = QDF_STATUS_E_FAILURE;
return status;
}
/**
* tdls_update_fw_tdls_state() - update tdls status info
* @tdls_soc_obj: TDLS soc object
@ -745,12 +762,15 @@ static void tdls_send_update_to_fw(struct tdls_vdev_priv_obj *tdls_vdev_obj,
tdls_soc_obj->set_state_info.set_state_cnt);
/* disable off channel and teardown links */
/* Go through the peer list and delete them */
tdls_disable_offchan_and_teardown_links(tdls_vdev_obj->vdev);
tdls_soc_obj->tdls_current_mode = TDLS_SUPPORT_DISABLED;
tdls_info_to_fw->vdev_id = tdls_soc_obj->set_state_info.vdev_id;
} else {
tdls_info_to_fw->vdev_id = session_id;
}
/* record the session id in vdev context */
tdls_vdev_obj->session_id = session_id;
tdls_info_to_fw->tdls_state = tdls_soc_obj->tdls_current_mode;
tdls_info_to_fw->tdls_options = 0;

View file

@ -180,6 +180,7 @@ struct tdls_set_state_info {
* @tdls_add_sta_req: store eWNI_SME_TDLS_ADD_STA_REQ value
* @tdls_del_sta_req: store eWNI_SME_TDLS_DEL_STA_REQ value
* @tdls_update_peer_state: store WMA_UPDATE_TDLS_PEER_STATE value
* @tdls_del_all_peers:store eWNI_SME_DEL_ALL_TDLS_PEERS
* @tdls_idle_peer_data: provide information about idle peer
* @tdls_ct_spinlock: connection tracker spin lock
*/
@ -221,6 +222,7 @@ struct tdls_soc_priv_obj {
uint16_t tdls_add_sta_req;
uint16_t tdls_del_sta_req;
uint16_t tdls_update_peer_state;
uint16_t tdls_del_all_peers;
struct tdls_ct_idle_peer_data tdls_idle_peer_data;
qdf_spinlock_t tdls_ct_spinlock;
};
@ -255,6 +257,7 @@ struct tdls_vdev_priv_obj {
ct_peer_table[WLAN_TDLS_CT_TABLE_SIZE];
uint8_t valid_mac_entries;
uint32_t magic;
uint8_t session_id;
qdf_list_t tx_queue;
};
@ -667,4 +670,16 @@ void tdls_scan_done_callback(struct tdls_soc_priv_obj *tdls_soc);
void tdls_scan_serialization_comp_info_cb(
union wlan_serialization_rules_info *comp_info);
/**
* tdls_set_offchan_mode() - update tdls status info
* @psoc: soc object
* @param: channel switch params
*
* send message to WMI to set TDLS off channel in f/w
*
* Return: QDF_STATUS.
*/
QDF_STATUS tdls_set_offchan_mode(struct wlan_objmgr_psoc *psoc,
struct tdls_channel_switch_params *param);
#endif

View file

@ -125,7 +125,7 @@ tdls_find_all_peer(struct tdls_soc_priv_obj *soc_obj, const uint8_t *macaddr)
return tdls_search_param.peer;
}
static uint8_t tdls_find_opclass(struct wlan_objmgr_psoc *psoc, uint8_t channel,
uint8_t tdls_find_opclass(struct wlan_objmgr_psoc *psoc, uint8_t channel,
uint8_t bw_offset)
{
char country[REG_ALPHA2_LEN + 1];

View file

@ -84,6 +84,20 @@ struct tdls_peer *tdls_find_peer(struct tdls_vdev_priv_obj *vdev_obj,
struct tdls_peer *
tdls_find_all_peer(struct tdls_soc_priv_obj *soc_obj, const uint8_t *macaddr);
/**
* tdls_find_all_peer() - find peer matching the input MACaddr in soc range
* @soc_obj: TDLS soc object
* @channel:channel number
* @bw_offset: offset to bandwidth
*
* This is in scheduler thread context, no lock required.
*
* Return: Operating class
*/
uint8_t tdls_find_opclass(struct wlan_objmgr_psoc *psoc,
uint8_t channel,
uint8_t bw_offset);
/**
* tdls_find_first_connected_peer() - find the 1st connected tdls peer from vdev
* @vdev_obj: tdls vdev object

View file

@ -29,7 +29,6 @@
#include <qdf_mc_timer.h>
#include <wlan_cmn.h>
#include <wlan_cmn_ieee80211.h>
#include <wlan_objmgr_psoc_obj.h>
#define WLAN_TDLS_STA_MAX_NUM 8
@ -63,6 +62,9 @@
/** Maximum time(ms) to wait for tdls mgmt to complete **/
#define WAIT_TIME_FOR_TDLS_MGMT 11000
/** Maximum waittime for TDLS teardown links **/
#define WAIT_TIME_FOR_TDLS_TEARDOWN_LINKS 10000
#define TDLS_TEARDOWN_PEER_UNREACHABLE 25
#define TDLS_TEARDOWN_PEER_UNSPEC_REASON 26
@ -188,6 +190,7 @@ enum tdls_command_type {
TDLS_CMD_SET_TDLS_MODE,
TDLS_CMD_SESSION_INCREMENT,
TDLS_CMD_SESSION_DECREMENT,
TDLS_CMD_TEARDOWN_LINKS,
};
/**
@ -210,6 +213,7 @@ enum tdls_event_type {
TDLS_EVENT_DISCOVERY_REQ,
TDLS_EVENT_TEARDOWN_REQ,
TDLS_EVENT_SETUP_REQ,
TDLS_EVENT_TEARDOWN_LINKS_DONE,
};
/**
@ -547,6 +551,7 @@ struct tdls_start_params {
uint16_t tdls_add_sta_req;
uint16_t tdls_del_sta_req;
uint16_t tdls_update_peer_state;
uint16_t tdls_del_all_peers;
tdls_rx_callback tdls_rx_cb;
void *tdls_rx_cb_data;
tdls_wmm_check tdls_wmm_cb;
@ -1001,4 +1006,16 @@ struct tdls_set_mode_params {
enum tdls_disable_sources source;
};
/**
* struct tdls_del_all_tdls_peers - delete all tdls peers
* @msg_type: type of message
* @msg_len: length of message
* @bssid: bssid of peer device
*/
struct tdls_del_all_tdls_peers {
uint16_t msg_type;
uint16_t msg_len;
struct qdf_mac_addr bssid;
};
#endif

View file

@ -138,6 +138,14 @@ QDF_STATUS ucfg_tdls_send_mgmt_frame(
*/
QDF_STATUS ucfg_tdls_responder(struct tdls_set_responder_req *msg_req);
/**
* ucfg_tdls_teardown_links() - teardown all TDLS links
* @vdev: vdev object manager
*
* Return: None
*/
QDF_STATUS ucfg_tdls_teardown_links(struct wlan_objmgr_vdev *vdev);
/**
* ucfg_tdls_notify_sta_connect() - notify sta connect
* @notify_info: sta notification info

View file

@ -216,6 +216,7 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc,
soc_obj->tdls_add_sta_req = req->tdls_add_sta_req;
soc_obj->tdls_del_sta_req = req->tdls_del_sta_req;
soc_obj->tdls_update_peer_state = req->tdls_update_peer_state;
soc_obj->tdls_del_all_peers = req->tdls_del_all_peers;
tdls_pm_call_backs.tdls_notify_increment_session =
tdls_notify_increment_session;
@ -238,6 +239,7 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc,
else
soc_obj->tdls_current_mode = TDLS_SUPPORT_IMP_MODE;
soc_obj->tdls_last_mode = soc_obj->tdls_current_mode;
return QDF_STATUS_SUCCESS;
}
@ -538,6 +540,26 @@ QDF_STATUS ucfg_tdls_responder(struct tdls_set_responder_req *req)
return status;
}
QDF_STATUS ucfg_tdls_teardown_links(struct wlan_objmgr_vdev *vdev)
{
QDF_STATUS status;
struct scheduler_msg msg = {0, };
if (!vdev) {
tdls_err("vdev is NULL ");
return QDF_STATUS_E_NULL_VALUE;
}
tdls_notice("Enter ");
msg.bodyptr = vdev;
msg.callback = tdls_process_cmd;
msg.type = TDLS_CMD_TEARDOWN_LINKS;
status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg);
tdls_notice("Exit ");
return status;
}
QDF_STATUS ucfg_tdls_notify_sta_connect(
struct tdls_sta_notify_params *notify_info)
{