qcacmn: Add TDLS management frames
Add TDLS management frames implementaion in TDLS umac component Change-Id: I46943f7df119894e0d54df2c6edb08ed4546a389 CRs-Fixed: 2034220
此提交包含在:
@@ -26,6 +26,7 @@
|
||||
#include "wlan_tdls_main.h"
|
||||
#include "wlan_tdls_peer.h"
|
||||
#include "wlan_tdls_ct.h"
|
||||
#include "wlan_tdls_mgmt.h"
|
||||
#include "wlan_tdls_cmds_process.h"
|
||||
#include "wlan_tdls_tgt_api.h"
|
||||
|
||||
|
@@ -250,4 +250,13 @@ QDF_STATUS tdls_process_should_teardown(struct wlan_objmgr_vdev *vdev,
|
||||
*/
|
||||
QDF_STATUS tdls_process_connection_tracker_notify(struct wlan_objmgr_vdev *vdev,
|
||||
struct tdls_event_info *evt);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
#endif
|
||||
|
@@ -26,6 +26,7 @@
|
||||
#include "wlan_tdls_cmds_process.h"
|
||||
#include "wlan_tdls_peer.h"
|
||||
#include "wlan_tdls_ct.h"
|
||||
#include "wlan_tdls_mgmt.h"
|
||||
|
||||
QDF_STATUS tdls_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc,
|
||||
void *arg_list)
|
||||
@@ -212,6 +213,7 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg)
|
||||
|
||||
switch (msg->type) {
|
||||
case TDLS_CMD_TX_ACTION:
|
||||
tdls_process_mgmt_req(msg->bodyptr);
|
||||
break;
|
||||
case TDLS_CMD_ADD_STA:
|
||||
tdls_process_add_peer(msg->bodyptr);
|
||||
|
@@ -21,3 +21,410 @@
|
||||
*
|
||||
* TDLS management frames implementation
|
||||
*/
|
||||
|
||||
#include "wlan_tdls_main.h"
|
||||
#include "wlan_tdls_tgt_api.h"
|
||||
#include <wlan_serialization_api.h>
|
||||
#include "wlan_mgmt_txrx_utils_api.h"
|
||||
#include "wlan_tdls_peer.h"
|
||||
#include "wlan_tdls_ct.h"
|
||||
#include "wlan_tdls_cmds_process.h"
|
||||
#include "wlan_tdls_mgmt.h"
|
||||
|
||||
static
|
||||
const char *const tdls_action_frames_type[] = { "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_set_rssi() - Set TDLS RSSI on peer given by mac
|
||||
* @tdls_vdev: tdls vdev object
|
||||
* @mac: MAC address of Peer
|
||||
* @rx_rssi: rssi value
|
||||
*
|
||||
* Set RSSI on TDSL peer
|
||||
*
|
||||
* Return: 0 for success or -EINVAL otherwise
|
||||
*/
|
||||
static int tdls_set_rssi(struct tdls_vdev_priv_obj *tdls_vdev,
|
||||
const uint8_t *mac,
|
||||
int8_t rx_rssi)
|
||||
{
|
||||
struct tdls_peer *curr_peer;
|
||||
|
||||
curr_peer = tdls_find_peer(tdls_vdev, mac);
|
||||
if (curr_peer == NULL) {
|
||||
tdls_err("curr_peer is NULL");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
curr_peer->rssi = rx_rssi;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* tdls_process_rx_mgmt() - process tdls rx mgmt frames
|
||||
* @rx_mgmt_event: tdls rx mgmt event
|
||||
* @tdls_vdev: tdls vdev object
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
static QDF_STATUS tdls_process_rx_mgmt(
|
||||
struct tdls_rx_mgmt_event *rx_mgmt_event,
|
||||
struct tdls_vdev_priv_obj *tdls_vdev)
|
||||
{
|
||||
struct tdls_rx_mgmt_frame *rx_mgmt;
|
||||
struct tdls_soc_priv_obj *tdls_soc_obj;
|
||||
uint8_t *mac;
|
||||
enum tdls_actioncode action_frame_type;
|
||||
|
||||
if (!rx_mgmt_event)
|
||||
return QDF_STATUS_E_INVAL;
|
||||
|
||||
tdls_soc_obj = rx_mgmt_event->tdls_soc_obj;
|
||||
rx_mgmt = rx_mgmt_event->rx_mgmt;
|
||||
|
||||
if (!tdls_soc_obj || !rx_mgmt) {
|
||||
tdls_err("invalid psoc object or rx mgmt");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
tdls_debug("soc:%p, frame_len:%d, rx_chan:%d, vdev_id:%d, frm_type:%d, rx_rssi:%d, buf:%p",
|
||||
tdls_soc_obj->soc, rx_mgmt->frame_len,
|
||||
rx_mgmt->rx_chan, rx_mgmt->vdev_id, rx_mgmt->frm_type,
|
||||
rx_mgmt->rx_rssi, rx_mgmt->buf);
|
||||
|
||||
if (rx_mgmt->buf[TDLS_PUBLIC_ACTION_FRAME_OFFSET + 1] ==
|
||||
TDLS_PUBLIC_ACTION_DISC_RESP) {
|
||||
mac = &rx_mgmt->buf[TDLS_80211_PEER_ADDR_OFFSET];
|
||||
tdls_notice("[TDLS] TDLS Discovery Response,"
|
||||
QDF_MAC_ADDRESS_STR " RSSI[%d] <--- OTA",
|
||||
QDF_MAC_ADDR_ARRAY(mac), rx_mgmt->rx_rssi);
|
||||
tdls_recv_discovery_resp(tdls_vdev, mac);
|
||||
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 =
|
||||
rx_mgmt->buf[TDLS_PUBLIC_ACTION_FRAME_OFFSET + 1];
|
||||
if (action_frame_type >= TDLS_ACTION_FRAME_TYPE_MAX) {
|
||||
tdls_debug("[TDLS] unknown[%d] <--- OTA",
|
||||
action_frame_type);
|
||||
} else {
|
||||
tdls_notice("[TDLS] %s <--- OTA",
|
||||
tdls_action_frames_type[action_frame_type]);
|
||||
}
|
||||
}
|
||||
|
||||
/* tdls_soc_obj->tdls_rx_cb ==> wlan_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);
|
||||
else
|
||||
tdls_debug("rx mgmt, but no valid up layer callback");
|
||||
|
||||
qdf_mem_free(rx_mgmt);
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
QDF_STATUS tdls_process_rx_frame(struct scheduler_msg *msg)
|
||||
{
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
struct tdls_rx_mgmt_event *tdls_rx;
|
||||
struct tdls_vdev_priv_obj *tdls_vdev;
|
||||
QDF_STATUS status = QDF_STATUS_E_FAILURE;
|
||||
|
||||
if (!(msg->bodyptr)) {
|
||||
tdls_err("invalid message body");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
tdls_rx = (struct tdls_rx_mgmt_event *) msg->bodyptr;
|
||||
|
||||
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(tdls_rx->tdls_soc_obj->soc,
|
||||
tdls_rx->rx_mgmt->vdev_id, WLAN_TDLS_NB_ID);
|
||||
|
||||
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)
|
||||
status = tdls_process_rx_mgmt(tdls_rx, tdls_vdev);
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
|
||||
}
|
||||
|
||||
qdf_mem_free(msg->bodyptr);
|
||||
msg->bodyptr = NULL;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
tdls_debug("psoc:%p, is register rx:%d", psoc, isregister);
|
||||
|
||||
frm_cb_info[0].frm_type = MGMT_PROBE_REQ;
|
||||
frm_cb_info[0].mgmt_rx_cb = tgt_tdls_mgmt_frame_rx_cb;
|
||||
frm_cb_info[1].frm_type = MGMT_ACTION_TDLS_DISCRESP;
|
||||
frm_cb_info[1].mgmt_rx_cb = tgt_tdls_mgmt_frame_rx_cb;
|
||||
frm_cb_info[2].frm_type = MGMT_ACTION_VENDOR_SPECIFIC;
|
||||
frm_cb_info[2].mgmt_rx_cb = tgt_tdls_mgmt_frame_rx_cb;
|
||||
num_of_entries = 3;
|
||||
|
||||
if (isregister)
|
||||
status = wlan_mgmt_txrx_register_rx_cb(psoc,
|
||||
WLAN_UMAC_COMP_TDLS, frm_cb_info,
|
||||
num_of_entries);
|
||||
else
|
||||
status = wlan_mgmt_txrx_deregister_rx_cb(psoc,
|
||||
WLAN_UMAC_COMP_TDLS, frm_cb_info,
|
||||
num_of_entries);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static QDF_STATUS
|
||||
tdls_internal_send_mgmt_tx_done(struct tdls_action_frame_request *req,
|
||||
QDF_STATUS status)
|
||||
{
|
||||
struct tdls_soc_priv_obj *tdls_soc_obj;
|
||||
struct tdls_osif_indication indication;
|
||||
|
||||
if (!req || !req->vdev)
|
||||
return QDF_STATUS_E_NULL_VALUE;
|
||||
|
||||
indication.status = status;
|
||||
indication.vdev = req->vdev;
|
||||
|
||||
tdls_soc_obj = wlan_vdev_get_tdls_soc_obj(req->vdev);
|
||||
if (tdls_soc_obj && tdls_soc_obj->tdls_event_cb)
|
||||
tdls_soc_obj->tdls_event_cb(tdls_soc_obj->tdls_evt_cb_data,
|
||||
TDLS_EVENT_MGMT_TX_ACK_CNF, &indication);
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static QDF_STATUS tdls_activate_send_mgmt_request(
|
||||
struct tdls_action_frame_request *action_req)
|
||||
{
|
||||
struct wlan_objmgr_peer *peer;
|
||||
struct tdls_soc_priv_obj *tdls_soc_obj;
|
||||
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
||||
|
||||
struct scheduler_msg msg;
|
||||
struct tdls_send_mgmt_request *tdls_mgmt_req;
|
||||
|
||||
if (!action_req || !action_req->vdev)
|
||||
return QDF_STATUS_E_NULL_VALUE;
|
||||
|
||||
if (QDF_STATUS_SUCCESS != wlan_objmgr_vdev_try_get_ref(action_req->vdev,
|
||||
WLAN_TDLS_SB_ID))
|
||||
return QDF_STATUS_E_NULL_VALUE;
|
||||
|
||||
|
||||
tdls_soc_obj = wlan_vdev_get_tdls_soc_obj(action_req->vdev);
|
||||
if (!tdls_soc_obj) {
|
||||
status = QDF_STATUS_E_NULL_VALUE;
|
||||
goto release_mgmt_ref;
|
||||
}
|
||||
|
||||
tdls_mgmt_req = qdf_mem_malloc(sizeof(struct tdls_send_mgmt_request) +
|
||||
action_req->tdls_mgmt.len);
|
||||
if (NULL == tdls_mgmt_req) {
|
||||
status = QDF_STATUS_E_NOMEM;
|
||||
tdls_err("mem alloc failed ");
|
||||
QDF_ASSERT(0);
|
||||
goto release_mgmt_ref;
|
||||
}
|
||||
|
||||
tdls_debug("session_id %d "
|
||||
"tdls_mgmt.dialog %d "
|
||||
"tdls_mgmt.frame_type %d "
|
||||
"tdls_mgmt.status_code %d "
|
||||
"tdls_mgmt.responder %d "
|
||||
"tdls_mgmt.peer_capability %d",
|
||||
action_req->session_id,
|
||||
action_req->tdls_mgmt.dialog,
|
||||
action_req->tdls_mgmt.frame_type,
|
||||
action_req->tdls_mgmt.status_code,
|
||||
action_req->tdls_mgmt.responder,
|
||||
action_req->tdls_mgmt.peer_capability);
|
||||
|
||||
tdls_mgmt_req->session_id = action_req->session_id;
|
||||
/* Using dialog as transactionId. This can be used to
|
||||
* match response with request
|
||||
*/
|
||||
tdls_mgmt_req->transaction_id = action_req->tdls_mgmt.dialog;
|
||||
tdls_mgmt_req->req_type = action_req->tdls_mgmt.frame_type;
|
||||
tdls_mgmt_req->dialog = action_req->tdls_mgmt.dialog;
|
||||
tdls_mgmt_req->status_code = action_req->tdls_mgmt.status_code;
|
||||
tdls_mgmt_req->responder = action_req->tdls_mgmt.responder;
|
||||
tdls_mgmt_req->peer_capability = action_req->tdls_mgmt.peer_capability;
|
||||
|
||||
peer = wlan_vdev_get_bsspeer(action_req->vdev);
|
||||
|
||||
if (QDF_STATUS_SUCCESS != wlan_objmgr_peer_try_get_ref(peer,
|
||||
WLAN_TDLS_SB_ID)) {
|
||||
qdf_mem_free(tdls_mgmt_req);
|
||||
goto release_mgmt_ref;
|
||||
}
|
||||
|
||||
qdf_mem_copy(tdls_mgmt_req->bssid.bytes,
|
||||
wlan_peer_get_macaddr(peer), QDF_MAC_ADDR_SIZE);
|
||||
|
||||
qdf_mem_copy(tdls_mgmt_req->peer_mac.bytes,
|
||||
action_req->tdls_mgmt.peer_mac.bytes, QDF_MAC_ADDR_SIZE);
|
||||
|
||||
if (action_req->tdls_mgmt.len && action_req->tdls_mgmt.buf) {
|
||||
qdf_mem_copy(tdls_mgmt_req->add_ie, action_req->tdls_mgmt.buf,
|
||||
action_req->tdls_mgmt.len);
|
||||
}
|
||||
|
||||
tdls_mgmt_req->length = sizeof(struct tdls_send_mgmt_request) +
|
||||
action_req->tdls_mgmt.len;
|
||||
|
||||
/* Send the request to PE. */
|
||||
qdf_mem_zero(&msg, sizeof(msg));
|
||||
|
||||
tdls_debug("sending TDLS Mgmt Frame req to PE ");
|
||||
tdls_mgmt_req->message_type = tdls_soc_obj->tdls_send_mgmt_req;
|
||||
|
||||
msg.type = tdls_soc_obj->tdls_send_mgmt_req;
|
||||
msg.bodyptr = tdls_mgmt_req;
|
||||
|
||||
status = scheduler_post_msg(QDF_MODULE_ID_PE, &msg);
|
||||
|
||||
wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_SB_ID);
|
||||
release_mgmt_ref:
|
||||
wlan_objmgr_vdev_release_ref(action_req->vdev, WLAN_TDLS_SB_ID);
|
||||
|
||||
/*update tdls nss infornation based on action code */
|
||||
tdls_reset_nss(tdls_soc_obj, action_req->chk_frame->action_code);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static QDF_STATUS
|
||||
tdls_send_mgmt_serialize_callback(struct wlan_serialization_command *cmd,
|
||||
enum wlan_serialization_cb_reason reason)
|
||||
{
|
||||
struct tdls_action_frame_request *req;
|
||||
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
||||
|
||||
if (!cmd || !cmd->umac_cmd) {
|
||||
tdls_err("invalid params cmd: %p, ", cmd);
|
||||
return QDF_STATUS_E_NULL_VALUE;
|
||||
}
|
||||
req = cmd->umac_cmd;
|
||||
|
||||
tdls_debug("reason: %d, vdev_id: %d",
|
||||
reason, req->vdev_id);
|
||||
|
||||
switch (reason) {
|
||||
case WLAN_SER_CB_ACTIVATE_CMD:
|
||||
/* command moved to active list */
|
||||
status = tdls_activate_send_mgmt_request(req);
|
||||
break;
|
||||
|
||||
case WLAN_SER_CB_CANCEL_CMD:
|
||||
case WLAN_SER_CB_ACTIVE_CMD_TIMEOUT:
|
||||
/* command removed from pending list.
|
||||
* notify status complete with failure
|
||||
*/
|
||||
status = tdls_internal_send_mgmt_tx_done(req,
|
||||
QDF_STATUS_E_FAILURE);
|
||||
qdf_mem_free(req);
|
||||
break;
|
||||
|
||||
case WLAN_SER_CB_RELEASE_MEM_CMD:
|
||||
/* command successfully completed.
|
||||
* release tdls_action_frame_request memory
|
||||
*/
|
||||
qdf_mem_free(req);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Do nothing but logging */
|
||||
QDF_ASSERT(0);
|
||||
status = QDF_STATUS_E_INVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
QDF_STATUS tdls_process_mgmt_req(
|
||||
struct tdls_action_frame_request *tdls_mgmt_req)
|
||||
{
|
||||
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
||||
struct wlan_serialization_command cmd = {0, };
|
||||
enum wlan_serialization_status ser_cmd_status;
|
||||
|
||||
/* If connected and in Infra. Only then allow this */
|
||||
status = tdls_validate_mgmt_request(tdls_mgmt_req->chk_frame);
|
||||
if (status != QDF_STATUS_SUCCESS) {
|
||||
status = tdls_internal_send_mgmt_tx_done(tdls_mgmt_req,
|
||||
status);
|
||||
qdf_mem_free(tdls_mgmt_req);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* update the responder, status code information
|
||||
* after the cmd validation
|
||||
*/
|
||||
tdls_mgmt_req->tdls_mgmt.responder =
|
||||
tdls_mgmt_req->chk_frame->responder;
|
||||
tdls_mgmt_req->tdls_mgmt.status_code =
|
||||
tdls_mgmt_req->chk_frame->status_code;
|
||||
|
||||
cmd.cmd_type = WLAN_SER_CMD_TDLS_SEND_MGMT;
|
||||
/* Cmd Id not applicable for non scan cmds */
|
||||
cmd.cmd_id = 0;
|
||||
cmd.cmd_cb = (wlan_serialization_cmd_callback)
|
||||
tdls_send_mgmt_serialize_callback;
|
||||
cmd.umac_cmd = tdls_mgmt_req;
|
||||
cmd.source = WLAN_UMAC_COMP_TDLS;
|
||||
cmd.is_high_priority = false;
|
||||
cmd.cmd_timeout_duration = TDLS_DEFAULT_SERIALIZE_CMD_TIMEOUT;
|
||||
|
||||
cmd.vdev = tdls_mgmt_req->vdev;
|
||||
|
||||
ser_cmd_status = wlan_serialization_request(&cmd);
|
||||
tdls_debug("wlan_serialization_request status:%d", ser_cmd_status);
|
||||
|
||||
switch (ser_cmd_status) {
|
||||
case WLAN_SER_CMD_PENDING:
|
||||
/* command moved to pending list.Do nothing */
|
||||
break;
|
||||
case WLAN_SER_CMD_ACTIVE:
|
||||
/* command moved to active list. Do nothing */
|
||||
break;
|
||||
case WLAN_SER_CMD_DENIED_LIST_FULL:
|
||||
case WLAN_SER_CMD_DENIED_RULES_FAILED:
|
||||
case WLAN_SER_CMD_DENIED_UNSPECIFIED:
|
||||
/* free the request */
|
||||
qdf_mem_free(tdls_mgmt_req);
|
||||
|
||||
default:
|
||||
QDF_ASSERT(0);
|
||||
status = QDF_STATUS_E_INVAL;
|
||||
break;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
@@ -21,3 +21,54 @@
|
||||
*
|
||||
* TDLS management frames include file
|
||||
*/
|
||||
|
||||
#ifndef _WLAN_TDLS_MGMT_H_
|
||||
#define _WLAN_TDLS_MGMT_H_
|
||||
|
||||
/* default tdls serialize timeout is set to 10 secs */
|
||||
#define TDLS_DEFAULT_SERIALIZE_CMD_TIMEOUT 10000
|
||||
|
||||
/*
|
||||
* struct tdls_send_mgmt_request - tdls management request
|
||||
* @message_type: type of pe message
|
||||
* @length: length of the frame.
|
||||
* @session_id: session id
|
||||
* @transaction_id: transaction ID for cmd
|
||||
* @req_type: type of action frame
|
||||
* @dialog: dialog token used in the frame.
|
||||
* @status_code: status to be incuded in the frame.
|
||||
* @responder: tdls request type
|
||||
* @peer_capability: peer capability information
|
||||
* @bssid: bssid
|
||||
* @peer_mac: mac address of the peer
|
||||
* @add_ie: additional ie's to be included
|
||||
*/
|
||||
struct tdls_send_mgmt_request {
|
||||
uint16_t message_type;
|
||||
uint16_t length;
|
||||
uint8_t session_id;
|
||||
uint16_t transaction_id;
|
||||
uint8_t req_type;
|
||||
uint8_t dialog;
|
||||
uint16_t status_code;
|
||||
uint8_t responder;
|
||||
uint32_t peer_capability;
|
||||
struct qdf_mac_addr bssid;
|
||||
struct qdf_mac_addr peer_mac;
|
||||
/* Variable length. Dont add any field after this. */
|
||||
uint8_t add_ie[1];
|
||||
};
|
||||
|
||||
/**
|
||||
* tdls_process_mgmt_req() - send a TDLS mgmt request to serialize module
|
||||
* @tdls_mgmt_req: tdls management request
|
||||
*
|
||||
* TDLS request API, called from cfg80211 to send a TDLS frame in
|
||||
* serialized manner to PE
|
||||
*
|
||||
*Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS tdls_process_mgmt_req(
|
||||
struct tdls_action_frame_request *tdls_mgmt_req);
|
||||
#endif
|
||||
|
||||
|
@@ -824,4 +824,44 @@ struct tdls_event_notify {
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
struct tdls_event_info event;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct tdls_event_notify - tdls event notify
|
||||
* @peer_mac: peer's mac address
|
||||
* @frame_type: Type of TDLS mgmt frame to be sent
|
||||
* @dialog: dialog token used in the frame.
|
||||
* @status_code: status to be incuded in the frame
|
||||
* @responder: Tdls request type
|
||||
* @peer_capability: peer cpabilities
|
||||
* @len: lenght of additional Ies
|
||||
* @buf: additional IEs to be included
|
||||
*/
|
||||
struct tdls_send_mgmt {
|
||||
struct qdf_mac_addr peer_mac;
|
||||
uint8_t frame_type;
|
||||
uint8_t dialog;
|
||||
uint16_t status_code;
|
||||
uint8_t responder;
|
||||
uint32_t peer_capability;
|
||||
uint8_t len;
|
||||
/* Variable length, do not add anything after this */
|
||||
uint8_t *buf;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct tdls_send_action_frame_request - tdls send mgmt request
|
||||
* @vdev: vdev object
|
||||
* @session_id: session id
|
||||
* @vdev_id: vdev id
|
||||
* @tdls_mgmt: tdls managment
|
||||
*/
|
||||
struct tdls_action_frame_request {
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
uint8_t session_id;
|
||||
uint8_t vdev_id;
|
||||
const uint8_t *cmd_buf;
|
||||
uint8_t len;
|
||||
struct tdls_send_mgmt tdls_mgmt;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -118,4 +118,16 @@ QDF_STATUS ucfg_tdls_update_peer(struct wlan_objmgr_vdev *vdev,
|
||||
*/
|
||||
QDF_STATUS ucfg_tdls_oper(struct wlan_objmgr_vdev *vdev,
|
||||
const uint8_t *macaddr, enum tdls_command_type cmd);
|
||||
|
||||
/**
|
||||
* ucfg_tdls_send_mgmt_frame() - send TDLS mgmt frame
|
||||
* @mgmt_req: pointer to TDLS action frame request struct
|
||||
*
|
||||
* This will TDLS action frames to peer
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS ucfg_tdls_send_mgmt_frame(
|
||||
struct tdls_action_frame_request *mgmt_req);
|
||||
|
||||
#endif
|
||||
|
@@ -436,3 +436,42 @@ error:
|
||||
qdf_mem_free(req);
|
||||
return status;
|
||||
}
|
||||
|
||||
QDF_STATUS ucfg_tdls_send_mgmt_frame(
|
||||
struct tdls_action_frame_request *req)
|
||||
{
|
||||
struct scheduler_msg msg = {0, };
|
||||
struct tdls_action_frame_request *mgmt_req;
|
||||
|
||||
if (!req || !req->vdev) {
|
||||
tdls_err("Invalid mgmt req params %p", req);
|
||||
return QDF_STATUS_E_NULL_VALUE;
|
||||
}
|
||||
|
||||
mgmt_req = qdf_mem_malloc(sizeof(*mgmt_req) +
|
||||
req->len);
|
||||
if (!mgmt_req) {
|
||||
tdls_err("mem allocate fail");
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
|
||||
qdf_mem_copy(mgmt_req, req, sizeof(*req));
|
||||
|
||||
/*populate the additional IE's */
|
||||
if ((0 != req->len) && (NULL != req->cmd_buf)) {
|
||||
qdf_mem_copy(mgmt_req->tdls_mgmt.buf, req->cmd_buf,
|
||||
req->len);
|
||||
mgmt_req->tdls_mgmt.len = req->len;
|
||||
} else {
|
||||
mgmt_req->tdls_mgmt.len = 0;
|
||||
}
|
||||
|
||||
tdls_notice("vdev id: %d, session id : %d", mgmt_req->vdev_id,
|
||||
mgmt_req->session_id);
|
||||
msg.bodyptr = mgmt_req;
|
||||
msg.callback = tdls_process_cmd;
|
||||
msg.type = TDLS_CMD_TX_ACTION;
|
||||
scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
新增問題並參考
封鎖使用者