mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-10 06:09:23 -04:00
qcacmn: TDLS component: core peer operations
TDLS peer operations: add, delete and update TDLS peer Change-Id: I7dba1a4b2b3b8597935db811da68ee5ba630bf4d CRs-Fixed: 2011330
This commit is contained in:
parent
a2e796c403
commit
d4b12dbff6
9 changed files with 2923 additions and 83 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -21,3 +21,177 @@
|
|||
*
|
||||
* TDLS north bound commands include file
|
||||
*/
|
||||
|
||||
#ifndef _WLAN_TDLS_CMDS_PROCESS_H_
|
||||
#define _WLAN_TDLS_CMDS_PROCESS_H_
|
||||
|
||||
/**
|
||||
* enum tdls_add_oper - add peer type
|
||||
* @TDLS_OPER_NONE: none
|
||||
* @TDLS_OPER_ADD: add new peer
|
||||
* @TDLS_OPER_UPDATE: used to update peer
|
||||
*/
|
||||
enum tdls_add_oper {
|
||||
TDLS_OPER_NONE,
|
||||
TDLS_OPER_ADD,
|
||||
TDLS_OPER_UPDATE
|
||||
};
|
||||
|
||||
/**
|
||||
* struct tdls_add_sta_req - TDLS request struct TDLS module --> PE
|
||||
* same as struct tSirTdlsAddStaReq;
|
||||
* @message_type: eWNI_SME_TDLS_ADD_STA_REQ
|
||||
* @length: message length
|
||||
* @session_id: session id
|
||||
* @transaction_id: transaction id for cmd
|
||||
* @bssid: bssid
|
||||
* @tdls_oper: add peer type
|
||||
* @peermac: MAC address for TDLS peer
|
||||
* @capability: mac capability as sSirMacCapabilityInfo
|
||||
* @extn_capability: extent capability
|
||||
* @supported_rates_length: rates length
|
||||
* @supported_rates: supported rates
|
||||
* @htcap_present: ht capability present
|
||||
* @ht_cap: ht capability
|
||||
* @vhtcap_present: vht capability present
|
||||
* @vht_cap: vht capability
|
||||
* @uapsd_queues: uapsd queue as sSirMacQosInfoStation
|
||||
* @max_sp: maximum service period
|
||||
*/
|
||||
struct tdls_add_sta_req {
|
||||
uint16_t message_type;
|
||||
uint16_t length;
|
||||
uint8_t session_id;
|
||||
uint16_t transaction_id;
|
||||
struct qdf_mac_addr bssid;
|
||||
enum tdls_add_oper tdls_oper;
|
||||
struct qdf_mac_addr peermac;
|
||||
uint16_t capability;
|
||||
uint8_t extn_capability[WLAN_MAC_MAX_EXTN_CAP];
|
||||
uint8_t supported_rates_length;
|
||||
uint8_t supported_rates[WLAN_MAC_MAX_SUPP_RATES];
|
||||
uint8_t htcap_present;
|
||||
struct htcap_cmn_ie ht_cap;
|
||||
uint8_t vhtcap_present;
|
||||
struct vhtcap vht_cap;
|
||||
uint8_t uapsd_queues;
|
||||
uint8_t max_sp;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct tdls_add_sta_rsp - TDLS Response struct PE --> TDLS module
|
||||
* same as struct sSirTdlsAddStaRsp
|
||||
* @message_type: message type eWNI_SME_TDLS_ADD_STA_RSP
|
||||
* @length: message length
|
||||
* @status_code: status code as tSirResultCodes
|
||||
* @peermac: MAC address of the TDLS peer
|
||||
* @session_id: session id
|
||||
* @sta_id: sta id
|
||||
* @sta_type: sta type
|
||||
* @ucast_sig: unicast signature
|
||||
* @bcast_sig: broadcast signature
|
||||
* @tdls_oper: add peer type
|
||||
* @psoc: soc object
|
||||
*/
|
||||
struct tdls_add_sta_rsp {
|
||||
uint16_t message_type;
|
||||
uint16_t length;
|
||||
QDF_STATUS status_code;
|
||||
struct qdf_mac_addr peermac;
|
||||
uint8_t session_id;
|
||||
uint16_t sta_id;
|
||||
uint16_t sta_type;
|
||||
uint8_t ucast_sig;
|
||||
uint8_t bcast_sig;
|
||||
enum tdls_add_oper tdls_oper;
|
||||
struct wlan_objmgr_psoc *psoc;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct tdls_del_sta_req - TDLS Request struct TDLS module --> PE
|
||||
* same as sSirTdlsDelStaReq
|
||||
* @message_type: message type eWNI_SME_TDLS_DEL_STA_REQ
|
||||
* @length: message length
|
||||
* @session_id: session id
|
||||
* @transaction_id: transaction id for cmd
|
||||
* @bssid: bssid
|
||||
* @peermac: MAC address of the TDLS peer
|
||||
*/
|
||||
struct tdls_del_sta_req {
|
||||
uint16_t message_type;
|
||||
uint16_t length;
|
||||
uint8_t session_id;
|
||||
uint16_t transaction_id;
|
||||
struct qdf_mac_addr bssid;
|
||||
struct qdf_mac_addr peermac;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct tdls_del_sta_rsp - TDLS Response struct PE --> TDLS module
|
||||
* same as sSirTdlsDelStaRsp
|
||||
* @message_type: message type eWNI_SME_TDLS_DEL_STA_RSP
|
||||
* @length: message length
|
||||
* @session_id: session id
|
||||
* @status_code: status code as tSirResultCodes
|
||||
* @peermac: MAC address of the TDLS peer
|
||||
* @sta_id: sta id
|
||||
* @psoc: soc object
|
||||
*/
|
||||
struct tdls_del_sta_rsp {
|
||||
uint16_t message_type;
|
||||
uint16_t length;
|
||||
uint8_t session_id;
|
||||
QDF_STATUS status_code;
|
||||
struct qdf_mac_addr peermac;
|
||||
uint16_t sta_id;
|
||||
struct wlan_objmgr_psoc *psoc;
|
||||
};
|
||||
|
||||
/**
|
||||
* tdls_process_add_peer() - add TDLS peer
|
||||
* @req: TDLS add peer request
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS if success; other value if failed
|
||||
*/
|
||||
QDF_STATUS tdls_process_add_peer(struct tdls_add_peer_request *req);
|
||||
|
||||
/**
|
||||
* tdls_process_del_peer() - del TDLS peer
|
||||
* @req: TDLS del peer request
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS if success; other value if failed
|
||||
*/
|
||||
QDF_STATUS tdls_process_del_peer(struct tdls_oper_request *req);
|
||||
|
||||
/**
|
||||
* tdls_process_update_peer() - update TDLS peer
|
||||
* @req: TDLS update peer request
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS if success; other value if failed
|
||||
*/
|
||||
QDF_STATUS tdls_process_update_peer(struct tdls_update_peer_request *req);
|
||||
|
||||
/**
|
||||
* tdls_pe_del_peer() - send TDLS delete peer request to PE
|
||||
* @req: TDLS delete peer request
|
||||
*
|
||||
* Return: QDF status
|
||||
*/
|
||||
QDF_STATUS tdls_pe_del_peer(struct tdls_del_peer_request *req);
|
||||
|
||||
/**
|
||||
* tdls_process_add_peer_rsp() - handle response for add or update TDLS peer
|
||||
* @rsp: TDLS add peer response
|
||||
*
|
||||
* Return: QDF status
|
||||
*/
|
||||
QDF_STATUS tdls_process_add_peer_rsp(struct tdls_add_sta_rsp *rsp);
|
||||
|
||||
/**
|
||||
* tdls_process_add_peer_rsp() - handle response for delete TDLS peer
|
||||
* @rsp: TDLS delete peer response
|
||||
*
|
||||
* Return: QDF status
|
||||
*/
|
||||
QDF_STATUS tdls_process_del_peer_rsp(struct tdls_del_sta_rsp *rsp);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@
|
|||
*/
|
||||
|
||||
#include "wlan_tdls_main.h"
|
||||
#include "wlan_tdls_cmds_process.h"
|
||||
#include "wlan_tdls_peer.h"
|
||||
|
||||
QDF_STATUS tdls_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc,
|
||||
void *arg_list)
|
||||
|
|
@ -31,7 +33,7 @@ QDF_STATUS tdls_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc,
|
|||
struct tdls_soc_priv_obj *tdls_soc_obj;
|
||||
|
||||
tdls_soc_obj = qdf_mem_malloc(sizeof(*tdls_soc_obj));
|
||||
if (tdls_soc_obj == NULL) {
|
||||
if (!tdls_soc_obj) {
|
||||
tdls_err("Failed to allocate memory for tdls object");
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
|
|
@ -61,7 +63,7 @@ QDF_STATUS tdls_psoc_obj_destroy_notification(struct wlan_objmgr_psoc *psoc,
|
|||
|
||||
tdls_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
|
||||
WLAN_UMAC_COMP_TDLS);
|
||||
if (tdls_soc_obj == NULL) {
|
||||
if (!tdls_soc_obj) {
|
||||
tdls_err("Failed to get tdls obj in psoc");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
|
@ -78,19 +80,53 @@ QDF_STATUS tdls_psoc_obj_destroy_notification(struct wlan_objmgr_psoc *psoc,
|
|||
return status;
|
||||
}
|
||||
|
||||
static void tdls_vdev_init(struct tdls_vdev_priv_obj *vdev)
|
||||
static QDF_STATUS tdls_vdev_init(struct tdls_vdev_priv_obj *vdev_obj)
|
||||
{
|
||||
uint8_t i;
|
||||
struct tdls_config_params *config;
|
||||
struct tdls_user_config *user_config;
|
||||
struct tdls_soc_priv_obj *soc_obj;
|
||||
|
||||
for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) {
|
||||
qdf_list_create(&vdev->peer_list[i],
|
||||
WLAN_TDLS_PEER_SUB_LIST_SIZE);
|
||||
soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev);
|
||||
if (!soc_obj) {
|
||||
tdls_err("tdls soc obj NULL");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
qdf_mc_timer_init(&vdev->peer_update_timer, QDF_TIMER_TYPE_SW,
|
||||
NULL, vdev);
|
||||
qdf_mc_timer_init(&vdev->peer_update_timer, QDF_TIMER_TYPE_SW,
|
||||
NULL, vdev);
|
||||
config = &vdev_obj->threshold_config;
|
||||
user_config = &soc_obj->tdls_configs;
|
||||
config->tx_period_t = user_config->tdls_tx_states_period;
|
||||
config->tx_packet_n = user_config->tdls_tx_pkt_threshold;
|
||||
config->discovery_tries_n = user_config->tdls_max_discovery_attempt;
|
||||
config->idle_timeout_t = user_config->tdls_idle_timeout;
|
||||
config->idle_packet_n = user_config->tdls_idle_pkt_threshold;
|
||||
config->rssi_trigger_threshold =
|
||||
user_config->tdls_rssi_trigger_threshold;
|
||||
config->rssi_teardown_threshold =
|
||||
user_config->tdls_rssi_teardown_threshold;
|
||||
config->rssi_delta = user_config->tdls_rssi_delta;
|
||||
|
||||
for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) {
|
||||
qdf_list_create(&vdev_obj->peer_list[i],
|
||||
WLAN_TDLS_PEER_SUB_LIST_SIZE);
|
||||
}
|
||||
qdf_mc_timer_init(&vdev_obj->peer_update_timer, QDF_TIMER_TYPE_SW,
|
||||
NULL, vdev_obj);
|
||||
qdf_mc_timer_init(&vdev_obj->peer_discovery_timer, QDF_TIMER_TYPE_SW,
|
||||
NULL, vdev_obj);
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void tdls_vdev_deinit(struct tdls_vdev_priv_obj *vdev_obj)
|
||||
{
|
||||
qdf_mc_timer_stop(&vdev_obj->peer_update_timer);
|
||||
qdf_mc_timer_stop(&vdev_obj->peer_discovery_timer);
|
||||
|
||||
qdf_mc_timer_destroy(&vdev_obj->peer_update_timer);
|
||||
qdf_mc_timer_destroy(&vdev_obj->peer_discovery_timer);
|
||||
|
||||
tdls_peer_idle_timers_destroy(vdev_obj);
|
||||
tdls_free_peer_list(vdev_obj);
|
||||
}
|
||||
|
||||
QDF_STATUS tdls_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev,
|
||||
|
|
@ -107,14 +143,11 @@ QDF_STATUS tdls_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev,
|
|||
/* TODO: Add concurrency check */
|
||||
|
||||
tdls_vdev_obj = qdf_mem_malloc(sizeof(*tdls_vdev_obj));
|
||||
if (tdls_vdev_obj == NULL) {
|
||||
if (!tdls_vdev_obj) {
|
||||
tdls_err("Failed to allocate memory for tdls vdev object");
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
|
||||
tdls_vdev_obj->vdev = vdev;
|
||||
tdls_vdev_init(tdls_vdev_obj);
|
||||
|
||||
status = wlan_objmgr_vdev_component_obj_attach(vdev,
|
||||
WLAN_UMAC_COMP_TDLS,
|
||||
(void *)tdls_vdev_obj,
|
||||
|
|
@ -122,10 +155,15 @@ QDF_STATUS tdls_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev,
|
|||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
tdls_err("Failed to attach vdev tdls component");
|
||||
qdf_mem_free(tdls_vdev_obj);
|
||||
goto out;
|
||||
}
|
||||
tdls_vdev_obj->vdev = vdev;
|
||||
status = tdls_vdev_init(tdls_vdev_obj);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
goto out;
|
||||
|
||||
tdls_notice("tdls object attach to vdev successfully");
|
||||
|
||||
out:
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
@ -142,7 +180,7 @@ QDF_STATUS tdls_vdev_obj_destroy_notification(struct wlan_objmgr_vdev *vdev,
|
|||
|
||||
tdls_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev,
|
||||
WLAN_UMAC_COMP_TDLS);
|
||||
if (tdls_vdev_obj == NULL) {
|
||||
if (!tdls_vdev_obj) {
|
||||
tdls_err("Failed to get tdls vdev object");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
|
@ -153,7 +191,47 @@ QDF_STATUS tdls_vdev_obj_destroy_notification(struct wlan_objmgr_vdev *vdev,
|
|||
if (QDF_IS_STATUS_ERROR(status))
|
||||
tdls_err("Failed to detach vdev tdls component");
|
||||
|
||||
tdls_vdev_deinit(tdls_vdev_obj);
|
||||
qdf_mem_free(tdls_vdev_obj);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg)
|
||||
{
|
||||
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
||||
|
||||
if (!msg || !msg->bodyptr) {
|
||||
tdls_err("msg: 0x%p, bodyptr: 0x%p", msg, msg->bodyptr);
|
||||
QDF_ASSERT(0);
|
||||
return QDF_STATUS_E_NULL_VALUE;
|
||||
}
|
||||
|
||||
switch (msg->type) {
|
||||
case TDLS_CMD_TX_ACTION:
|
||||
break;
|
||||
case TDLS_CMD_ADD_STA:
|
||||
tdls_process_add_peer(msg->bodyptr);
|
||||
break;
|
||||
case TDLS_CMD_CHANGE_STA:
|
||||
tdls_process_update_peer(msg->bodyptr);
|
||||
break;
|
||||
case TDLS_CMD_ENABLE_LINK:
|
||||
break;
|
||||
case TDLS_CMD_DISABLE_LINK:
|
||||
tdls_process_del_peer(msg->bodyptr);
|
||||
break;
|
||||
case TDLS_CMD_CONFIG_FORCE_PEER:
|
||||
break;
|
||||
case TDLS_CMD_REMOVE_FORCE_PEER:
|
||||
break;
|
||||
case TDLS_CMD_STATS_UPDATE:
|
||||
break;
|
||||
case TDLS_CMD_CONFIG_UPDATE:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,17 @@
|
|||
#define ENA_TDLS_BUFFER_STA (1 << 1) /* TDLS Buffer STA support */
|
||||
#define ENA_TDLS_SLEEP_STA (1 << 2) /* TDLS Sleep STA support */
|
||||
|
||||
#define BW_20_OFFSET_BIT 0
|
||||
#define BW_40_OFFSET_BIT 1
|
||||
#define BW_80_OFFSET_BIT 2
|
||||
#define BW_160_OFFSET_BIT 3
|
||||
|
||||
#define TDLS_SEC_OFFCHAN_OFFSET_0 0
|
||||
#define TDLS_SEC_OFFCHAN_OFFSET_40PLUS 40
|
||||
#define TDLS_SEC_OFFCHAN_OFFSET_40MINUS (-40)
|
||||
#define TDLS_SEC_OFFCHAN_OFFSET_80 80
|
||||
#define TDLS_SEC_OFFCHAN_OFFSET_160 160
|
||||
|
||||
#define tdls_log(level, args...) \
|
||||
QDF_TRACE(QDF_MODULE_ID_TDLS, level, ## args)
|
||||
#define tdls_logfl(level, format, args...) \
|
||||
|
|
@ -163,13 +174,20 @@ struct tdls_set_state_info {
|
|||
* @tx_ack_cnf_cb_data: user data to tdls_tx_cnf_cb
|
||||
* @tdls_event_cb: tdls event callback
|
||||
* @tdls_evt_cb_data: tdls event user data
|
||||
* @tdls_reg_tl_peer: callback to register the TDLS peer with TL
|
||||
* @tdls_dereg_tl_peer: callback to unregister the TDLS peer
|
||||
* @tdls_tl_peer_data: userdata for register/deregister TDLS peer
|
||||
* @tx_q_ack: queue for tx frames waiting for ack
|
||||
* @tdls_con_cap: tdls concurrency support
|
||||
* @tdls_send_mgmt_req: store eWNI_SME_TDLS_SEND_MGMT_REQ value
|
||||
* @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
|
||||
*/
|
||||
struct tdls_soc_priv_obj {
|
||||
struct wlan_objmgr_psoc *soc;
|
||||
enum tdls_support_mode tdls_current_mode;
|
||||
enum tdls_support_mode tdls_user_config_mode;
|
||||
enum tdls_feature_mode tdls_current_mode;
|
||||
enum tdls_feature_mode tdls_user_config_mode;
|
||||
struct tdls_conn_info tdls_conn_info[WLAN_TDLS_STA_MAX_NUM];
|
||||
struct tdls_user_config tdls_configs;
|
||||
uint16_t max_num_tdls_sta;
|
||||
|
|
@ -188,8 +206,15 @@ struct tdls_soc_priv_obj {
|
|||
void *tx_ack_cnf_cb_data;
|
||||
tdls_evt_callback tdls_event_cb;
|
||||
void *tdls_evt_cb_data;
|
||||
tdls_register_tl_peer_callback tdls_reg_tl_peer;
|
||||
tdls_deregister_tl_peer_callback tdls_dereg_tl_peer;
|
||||
void *tdls_tl_peer_data;
|
||||
qdf_list_t tx_q_ack;
|
||||
enum tdls_conc_cap tdls_con_cap;
|
||||
uint16_t tdls_send_mgmt_req;
|
||||
uint16_t tdls_add_sta_req;
|
||||
uint16_t tdls_del_sta_req;
|
||||
uint16_t tdls_update_peer_state;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -225,6 +250,12 @@ struct tdls_vdev_priv_obj {
|
|||
qdf_list_t tx_queue;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct tdls_peer_mlme_info - tdls peer mlme info
|
||||
**/
|
||||
struct tdls_peer_mlme_info {
|
||||
};
|
||||
|
||||
/**
|
||||
* struct tdls_peer - tdls peer data
|
||||
* @node: node
|
||||
|
|
@ -266,7 +297,7 @@ struct tdls_peer {
|
|||
uint16_t sta_id;
|
||||
int8_t rssi;
|
||||
enum tdls_peer_capab tdls_support;
|
||||
enum tdls_link_status link_status;
|
||||
enum tdls_link_state link_status;
|
||||
uint8_t signature;
|
||||
uint8_t is_responder;
|
||||
uint8_t discovery_processed;
|
||||
|
|
@ -288,9 +319,10 @@ struct tdls_peer {
|
|||
qdf_mc_timer_t peer_idle_timer;
|
||||
bool is_peer_idle_timer_initialised;
|
||||
uint8_t spatial_streams;
|
||||
enum tdls_link_reason reason;
|
||||
enum tdls_link_state_reason reason;
|
||||
tdls_state_change_callback state_change_notification;
|
||||
uint8_t qos;
|
||||
struct tdls_peer_mlme_info *tdls_info;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -302,12 +334,29 @@ struct tdls_peer {
|
|||
static inline struct tdls_soc_priv_obj *
|
||||
wlan_vdev_get_tdls_soc_obj(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
struct wlan_objmgr_psoc *psoc =
|
||||
wlan_pdev_get_psoc(wlan_vdev_get_pdev(vdev));
|
||||
struct wlan_objmgr_psoc *psoc;
|
||||
struct tdls_soc_priv_obj *soc_obj;
|
||||
|
||||
return (struct tdls_soc_priv_obj *)
|
||||
if (!vdev) {
|
||||
tdls_err("NULL vdev");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wlan_vdev_obj_lock(vdev);
|
||||
psoc = wlan_vdev_get_psoc(vdev);
|
||||
wlan_vdev_obj_unlock(vdev);
|
||||
if (!psoc) {
|
||||
tdls_err("can't get psoc");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wlan_psoc_obj_lock(psoc);
|
||||
soc_obj = (struct tdls_soc_priv_obj *)
|
||||
wlan_objmgr_psoc_get_comp_private_obj(psoc,
|
||||
WLAN_UMAC_COMP_TDLS);
|
||||
wlan_psoc_obj_unlock(psoc);
|
||||
|
||||
return soc_obj;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -319,9 +368,18 @@ wlan_vdev_get_tdls_soc_obj(struct wlan_objmgr_vdev *vdev)
|
|||
static inline struct tdls_soc_priv_obj *
|
||||
wlan_psoc_get_tdls_soc_obj(struct wlan_objmgr_psoc *psoc)
|
||||
{
|
||||
return (struct tdls_soc_priv_obj *)
|
||||
struct tdls_soc_priv_obj *soc_obj;
|
||||
if (!psoc) {
|
||||
tdls_err("NULL psoc");
|
||||
return NULL;
|
||||
}
|
||||
wlan_psoc_obj_lock(psoc);
|
||||
soc_obj = (struct tdls_soc_priv_obj *)
|
||||
wlan_objmgr_psoc_get_comp_private_obj(psoc,
|
||||
WLAN_UMAC_COMP_TDLS);
|
||||
wlan_psoc_obj_unlock(psoc);
|
||||
|
||||
return soc_obj;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -333,22 +391,33 @@ wlan_psoc_get_tdls_soc_obj(struct wlan_objmgr_psoc *psoc)
|
|||
static inline struct tdls_vdev_priv_obj *
|
||||
wlan_vdev_get_tdls_vdev_obj(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
return (struct tdls_vdev_priv_obj *)
|
||||
struct tdls_vdev_priv_obj *vdev_obj;
|
||||
|
||||
if (!vdev) {
|
||||
tdls_err("NULL vdev");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wlan_vdev_obj_lock(vdev);
|
||||
vdev_obj = (struct tdls_vdev_priv_obj *)
|
||||
wlan_objmgr_vdev_get_comp_private_obj(vdev,
|
||||
WLAN_UMAC_COMP_TDLS);
|
||||
wlan_vdev_obj_unlock(vdev);
|
||||
|
||||
return vdev_obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* tdls_set_link_status - tdls set link status
|
||||
* @vdev: vdev object
|
||||
* @mac: mac address of tdls peer
|
||||
* @link_status: tdls link status
|
||||
* @link_state: tdls link state
|
||||
* @link_reason: reason
|
||||
*/
|
||||
void tdls_set_link_status(struct tdls_vdev_priv_obj *vdev,
|
||||
const uint8_t *mac,
|
||||
enum tdls_link_status link_status,
|
||||
enum tdls_link_reason link_reason);
|
||||
enum tdls_link_state link_state,
|
||||
enum tdls_link_state_reason link_reason);
|
||||
/**
|
||||
* tdls_psoc_obj_create_notification() - tdls psoc create notification handler
|
||||
* @psoc: psoc object
|
||||
|
|
|
|||
836
umac/tdls/core/src/wlan_tdls_peer.c
Normal file
836
umac/tdls/core/src/wlan_tdls_peer.c
Normal file
|
|
@ -0,0 +1,836 @@
|
|||
/*
|
||||
* Copyright (c) 2017 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for
|
||||
* any purpose with or without fee is hereby granted, provided that the
|
||||
* above copyright notice and this permission notice appear in all
|
||||
* copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* DOC: wlan_tdls_peer.c
|
||||
*
|
||||
* TDLS peer basic operations
|
||||
*/
|
||||
#include "wlan_tdls_main.h"
|
||||
#include "wlan_tdls_peer.h"
|
||||
#include <wlan_reg_services_api.h>
|
||||
#include <wlan_utility.h>
|
||||
#include <wlan_policy_mgr_api.h>
|
||||
|
||||
static uint8_t calculate_hash_key(const uint8_t *macaddr)
|
||||
{
|
||||
uint8_t i, key;
|
||||
|
||||
for (i = 0, key = 0; i < 6; i++)
|
||||
key ^= macaddr[i];
|
||||
|
||||
return key % WLAN_TDLS_PEER_LIST_SIZE;
|
||||
}
|
||||
|
||||
struct tdls_peer *tdls_find_peer(struct tdls_vdev_priv_obj *vdev_obj,
|
||||
const uint8_t *macaddr)
|
||||
{
|
||||
uint8_t key;
|
||||
QDF_STATUS status;
|
||||
struct tdls_peer *peer;
|
||||
qdf_list_t *head;
|
||||
qdf_list_node_t *p_node;
|
||||
|
||||
key = calculate_hash_key(macaddr);
|
||||
head = &vdev_obj->peer_list[key];
|
||||
|
||||
status = qdf_list_peek_front(head, &p_node);
|
||||
while (QDF_IS_STATUS_SUCCESS(status)) {
|
||||
peer = qdf_container_of(p_node, struct tdls_peer, node);
|
||||
if (WLAN_ADDR_EQ(&peer->peer_mac, macaddr)
|
||||
== QDF_STATUS_SUCCESS) {
|
||||
return peer;
|
||||
}
|
||||
status = qdf_list_peek_next(head, p_node, &p_node);
|
||||
}
|
||||
|
||||
tdls_debug("no tdls peer " QDF_MAC_ADDRESS_STR,
|
||||
QDF_MAC_ADDR_ARRAY(macaddr));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* tdls_find_peer_handler() - helper function for tdls_find_all_peer
|
||||
* @psoc: soc object
|
||||
* @obj: vdev object
|
||||
* @arg: used to keep search peer parameters
|
||||
*
|
||||
* Return: None.
|
||||
*/
|
||||
static void
|
||||
tdls_find_peer_handler(struct wlan_objmgr_psoc *psoc, void *obj, void *arg)
|
||||
{
|
||||
struct wlan_objmgr_vdev *vdev = obj;
|
||||
struct tdls_search_peer_param *tdls_param = arg;
|
||||
struct tdls_vdev_priv_obj *vdev_obj;
|
||||
|
||||
if (tdls_param->peer)
|
||||
return;
|
||||
|
||||
if (!vdev) {
|
||||
tdls_err("invalid vdev");
|
||||
return;
|
||||
}
|
||||
|
||||
if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE &&
|
||||
wlan_vdev_mlme_get_opmode(vdev) != QDF_P2P_CLIENT_MODE)
|
||||
return;
|
||||
|
||||
vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev,
|
||||
WLAN_UMAC_COMP_TDLS);
|
||||
if (!vdev_obj)
|
||||
return;
|
||||
|
||||
tdls_param->peer = tdls_find_peer(vdev_obj, tdls_param->macaddr);
|
||||
}
|
||||
|
||||
struct tdls_peer *
|
||||
tdls_find_all_peer(struct tdls_soc_priv_obj *soc_obj, const uint8_t *macaddr)
|
||||
{
|
||||
struct tdls_search_peer_param tdls_search_param;
|
||||
struct wlan_objmgr_psoc *psoc;
|
||||
|
||||
if (!soc_obj) {
|
||||
tdls_err("tdls soc object is NULL");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
psoc = soc_obj->soc;
|
||||
if (!psoc) {
|
||||
tdls_err("psoc is NULL");
|
||||
return NULL;
|
||||
}
|
||||
tdls_search_param.macaddr = macaddr;
|
||||
tdls_search_param.peer = NULL;
|
||||
|
||||
wlan_objmgr_iterate_obj_list(psoc, WLAN_VDEV_OP,
|
||||
tdls_find_peer_handler,
|
||||
&tdls_search_param, 0, WLAN_TDLS_NB_ID);
|
||||
|
||||
return tdls_search_param.peer;
|
||||
}
|
||||
|
||||
static uint8_t tdls_find_opclass(struct wlan_objmgr_psoc *psoc, uint8_t channel,
|
||||
uint8_t bw_offset)
|
||||
{
|
||||
char country[REG_ALPHA2_LEN + 1];
|
||||
QDF_STATUS status;
|
||||
|
||||
if (!psoc) {
|
||||
tdls_err("psoc is NULL");
|
||||
return 0;
|
||||
}
|
||||
|
||||
status = wlan_reg_read_default_country(psoc, country);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
return 0;
|
||||
|
||||
return wlan_reg_dmn_get_opclass_from_channel(country, channel,
|
||||
bw_offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* tdls_add_peer() - add TDLS peer in TDLS vdev object
|
||||
* @vdev_obj: TDLS vdev object
|
||||
* @macaddr: MAC address of peer
|
||||
*
|
||||
* Allocate memory for the new peer, and add it to hash table.
|
||||
*
|
||||
* Return: new added TDLS peer, NULL if failed.
|
||||
*/
|
||||
static struct tdls_peer *tdls_add_peer(struct tdls_vdev_priv_obj *vdev_obj,
|
||||
const uint8_t *macaddr)
|
||||
{
|
||||
struct tdls_peer *peer;
|
||||
struct tdls_soc_priv_obj *soc_obj;
|
||||
uint8_t key = 0;
|
||||
qdf_list_t *head;
|
||||
|
||||
peer = qdf_mem_malloc(sizeof(*peer));
|
||||
if (!peer) {
|
||||
tdls_err("add tdls peer malloc memory failed!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev);
|
||||
if (!soc_obj) {
|
||||
tdls_err("NULL tdls soc object");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
key = calculate_hash_key(macaddr);
|
||||
head = &vdev_obj->peer_list[key];
|
||||
|
||||
qdf_mem_copy(&peer->peer_mac, macaddr, sizeof(peer->peer_mac));
|
||||
peer->vdev_priv = vdev_obj;
|
||||
|
||||
peer->pref_off_chan_num =
|
||||
soc_obj->tdls_configs.tdls_pre_off_chan_num;
|
||||
peer->op_class_for_pref_off_chan =
|
||||
tdls_find_opclass(soc_obj->soc,
|
||||
peer->pref_off_chan_num,
|
||||
soc_obj->tdls_configs.tdls_pre_off_chan_bw);
|
||||
|
||||
qdf_list_insert_back(head, &peer->node);
|
||||
|
||||
tdls_debug("add tdls peer: " QDF_MAC_ADDRESS_STR,
|
||||
QDF_MAC_ADDR_ARRAY(macaddr));
|
||||
return peer;
|
||||
}
|
||||
|
||||
struct tdls_peer *tdls_get_peer(struct tdls_vdev_priv_obj *vdev_obj,
|
||||
const uint8_t *macaddr)
|
||||
{
|
||||
struct tdls_peer *peer;
|
||||
|
||||
peer = tdls_find_peer(vdev_obj, macaddr);
|
||||
if (!peer)
|
||||
peer = tdls_add_peer(vdev_obj, macaddr);
|
||||
|
||||
return peer;
|
||||
}
|
||||
|
||||
static struct tdls_peer *
|
||||
tdls_find_progress_peer_in_list(qdf_list_t *head,
|
||||
const uint8_t *macaddr, uint8_t skip_self)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
struct tdls_peer *peer;
|
||||
qdf_list_node_t *p_node;
|
||||
|
||||
status = qdf_list_peek_front(head, &p_node);
|
||||
while (QDF_IS_STATUS_SUCCESS(status)) {
|
||||
peer = qdf_container_of(p_node, struct tdls_peer, node);
|
||||
if (skip_self && macaddr &&
|
||||
WLAN_ADDR_EQ(&peer->peer_mac, macaddr)
|
||||
== QDF_STATUS_SUCCESS) {
|
||||
status = qdf_list_peek_next(head, p_node, &p_node);
|
||||
continue;
|
||||
} else if (TDLS_LINK_CONNECTING == peer->link_status) {
|
||||
tdls_debug(QDF_MAC_ADDRESS_STR " TDLS_LINK_CONNECTING",
|
||||
QDF_MAC_ADDR_ARRAY(peer->peer_mac.bytes));
|
||||
return peer;
|
||||
}
|
||||
status = qdf_list_peek_next(head, p_node, &p_node);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* tdls_find_progress_peer() - find the peer with ongoing TDLS progress
|
||||
* on present vdev
|
||||
* @vdev_obj: TDLS vdev object
|
||||
* @macaddr: MAC address of peer, if NULL check for all the peer list
|
||||
* @skip_self: If true, skip this macaddr. Otherwise, check all the peer list.
|
||||
* if macaddr is NULL, this argument is ignored, and check for all
|
||||
* the peer list.
|
||||
*
|
||||
* Return: Pointer to tdls_peer if TDLS is ongoing. Otherwise return NULL.
|
||||
*/
|
||||
static struct tdls_peer *
|
||||
tdls_find_progress_peer(struct tdls_vdev_priv_obj *vdev_obj,
|
||||
const uint8_t *macaddr, uint8_t skip_self)
|
||||
{
|
||||
uint8_t i;
|
||||
struct tdls_peer *peer;
|
||||
qdf_list_t *head;
|
||||
|
||||
if (!vdev_obj) {
|
||||
tdls_err("invalid tdls vdev object");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) {
|
||||
head = &vdev_obj->peer_list[i];
|
||||
|
||||
peer = tdls_find_progress_peer_in_list(head, macaddr,
|
||||
skip_self);
|
||||
if (peer)
|
||||
return peer;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* tdls_find_progress_peer_handler() - helper function for tdls_is_progress
|
||||
* @psoc: soc object
|
||||
* @obj: vdev object
|
||||
* @arg: used to keep search peer parameters
|
||||
*
|
||||
* Return: None.
|
||||
*/
|
||||
static void
|
||||
tdls_find_progress_peer_handler(struct wlan_objmgr_psoc *psoc,
|
||||
void *obj, void *arg)
|
||||
{
|
||||
struct wlan_objmgr_vdev *vdev = obj;
|
||||
struct tdls_search_progress_param *tdls_progress = arg;
|
||||
struct tdls_vdev_priv_obj *vdev_obj;
|
||||
|
||||
if (tdls_progress->peer)
|
||||
return;
|
||||
|
||||
if (!vdev) {
|
||||
tdls_err("invalid vdev");
|
||||
return;
|
||||
}
|
||||
|
||||
if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE &&
|
||||
wlan_vdev_mlme_get_opmode(vdev) != QDF_P2P_CLIENT_MODE)
|
||||
return;
|
||||
|
||||
vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev,
|
||||
WLAN_UMAC_COMP_TDLS);
|
||||
|
||||
tdls_progress->peer = tdls_find_progress_peer(vdev_obj,
|
||||
tdls_progress->macaddr,
|
||||
tdls_progress->skip_self);
|
||||
}
|
||||
|
||||
struct tdls_peer *tdls_is_progress(struct tdls_vdev_priv_obj *vdev_obj,
|
||||
const uint8_t *macaddr, uint8_t skip_self)
|
||||
{
|
||||
struct tdls_search_progress_param tdls_progress;
|
||||
struct wlan_objmgr_psoc *psoc;
|
||||
|
||||
if (!vdev_obj) {
|
||||
tdls_err("invalid tdls vdev object");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wlan_vdev_obj_lock(vdev_obj->vdev);
|
||||
psoc = wlan_vdev_get_psoc(vdev_obj->vdev);
|
||||
wlan_vdev_obj_unlock(vdev_obj->vdev);
|
||||
if (!psoc) {
|
||||
tdls_err("invalid psoc");
|
||||
return NULL;
|
||||
}
|
||||
tdls_progress.macaddr = macaddr;
|
||||
tdls_progress.skip_self = skip_self;
|
||||
tdls_progress.peer = NULL;
|
||||
|
||||
wlan_objmgr_iterate_obj_list(psoc, WLAN_VDEV_OP,
|
||||
tdls_find_progress_peer_handler,
|
||||
&tdls_progress, 0, WLAN_TDLS_NB_ID);
|
||||
|
||||
return tdls_progress.peer;
|
||||
}
|
||||
|
||||
struct tdls_peer *
|
||||
tdls_find_first_connected_peer(struct tdls_vdev_priv_obj *vdev_obj)
|
||||
{
|
||||
uint16_t i;
|
||||
struct tdls_peer *peer;
|
||||
qdf_list_t *head;
|
||||
qdf_list_node_t *p_node;
|
||||
QDF_STATUS status;
|
||||
|
||||
if (!vdev_obj) {
|
||||
tdls_err("invalid tdls vdev object");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) {
|
||||
head = &vdev_obj->peer_list[i];
|
||||
|
||||
status = qdf_list_peek_front(head, &p_node);
|
||||
while (QDF_IS_STATUS_SUCCESS(status)) {
|
||||
peer = qdf_container_of(p_node, struct tdls_peer, node);
|
||||
|
||||
if (peer && TDLS_LINK_CONNECTED == peer->link_status) {
|
||||
tdls_debug(QDF_MAC_ADDRESS_STR
|
||||
" TDLS_LINK_CONNECTED",
|
||||
QDF_MAC_ADDR_ARRAY(
|
||||
peer->peer_mac.bytes));
|
||||
return peer;
|
||||
}
|
||||
status = qdf_list_peek_next(head, p_node, &p_node);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* tdls_determine_channel_opclass() - determine channel and opclass
|
||||
* @soc_obj: TDLS soc object
|
||||
* @vdev_obj: TDLS vdev object
|
||||
* @peer: TDLS peer
|
||||
* @channel: pointer to channel
|
||||
* @opclass: pinter to opclass
|
||||
*
|
||||
* Function determines the channel and operating class
|
||||
*
|
||||
* Return: None.
|
||||
*/
|
||||
static void tdls_determine_channel_opclass(struct tdls_soc_priv_obj *soc_obj,
|
||||
struct tdls_vdev_priv_obj *vdev_obj,
|
||||
struct tdls_peer *peer,
|
||||
uint32_t *channel, uint32_t *opclass)
|
||||
{
|
||||
uint32_t vdev_id;
|
||||
enum tQDF_ADAPTER_MODE opmode;
|
||||
/*
|
||||
* If tdls offchannel is not enabled then we provide base channel
|
||||
* and in that case pass opclass as 0 since opclass is mainly needed
|
||||
* for offchannel cases.
|
||||
*/
|
||||
if (!(TDLS_IS_OFF_CHANNEL_ENABLED(
|
||||
soc_obj->tdls_configs.tdls_feature_flags)) ||
|
||||
soc_obj->tdls_fw_off_chan_mode != ENABLE_CHANSWITCH) {
|
||||
wlan_vdev_obj_lock(vdev_obj->vdev);
|
||||
vdev_id = wlan_vdev_get_id(vdev_obj->vdev);
|
||||
opmode = wlan_vdev_mlme_get_opmode(vdev_obj->vdev);
|
||||
wlan_vdev_obj_unlock(vdev_obj->vdev);
|
||||
|
||||
*channel = policy_mgr_get_channel(soc_obj->soc,
|
||||
opmode, &vdev_id);
|
||||
*opclass = 0;
|
||||
} else {
|
||||
*channel = peer->pref_off_chan_num;
|
||||
*opclass = peer->op_class_for_pref_off_chan;
|
||||
}
|
||||
tdls_debug("channel:%d opclass:%d", *channel, *opclass);
|
||||
}
|
||||
|
||||
/**
|
||||
* tdls_get_wifi_hal_state() - get TDLS wifi hal state on current peer
|
||||
* @peer: TDLS peer
|
||||
* @state: output parameter to store the TDLS wifi hal state
|
||||
* @reason: output parameter to store the reason of the current peer
|
||||
*
|
||||
* Return: None.
|
||||
*/
|
||||
static void tdls_get_wifi_hal_state(struct tdls_peer *peer, uint32_t *state,
|
||||
int32_t *reason)
|
||||
{
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
struct tdls_soc_priv_obj *soc_obj;
|
||||
|
||||
vdev = peer->vdev_priv->vdev;
|
||||
soc_obj = wlan_vdev_get_tdls_soc_obj(vdev);
|
||||
if (!soc_obj) {
|
||||
tdls_err("can't get tdls object");
|
||||
return;
|
||||
}
|
||||
|
||||
*reason = peer->reason;
|
||||
|
||||
switch (peer->link_status) {
|
||||
case TDLS_LINK_IDLE:
|
||||
case TDLS_LINK_DISCOVERED:
|
||||
case TDLS_LINK_DISCOVERING:
|
||||
case TDLS_LINK_CONNECTING:
|
||||
*state = QCA_WIFI_HAL_TDLS_S_ENABLED;
|
||||
break;
|
||||
case TDLS_LINK_CONNECTED:
|
||||
if ((TDLS_IS_OFF_CHANNEL_ENABLED(
|
||||
soc_obj->tdls_configs.tdls_feature_flags)) &&
|
||||
(soc_obj->tdls_fw_off_chan_mode == ENABLE_CHANSWITCH))
|
||||
*state = QCA_WIFI_HAL_TDLS_S_ESTABLISHED_OFF_CHANNEL;
|
||||
else
|
||||
*state = QCA_WIFI_HAL_TDLS_S_ENABLED;
|
||||
break;
|
||||
case TDLS_LINK_TEARING:
|
||||
*state = QCA_WIFI_HAL_TDLS_S_DROPPED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* tdls_extract_peer_state_param() - extract peer update params from TDLS peer
|
||||
* @peer_param: output peer update params
|
||||
* @peer: TDLS peer
|
||||
*
|
||||
* This is used when enable TDLS link
|
||||
*
|
||||
* Return: None.
|
||||
*/
|
||||
void tdls_extract_peer_state_param(struct tdls_peer_update_state *peer_param,
|
||||
struct tdls_peer *peer)
|
||||
{
|
||||
uint16_t i, num;
|
||||
struct tdls_vdev_priv_obj *vdev_obj;
|
||||
struct tdls_soc_priv_obj *soc_obj;
|
||||
enum channel_state ch_state;
|
||||
struct wlan_objmgr_pdev *pdev;
|
||||
uint8_t chan_id;
|
||||
|
||||
vdev_obj = peer->vdev_priv;
|
||||
soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev);
|
||||
pdev = wlan_vdev_get_pdev(vdev_obj->vdev);
|
||||
if (!soc_obj || !pdev) {
|
||||
tdls_err("soc_obj: %p, pdev: %p", soc_obj, pdev);
|
||||
return;
|
||||
}
|
||||
|
||||
qdf_mem_zero(peer_param, sizeof(*peer_param));
|
||||
wlan_vdev_obj_lock(vdev_obj->vdev);
|
||||
peer_param->vdev_id = wlan_vdev_get_id(vdev_obj->vdev);
|
||||
wlan_vdev_obj_unlock(vdev_obj->vdev);
|
||||
|
||||
qdf_mem_copy(peer_param->peer_macaddr,
|
||||
peer->peer_mac.bytes, QDF_MAC_ADDR_SIZE);
|
||||
peer_param->peer_state = TDLS_PEER_STATE_CONNCTED;
|
||||
peer_param->peer_cap.is_peer_responder = peer->is_responder;
|
||||
peer_param->peer_cap.peer_uapsd_queue = peer->uapsd_queues;
|
||||
peer_param->peer_cap.peer_max_sp = peer->max_sp;
|
||||
peer_param->peer_cap.peer_buff_sta_support = peer->buf_sta_capable;
|
||||
peer_param->peer_cap.peer_off_chan_support =
|
||||
peer->off_channel_capable;
|
||||
peer_param->peer_cap.peer_curr_operclass = 0;
|
||||
peer_param->peer_cap.self_curr_operclass = 0;
|
||||
peer_param->peer_cap.peer_chanlen = peer->supported_channels_len;
|
||||
peer_param->peer_cap.pref_off_channum = peer->pref_off_chan_num;
|
||||
peer_param->peer_cap.pref_off_chan_bandwidth =
|
||||
soc_obj->tdls_configs.tdls_pre_off_chan_bw;
|
||||
peer_param->peer_cap.opclass_for_prefoffchan =
|
||||
peer->op_class_for_pref_off_chan;
|
||||
|
||||
if (wlan_reg_is_dfs_ch(pdev, peer_param->peer_cap.pref_off_channum)) {
|
||||
tdls_err("Resetting TDLS off-channel from %d to %d",
|
||||
peer_param->peer_cap.pref_off_channum,
|
||||
WLAN_TDLS_PREFERRED_OFF_CHANNEL_NUM_DEF);
|
||||
peer_param->peer_cap.pref_off_channum =
|
||||
WLAN_TDLS_PREFERRED_OFF_CHANNEL_NUM_DEF;
|
||||
}
|
||||
|
||||
num = 0;
|
||||
for (i = 0; i < peer->supported_channels_len; i++) {
|
||||
chan_id = peer->supported_channels[i];
|
||||
ch_state = wlan_reg_get_channel_state(pdev, chan_id);
|
||||
|
||||
if (CHANNEL_STATE_INVALID != ch_state &&
|
||||
CHANNEL_STATE_DFS != ch_state &&
|
||||
!wlan_is_dsrc_channel(wlan_is_dsrc_channel(chan_id))) {
|
||||
peer_param->peer_cap.peer_chan[num].chan_id = chan_id;
|
||||
peer_param->peer_cap.peer_chan[num].pwr =
|
||||
wlan_reg_get_channel_reg_power(pdev, chan_id);
|
||||
peer_param->peer_cap.peer_chan[num].dfs_set = false;
|
||||
num++;
|
||||
}
|
||||
}
|
||||
|
||||
peer_param->peer_cap.peer_oper_classlen =
|
||||
peer->supported_oper_classes_len;
|
||||
for (i = 0; i < peer->supported_oper_classes_len; i++)
|
||||
peer_param->peer_cap.peer_oper_class[i] =
|
||||
peer->supported_oper_classes[i];
|
||||
}
|
||||
|
||||
/**
|
||||
* tdls_set_link_status() - set link statue for TDLS peer
|
||||
* @vdev_obj: TDLS vdev object
|
||||
* @mac: MAC address of current TDLS peer
|
||||
* @link_status: link status
|
||||
* @link_reason: reason with link status
|
||||
*
|
||||
* Return: None.
|
||||
*/
|
||||
void tdls_set_link_status(struct tdls_vdev_priv_obj *vdev_obj,
|
||||
const uint8_t *mac,
|
||||
enum tdls_link_state link_status,
|
||||
enum tdls_link_state_reason link_reason)
|
||||
{
|
||||
uint32_t state = 0;
|
||||
int32_t res = 0;
|
||||
uint32_t op_class = 0;
|
||||
uint32_t channel = 0;
|
||||
struct tdls_peer *peer;
|
||||
struct tdls_soc_priv_obj *soc_obj;
|
||||
|
||||
peer = tdls_find_peer(vdev_obj, mac);
|
||||
if (!peer) {
|
||||
tdls_err("peer is NULL, can't set link status %d, reason %d",
|
||||
link_status, link_reason);
|
||||
return;
|
||||
}
|
||||
|
||||
peer->link_status = link_status;
|
||||
|
||||
if (link_status >= TDLS_LINK_DISCOVERED)
|
||||
peer->discovery_attempt = 0;
|
||||
|
||||
if (peer->is_forced_peer && peer->state_change_notification) {
|
||||
peer->reason = link_reason;
|
||||
|
||||
soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev);
|
||||
if (!soc_obj) {
|
||||
tdls_err("NULL psoc object");
|
||||
return;
|
||||
}
|
||||
|
||||
tdls_determine_channel_opclass(soc_obj, vdev_obj,
|
||||
peer, &channel, &op_class);
|
||||
tdls_get_wifi_hal_state(peer, &state, &res);
|
||||
peer->state_change_notification(mac, op_class, channel,
|
||||
state, res, soc_obj->soc);
|
||||
}
|
||||
}
|
||||
|
||||
void tdls_set_peer_link_status(struct tdls_peer *peer,
|
||||
enum tdls_link_state link_status,
|
||||
enum tdls_link_state_reason link_reason)
|
||||
{
|
||||
uint32_t state = 0;
|
||||
int32_t res = 0;
|
||||
uint32_t op_class = 0;
|
||||
uint32_t channel = 0;
|
||||
struct tdls_soc_priv_obj *soc_obj;
|
||||
struct tdls_vdev_priv_obj *vdev_obj;
|
||||
|
||||
peer->link_status = link_status;
|
||||
|
||||
if (link_status >= TDLS_LINK_DISCOVERED)
|
||||
peer->discovery_attempt = 0;
|
||||
|
||||
if (peer->is_forced_peer && peer->state_change_notification) {
|
||||
peer->reason = link_reason;
|
||||
|
||||
vdev_obj = peer->vdev_priv;
|
||||
soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev);
|
||||
if (!soc_obj) {
|
||||
tdls_err("NULL psoc object");
|
||||
return;
|
||||
}
|
||||
|
||||
tdls_determine_channel_opclass(soc_obj, vdev_obj,
|
||||
peer, &channel, &op_class);
|
||||
tdls_get_wifi_hal_state(peer, &state, &res);
|
||||
peer->state_change_notification(peer->peer_mac.bytes,
|
||||
op_class, channel, state,
|
||||
res, soc_obj->soc);
|
||||
}
|
||||
}
|
||||
|
||||
void tdls_set_peer_caps(struct tdls_vdev_priv_obj *vdev_obj,
|
||||
const uint8_t *macaddr,
|
||||
struct tdls_update_peer_params *req_info)
|
||||
{
|
||||
uint8_t is_buffer_sta, is_off_channel_supported, is_qos_wmm_sta;
|
||||
struct tdls_soc_priv_obj *soc_obj;
|
||||
struct tdls_peer *curr_peer;
|
||||
uint32_t feature;
|
||||
|
||||
soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev);
|
||||
if (!soc_obj) {
|
||||
tdls_err("NULL psoc object");
|
||||
return;
|
||||
}
|
||||
|
||||
curr_peer = tdls_find_peer(vdev_obj, macaddr);
|
||||
if (!curr_peer) {
|
||||
tdls_err("NULL tdls peer");
|
||||
return;
|
||||
}
|
||||
|
||||
feature = soc_obj->tdls_configs.tdls_feature_flags;
|
||||
if ((1 << 4) & req_info->extn_capability[3])
|
||||
is_buffer_sta = 1;
|
||||
|
||||
if ((1 << 6) & req_info->extn_capability[3])
|
||||
is_off_channel_supported = 1;
|
||||
|
||||
if (TDLS_IS_WMM_ENABLED(feature) && req_info->is_qos_wmm_sta)
|
||||
is_qos_wmm_sta = true;
|
||||
|
||||
curr_peer->uapsd_queues = req_info->uapsd_queues;
|
||||
curr_peer->max_sp = req_info->max_sp;
|
||||
curr_peer->buf_sta_capable = is_buffer_sta;
|
||||
curr_peer->off_channel_capable = is_off_channel_supported;
|
||||
|
||||
qdf_mem_copy(curr_peer->supported_channels,
|
||||
req_info->supported_channels,
|
||||
req_info->supported_channels_len);
|
||||
|
||||
curr_peer->supported_channels_len = req_info->supported_channels_len;
|
||||
|
||||
qdf_mem_copy(curr_peer->supported_oper_classes,
|
||||
req_info->supported_oper_classes,
|
||||
req_info->supported_oper_classes_len);
|
||||
|
||||
curr_peer->supported_oper_classes_len =
|
||||
req_info->supported_oper_classes_len;
|
||||
|
||||
curr_peer->qos = is_qos_wmm_sta;
|
||||
}
|
||||
|
||||
QDF_STATUS tdls_set_sta_id(struct tdls_vdev_priv_obj *vdev_obj,
|
||||
const uint8_t *macaddr, uint8_t sta_id)
|
||||
{
|
||||
struct tdls_peer *peer;
|
||||
|
||||
peer = tdls_find_peer(vdev_obj, macaddr);
|
||||
if (!peer) {
|
||||
tdls_err("peer is NULL");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
peer->sta_id = sta_id;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
QDF_STATUS tdls_set_signature(struct tdls_vdev_priv_obj *vdev_obj,
|
||||
const uint8_t *macaddr, uint8_t signature)
|
||||
{
|
||||
struct tdls_peer *peer;
|
||||
|
||||
peer = tdls_find_peer(vdev_obj, macaddr);
|
||||
if (!peer) {
|
||||
tdls_err("peer is NULL");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
peer->signature = signature;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
QDF_STATUS tdls_set_force_peer(struct tdls_vdev_priv_obj *vdev_obj,
|
||||
const uint8_t *macaddr, bool forcepeer)
|
||||
{
|
||||
struct tdls_peer *peer;
|
||||
|
||||
peer = tdls_find_peer(vdev_obj, macaddr);
|
||||
if (!peer) {
|
||||
tdls_err("peer is NULL");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
peer->is_forced_peer = forcepeer;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
QDF_STATUS tdls_set_callback(struct tdls_peer *peer,
|
||||
tdls_state_change_callback callback)
|
||||
{
|
||||
if (!peer) {
|
||||
tdls_err("peer is NULL");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
peer->state_change_notification = callback;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
QDF_STATUS tdls_set_extctrl_param(struct tdls_peer *peer, uint32_t chan,
|
||||
uint32_t max_latency, uint32_t op_class,
|
||||
uint32_t min_bandwidth)
|
||||
{
|
||||
if (!peer) {
|
||||
tdls_err("peer is NULL");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
peer->op_class_for_pref_off_chan = (uint8_t)op_class;
|
||||
peer->pref_off_chan_num = (uint8_t)chan;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
QDF_STATUS tdls_reset_peer(struct tdls_vdev_priv_obj *vdev_obj,
|
||||
const uint8_t *macaddr)
|
||||
{
|
||||
struct tdls_soc_priv_obj *soc_obj;
|
||||
struct tdls_peer *curr_peer;
|
||||
struct tdls_user_config *config;
|
||||
|
||||
soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev);
|
||||
if (!soc_obj) {
|
||||
tdls_err("NULL psoc object");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
curr_peer = tdls_find_peer(vdev_obj, macaddr);
|
||||
if (!curr_peer) {
|
||||
tdls_err("NULL tdls peer");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (!curr_peer->is_forced_peer) {
|
||||
config = &soc_obj->tdls_configs;
|
||||
curr_peer->pref_off_chan_num = config->tdls_pre_off_chan_num;
|
||||
curr_peer->op_class_for_pref_off_chan =
|
||||
tdls_find_opclass(soc_obj->soc,
|
||||
curr_peer->pref_off_chan_num,
|
||||
config->tdls_pre_off_chan_bw);
|
||||
}
|
||||
|
||||
tdls_set_peer_link_status(curr_peer, TDLS_LINK_IDLE,
|
||||
TDLS_LINK_UNSPECIFIED);
|
||||
curr_peer->sta_id = 0;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void tdls_peer_idle_timers_destroy(struct tdls_vdev_priv_obj *vdev_obj)
|
||||
{
|
||||
uint16_t i;
|
||||
struct tdls_peer *peer;
|
||||
qdf_list_t *head;
|
||||
qdf_list_node_t *p_node;
|
||||
QDF_STATUS status;
|
||||
|
||||
if (!vdev_obj) {
|
||||
tdls_err("NULL tdls vdev object");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) {
|
||||
head = &vdev_obj->peer_list[i];
|
||||
|
||||
status = qdf_list_peek_front(head, &p_node);
|
||||
while (QDF_IS_STATUS_SUCCESS(status)) {
|
||||
peer = qdf_container_of(p_node, struct tdls_peer, node);
|
||||
if (peer && peer->is_peer_idle_timer_initialised) {
|
||||
tdls_debug(QDF_MAC_ADDRESS_STR
|
||||
": destroy idle timer ",
|
||||
QDF_MAC_ADDR_ARRAY(
|
||||
peer->peer_mac.bytes));
|
||||
qdf_mc_timer_stop(&peer->peer_idle_timer);
|
||||
qdf_mc_timer_destroy(&peer->peer_idle_timer);
|
||||
}
|
||||
status = qdf_list_peek_next(head, p_node, &p_node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tdls_free_peer_list(struct tdls_vdev_priv_obj *vdev_obj)
|
||||
{
|
||||
uint16_t i;
|
||||
struct tdls_peer *peer;
|
||||
qdf_list_t *head;
|
||||
qdf_list_node_t *p_node;
|
||||
|
||||
if (!vdev_obj) {
|
||||
tdls_err("NULL tdls vdev object");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) {
|
||||
head = &vdev_obj->peer_list[i];
|
||||
|
||||
while (QDF_IS_STATUS_SUCCESS(
|
||||
qdf_list_remove_front(head, &p_node))) {
|
||||
peer = qdf_container_of(p_node, struct tdls_peer, node);
|
||||
qdf_mem_free(peer);
|
||||
}
|
||||
qdf_list_destroy(head);
|
||||
}
|
||||
}
|
||||
245
umac/tdls/core/src/wlan_tdls_peer.h
Normal file
245
umac/tdls/core/src/wlan_tdls_peer.h
Normal file
|
|
@ -0,0 +1,245 @@
|
|||
/*
|
||||
* Copyright (c) 2017 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for
|
||||
* any purpose with or without fee is hereby granted, provided that the
|
||||
* above copyright notice and this permission notice appear in all
|
||||
* copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* DOC: wlan_tdls_peer.h
|
||||
*
|
||||
* TDLS peer function declaration
|
||||
*/
|
||||
|
||||
#if !defined(_WLAN_TDLS_PEER_H_)
|
||||
#define _WLAN_TDLS_PEER_H_
|
||||
|
||||
/**
|
||||
* struct tdls_search_peer_param - used to search TDLS peer
|
||||
* @macaddr: MAC address of peer
|
||||
* @peer: pointer to the found peer
|
||||
*/
|
||||
struct tdls_search_peer_param {
|
||||
const uint8_t *macaddr;
|
||||
struct tdls_peer *peer;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct tdls_progress_param - used to search progress TDLS peer
|
||||
* @skip_self: skip self peer
|
||||
* @macaddr: MAC address of peer
|
||||
* @peer: pointer to the found peer
|
||||
*/
|
||||
struct tdls_search_progress_param {
|
||||
uint8_t skip_self;
|
||||
const uint8_t *macaddr;
|
||||
struct tdls_peer *peer;
|
||||
};
|
||||
|
||||
/**
|
||||
* tdls_get_peer() - find or add an TDLS peer in TDLS vdev object
|
||||
* @vdev_obj: TDLS vdev object
|
||||
* @macaddr: MAC address of peer
|
||||
*
|
||||
* Search the TDLS peer in the hash table and create a new one if not found.
|
||||
*
|
||||
* Return: Pointer to tdls_peer, NULL if failed.
|
||||
*/
|
||||
struct tdls_peer *tdls_get_peer(struct tdls_vdev_priv_obj *vdev_obj,
|
||||
const uint8_t *macaddr);
|
||||
|
||||
/**
|
||||
* tdls_find_peer() - find TDLS peer in TDLS vdev object
|
||||
* @vdev_obj: TDLS vdev object
|
||||
* @macaddr: MAC address of peer
|
||||
*
|
||||
* This is in scheduler thread context, no lock required.
|
||||
*
|
||||
* Return: If peer is found, then it returns pointer to tdls_peer;
|
||||
* otherwise, it returns NULL.
|
||||
*/
|
||||
struct tdls_peer *tdls_find_peer(struct tdls_vdev_priv_obj *vdev_obj,
|
||||
const uint8_t *macaddr);
|
||||
|
||||
/**
|
||||
* tdls_find_all_peer() - find peer matching the input MACaddr in soc range
|
||||
* @soc_obj: TDLS soc object
|
||||
* @macaddr: MAC address of TDLS peer
|
||||
*
|
||||
* This is in scheduler thread context, no lock required.
|
||||
*
|
||||
* Return: TDLS peer if a matching is detected; NULL otherwise
|
||||
*/
|
||||
struct tdls_peer *
|
||||
tdls_find_all_peer(struct tdls_soc_priv_obj *soc_obj, const uint8_t *macaddr);
|
||||
|
||||
/**
|
||||
* tdls_find_first_connected_peer() - find the 1st connected tdls peer from vdev
|
||||
* @vdev_obj: tdls vdev object
|
||||
*
|
||||
* This function searches for the 1st connected TDLS peer
|
||||
*
|
||||
* Return: The 1st connected TDLS peer if found; NULL otherwise
|
||||
*/
|
||||
struct tdls_peer *
|
||||
tdls_find_first_connected_peer(struct tdls_vdev_priv_obj *vdev_obj);
|
||||
|
||||
/**
|
||||
* tdls_is_progress() - find the peer with ongoing TDLS progress on present psoc
|
||||
* @vdev_obj: TDLS vdev object
|
||||
* @macaddr: MAC address of the peer
|
||||
* @skip_self: if 1, skip checking self. If 0, search include self
|
||||
*
|
||||
* This is used in scheduler thread context, no lock required.
|
||||
*
|
||||
* Return: TDLS peer if found; NULL otherwise
|
||||
*/
|
||||
struct tdls_peer *tdls_is_progress(struct tdls_vdev_priv_obj *vdev_obj,
|
||||
const uint8_t *macaddr, uint8_t skip_self);
|
||||
|
||||
/**
|
||||
* tdls_extract_peer_state_param() - extract peer update params from TDL peer
|
||||
* @peer_param: output peer update params
|
||||
* @peer: TDLS peer
|
||||
*
|
||||
* This is used when enable TDLS link
|
||||
*
|
||||
* Return: None.
|
||||
*/
|
||||
void tdls_extract_peer_state_param(struct tdls_peer_update_state *peer_param,
|
||||
struct tdls_peer *peer);
|
||||
|
||||
/**
|
||||
* tdls_set_link_status() - set link statue for TDLS peer
|
||||
* @peer: TDLS peer
|
||||
* @link_state: link state
|
||||
* @link_reason: reason with link status
|
||||
*
|
||||
* This is in scheduler thread context, no lock required.
|
||||
*
|
||||
* Return: None.
|
||||
*/
|
||||
void tdls_set_peer_link_status(struct tdls_peer *peer,
|
||||
enum tdls_link_state link_state,
|
||||
enum tdls_link_state_reason link_reason);
|
||||
|
||||
/**
|
||||
* tdls_set_peer_caps() - set capability for TDLS peer
|
||||
* @vdev_obj: TDLS vdev object
|
||||
* @macaddr: MAC address for the TDLS peer
|
||||
* @req_info: parameters to update peer capability
|
||||
*
|
||||
* This is in scheduler thread context, no lock required.
|
||||
*
|
||||
* Return: None.
|
||||
*/
|
||||
void tdls_set_peer_caps(struct tdls_vdev_priv_obj *vdev_obj,
|
||||
const uint8_t *macaddr,
|
||||
struct tdls_update_peer_params *req_info);
|
||||
|
||||
/**
|
||||
* tdls_set_sta_id() - set station ID on a TDLS peer
|
||||
* @vdev_obj: TDLS vdev object
|
||||
* @macaddr: MAC address of the TDLS peer
|
||||
* @sta_id: station ID
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS if success; other values if failed
|
||||
*/
|
||||
QDF_STATUS tdls_set_sta_id(struct tdls_vdev_priv_obj *vdev_obj,
|
||||
const uint8_t *macaddr, uint8_t sta_id);
|
||||
|
||||
/**
|
||||
* tdls_set_signature() - set TDLS peer's signature
|
||||
* @vdev_obj: TDLS vdev object
|
||||
* @macaddr: MAC address of the TDLS peer
|
||||
* @signature: signature value
|
||||
*
|
||||
* This is used in scheduler thread context, no lock required.
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS if success; other values if failed
|
||||
*/
|
||||
QDF_STATUS tdls_set_signature(struct tdls_vdev_priv_obj *vdev_obj,
|
||||
const uint8_t *macaddr, uint8_t signature);
|
||||
|
||||
/**
|
||||
* tdls_set_force_peer() - set/clear is_forced_peer flag on peer
|
||||
* @vdev_obj: TDLS vdev object
|
||||
* @macaddr: MAC address of TDLS peer
|
||||
* @forcepeer: value used to set is_forced_peer flag
|
||||
*
|
||||
* This is used in scheduler thread context, no lock required.
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS if success; other values if failed
|
||||
*/
|
||||
QDF_STATUS tdls_set_force_peer(struct tdls_vdev_priv_obj *vdev_obj,
|
||||
const uint8_t *macaddr, bool forcepeer);
|
||||
|
||||
/**
|
||||
* tdls_set_callback() - set state change callback on current TDLS peer
|
||||
* @peer: TDLS peer
|
||||
* @callback: state change callback
|
||||
*
|
||||
* This is used in scheduler thread context, no lock required.
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS if success; other values if failed
|
||||
*/
|
||||
QDF_STATUS tdls_set_callback(struct tdls_peer *peer,
|
||||
tdls_state_change_callback callback);
|
||||
|
||||
/**
|
||||
* tdls_set_extctrl_param() - set external control parameter on TDLS peer
|
||||
* @peer: TDLS peer
|
||||
* @chan: channel
|
||||
* @max_latency: maximum latency
|
||||
* @op_class: operation class
|
||||
* @min_bandwidth: minimal bandwidth
|
||||
*
|
||||
* This is used in scheduler thread context, no lock required.
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS if success; other values if failed
|
||||
*/
|
||||
QDF_STATUS tdls_set_extctrl_param(struct tdls_peer *peer, uint32_t chan,
|
||||
uint32_t max_latency, uint32_t op_class,
|
||||
uint32_t min_bandwidth);
|
||||
|
||||
/**
|
||||
* tdls_reset_peer() - reset TDLS peer identified by MAC address
|
||||
* @vdev_obj: TDLS vdev object
|
||||
* @mac: MAC address of the peer
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS if success; other values if failed
|
||||
*/
|
||||
QDF_STATUS tdls_reset_peer(struct tdls_vdev_priv_obj *vdev_obj,
|
||||
const uint8_t *mac);
|
||||
|
||||
/**
|
||||
* tdls_peer_idle_timers_destroy() - destroy peer idle timers
|
||||
* @vdev_obj: TDLS vdev object
|
||||
*
|
||||
* Loop through the idle peer list and destroy their timers
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void tdls_peer_idle_timers_destroy(struct tdls_vdev_priv_obj *vdev_obj);
|
||||
|
||||
/**
|
||||
* tdls_free_peer_list() - free TDLS peer list
|
||||
* @vdev_obj: TDLS vdev object
|
||||
*
|
||||
* Free all the tdls peers
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void tdls_free_peer_list(struct tdls_vdev_priv_obj *vdev_obj);
|
||||
#endif
|
||||
|
|
@ -30,15 +30,36 @@
|
|||
#include <wlan_cmn.h>
|
||||
#include <wlan_cmn_ieee80211.h>
|
||||
|
||||
#define WLAN_TDLS_STA_MAX_NUM 8
|
||||
#define WLAN_TDLS_PEER_LIST_SIZE 256
|
||||
#define WLAN_TDLS_CT_TABLE_SIZE 8
|
||||
#define WLAN_TDLS_PEER_SUB_LIST_SIZE 10
|
||||
#define WLAN_MAC_MAX_EXTN_CAP 8
|
||||
#define WLAN_MAC_MAX_SUPP_CHANNELS 100
|
||||
#define WLAN_MAX_SUPP_OPER_CLASSES 32
|
||||
#define WLAN_MAC_MAX_SUPP_RATES 32
|
||||
#define ENABLE_CHANSWITCH 1
|
||||
#define WLAN_TDLS_STA_MAX_NUM 8
|
||||
#define WLAN_TDLS_STA_P_UAPSD_OFFCHAN_MAX_NUM 1
|
||||
#define WLAN_TDLS_PEER_LIST_SIZE 16
|
||||
#define WLAN_TDLS_CT_TABLE_SIZE 8
|
||||
#define WLAN_TDLS_PEER_SUB_LIST_SIZE 10
|
||||
#define WLAN_MAC_MAX_EXTN_CAP 8
|
||||
#define WLAN_MAC_MAX_SUPP_CHANNELS 100
|
||||
#define WLAN_MAX_SUPP_OPER_CLASSES 32
|
||||
#define WLAN_MAC_MAX_SUPP_RATES 32
|
||||
#define WLAN_CHANNEL_14 14
|
||||
#define ENABLE_CHANSWITCH 1
|
||||
#define DISABLE_CHANSWITCH 2
|
||||
#define WLAN_TDLS_PREFERRED_OFF_CHANNEL_NUM_MIN 1
|
||||
#define WLAN_TDLS_PREFERRED_OFF_CHANNEL_NUM_MAX 165
|
||||
#define WLAN_TDLS_PREFERRED_OFF_CHANNEL_NUM_DEF 36
|
||||
|
||||
/** Maximum time(ms) to wait for tdls add sta to complete **/
|
||||
#define WAIT_TIME_TDLS_ADD_STA 1500
|
||||
|
||||
/** Maximum time(ms) to wait for tdls del sta to complete **/
|
||||
#define WAIT_TIME_TDLS_DEL_STA 1500
|
||||
|
||||
/** Maximum time(ms) to wait for Link Establish Req to complete **/
|
||||
#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 TDLS_TEARDOWN_PEER_UNREACHABLE 25
|
||||
#define TDLS_TEARDOWN_PEER_UNSPEC_REASON 26
|
||||
|
||||
#define TDLS_STA_INDEX_CHECK(sta_id) \
|
||||
(((sta_id) >= 1) && ((sta_id) < 0xFF))
|
||||
|
|
@ -65,7 +86,23 @@ enum tdls_peer_capab {
|
|||
};
|
||||
|
||||
/**
|
||||
* enum tdls_link_status - tdls link status
|
||||
* enum tdls_peer_state - tdls peer state
|
||||
* @TDLS_PEER_STATE_PEERING: tdls connection in progress
|
||||
* @TDLS_PEER_STATE_CONNCTED: tdls peer is connected
|
||||
* @TDLS_PEER_STATE_TEARDOWN: tdls peer is tear down
|
||||
* @TDLS_PEER_ADD_MAC_ADDR: add peer mac into connection table
|
||||
* @TDLS_PEER_REMOVE_MAC_ADDR: remove peer mac from connection table
|
||||
*/
|
||||
enum tdls_peer_state {
|
||||
TDLS_PEER_STATE_PEERING,
|
||||
TDLS_PEER_STATE_CONNCTED,
|
||||
TDLS_PEER_STATE_TEARDOWN,
|
||||
TDLS_PEER_ADD_MAC_ADDR,
|
||||
TDLS_PEER_REMOVE_MAC_ADDR
|
||||
};
|
||||
|
||||
/**
|
||||
* enum tdls_link_state - tdls link state
|
||||
* @TDLS_LINK_IDLE: tdls link idle
|
||||
* @TDLS_LINK_DISCOVERING: tdls link discovering
|
||||
* @TDLS_LINK_DISCOVERED: tdls link discovered
|
||||
|
|
@ -73,7 +110,7 @@ enum tdls_peer_capab {
|
|||
* @TDLS_LINK_CONNECTED: tdls link connected
|
||||
* @TDLS_LINK_TEARING: tdls link tearing
|
||||
*/
|
||||
enum tdls_link_status {
|
||||
enum tdls_link_state {
|
||||
TDLS_LINK_IDLE = 0,
|
||||
TDLS_LINK_DISCOVERING,
|
||||
TDLS_LINK_DISCOVERED,
|
||||
|
|
@ -83,7 +120,7 @@ enum tdls_link_status {
|
|||
};
|
||||
|
||||
/**
|
||||
* enum tdls_link_reason - tdls link reason
|
||||
* enum tdls_link_state_reason - tdls link reason
|
||||
* @TDLS_LINK_SUCCESS: Success
|
||||
* @TDLS_LINK_UNSPECIFIED: Unspecified reason
|
||||
* @TDLS_LINK_NOT_SUPPORTED: Remote side doesn't support TDLS
|
||||
|
|
@ -91,7 +128,7 @@ enum tdls_link_status {
|
|||
* @TDLS_LINK_NOT_BENEFICIAL: Going to AP is better than direct
|
||||
* @TDLS_LINK_DROPPED_BY_REMOTE: Remote side doesn't want it anymore
|
||||
*/
|
||||
enum tdls_link_reason {
|
||||
enum tdls_link_state_reason {
|
||||
TDLS_LINK_SUCCESS,
|
||||
TDLS_LINK_UNSPECIFIED = -1,
|
||||
TDLS_LINK_NOT_SUPPORTED = -2,
|
||||
|
|
@ -101,7 +138,7 @@ enum tdls_link_reason {
|
|||
};
|
||||
|
||||
/**
|
||||
* enum tdls_support_mode - TDLS support mode
|
||||
* enum tdls_feature_mode - TDLS support mode
|
||||
* @TDLS_SUPPORT_DISABLED: Disabled in ini or FW
|
||||
* @TDLS_SUPPORT_SUSPENDED: TDLS supported by ini and FW, but disabled
|
||||
* temporarily due to off-channel operations or due to other reasons
|
||||
|
|
@ -109,7 +146,7 @@ enum tdls_link_reason {
|
|||
* @TDLS_SUPPORT_IMP_MODE: Implicit mode
|
||||
* @TDLS_SUPPORT_EXT_CONTROL: External control mode
|
||||
*/
|
||||
enum tdls_support_mode {
|
||||
enum tdls_feature_mode {
|
||||
TDLS_SUPPORT_DISABLED = 0,
|
||||
TDLS_SUPPORT_SUSPENDED,
|
||||
TDLS_SUPPORT_EXP_TRIG_ONLY,
|
||||
|
|
@ -124,6 +161,9 @@ enum tdls_support_mode {
|
|||
* @TDLS_EVENT_RX_MGMT: rx discovery response frame
|
||||
* @TDLS_EVENT_ADD_PEER: add peer or update peer
|
||||
* @TDLS_EVENT_DEL_PEER: delete peer
|
||||
* @TDLS_EVENT_DISCOVERY_REQ: dicovery request
|
||||
* @TDLS_EVENT_TEARDOWN_REQ: teardown request
|
||||
* @TDLS_EVENT_SETUP_REQ: setup request
|
||||
*/
|
||||
enum tdls_event_type {
|
||||
TDLS_EVENT_VDEV_STATE_CHANGE = 0,
|
||||
|
|
@ -131,11 +171,13 @@ enum tdls_event_type {
|
|||
TDLS_EVENT_RX_MGMT,
|
||||
TDLS_EVENT_ADD_PEER,
|
||||
TDLS_EVENT_DEL_PEER,
|
||||
TDLS_EVENT_DISCOVERY_REQ,
|
||||
TDLS_EVENT_TEARDOWN_REQ,
|
||||
TDLS_EVENT_SETUP_REQ,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum tdls_state_t - tdls state
|
||||
*
|
||||
* @QCA_WIFI_HAL_TDLS_DISABLED: TDLS is not enabled, or is disabled now
|
||||
* @QCA_WIFI_HAL_TDLS_ENABLED: TDLS is enabled, but not yet tried
|
||||
* @QCA_WIFI_HAL_TDLS_ESTABLISHED: Direct link is established
|
||||
|
|
@ -152,12 +194,25 @@ enum tdls_state_t {
|
|||
QCA_WIFI_HAL_TDLS_S_FAILED,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum tdls_off_chan_mode - mode for WMI_TDLS_SET_OFFCHAN_MODE_CMDID
|
||||
* @TDLS_ENABLE_OFFCHANNEL: enable off channel
|
||||
* @TDLS_DISABLE_OFFCHANNEL: disable off channel
|
||||
*/
|
||||
enum tdls_off_chan_mode {
|
||||
TDLS_ENABLE_OFFCHANNEL,
|
||||
TDLS_DISABLE_OFFCHANNEL
|
||||
};
|
||||
|
||||
/**
|
||||
* enum tdls_event_msg_type - TDLS event message type
|
||||
* @TDLS_SHOULD_DISCOVER: should do discover
|
||||
* @TDLS_SHOULD_TEARDOWN: notify teardown the link
|
||||
* @TDLS_SHOULD_DISCOVER: should do discover for peer (based on tx bytes per
|
||||
* second > tx_discover threshold)
|
||||
* @TDLS_SHOULD_TEARDOWN: recommend teardown the link for peer due to tx bytes
|
||||
* per second below tx_teardown_threshold
|
||||
* @TDLS_PEER_DISCONNECTED: tdls peer disconnected
|
||||
* @TDLS_CONNECTION_TRACKER_NOTIFY: connection tracker notify
|
||||
* @TDLS_CONNECTION_TRACKER_NOTIFY: TDLS/BT role change notification for
|
||||
* connection tracker
|
||||
*/
|
||||
enum tdls_event_msg_type {
|
||||
TDLS_SHOULD_DISCOVER = 0,
|
||||
|
|
@ -168,19 +223,25 @@ enum tdls_event_msg_type {
|
|||
|
||||
/**
|
||||
* enum tdls_event_reason - TDLS event reason
|
||||
* @TDLS_TEARDOWN_TX:
|
||||
* @TDLS_TEARDOWN_RSSI:
|
||||
* @TDLS_TEARDOWN_SCAN:
|
||||
* @TDLS_TEARDOWN_PTR_TIMEOUT:
|
||||
* @TDLS_TEARDOWN_BAD_PTR:
|
||||
* @TDLS_TEARDOWN_NO_RSP:
|
||||
* @TDLS_DISCONNECTED_PEER_DELETE:
|
||||
* @TDLS_PEER_ENTER_BUF_STA:
|
||||
* @TDLS_PEER_EXIT_BUF_STA:
|
||||
* @TDLS_ENTER_BT_BUSY:
|
||||
* @TDLS_EXIT_BT_BUSY:
|
||||
* @DLS_SCAN_STARTED:
|
||||
* @TDLS_SCAN_COMPLETED:
|
||||
* @TDLS_TEARDOWN_TX: tdls teardown recommended due to low transmits
|
||||
* @TDLS_TEARDOWN_RSSI: tdls link tear down recommended due to poor RSSI
|
||||
* @TDLS_TEARDOWN_SCAN: tdls link tear down recommended due to offchannel scan
|
||||
* @TDLS_TEARDOWN_PTR_TIMEOUT: tdls peer disconnected due to PTR timeout
|
||||
* @TDLS_TEARDOWN_BAD_PTR: tdls peer disconnected due wrong PTR format
|
||||
* @TDLS_TEARDOWN_NO_RSP: tdls peer not responding
|
||||
* @TDLS_DISCONNECTED_PEER_DELETE: tdls peer disconnected due to peer deletion
|
||||
* @TDLS_PEER_ENTER_BUF_STA: tdls entered buffer STA role, TDLS connection
|
||||
* tracker needs to handle this
|
||||
* @TDLS_PEER_EXIT_BUF_STA: tdls exited buffer STA role, TDLS connection tracker
|
||||
* needs to handle this
|
||||
* @TDLS_ENTER_BT_BUSY: BT entered busy mode, TDLS connection tracker needs to
|
||||
* handle this
|
||||
* @TDLS_EXIT_BT_BUSY: BT exited busy mode, TDLS connection tracker needs to
|
||||
* handle this
|
||||
* @DLS_SCAN_STARTED: TDLS module received a scan start event, TDLS connection
|
||||
* tracker needs to handle this
|
||||
* @TDLS_SCAN_COMPLETED: TDLS module received a scan complete event, TDLS
|
||||
* connection tracker needs to handle this
|
||||
*/
|
||||
enum tdls_event_reason {
|
||||
TDLS_TEARDOWN_TX,
|
||||
|
|
@ -198,6 +259,19 @@ enum tdls_event_reason {
|
|||
TDLS_SCAN_COMPLETED,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct tdls_osif_indication - tdls indication to os if layer
|
||||
* @vdev: vdev object
|
||||
* @reason: used with teardown indication
|
||||
* @peer_mac: MAC address of the TDLS peer
|
||||
*/
|
||||
struct tdls_osif_indication {
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
uint16_t reason;
|
||||
uint8_t peer_mac[QDF_MAC_ADDR_SIZE];
|
||||
QDF_STATUS status;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct tx_frame - tx frame
|
||||
* @buf: frame buffer
|
||||
|
|
@ -268,13 +342,14 @@ enum tdls_feature_bit {
|
|||
* @tdls_pre_off_chan_num: tdls off channel number
|
||||
* @tdls_pre_off_chan_bw: tdls off channel bandwidth
|
||||
* @tdls_peer_kickout_threshold: sta kickout threshold for tdls peer
|
||||
* @delayed_trig_framint: delayed trigger frame interval
|
||||
*/
|
||||
struct tdls_user_config {
|
||||
uint32_t tdls_tx_states_period;
|
||||
uint32_t tdls_tx_pkt_threshold;
|
||||
uint32_t tdls_rx_pkt_threshold;
|
||||
uint32_t tdls_max_discovery_attempt;
|
||||
uint32_t tdls_idle_timeoute;
|
||||
uint32_t tdls_idle_timeout;
|
||||
uint32_t tdls_idle_pkt_threshold;
|
||||
uint32_t tdls_rssi_trigger_threshold;
|
||||
uint32_t tdls_rssi_teardown_threshold;
|
||||
|
|
@ -287,6 +362,7 @@ struct tdls_user_config {
|
|||
uint32_t tdls_pre_off_chan_num;
|
||||
uint32_t tdls_pre_off_chan_bw;
|
||||
uint32_t tdls_peer_kickout_threshold;
|
||||
uint32_t delayed_trig_framint;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -331,32 +407,60 @@ struct tdls_tx_cnf {
|
|||
|
||||
/* This callback is used to report state change of peer to wpa_supplicant */
|
||||
typedef int (*tdls_state_change_callback)(const uint8_t *mac,
|
||||
uint32_t opclass,
|
||||
uint32_t channel,
|
||||
uint32_t state,
|
||||
int32_t reason, void *ctx);
|
||||
uint32_t opclass,
|
||||
uint32_t channel,
|
||||
uint32_t state,
|
||||
int32_t reason, void *ctx);
|
||||
|
||||
/* This callback is used to report events to os_if layer */
|
||||
typedef QDF_STATUS (*tdls_evt_callback) (void *data,
|
||||
enum tdls_event_type ev_type,
|
||||
void *event);
|
||||
typedef void (*tdls_evt_callback) (void *data,
|
||||
enum tdls_event_type ev_type,
|
||||
struct tdls_osif_indication *event);
|
||||
|
||||
/* prototype of callback registered by hdd to receive the ack cnf */
|
||||
typedef int (*tdls_tx_ack_cnf_callback)(void *user_data,
|
||||
struct tdls_tx_cnf *tx_ack_cnf_cb_data);
|
||||
struct tdls_tx_cnf *tx_ack_cnf_cb_data);
|
||||
|
||||
/* This callback is used to register TDLS peer with TL */
|
||||
typedef QDF_STATUS (*tdls_register_tl_peer_callback)(void *userdata,
|
||||
uint32_t vdev_id,
|
||||
const uint8_t *mac,
|
||||
uint16_t stat_id,
|
||||
uint8_t ucastsig,
|
||||
uint8_t qos);
|
||||
|
||||
/* This callback is used to deregister TDLS peer */
|
||||
typedef QDF_STATUS (*tdls_deregister_tl_peer_callback)(void *userdata,
|
||||
uint32_t vdev_id,
|
||||
uint8_t sta_id);
|
||||
/**
|
||||
* struct tdls_start_params - tdls start params
|
||||
* @config: tdls user config
|
||||
* @tdls_send_mgmt_req: pass eWNI_SME_TDLS_SEND_MGMT_REQ value
|
||||
* @tdls_add_sta_req: pass eWNI_SME_TDLS_ADD_STA_REQ value
|
||||
* @tdls_del_sta_req: pass eWNI_SME_TDLS_DEL_STA_REQ value
|
||||
* @tdls_update_peer_state: pass WMA_UPDATE_TDLS_PEER_STATE value
|
||||
* @tdls_event_cb: tdls event callback
|
||||
* @tdls_evt_cb_data: tdls event data
|
||||
* @ack_cnf_cb: tdls tx ack callback to indicate the tx status
|
||||
* @tx_ack_cnf_cb_data: tdls tx ack user data
|
||||
* @tdls_reg_tl_peer: tdls register tdls peer
|
||||
* @tdls_dereg_tl_peer: tdls deregister tdls peer
|
||||
* @tdls_tl_peer_data: userdata for register/deregister TDLS peer
|
||||
*/
|
||||
struct tdls_start_params {
|
||||
struct tdls_user_config config;
|
||||
uint16_t tdls_send_mgmt_req;
|
||||
uint16_t tdls_add_sta_req;
|
||||
uint16_t tdls_del_sta_req;
|
||||
uint16_t tdls_update_peer_state;
|
||||
tdls_evt_callback tdls_event_cb;
|
||||
void *tdls_evt_cb_data;
|
||||
tdls_tx_ack_cnf_callback ack_cnf_cb;
|
||||
void *tx_ack_cnf_cb_data;
|
||||
tdls_register_tl_peer_callback tdls_reg_tl_peer;
|
||||
tdls_deregister_tl_peer_callback tdls_dereg_tl_peer;
|
||||
void *tdls_tl_peer_data;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -366,7 +470,7 @@ struct tdls_start_params {
|
|||
* @vdev_id: vdev id
|
||||
*/
|
||||
struct tdls_add_peer_params {
|
||||
const uint8_t *peer_addr;
|
||||
uint8_t peer_addr[QDF_MAC_ADDR_SIZE];
|
||||
uint32_t peer_type;
|
||||
uint32_t vdev_id;
|
||||
};
|
||||
|
|
@ -437,7 +541,7 @@ struct vhtcap {
|
|||
};
|
||||
|
||||
struct tdls_update_peer_params {
|
||||
const uint8_t *peer_addr;
|
||||
uint8_t peer_addr[QDF_MAC_ADDR_SIZE];
|
||||
uint32_t peer_type;
|
||||
uint32_t vdev_id;
|
||||
uint16_t capability;
|
||||
|
|
@ -454,6 +558,7 @@ struct tdls_update_peer_params {
|
|||
uint8_t supported_channels[WLAN_MAC_MAX_SUPP_CHANNELS];
|
||||
uint8_t supported_oper_classes_len;
|
||||
uint8_t supported_oper_classes[WLAN_MAX_SUPP_OPER_CLASSES];
|
||||
bool is_qos_wmm_sta;
|
||||
};
|
||||
|
||||
struct tdls_update_peer_request {
|
||||
|
|
@ -461,6 +566,36 @@ struct tdls_update_peer_request {
|
|||
struct tdls_update_peer_params update_peer_req;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct tdls_oper_request - tdls operation request
|
||||
* @vdev: vdev object
|
||||
* @peer_addr: MAC address of the TDLS peer
|
||||
*/
|
||||
struct tdls_oper_request {
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
uint8_t peer_addr[QDF_MAC_ADDR_SIZE];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct tdls_oper_config_force_peer_request - tdls enable force peer request
|
||||
* @vdev: vdev object
|
||||
* @peer_addr: MAC address of the TDLS peer
|
||||
* @chan: channel
|
||||
* @max_latency: maximum latency
|
||||
* @op_class: operation class
|
||||
* @min_bandwidth: minimal bandwidth
|
||||
* @callback: state change callback
|
||||
*/
|
||||
struct tdls_oper_config_force_peer_request {
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
uint8_t peer_addr[QDF_MAC_ADDR_SIZE];
|
||||
uint32_t chan;
|
||||
uint32_t max_latency;
|
||||
uint32_t op_class;
|
||||
uint32_t min_bandwidth;
|
||||
tdls_state_change_callback callback;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct tdls_info - tdls info
|
||||
*
|
||||
|
|
@ -550,20 +685,22 @@ struct tdls_peer_params {
|
|||
};
|
||||
|
||||
/**
|
||||
* struct tdls_peer_update_params - TDLS peer state parameters
|
||||
* struct tdls_peer_update_state - TDLS peer state parameters
|
||||
* @vdev_id: vdev id
|
||||
* @peer_macaddr: peer mac address
|
||||
* @peer_cap: peer capabality
|
||||
* @resp_reqd: response needed
|
||||
*/
|
||||
struct tdls_peer_update_params {
|
||||
struct tdls_peer_update_state {
|
||||
uint32_t vdev_id;
|
||||
uint8_t peer_macaddr[QDF_MAC_ADDR_SIZE];
|
||||
uint32_t peer_state;
|
||||
struct tdls_peer_params peer_cap;
|
||||
bool resp_reqd;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct tdls_chan_switch_params - channel switch parameter structure
|
||||
* struct tdls_channel_switch_params - channel switch parameter structure
|
||||
* @vdev_id: vdev ID
|
||||
* @peer_mac_addr: Peer mac address
|
||||
* @tdls_off_ch_bw_offset: Target off-channel bandwitdh offset
|
||||
|
|
@ -571,7 +708,7 @@ struct tdls_peer_update_params {
|
|||
* @oper_class: Operating class for target channel
|
||||
* @is_responder: Responder or initiator
|
||||
*/
|
||||
struct tdls_chan_switch_params {
|
||||
struct tdls_channel_switch_params {
|
||||
uint32_t vdev_id;
|
||||
uint8_t peer_mac_addr[QDF_MAC_ADDR_SIZE];
|
||||
uint16_t tdls_off_ch_bw_offset;
|
||||
|
|
|
|||
|
|
@ -28,6 +28,9 @@
|
|||
#include <scheduler_api.h>
|
||||
#include <wlan_tdls_public_structs.h>
|
||||
#include <wlan_objmgr_cmn.h>
|
||||
#include <wlan_objmgr_psoc_obj.h>
|
||||
#include <wlan_objmgr_pdev_obj.h>
|
||||
#include <wlan_objmgr_vdev_obj.h>
|
||||
|
||||
/**
|
||||
* ucfg_tdls_init() - TDLS module initialization API
|
||||
|
|
@ -66,8 +69,9 @@ QDF_STATUS ucfg_tdls_psoc_close(struct wlan_objmgr_psoc *psoc);
|
|||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS ucfg_tdls_psoc_start(struct wlan_objmgr_psoc *psoc,
|
||||
struct tdls_start_params *req);
|
||||
QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc,
|
||||
struct tdls_start_params *req);
|
||||
|
||||
/**
|
||||
* ucfg_tdls_psoc_stop() - TDLS module stop
|
||||
* @psoc: psoc object
|
||||
|
|
@ -75,4 +79,24 @@ QDF_STATUS ucfg_tdls_psoc_start(struct wlan_objmgr_psoc *psoc,
|
|||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS ucfg_tdls_psoc_stop(struct wlan_objmgr_psoc *psoc);
|
||||
|
||||
/**
|
||||
* ucfg_tdls_add_peer() - handle TDLS add peer
|
||||
* @vdev: vdev object
|
||||
* @add_peer_req: add peer request parameters
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS ucfg_tdls_add_peer(struct wlan_objmgr_vdev *vdev,
|
||||
struct tdls_add_peer_params *add_peer_req);
|
||||
|
||||
/**
|
||||
* ucfg_tdls_update_peer() - handle TDLS update peer
|
||||
* @vdev: vdev object
|
||||
* @update_peer: update TDLS request parameters
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS ucfg_tdls_update_peer(struct wlan_objmgr_vdev *vdev,
|
||||
struct tdls_update_peer_params *update_peer);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include <wlan_tdls_ucfg_api.h>
|
||||
#include "../../core/src/wlan_tdls_main.h"
|
||||
#include "../../core/src/wlan_tdls_cmds_process.h"
|
||||
#include <wlan_objmgr_global_obj.h>
|
||||
#include <wlan_objmgr_cmn.h>
|
||||
|
||||
|
|
@ -113,6 +114,7 @@ QDF_STATUS ucfg_tdls_deinit(void)
|
|||
static QDF_STATUS tdls_global_init(struct tdls_soc_priv_obj *soc_obj)
|
||||
{
|
||||
uint8_t sta_idx;
|
||||
uint32_t feature;
|
||||
|
||||
soc_obj->connected_peer_count = 0;
|
||||
soc_obj->tdls_nss_switch_in_progress = false;
|
||||
|
|
@ -120,7 +122,16 @@ static QDF_STATUS tdls_global_init(struct tdls_soc_priv_obj *soc_obj)
|
|||
soc_obj->tdls_nss_teardown_complete = false;
|
||||
soc_obj->tdls_nss_transition_mode = TDLS_NSS_TRANSITION_S_UNKNOWN;
|
||||
soc_obj->tdls_user_config_mode = TDLS_SUPPORT_DISABLED;
|
||||
soc_obj->max_num_tdls_sta = WLAN_TDLS_STA_MAX_NUM;
|
||||
|
||||
feature = soc_obj->tdls_configs.tdls_feature_flags;
|
||||
if (TDLS_IS_BUFFER_STA_ENABLED(feature) ||
|
||||
TDLS_IS_SLEEP_STA_ENABLED(feature) ||
|
||||
TDLS_IS_OFF_CHANNEL_ENABLED(feature))
|
||||
soc_obj->max_num_tdls_sta =
|
||||
WLAN_TDLS_STA_P_UAPSD_OFFCHAN_MAX_NUM;
|
||||
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;
|
||||
|
|
@ -142,7 +153,7 @@ QDF_STATUS ucfg_tdls_psoc_open(struct wlan_objmgr_psoc *psoc)
|
|||
tdls_notice("tdls psoc open");
|
||||
soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
|
||||
WLAN_UMAC_COMP_TDLS);
|
||||
if (soc_obj == NULL) {
|
||||
if (!soc_obj) {
|
||||
tdls_err("Failed to get tdls psoc component");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
|
@ -152,15 +163,21 @@ QDF_STATUS ucfg_tdls_psoc_open(struct wlan_objmgr_psoc *psoc)
|
|||
return status;
|
||||
}
|
||||
|
||||
QDF_STATUS ucfg_tdls_psoc_start(struct wlan_objmgr_psoc *psoc,
|
||||
struct tdls_start_params *req)
|
||||
QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc,
|
||||
struct tdls_start_params *req)
|
||||
{
|
||||
struct tdls_soc_priv_obj *soc_obj;
|
||||
uint32_t tdls_feature_flags;
|
||||
|
||||
tdls_notice("tdls update config ");
|
||||
if (!psoc || !req) {
|
||||
tdls_err("psoc: 0x%p, req: 0x%p", psoc, req);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
tdls_notice("tdls psoc start");
|
||||
soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
|
||||
WLAN_UMAC_COMP_TDLS);
|
||||
if (soc_obj == NULL) {
|
||||
if (!soc_obj) {
|
||||
tdls_err("Failed to get tdls psoc component");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
|
@ -171,6 +188,28 @@ QDF_STATUS ucfg_tdls_psoc_start(struct wlan_objmgr_psoc *psoc,
|
|||
soc_obj->tdls_tx_cnf_cb = req->ack_cnf_cb;
|
||||
soc_obj->tx_ack_cnf_cb_data = req->tx_ack_cnf_cb_data;
|
||||
|
||||
/* Save callbacks to register/deregister TDLS sta with TL */
|
||||
soc_obj->tdls_reg_tl_peer = req->tdls_reg_tl_peer;
|
||||
soc_obj->tdls_dereg_tl_peer = req->tdls_dereg_tl_peer;
|
||||
soc_obj->tdls_tl_peer_data = req->tdls_tl_peer_data;
|
||||
|
||||
/* Save legacy PE/WMA commands in TDLS soc object */
|
||||
soc_obj->tdls_send_mgmt_req = req->tdls_send_mgmt_req;
|
||||
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;
|
||||
|
||||
/* Update TDLS user config */
|
||||
qdf_mem_copy(&soc_obj->tdls_configs, &req->config, sizeof(req->config));
|
||||
tdls_feature_flags = soc_obj->tdls_configs.tdls_feature_flags;
|
||||
|
||||
if (!TDLS_IS_IMPLICIT_TRIG_ENABLED(tdls_feature_flags))
|
||||
soc_obj->tdls_current_mode = TDLS_SUPPORT_EXP_TRIG_ONLY;
|
||||
else if (TDLS_IS_EXTERNAL_CONTROL_ENABLED(tdls_feature_flags))
|
||||
soc_obj->tdls_current_mode = TDLS_SUPPORT_EXT_CONTROL;
|
||||
else
|
||||
soc_obj->tdls_current_mode = TDLS_SUPPORT_IMP_MODE;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -181,7 +220,7 @@ QDF_STATUS ucfg_tdls_psoc_stop(struct wlan_objmgr_psoc *psoc)
|
|||
tdls_notice("tdls psoc stop");
|
||||
soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
|
||||
WLAN_UMAC_COMP_TDLS);
|
||||
if (soc_obj == NULL) {
|
||||
if (!soc_obj) {
|
||||
tdls_err("Failed to get tdls psoc component");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
|
@ -203,3 +242,93 @@ QDF_STATUS ucfg_tdls_psoc_close(struct wlan_objmgr_psoc *psoc)
|
|||
|
||||
return status;
|
||||
}
|
||||
|
||||
QDF_STATUS ucfg_tdls_add_peer(struct wlan_objmgr_vdev *vdev,
|
||||
struct tdls_add_peer_params *add_peer_req)
|
||||
{
|
||||
struct scheduler_msg msg = {0, };
|
||||
struct tdls_add_peer_request *req;
|
||||
QDF_STATUS status;
|
||||
|
||||
if (!vdev || !add_peer_req) {
|
||||
tdls_err("vdev: %p, req %p", vdev, add_peer_req);
|
||||
return QDF_STATUS_E_NULL_VALUE;
|
||||
}
|
||||
tdls_debug("vdevid: %d, peertype: %d",
|
||||
add_peer_req->vdev_id, add_peer_req->peer_type);
|
||||
|
||||
status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
tdls_err("can't get vdev");
|
||||
return status;
|
||||
}
|
||||
|
||||
req = qdf_mem_malloc(sizeof(*req));
|
||||
if (!req) {
|
||||
tdls_err("mem allocate fail");
|
||||
status = QDF_STATUS_E_NOMEM;
|
||||
goto dec_ref;
|
||||
}
|
||||
|
||||
qdf_mem_copy(&req->add_peer_req, add_peer_req, sizeof(*add_peer_req));
|
||||
req->vdev = vdev;
|
||||
|
||||
msg.bodyptr = req;
|
||||
msg.callback = tdls_process_cmd;
|
||||
msg.type = TDLS_CMD_ADD_STA;
|
||||
status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
tdls_err("post add peer msg fail");
|
||||
qdf_mem_free(req);
|
||||
goto dec_ref;
|
||||
}
|
||||
|
||||
return status;
|
||||
dec_ref:
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
|
||||
return status;
|
||||
}
|
||||
|
||||
QDF_STATUS ucfg_tdls_update_peer(struct wlan_objmgr_vdev *vdev,
|
||||
struct tdls_update_peer_params *update_peer)
|
||||
{
|
||||
struct scheduler_msg msg = {0,};
|
||||
struct tdls_update_peer_request *req;
|
||||
QDF_STATUS status;
|
||||
|
||||
if (!vdev || !update_peer) {
|
||||
tdls_err("vdev: %p, update_peer: %p", vdev, update_peer);
|
||||
return QDF_STATUS_E_NULL_VALUE;
|
||||
}
|
||||
|
||||
tdls_debug("vdev_id: %d, peertype: %d",
|
||||
update_peer->vdev_id, update_peer->peer_type);
|
||||
status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
tdls_err("can't get vdev");
|
||||
return status;
|
||||
}
|
||||
req = qdf_mem_malloc(sizeof(*req));
|
||||
if (!req) {
|
||||
tdls_err("mem allocate fail");
|
||||
status = QDF_STATUS_E_NOMEM;
|
||||
goto dec_ref;
|
||||
}
|
||||
qdf_mem_copy(&req->update_peer_req, update_peer, sizeof(*update_peer));
|
||||
req->vdev = vdev;
|
||||
|
||||
msg.bodyptr = req;
|
||||
msg.callback = tdls_process_cmd;
|
||||
msg.type = TDLS_CMD_CHANGE_STA;
|
||||
status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
tdls_err("post update peer msg fail");
|
||||
qdf_mem_free(req);
|
||||
goto dec_ref;
|
||||
}
|
||||
|
||||
return status;
|
||||
dec_ref:
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
|
||||
return status;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue