qcacmn: Add os_if changes for tdls management

Add os interface changes to send tdls management
frames to tdls component

Change-Id: Ib675e4b089a88ad618f918d9992a777c7221b34c
CRs-Fixed: 2034220
此提交包含在:
Kabilan Kannan
2017-03-26 18:52:47 -07:00
提交者 Sandeep Puligilla
父節點 8398292c6d
當前提交 e81cb8eac8
共有 16 個檔案被更改,包括 1085 行新增20 行删除

查看文件

@@ -309,17 +309,18 @@ enum wnm_actioncode {
* @TDLS_DISCOVERY_REQUEST: tdls discovery request frame
*/
enum tdls_actioncode {
TDLS_SETUP_REQUEST,
TDLS_SETUP_RESPONSE,
TDLS_SETUP_CONFIRM,
TDLS_TEARDOWN,
TDLS_PEER_TRAFFIC_INDICATION,
TDLS_CHANNEL_SWITCH_REQUEST,
TDLS_CHANNEL_SWITCH_RESPONSE,
TDLS_PEER_PSM_REQUEST,
TDLS_PEER_PSM_RESPONSE,
TDLS_PEER_TRAFFIC_RESPONSE,
TDLS_DISCOVERY_REQUEST,
TDLS_SETUP_REQUEST = 0,
TDLS_SETUP_RESPONSE = 1,
TDLS_SETUP_CONFIRM = 2,
TDLS_TEARDOWN = 3,
TDLS_PEER_TRAFFIC_INDICATION = 4,
TDLS_CHANNEL_SWITCH_REQUEST = 5,
TDLS_CHANNEL_SWITCH_RESPONSE = 6,
TDLS_PEER_PSM_REQUEST = 7,
TDLS_PEER_PSM_RESPONSE = 8,
TDLS_PEER_TRAFFIC_RESPONSE = 9,
TDLS_DISCOVERY_REQUEST = 10,
TDLS_DISCOVERY_RESPONSE = 14,
};
/**

查看文件

@@ -133,6 +133,7 @@ struct wlan_objmgr_peer_mlme {
uint32_t max_rate;
uint16_t seq_num;
enum wlan_peer_state state;
bool is_authenticated;
};
/**
@@ -732,6 +733,25 @@ static inline void wlan_peer_mlme_set_state(
peer->peer_mlme.state = state;
}
/**
* wlan_peer_mlme_set_auth_state() - peer mlme auth state
* @peer: PEER object
* @is_authenticated: true or false
*
* API to update the current peer auth state
*
* Caller need to acquire lock with wlan_peer_obj_lock()
*
* Return: void
*/
static inline void wlan_peer_mlme_set_auth_state(
struct wlan_objmgr_peer *peer,
bool is_authenticated)
{
/* This API is invoked with lock acquired, do not add log prints */
peer->peer_mlme.is_authenticated = is_authenticated;
}
/**
* wlan_peer_mlme_get_state() - peer mlme state
* @peer: PEER object
@@ -749,6 +769,23 @@ static inline enum wlan_peer_state wlan_peer_mlme_get_state(
return peer->peer_mlme.state;
}
/**
* wlan_peer_mlme_get_auth_state() - peer mlme auth state
* @peer: PEER object
*
* API to get peer auth state
*
* Caller need to acquire lock with wlan_peer_obj_lock()
*
* Return: auth state true/false
*/
static inline bool wlan_peer_mlme_get_auth_state(
struct wlan_objmgr_peer *peer)
{
/* This API is invoked with lock acquired, do not add log prints */
return peer->peer_mlme.is_authenticated;
}
/**
* wlan_peer_mlme_get_next_seq_num() - get peer mlme next sequence number
* @peer: PEER object

查看文件

@@ -569,6 +569,244 @@ tdls_add_peer_serialize_callback(struct wlan_serialization_command *cmd,
return status;
}
void tdls_reset_nss(struct tdls_soc_priv_obj *tdls_soc,
uint8_t action_code)
{
if (!tdls_soc)
return;
if (TDLS_TEARDOWN != action_code ||
tdls_soc->tdls_nss_switch_in_progress)
return;
if (tdls_soc->tdls_teardown_peers_cnt != 0)
tdls_soc->tdls_teardown_peers_cnt--;
if (tdls_soc->tdls_teardown_peers_cnt == 0) {
if (tdls_soc->tdls_nss_transition_mode ==
TDLS_NSS_TRANSITION_S_1x1_to_2x2) {
/* TDLS NSS switch is fully completed, so
* reset the flags.
*/
tdls_notice("TDLS NSS switch is fully completed");
tdls_soc->tdls_nss_switch_in_progress = false;
tdls_soc->tdls_nss_teardown_complete = false;
} else {
/* TDLS NSS switch is not yet completed, but
* tdls teardown is completed for all the
* peers.
*/
tdls_notice("teardown done & NSS switch in progress");
tdls_soc->tdls_nss_teardown_complete = true;
}
}
}
/**
* tdls_set_cap() - set TDLS capability type
* @tdls_vdev: tdls vdev object
* @mac: peer mac address
* @cap: TDLS capability type
*
* Return: 0 if successful or negative errno otherwise
*/
int tdls_set_cap(struct tdls_vdev_priv_obj *tdls_vdev, const uint8_t *mac,
enum tdls_peer_capab cap)
{
struct tdls_peer *curr_peer;
curr_peer = tdls_get_peer(tdls_vdev, mac);
if (curr_peer == NULL) {
tdls_err("curr_peer is NULL");
return -EINVAL;
}
curr_peer->tdls_support = cap;
return 0;
}
static int tdls_validate_setup_frames(struct tdls_soc_priv_obj *tdls_soc,
struct tdls_validate_action_req *tdls_validate)
{
/* supplicant still sends tdls_mgmt(SETUP_REQ)
* even after we return error code at
* 'add_station()'. Hence we have this check
* again in addition to add_station(). Anyway,
* there is no harm to double-check.
*/
if (TDLS_SETUP_REQUEST == tdls_validate->action_code) {
tdls_err(QDF_MAC_ADDRESS_STR " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac),
tdls_validate->action_code,
tdls_soc->connected_peer_count,
tdls_soc->max_num_tdls_sta);
return -EINVAL;
}
/* maximum reached. tweak to send
* error code to peer and return error
* code to supplicant
*/
tdls_validate->status_code = QDF_STATUS_E_RESOURCES;
tdls_err(QDF_MAC_ADDRESS_STR " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac),
tdls_validate->action_code,
tdls_soc->connected_peer_count,
tdls_soc->max_num_tdls_sta);
tdls_validate->max_sta_failed = -EPERM;
return 0;
}
int tdls_validate_mgmt_request(struct tdls_validate_action_req *tdls_validate)
{
struct tdls_vdev_priv_obj *tdls_vdev;
struct tdls_soc_priv_obj *tdls_soc;
struct tdls_peer *curr_peer;
struct tdls_peer *temp_peer;
QDF_STATUS status;
if (!tdls_validate || !tdls_validate->vdev)
return -EINVAL;
if (QDF_STATUS_SUCCESS != tdls_get_vdev_objects(tdls_validate->vdev,
&tdls_vdev,
&tdls_soc))
return -ENOTSUPP;
/*
* STA or P2P client should be connected and authenticated before
* sending any TDLS frames
*/
if (!tdls_is_vdev_connected(tdls_validate->vdev) ||
!tdls_is_vdev_authenticated(tdls_validate->vdev)) {
tdls_err("STA is not connected or not authenticated.");
return -EAGAIN;
}
/* other than teardown frame, mgmt frames are not sent if disabled */
if (TDLS_TEARDOWN != tdls_validate->action_code) {
if (!tdls_check_is_tdls_allowed(tdls_validate->vdev)) {
tdls_err("TDLS not allowed, reject MGMT, action = %d",
tdls_validate->action_code);
return -EPERM;
}
/* if tdls_mode is disabled, then decline the peer's request */
if (TDLS_SUPPORT_DISABLED == tdls_soc->tdls_current_mode ||
TDLS_SUPPORT_SUSPENDED == tdls_soc->tdls_current_mode) {
tdls_notice(QDF_MAC_ADDRESS_STR
" TDLS mode is disabled. action %d declined.",
QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac),
tdls_validate->action_code);
return -ENOTSUPP;
}
if (tdls_soc->tdls_nss_switch_in_progress) {
tdls_err("nss switch in progress, action %d declined "
QDF_MAC_ADDRESS_STR,
tdls_validate->action_code,
QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac));
return -EAGAIN;
}
}
if (TDLS_IS_SETUP_ACTION(tdls_validate->action_code)) {
if (NULL != tdls_is_progress(tdls_vdev,
tdls_validate->peer_mac, true)) {
tdls_err("setup is ongoing. action %d declined for "
QDF_MAC_ADDRESS_STR,
tdls_validate->action_code,
QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac));
return -EPERM;
}
}
/*
* Discard TDLS Discovery request and setup confirm if violates
* ACM rules
*/
if ((TDLS_DISCOVERY_REQUEST == tdls_validate->action_code ||
TDLS_SETUP_CONFIRM == tdls_validate->action_code)) {
/* call hdd_wmm_is_acm_allowed() */
if (!tdls_soc->tdls_wmm_cb(&tdls_vdev->vdev)) {
tdls_err("admission ctrl set to VI, action %d declined",
tdls_validate->action_code);
return -EPERM;
}
}
if (TDLS_SETUP_REQUEST == tdls_validate->action_code ||
TDLS_SETUP_RESPONSE == tdls_validate->action_code) {
if (tdls_soc->max_num_tdls_sta <=
tdls_soc->connected_peer_count) {
status = tdls_validate_setup_frames(tdls_soc,
tdls_validate);
if (QDF_STATUS_SUCCESS != status)
return status;
/* fall through to send setup resp
* with failure status code
*/
} else {
curr_peer =
tdls_find_peer(tdls_vdev,
tdls_validate->peer_mac);
if (curr_peer) {
if (TDLS_IS_LINK_CONNECTED(curr_peer)) {
tdls_err(QDF_MAC_ADDRESS_STR " already connected action %d declined.",
QDF_MAC_ADDR_ARRAY(
tdls_validate->peer_mac),
tdls_validate->action_code);
return -EPERM;
}
}
}
}
tdls_notice("tdls_mgmt" QDF_MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac),
tdls_validate->action_code, tdls_validate->dialog_token,
tdls_validate->status_code, tdls_validate->len);
/*Except teardown responder will not be used so just make 0 */
tdls_validate->responder = 0;
if (TDLS_TEARDOWN == tdls_validate->action_code) {
temp_peer = tdls_find_peer(tdls_vdev, tdls_validate->peer_mac);
if (!temp_peer) {
tdls_err(QDF_MAC_ADDRESS_STR " peer doesn't exist",
QDF_MAC_ADDR_ARRAY(
tdls_validate->peer_mac));
return -EPERM;
}
if (TDLS_IS_LINK_CONNECTED(temp_peer))
tdls_validate->responder = temp_peer->is_responder;
else {
tdls_err(QDF_MAC_ADDRESS_STR " peer doesn't exist or not connected %d dialog_token %d status %d, tdls_validate->len = %zu",
QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac),
temp_peer->link_status,
tdls_validate->dialog_token,
tdls_validate->status_code,
tdls_validate->len);
return -EPERM;
}
}
/* For explicit trigger of DIS_REQ come out of BMPS for
* successfully receiving DIS_RSP from peer.
*/
if ((TDLS_SETUP_RESPONSE == tdls_validate->action_code) ||
(TDLS_SETUP_CONFIRM == tdls_validate->action_code) ||
(TDLS_DISCOVERY_RESPONSE == tdls_validate->action_code) ||
(TDLS_DISCOVERY_REQUEST == tdls_validate->action_code)) {
/* Fw will take care if PS offload is enabled. */
if (TDLS_DISCOVERY_REQUEST != tdls_validate->action_code)
tdls_set_cap(tdls_vdev, tdls_validate->peer_mac,
TDLS_CAP_SUPPORTED);
}
return 0;
}
QDF_STATUS tdls_process_add_peer(struct tdls_add_peer_request *req)
{
struct wlan_serialization_command cmd = {0,};
@@ -1000,6 +1238,105 @@ error:
return status;
}
/**
* tdls_process_send_mgmt_rsp() - handle response for send mgmt
* @rsp: TDLS send mgmt response
*
* Return: QDF_STATUS_SUCCESS for success; other values if failed
*/
QDF_STATUS tdls_process_send_mgmt_rsp(struct tdls_send_mgmt_rsp *rsp)
{
struct wlan_objmgr_vdev *vdev;
struct wlan_objmgr_psoc *psoc;
struct tdls_vdev_priv_obj *tdls_vdev;
struct tdls_soc_priv_obj *tdls_soc = NULL;
QDF_STATUS status = QDF_STATUS_SUCCESS;
struct tdls_osif_indication ind;
psoc = rsp->psoc;
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, rsp->session_id,
WLAN_TDLS_SB_ID);
if (!vdev) {
tdls_err("invalid vdev");
status = QDF_STATUS_E_INVAL;
qdf_mem_free(rsp);
return status;
}
tdls_soc = wlan_psoc_get_tdls_soc_obj(psoc);
tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev);
if (!tdls_soc || !tdls_vdev) {
tdls_err("soc object:%p, vdev object:%p", tdls_soc, tdls_vdev);
status = QDF_STATUS_E_FAILURE;
}
tdls_release_serialization_command(vdev, WLAN_SER_CMD_TDLS_SEND_MGMT);
if (legacy_result_success == rsp->status_code)
goto free_rsp;
tdls_err("send mgmt failed. status code(=%d)", rsp->status_code);
status = QDF_STATUS_E_FAILURE;
if (tdls_soc && tdls_soc->tdls_event_cb) {
ind.vdev = vdev;
ind.status = rsp->status_code;
tdls_soc->tdls_event_cb(tdls_soc->tdls_evt_cb_data,
TDLS_EVENT_MGMT_TX_ACK_CNF, &ind);
}
free_rsp:
qdf_mem_free(rsp);
wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID);
return status;
}
/**
* tdls_send_mgmt_tx_completion() - process tx completion
* @tx_complete: TDLS mgmt completion info
*
* Return: QDF_STATUS_SUCCESS for success; other values if failed
*/
QDF_STATUS tdls_send_mgmt_tx_completion(
struct tdls_mgmt_tx_completion_ind *tx_complete)
{
struct wlan_objmgr_vdev *vdev;
struct wlan_objmgr_psoc *psoc;
struct tdls_vdev_priv_obj *tdls_vdev;
struct tdls_soc_priv_obj *tdls_soc = NULL;
QDF_STATUS status = QDF_STATUS_SUCCESS;
struct tdls_osif_indication ind;
psoc = tx_complete->psoc;
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
tx_complete->session_id,
WLAN_TDLS_SB_ID);
if (!vdev) {
tdls_err("invalid vdev");
status = QDF_STATUS_E_INVAL;
goto free_tx_complete;
}
tdls_soc = wlan_psoc_get_tdls_soc_obj(psoc);
tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev);
if (!tdls_soc || !tdls_vdev) {
tdls_err("soc object:%p, vdev object:%p", tdls_soc, tdls_vdev);
status = QDF_STATUS_E_FAILURE;
}
if (tdls_soc && tdls_soc->tdls_event_cb) {
ind.vdev = vdev;
ind.status = tx_complete->tx_complete_status;
tdls_soc->tdls_event_cb(tdls_soc->tdls_evt_cb_data,
TDLS_EVENT_MGMT_TX_ACK_CNF, &ind);
}
wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID);
free_tx_complete:
qdf_mem_free(tx_complete);
return status;
}
/**
* tdls_add_peer_rsp() - handle response for add TDLS peer
* @rsp: TDLS add peer response
@@ -1139,10 +1476,12 @@ QDF_STATUS tdls_process_del_peer_rsp(struct tdls_del_sta_rsp *rsp)
tdls_debug(QDF_MAC_ADDRESS_STR " status is %d",
QDF_MAC_ADDR_ARRAY(macaddr),
curr_peer->link_status);
wlan_vdev_obj_lock(vdev);
id = wlan_vdev_get_id(vdev);
wlan_vdev_obj_unlock(vdev);
if (TDLS_IS_CONNECTED(curr_peer)) {
if (TDLS_IS_LINK_CONNECTED(curr_peer)) {
soc_obj->tdls_dereg_tl_peer(
soc_obj->tdls_tl_peer_data,
id, curr_peer->sta_id);
@@ -1464,6 +1803,10 @@ static QDF_STATUS tdls_config_force_peer(
tdls_set_callback(peer, req->callback);
tdls_set_ct_mode(soc_obj->soc);
if (soc_obj->enable_tdls_connection_tracker)
tdls_implicit_enable(vdev_obj);
return status;
error:
qdf_mem_free(peer_update_param);
@@ -1605,8 +1948,10 @@ QDF_STATUS tdls_process_remove_force_peer(struct tdls_oper_request *req)
qdf_mem_free(peer_update_param);
goto error;
}
tdls_set_ct_mode(soc_obj->soc);
if (!soc_obj->enable_tdls_connection_tracker)
tdls_implicit_disable(vdev_obj);
/*TODO set tdls connection tracker state*/
error:
wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
qdf_mem_free(req);

查看文件

@@ -25,6 +25,11 @@
#ifndef _WLAN_TDLS_CMDS_PROCESS_H_
#define _WLAN_TDLS_CMDS_PROCESS_H_
#define TDLS_IS_SETUP_ACTION(action) \
((TDLS_SETUP_REQUEST <= action) && \
(TDLS_SETUP_CONFIRM >= action))
/**
* enum tdls_add_oper - add peer type
* @TDLS_OPER_NONE: none
@@ -37,6 +42,53 @@ enum tdls_add_oper {
TDLS_OPER_UPDATE
};
/**
* enum legacy_result_code - defined to comply with tSirResultCodes, need refine
* when mlme converged.
* @legacy_result_success: success
* @legacy_result_max: max result value
*/
enum legacy_result_code {
legacy_result_success,
legacy_result_max = 0x7FFFFFFF
};
/**
* struct tdls_send_mgmt_rsp - TDLS Response struct PE --> TDLS module
* same as struct tSirSmeRsp
* @message_type: message type eWNI_SME_TDLS_SEND_MGMT_RSP
* @length: message length
* @session_id: session id
* @transaction_id: transaction id
* @status_code: status code as tSirResultCodes
* @psoc: soc object
*/
struct tdls_send_mgmt_rsp {
uint16_t message_type;
uint16_t length;
uint8_t session_id;
uint16_t transaction_id;
enum legacy_result_code status_code;
struct wlan_objmgr_psoc *psoc;
};
/**
* struct tdls_mgmt_tx_completion_ind - TDLS TX completion PE --> TDLS module
* same as struct sSirMgmtTxCompletionInd
* @message_type: message type eWNI_SME_MGMT_FRM_TX_COMPLETION_IND
* @length: message length
* @session_id: session id
* @tx_complete_status: tx complete status
* @psoc: soc object
*/
struct tdls_mgmt_tx_completion_ind {
uint16_t message_type;
uint16_t length;
uint8_t session_id; /* Session ID */
uint32_t tx_complete_status;
struct wlan_objmgr_psoc *psoc;
};
/**
* struct tdls_add_sta_req - TDLS request struct TDLS module --> PE
* same as struct tSirTdlsAddStaReq;
@@ -213,6 +265,52 @@ QDF_STATUS tdls_pe_del_peer(struct tdls_del_peer_request *req);
*/
QDF_STATUS tdls_process_add_peer_rsp(struct tdls_add_sta_rsp *rsp);
/**
* tdls_reset_nss() - reset tdls nss parameters
* @tdls_soc: TDLS soc object
* @action_code: action code
*
* Return: None
*/
void tdls_reset_nss(struct tdls_soc_priv_obj *tdls_soc,
uint8_t action_code);
/**
* tdls_set_cap() - set TDLS capability type
* @tdls_vdev: tdls vdev object
* @mac: peer mac address
* @cap: TDLS capability type
*
* Return: 0 if successful or negative errno otherwise
*/
int tdls_set_cap(struct tdls_vdev_priv_obj *tdls_vdev, const uint8_t *mac,
enum tdls_peer_capab cap);
/**
* tdls_validate_mgmt_request() -validate mgmt request
* @tdls_validate: action frame request
*
* Return: 0 for success or -EINVAL otherwise
*/
int tdls_validate_mgmt_request(struct tdls_validate_action_req *tdls_validate);
/**
* tdls_process_send_mgmt_rsp() - handle response for send mgmt
* @rsp: TDLS send mgmt response
*
* Return: QDF_STATUS_SUCCESS for success; other values if failed
*/
QDF_STATUS tdls_process_send_mgmt_rsp(struct tdls_send_mgmt_rsp *rsp);
/**
* tdls_send_mgmt_tx_completion() - process tx completion
* @tx_complete: TDLS mgmt completion info
*
* Return: QDF_STATUS_SUCCESS for success; other values if failed
*/
QDF_STATUS tdls_send_mgmt_tx_completion(
struct tdls_mgmt_tx_completion_ind *tx_complete);
/**
* tdls_process_add_peer_rsp() - handle response for delete TDLS peer
* @rsp: TDLS delete peer response

查看文件

@@ -52,6 +52,27 @@ bool tdls_is_vdev_connected(struct wlan_objmgr_vdev *vdev)
return true;
}
bool tdls_is_vdev_authenticated(struct wlan_objmgr_vdev *vdev)
{
struct wlan_objmgr_peer *peer;
bool is_authenticated = false;
wlan_vdev_obj_lock(vdev);
peer = wlan_vdev_get_bsspeer(vdev);
wlan_vdev_obj_unlock(vdev);
if (!peer) {
tdls_err("peer is null");
return false;
}
wlan_peer_obj_lock(peer);
is_authenticated = wlan_peer_mlme_get_auth_state(peer);
wlan_peer_obj_unlock(peer);
return is_authenticated;
}
/**
* tdls_peer_reset_discovery_processed() - reset discovery status
* @tdls_vdev: TDLS vdev object

查看文件

@@ -155,4 +155,21 @@ void tdls_discovery_timeout_peer_cb(void *user_data);
* Return: Void
*/
void tdls_implicit_disable(struct tdls_vdev_priv_obj *tdls_vdev);
/**
* tdls_is_vdev_connected() -check the vdev connection
* @vdev: vdev oobject
*
* Return: true or false
*/
bool tdls_is_vdev_connected(struct wlan_objmgr_vdev *vdev);
/**
* tdls_is_vdev_authenticated() -check the vdev authentication state
* @vdev: vdev oobject
*
* Return: true or false
*/
bool tdls_is_vdev_authenticated(struct wlan_objmgr_vdev *vdev);
#endif

查看文件

@@ -30,6 +30,8 @@
#include "wlan_tdls_tgt_api.h"
#include "wlan_policy_mgr_public_struct.h"
#include "wlan_policy_mgr_api.h"
#include "wlan_scan_ucfg_api.h"
/* Global tdls soc pvt object
* this is useful for some functions which does not receive either vdev or psoc

查看文件

@@ -34,6 +34,7 @@
#include <wlan_tdls_public_structs.h>
#include <scheduler_api.h>
#include "wlan_serialization_api.h"
#include "wlan_tdls_mgmt.h"
/* Bit mask flag for tdls_option to FW */
#define ENA_TDLS_OFFCHAN (1 << 0) /* TDLS Off Channel support */
@@ -74,7 +75,7 @@
#define tdls_alert(format, args...) \
tdls_logfl(QDF_TRACE_LEVEL_FATAL, format, ## args)
#define TDLS_IS_CONNECTED(peer) \
#define TDLS_IS_LINK_CONNECTED(peer) \
((TDLS_LINK_CONNECTED == (peer)->link_status) || \
(TDLS_LINK_TEARING == (peer)->link_status))
@@ -203,6 +204,10 @@ struct tdls_soc_priv_obj {
enum tdls_nss_transition_state tdls_nss_transition_mode;
int32_t tdls_teardown_peers_cnt;
struct tdls_set_state_info set_state_info;
tdls_rx_callback tdls_rx_cb;
void *tdls_rx_cb_data;
tdls_wmm_check tdls_wmm_cb;
void *tdls_wmm_cb_data;
tdls_tx_ack_cnf_callback tdls_tx_cnf_cb;
void *tx_ack_cnf_cb_data;
tdls_evt_callback tdls_event_cb;

查看文件

@@ -113,7 +113,6 @@ static QDF_STATUS tdls_process_rx_mgmt(
tdls_set_rssi(tdls_vdev, mac, rx_mgmt->rx_rssi);
}
if (rx_mgmt->buf[TDLS_PUBLIC_ACTION_FRAME_OFFSET] ==
TDLS_ACTION_FRAME) {
action_frame_type =
@@ -127,7 +126,7 @@ static QDF_STATUS tdls_process_rx_mgmt(
}
}
/* tdls_soc_obj->tdls_rx_cb ==> wlan_tdls_rx_callback() */
/* tdls_soc_obj->tdls_rx_cb ==> wlan_cfg80211_tdls_rx_callback() */
if (tdls_soc_obj && tdls_soc_obj->tdls_rx_cb)
tdls_soc_obj->tdls_rx_cb(tdls_soc_obj->tdls_rx_cb_data,
rx_mgmt);
@@ -157,7 +156,6 @@ QDF_STATUS tdls_process_rx_frame(struct scheduler_msg *msg)
if (vdev) {
tdls_debug("tdls rx mgmt frame received");
tdls_vdev = wlan_objmgr_vdev_get_comp_private_obj(vdev,
WLAN_UMAC_COMP_TDLS);
if (tdls_vdev)
@@ -175,6 +173,7 @@ QDF_STATUS tdls_mgmt_rx_ops(struct wlan_objmgr_psoc *psoc,
bool isregister)
{
struct mgmt_txrx_mgmt_frame_cb_info frm_cb_info[3];
QDF_STATUS status;
int num_of_entries;

查看文件

@@ -28,6 +28,24 @@
/* default tdls serialize timeout is set to 10 secs */
#define TDLS_DEFAULT_SERIALIZE_CMD_TIMEOUT 10000
#define TDLS_PUBLIC_ACTION_FRAME_OFFSET 24
#define TDLS_PUBLIC_ACTION_FRAME 4
#define TDLS_PUBLIC_ACTION_DISC_RESP 14
#define TDLS_ACTION_FRAME 12
#define TDLS_80211_PEER_ADDR_OFFSET (TDLS_PUBLIC_ACTION_FRAME + \
QDF_MAC_ADDR_SIZE)
#define TDLS_ACTION_FRAME_TYPE_MAX 11
/**
* struct tdls_rx_mgmt_event - tdls rx mgmt frame event
* @tdls_soc_obj: tdls soc private object
* @rx_mgmt: tdls rx mgmt frame structure
*/
struct tdls_rx_mgmt_event {
struct tdls_soc_priv_obj *tdls_soc_obj;
struct tdls_rx_mgmt_frame *rx_mgmt;
};
/*
* struct tdls_send_mgmt_request - tdls management request
* @message_type: type of pe message
@@ -70,5 +88,26 @@ struct tdls_send_mgmt_request {
*/
QDF_STATUS tdls_process_mgmt_req(
struct tdls_action_frame_request *tdls_mgmt_req);
/**
* tdls_mgmt_rx_ops() - register or unregister rx callback
* @psoc: psoc object
* @isregister: register if true, unregister if false
*
* This function registers or unregisters rx callback to mgmt txrx
* component.
*
* Return: QDF_STATUS
*/
QDF_STATUS tdls_mgmt_rx_ops(struct wlan_objmgr_psoc *psoc,
bool isregister);
/**
* tdls_process_rx_frame() - process tdls rx frames
* @msg: scheduler msg
*
* Return: QDF_STATUS
*/
QDF_STATUS tdls_process_rx_frame(struct scheduler_msg *msg);
#endif

查看文件

@@ -29,6 +29,8 @@
#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
#define WLAN_TDLS_STA_P_UAPSD_OFFCHAN_MAX_NUM 1
@@ -59,7 +61,7 @@
#define WAIT_TIME_TDLS_LINK_ESTABLISH_REQ 1500
/** Maximum time(ms) to wait for tdls mgmt to complete **/
#define WAIT_TIME_TDLS_MGMT 11000
#define WAIT_TIME_FOR_TDLS_MGMT 11000
#define TDLS_TEARDOWN_PEER_UNREACHABLE 25
#define TDLS_TEARDOWN_PEER_UNSPEC_REASON 26
@@ -252,7 +254,7 @@ enum tdls_event_msg_type {
TDLS_SHOULD_DISCOVER = 0,
TDLS_SHOULD_TEARDOWN,
TDLS_PEER_DISCONNECTED,
TDLS_CONNECTION_TRACKER_NOTIFY,
TDLS_CONNECTION_TRACKER_NOTIFY
};
/**

查看文件

@@ -67,6 +67,22 @@ QDF_STATUS tgt_tdls_set_offchan_mode(struct wlan_objmgr_psoc *psoc,
QDF_STATUS tgt_tdls_set_uapsd(struct wlan_objmgr_psoc *psoc,
struct sta_uapsd_trig_params *params);
/**
* tgt_tdls_send_mgmt_rsp() - process tdls mgmt response
* @pmsg: sheduler msg
*
* Return: QDF_STATUS
*/
QDF_STATUS tgt_tdls_send_mgmt_rsp(struct scheduler_msg *pmsg);
/**
* tgt_tdls_send_mgmt_tx_completion() -process tx completion message
* @pmsg: sheduler msg
*
* Return: QDF_STATUS
*/
QDF_STATUS tgt_tdls_send_mgmt_tx_completion(struct scheduler_msg *pmsg);
/**
* tgt_tdls_del_peer_rsp() - handle TDLS del peer response
* @pmsg: sheduler msg
@@ -111,4 +127,23 @@ QDF_STATUS tgt_tdls_unregister_ev_handler(struct wlan_objmgr_psoc *psoc);
QDF_STATUS
tgt_tdls_event_handler(struct wlan_objmgr_psoc *psoc,
struct tdls_event_info *info);
/**
* tgt_tdls_mgmt_frame_rx_cb() - callback for rx mgmt frame
* @psoc: soc context
* @peer: peer context
* @buf: rx buffer
* @mgmt_rx_params: mgmt rx parameters
* @frm_type: frame type
*
* This function gets called from mgmt tx/rx component when rx mgmt
* received.
*
* Return: QDF_STATUS_SUCCESS
*/
QDF_STATUS tgt_tdls_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_peer *peer, qdf_nbuf_t buf,
struct mgmt_rx_event_params *mgmt_rx_params,
enum mgmt_frame_type frm_type);
#endif

查看文件

@@ -87,6 +87,36 @@ QDF_STATUS tgt_tdls_set_uapsd(struct wlan_objmgr_psoc *psoc,
return QDF_STATUS_SUCCESS;
}
QDF_STATUS tgt_tdls_send_mgmt_tx_completion(struct scheduler_msg *pmsg)
{
QDF_STATUS status = QDF_STATUS_SUCCESS;
if (!pmsg || !pmsg->bodyptr) {
tdls_err("msg: 0x%p", pmsg);
QDF_ASSERT(0);
return QDF_STATUS_E_NULL_VALUE;
}
status = tdls_send_mgmt_tx_completion(pmsg->bodyptr);
return status;
}
QDF_STATUS tgt_tdls_send_mgmt_rsp(struct scheduler_msg *pmsg)
{
QDF_STATUS status = QDF_STATUS_SUCCESS;
if (!pmsg || !pmsg->bodyptr) {
tdls_err("msg: 0x%p", pmsg);
QDF_ASSERT(0);
return QDF_STATUS_E_NULL_VALUE;
}
status = tdls_process_send_mgmt_rsp(pmsg->bodyptr);
return status;
}
QDF_STATUS tgt_tdls_add_peer_rsp(struct scheduler_msg *pmsg)
{
QDF_STATUS status = QDF_STATUS_SUCCESS;
@@ -183,3 +213,124 @@ tgt_tdls_event_handler(struct wlan_objmgr_psoc *psoc,
return status;
}
static
QDF_STATUS tgt_tdls_mgmt_frame_process_rx_cb(
struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_peer *peer,
qdf_nbuf_t buf,
struct mgmt_rx_event_params *mgmt_rx_params,
enum mgmt_frame_type frm_type)
{
struct tdls_rx_mgmt_frame *rx_mgmt;
struct tdls_rx_mgmt_event *rx_mgmt_event;
struct tdls_soc_priv_obj *tdls_soc_obj;
struct scheduler_msg msg;
struct wlan_objmgr_vdev *vdev;
uint32_t vdev_id;
uint8_t *pdata;
QDF_STATUS status;
tdls_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
WLAN_UMAC_COMP_TDLS);
if (!tdls_soc_obj) {
tdls_err("tdls ctx is NULL, drop this frame");
return QDF_STATUS_E_FAILURE;
}
if (!peer) {
vdev = tdls_get_vdev(psoc, WLAN_TDLS_SB_ID);
if (!vdev) {
tdls_err("current tdls vdev is null, can't get vdev id");
return QDF_STATUS_E_FAILURE;
}
wlan_vdev_obj_lock(vdev);
vdev_id = wlan_vdev_get_id(vdev);
wlan_vdev_obj_unlock(vdev);
wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID);
} else {
wlan_peer_obj_lock(peer);
vdev = wlan_peer_get_vdev(peer);
wlan_peer_obj_unlock(peer);
if (!vdev) {
tdls_err("vdev is NULL in peer, drop this frame");
return QDF_STATUS_E_FAILURE;
}
wlan_vdev_obj_lock(vdev);
vdev_id = wlan_vdev_get_id(vdev);
wlan_vdev_obj_unlock(vdev);
}
rx_mgmt_event = qdf_mem_malloc(sizeof(*rx_mgmt_event));
if (!rx_mgmt_event) {
tdls_err("Failed to allocate rx mgmt event");
return QDF_STATUS_E_NOMEM;
}
rx_mgmt = qdf_mem_malloc(sizeof(*rx_mgmt) +
mgmt_rx_params->buf_len);
if (!rx_mgmt) {
tdls_err("Failed to allocate rx mgmt frame");
qdf_mem_free(rx_mgmt_event);
return QDF_STATUS_E_NOMEM;
}
pdata = (uint8_t *)qdf_nbuf_data(buf);
rx_mgmt->frame_len = mgmt_rx_params->buf_len;
rx_mgmt->rx_chan = mgmt_rx_params->channel;
rx_mgmt->vdev_id = vdev_id;
rx_mgmt->frm_type = frm_type;
rx_mgmt->rx_rssi = mgmt_rx_params->rssi;
rx_mgmt_event->rx_mgmt = rx_mgmt;
rx_mgmt_event->tdls_soc_obj = tdls_soc_obj;
qdf_mem_copy(rx_mgmt->buf, pdata, mgmt_rx_params->buf_len);
msg.type = TDLS_EVENT_RX_MGMT;
msg.bodyptr = rx_mgmt_event;
msg.callback = tdls_process_rx_frame;
status = scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg);
qdf_nbuf_free(buf);
return status;
}
QDF_STATUS tgt_tdls_mgmt_frame_rx_cb(
struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_peer *peer,
qdf_nbuf_t buf,
struct mgmt_rx_event_params *mgmt_rx_params,
enum mgmt_frame_type frm_type)
{
QDF_STATUS status;
tdls_debug("psoc:%p, peer:%p, type:%d", psoc, peer, frm_type);
if (!buf) {
tdls_err("rx frame buff is null buf:%p", buf);
return QDF_STATUS_E_INVAL;
}
if (!mgmt_rx_params || !psoc) {
tdls_err("input is NULL mgmt_rx_params:%p psoc:%p, peer:%p",
mgmt_rx_params, psoc, peer);
status = QDF_STATUS_E_INVAL;
goto release_nbuf;
}
status = wlan_objmgr_peer_try_get_ref(peer, WLAN_TDLS_SB_ID);
if (QDF_STATUS_SUCCESS != status)
goto release_nbuf;
status = tgt_tdls_mgmt_frame_process_rx_cb(psoc, peer, buf,
mgmt_rx_params, frm_type);
wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_SB_ID);
if (QDF_STATUS_SUCCESS != status)
release_nbuf:
qdf_nbuf_free(buf);
return status;
}

查看文件

@@ -194,6 +194,12 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc,
return QDF_STATUS_E_FAILURE;
}
soc_obj->tdls_rx_cb = req->tdls_rx_cb;
soc_obj->tdls_rx_cb_data = req->tdls_rx_cb_data;
soc_obj->tdls_wmm_cb = req->tdls_wmm_cb;
soc_obj->tdls_wmm_cb_data = req->tdls_wmm_cb_data;
soc_obj->tdls_event_cb = req->tdls_event_cb;
soc_obj->tdls_evt_cb_data = req->tdls_evt_cb_data;
@@ -256,9 +262,14 @@ QDF_STATUS ucfg_tdls_psoc_enable(struct wlan_objmgr_psoc *psoc)
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;
}
/* register callbacks with tx/rx mgmt */
status = tdls_mgmt_rx_ops(psoc, true);
if (status != QDF_STATUS_SUCCESS)
tdls_err("Failed to register mgmt rx callback, status:%d",
status);
return status;
}
@@ -647,4 +658,6 @@ void ucfg_tdls_update_tx_pkt_cnt(struct wlan_objmgr_vdev *vdev,
tdls_update_tx_pkt_cnt(vdev, mac_addr);
wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
}