Move umac/tdls to components/tdls

Change-Id: I12eedee6215337be7f5dbcf6d546910cecedd3c3
This commit is contained in:
Linux Build Service Account
2018-12-04 15:47:36 +05:30
commit 4ed08e812b
21 changed files with 12925 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,420 @@
/*
* Copyright (c) 2017-2018 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_cmds_process.h
*
* TDLS north bound commands include file
*/
#ifndef _WLAN_TDLS_CMDS_PROCESS_H_
#define _WLAN_TDLS_CMDS_PROCESS_H_
#define TDLS_IS_SETUP_ACTION(action) \
((TDLS_SETUP_REQUEST <= action) && \
(TDLS_SETUP_CONFIRM >= action))
/**
* enum legacy_result_code - defined to comply with tSirResultCodes, need refine
* when mlme converged.
* @legacy_result_success: success
* @legacy_result_max: max result value
*/
enum legacy_result_code {
legacy_result_success,
legacy_result_max = 0x7FFFFFFF
};
/**
* struct tdls_send_mgmt_rsp - TDLS Response struct PE --> TDLS module
* same as struct tSirSmeRsp
* @message_type: message type eWNI_SME_TDLS_SEND_MGMT_RSP
* @length: message length
* @session_id: session id
* @transaction_id: transaction id
* @status_code: status code as tSirResultCodes
* @psoc: soc object
*/
struct tdls_send_mgmt_rsp {
uint16_t message_type;
uint16_t length;
uint8_t session_id;
uint16_t transaction_id;
enum legacy_result_code status_code;
struct wlan_objmgr_psoc *psoc;
};
/**
* struct tdls_mgmt_tx_completion_ind - TDLS TX completion PE --> TDLS module
* same as struct sSirMgmtTxCompletionInd
* @message_type: message type eWNI_SME_MGMT_FRM_TX_COMPLETION_IND
* @length: message length
* @session_id: session id
* @tx_complete_status: tx complete status
* @psoc: soc object
*/
struct tdls_mgmt_tx_completion_ind {
uint16_t message_type;
uint16_t length;
uint8_t session_id; /* Session ID */
uint32_t tx_complete_status;
struct wlan_objmgr_psoc *psoc;
};
/**
* struct tdls_add_sta_req - TDLS request struct TDLS module --> PE
* same as struct tSirTdlsAddStaReq;
* @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
* @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;
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_enable_link() - enable TDLS link
* @req: TDLS enable link request
*
* Return: QDF_STATUS_SUCCESS if success; other value if failed
*/
QDF_STATUS tdls_process_enable_link(struct tdls_oper_request *req);
/**
* tdls_process_setup_peer() - process configure an externally
* controllable TDLS peer
* @req: TDLS configure force peer request
*
* Return: QDF_STATUS_SUCCESS if success; other values if failed
*/
QDF_STATUS tdls_process_setup_peer(struct tdls_oper_request *req);
/**
* tdls_process_remove_force_peer() - process remove an externally controllable
* TDLS peer
* @req: TDLS operation request
*
* Return: QDF_STATUS_SUCCESS if success; other values if failed
*/
QDF_STATUS tdls_process_remove_force_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_process_antenna_switch() - handle TDLS antenna switch
* @req: TDLS antenna switch request
*
* Rely on callback to indicate the antenna switch state to caller.
*
* Return: QDF_STATUS_SUCCESS if success; other value if failed.
*/
QDF_STATUS tdls_process_antenna_switch(struct tdls_antenna_switch_request *req);
/**
* tdls_antenna_switch_flush_callback() - flush TDLS antenna switch request
* @msg: scheduler message contains tdls antenna switch event
*
* This function call is invoked when scheduler thread is going down
*
* Return: QDF_STATUS
*/
QDF_STATUS tdls_antenna_switch_flush_callback(struct scheduler_msg *msg);
/**
* 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_reset_nss() - reset tdls nss parameters
* @tdls_soc: TDLS soc object
* @action_code: action code
*
* Return: None
*/
void tdls_reset_nss(struct tdls_soc_priv_obj *tdls_soc,
uint8_t action_code);
/**
* tdls_release_serialization_command() - TDLS wrapper to
* relases serialization command.
* @vdev: Object manager vdev
* @type: command to release.
*
* Return: None
*/
void
tdls_release_serialization_command(struct wlan_objmgr_vdev *vdev,
enum wlan_serialization_cmd_type type);
/**
* tdls_set_cap() - set TDLS capability type
* @tdls_vdev: tdls vdev object
* @mac: peer mac address
* @cap: TDLS capability type
*
* Return: 0 if successful or negative errno otherwise
*/
int tdls_set_cap(struct tdls_vdev_priv_obj *tdls_vdev, const uint8_t *mac,
enum tdls_peer_capab cap);
/**
* tdls_process_send_mgmt_rsp() - handle response for send mgmt
* @rsp: TDLS send mgmt response
*
* Return: QDF_STATUS_SUCCESS for success; other values if failed
*/
QDF_STATUS tdls_process_send_mgmt_rsp(struct tdls_send_mgmt_rsp *rsp);
/**
* tdls_send_mgmt_tx_completion() - process tx completion
* @tx_complete: TDLS mgmt completion info
*
* Return: QDF_STATUS_SUCCESS for success; other values if failed
*/
QDF_STATUS tdls_send_mgmt_tx_completion(
struct tdls_mgmt_tx_completion_ind *tx_complete);
/**
* tdls_process_add_peer_rsp() - handle response for delete TDLS peer
* @rsp: TDLS delete peer response
*
* Return: QDF status
*/
QDF_STATUS tdls_process_del_peer_rsp(struct tdls_del_sta_rsp *rsp);
/**
* tdls_process_should_discover() - handle tdls should_discover event
* @vdev: vdev object
* @evt: event info
*
* Return: QDF_STATUS
*/
QDF_STATUS tdls_process_should_discover(struct wlan_objmgr_vdev *vdev,
struct tdls_event_info *evt);
/**
* tdls_process_should_teardown() - handle tdls should_teardown event
* @vdev: vdev object
* @evt: event info
*
* Return: QDF_STATUS
*/
QDF_STATUS tdls_process_should_teardown(struct wlan_objmgr_vdev *vdev,
struct tdls_event_info *evt);
/**
* tdls_process_connection_tracker_notify() -handle tdls connect tracker notify
* @vdev: vdev object
* @evt: event info
*
* Return: QDF_STATUS
*/
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_action_frame_request *tdls_mgmt_req);
/**
* tdls_set_responder() - Set/clear TDLS peer's responder role
* @set_req: set responder request
*
* Return: 0 for success or -EINVAL otherwise
*/
int tdls_set_responder(struct tdls_set_responder_req *set_req);
/**
* tdls_decrement_peer_count() - decrement connected TDLS peer counter
* @soc_obj: TDLS soc object
*
* Used in scheduler thread context, no lock needed.
*
* Return: None.
*/
void tdls_decrement_peer_count(struct tdls_soc_priv_obj *soc_obj);
/**
* wlan_tdls_offchan_parms_callback() - Callback to release ref count
* @vdev: vdev object
*
* Return: none
*/
void wlan_tdls_offchan_parms_callback(struct wlan_objmgr_vdev *vdev);
/**
* tdls_process_set_offchannel() - Handle set offchannel request for TDLS
* @req: TDLS set offchannel request
*
* Return: int status
*/
int tdls_process_set_offchannel(struct tdls_set_offchannel *req);
/**
* tdls_process_set_offchan_mode() - Handle set offchan mode request for TDLS
* @req: TDLS set offchannel mode request
*
* Return: int status
*/
int tdls_process_set_offchan_mode(struct tdls_set_offchanmode *req);
/**
* tdls_process_set_secoffchanneloffset() - Handle set sec offchannel
* offset request for TDLS
* @req: TDLS set secoffchannel offchannel request
*
* Return: int status
*/
int tdls_process_set_secoffchanneloffset(
struct tdls_set_secoffchanneloffset *req);
#endif

1319
tdls/core/src/wlan_tdls_ct.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,247 @@
/*
* Copyright (c) 2017-2018 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_ct.h
*
* TDLS connection tracker declarations
*/
#ifndef _WLAN_TDLS_CT_H_
#define _WLAN_TDLS_CT_H_
/*
* Before UpdateTimer expires, we want to timeout discovery response
* should not be more than 2000.
*/
#define TDLS_DISCOVERY_TIMEOUT_ERE_UPDATE 1000
#define TDLS_PREFERRED_OFF_CHANNEL_NUM_MIN 1
#define TDLS_PREFERRED_OFF_CHANNEL_NUM_MAX 165
#define TDLS_PREFERRED_OFF_CHANNEL_NUM_DEFAULT 36
/**
* tdls_is_vdev_connected() - check the vdev is connected to ap
* @vdev: vdev object manager
*
* This function will check the vdev connection status and return
* true or false
*
* Return: true - Connected, false - Not connected
*/
bool tdls_is_vdev_connected(struct wlan_objmgr_vdev *vdev);
/**
* tdls_implicit_enable() - enable implicit tdls triggering
* @tdls_vdev: TDLS vdev
*
* Return: Void
*/
void tdls_implicit_enable(struct tdls_vdev_priv_obj *tdls_vdev);
/**
* tdls_update_rx_pkt_cnt() - Update rx packet count
* @vdev: vdev object manager
* @mac_addr: mac address of the data
*
* Increase the rx packet count, if the sender is not bssid and the packet is
* not broadcast and multicast packet
*
* This sampling information will be used in TDLS connection tracker
*
* This function expected to be called in an atomic context so blocking APIs
* not allowed
*
* Return: None
*/
void tdls_update_rx_pkt_cnt(struct wlan_objmgr_vdev *vdev,
struct qdf_mac_addr *mac_addr);
/**
* tdls_update_tx_pkt_cnt() - update tx packet
* @vdev: vdev object
* @mac_addr: mac address of the data
*
* Increase the tx packet count, if the sender is not bssid and the packet is
* not broadcast and multicast packet
*
* This sampling information will be used in TDLS connection tracker
*
* This function expected to be called in an atomic context so blocking APIs
* not allowed
*
* Return: None
*/
void tdls_update_tx_pkt_cnt(struct wlan_objmgr_vdev *vdev,
struct qdf_mac_addr *mac_addr);
/**
* wlan_hdd_tdls_implicit_send_discovery_request() - send discovery request
* @tdls_vdev_obj: tdls vdev object
*
* Return: None
*/
void tdls_implicit_send_discovery_request(
struct tdls_vdev_priv_obj *tdls_vdev_obj);
/**
* tdls_recv_discovery_resp() - handling of tdls discovery response
* @soc: object manager
* @mac: mac address of peer from which the response was received
*
* Return: 0 for success or negative errno otherwise
*/
int tdls_recv_discovery_resp(struct tdls_vdev_priv_obj *tdls_vdev,
const uint8_t *mac);
/**
* tdls_indicate_teardown() - indicate teardown to upper layer
* @tdls_vdev: tdls vdev object
* @curr_peer: teardown peer
* @reason: teardown reason
*
* Return: Void
*/
void tdls_indicate_teardown(struct tdls_vdev_priv_obj *tdls_vdev,
struct tdls_peer *curr_peer,
uint16_t reason);
/**
* tdls_ct_handler() - TDLS connection tracker handler
* @user_data: user data from timer
*
* tdls connection tracker timer starts, when the STA connected to AP
* and it's scan the traffic between two STA peers and make TDLS
* connection and teardown, based on the traffic threshold
*
* Return: None
*/
void tdls_ct_handler(void *user_data);
/**
* tdls_ct_idle_handler() - Check tdls idle traffic
* @user_data: data from tdls idle timer
*
* Function to check the tdls idle traffic and make a decision about
* tdls teardown
*
* Return: None
*/
void tdls_ct_idle_handler(void *user_data);
/**
* tdls_discovery_timeout_peer_cb() - tdls discovery timeout callback
* @userData: tdls vdev
*
* Return: None
*/
void tdls_discovery_timeout_peer_cb(void *user_data);
/**
* tdls_implicit_disable() - disable implicit tdls triggering
* @pHddTdlsCtx: TDLS context
*
* Return: Void
*/
void tdls_implicit_disable(struct tdls_vdev_priv_obj *tdls_vdev);
/**
* tdls_is_vdev_connected() -check the vdev connection
* @vdev: vdev oobject
*
* Return: true or false
*/
bool tdls_is_vdev_connected(struct wlan_objmgr_vdev *vdev);
/**
* tdls_is_vdev_authenticated() -check the vdev authentication state
* @vdev: vdev oobject
*
* Return: true or false
*/
bool tdls_is_vdev_authenticated(struct wlan_objmgr_vdev *vdev);
/**
* tdls_teardown_connections() -teardown and delete all the tdls peers
* @vdev: vdev oobject
*
* Return: true or false
*/
void tdls_teardown_connections(struct wlan_objmgr_vdev *vdev);
/**
* tdls_disable_offchan_and_teardown_links - Disable offchannel
* and teardown TDLS links
* @tdls_soc : tdls soc object
*
* Return: None
*/
void tdls_disable_offchan_and_teardown_links(
struct wlan_objmgr_vdev *vdev);
/**
* tdls_delete_all_tdls_peers(): send request to delete tdls peers
* @vdev: vdev object
* @tdls_soc: tdls soc object
*
* This function sends request to lim to delete tdls peers
*
* Return: QDF_STATUS
*/
QDF_STATUS tdls_delete_all_tdls_peers(struct wlan_objmgr_vdev *vdev,
struct tdls_soc_priv_obj *tdls_soc);
/**
* tdls_set_tdls_offchannel() - set tdls off-channel number
* @tdls_soc: tdls soc object
* @offchannel: tdls off-channel number
*
* This function sets tdls off-channel number
*
* Return: 0 on success; negative errno otherwise
*/
int tdls_set_tdls_offchannel(struct tdls_soc_priv_obj *tdls_soc,
int offchannel);
/**
* tdls_set_tdls_offchannelmode() - set tdls off-channel mode
* @adapter: Pointer to the HDD adapter
* @offchanmode: tdls off-channel mode
*
* This function sets tdls off-channel mode
*
* Return: 0 on success; negative errno otherwise
*/
int tdls_set_tdls_offchannelmode(struct wlan_objmgr_vdev *vdev,
int offchanmode);
/**
* tdls_set_tdls_secoffchanneloffset() - set secondary tdls off-channel offset
* @tdls_soc: tdls soc object
* @offchanoffset: tdls off-channel offset
*
* This function sets secondary tdls off-channel offset
*
* Return: 0 on success; negative errno otherwise
*/
int tdls_set_tdls_secoffchanneloffset(struct tdls_soc_priv_obj *tdls_soc,
int offchanoffset);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,741 @@
/*
* Copyright (c) 2017-2018 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_main.h
*
* TDLS core function declaration
*/
#if !defined(_WLAN_TDLS_MAIN_H_)
#define _WLAN_TDLS_MAIN_H_
#include <qdf_trace.h>
#include <qdf_list.h>
#include <wlan_objmgr_psoc_obj.h>
#include <wlan_objmgr_pdev_obj.h>
#include <wlan_objmgr_vdev_obj.h>
#include <wlan_objmgr_peer_obj.h>
#include <wlan_tdls_public_structs.h>
#include <scheduler_api.h>
#include "wlan_serialization_api.h"
/* Bit mask flag for tdls_option to FW */
#define ENA_TDLS_OFFCHAN (1 << 0) /* TDLS Off Channel support */
#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
/*
* Before UpdateTimer expires, we want to timeout discovery response
* should not be more than 2000.
*/
#define TDLS_DISCOVERY_TIMEOUT_BEFORE_UPDATE 1000
#define TDLS_SCAN_REJECT_MAX 5
#define tdls_debug(params...) \
QDF_TRACE_DEBUG(QDF_MODULE_ID_TDLS, params)
#define tdls_notice(params...) \
QDF_TRACE_INFO(QDF_MODULE_ID_TDLS, params)
#define tdls_warn(params...) \
QDF_TRACE_WARN(QDF_MODULE_ID_TDLS, params)
#define tdls_err(params...) \
QDF_TRACE_ERROR(QDF_MODULE_ID_TDLS, params)
#define tdls_alert(params...) \
QDF_TRACE_FATAL(QDF_MODULE_ID_TDLS, params)
#define tdls_nofl_debug(params...) \
QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_TDLS, params)
#define tdls_nofl_notice(params...) \
QDF_TRACE_INFO_NO_FL(QDF_MODULE_ID_TDLS, params)
#define tdls_nofl_warn(params...) \
QDF_TRACE_WARN_NO_FL(QDF_MODULE_ID_TDLS, params)
#define tdls_nofl_err(params...) \
QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_TDLS, params)
#define tdls_nofl_alert(params...) \
QDF_TRACE_FATAL_NO_FL(QDF_MODULE_ID_TDLS, params)
#define TDLS_IS_LINK_CONNECTED(peer) \
((TDLS_LINK_CONNECTED == (peer)->link_status) || \
(TDLS_LINK_TEARING == (peer)->link_status))
#define SET_BIT(value, mask) ((value) |= (1 << (mask)))
#define CLEAR_BIT(value, mask) ((value) &= ~(1 << (mask)))
#define CHECK_BIT(value, mask) ((value) & (1 << (mask)))
/**
* struct tdls_conn_info - TDLS connection record
* @session_id: session id
* @sta_id: sta id
* @peer_mac: peer address
*/
struct tdls_conn_info {
uint8_t session_id;
uint8_t sta_id;
struct qdf_mac_addr peer_mac;
};
/**
* enum tdls_nss_transition_state - TDLS NSS transition states
* @TDLS_NSS_TRANSITION_UNKNOWN: default state
* @TDLS_NSS_TRANSITION_2x2_to_1x1: transition from 2x2 to 1x1 stream
* @TDLS_NSS_TRANSITION_1x1_to_2x2: transition from 1x1 to 2x2 stream
*/
enum tdls_nss_transition_state {
TDLS_NSS_TRANSITION_S_UNKNOWN = 0,
TDLS_NSS_TRANSITION_S_2x2_to_1x1,
TDLS_NSS_TRANSITION_S_1x1_to_2x2,
};
/**
* struct tdls_conn_tracker_mac_table - connection tracker peer table
* @mac_address: peer mac address
* @tx_packet_cnt: number of tx pkts
* @rx_packet_cnt: number of rx pkts
* @peer_timestamp_ms: time stamp of latest peer traffic
*/
struct tdls_conn_tracker_mac_table {
struct qdf_mac_addr mac_address;
uint32_t tx_packet_cnt;
uint32_t rx_packet_cnt;
uint32_t peer_timestamp_ms;
};
/**
* struct tdls_ct_idle_peer_data - connection tracker idle peer info
* @vdev: vdev object
* @tdls_info: tdls connection info
*/
struct tdls_ct_idle_peer_data {
struct wlan_objmgr_vdev *vdev;
struct tdls_conn_info *tdls_info;
};
/**
* struct tdls_set_state_db - to record set tdls state command, we need to
* set correct tdls state to firmware:
* 1. enable tdls in firmware before tdls connection;
* 2. disable tdls if concurrency happen, before disable tdls, all active peer
* should be deleted in firmware.
*
* @set_state_cnt: tdls set state count
* @vdev_id: vdev id of last set state command
*/
struct tdls_set_state_info {
uint8_t set_state_cnt;
uint8_t vdev_id;
};
/**
* struct tdls_psoc_priv_ctx - tdls context
* @soc: objmgr psoc
* @tdls_current_mode: current tdls mode
* @tdls_last_mode: last tdls mode
* @scan_reject_count: number of times scan rejected due to TDLS
* @tdls_source_bitmap: bit map to set/reset TDLS by different sources
* @tdls_conn_info: this tdls_conn_info can be removed and we can use peer type
* of peer object to get the active tdls peers
* @tdls_configs: tdls user configure
* @max_num_tdls_sta: maximum TDLS station number allowed upon runtime condition
* @connected_peer_count: tdls peer connected count
* @tdls_off_channel: tdls off channel number
* @tdls_channel_offset: tdls channel offset
* @tdls_fw_off_chan_mode: tdls fw off channel mode
* @enable_tdls_connection_tracker: enable tdls connection tracker
* @tdls_external_peer_count: external tdls peer count
* @tdls_nss_switch_in_progress: tdls antenna switch in progress
* @tdls_nss_teardown_complete: tdls tear down complete
* @tdls_nss_transition_mode: tdls nss transition mode
* @tdls_teardown_peers_cnt: tdls tear down peer count
* @set_state_info: set tdls state info
* @tdls_event_cb: tdls event callback
* @tdls_evt_cb_data: tdls event user data
* @tdls_peer_context: userdata for register/deregister TDLS peer
* @tdls_reg_peer: register tdls peer with datapath
* @tdls_dereg_peer: deregister tdls peer from datapath
* @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
* @tdls_del_all_peers:store eWNI_SME_DEL_ALL_TDLS_PEERS
* @tdls_update_dp_vdev_flags store CDP_UPDATE_TDLS_FLAGS
* @tdls_idle_peer_data: provide information about idle peer
* @tdls_ct_spinlock: connection tracker spin lock
*/
struct tdls_soc_priv_obj {
struct wlan_objmgr_psoc *soc;
enum tdls_feature_mode tdls_current_mode;
enum tdls_feature_mode tdls_last_mode;
int scan_reject_count;
unsigned long tdls_source_bitmap;
struct tdls_conn_info tdls_conn_info[WLAN_TDLS_STA_MAX_NUM];
struct tdls_user_config tdls_configs;
uint16_t max_num_tdls_sta;
uint16_t connected_peer_count;
uint8_t tdls_off_channel;
uint16_t tdls_channel_offset;
int32_t tdls_fw_off_chan_mode;
bool enable_tdls_connection_tracker;
uint8_t tdls_external_peer_count;
bool tdls_nss_switch_in_progress;
bool tdls_nss_teardown_complete;
bool tdls_disable_in_progress;
enum tdls_nss_transition_state tdls_nss_transition_mode;
int32_t tdls_teardown_peers_cnt;
struct tdls_set_state_info set_state_info;
tdls_rx_callback tdls_rx_cb;
void *tdls_rx_cb_data;
tdls_wmm_check tdls_wmm_cb;
void *tdls_wmm_cb_data;
tdls_evt_callback tdls_event_cb;
void *tdls_evt_cb_data;
void *tdls_peer_context;
tdls_register_peer_callback tdls_reg_peer;
tdls_deregister_peer_callback tdls_dereg_peer;
tdls_dp_vdev_update_flags_callback tdls_dp_vdev_update;
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;
uint16_t tdls_del_all_peers;
uint32_t tdls_update_dp_vdev_flags;
struct tdls_ct_idle_peer_data tdls_idle_peer_data;
qdf_spinlock_t tdls_ct_spinlock;
};
/**
* struct tdls_vdev_priv_obj - tdls private vdev object
* @vdev: vdev objmgr object
* @peer_list: tdls peer list on this vdev
* @peer_update_timer: connection tracker timer
* @peer_dicovery_timer: peer discovery timer
* @threshold_config: threshold config
* @discovery_peer_cnt: discovery peer count
* @discovery_sent_cnt: discovery sent count
* @ap_rssi: ap rssi
* @curr_candidate: current candidate
* @ct_peer_table: linear mac address table for counting the packets
* @valid_mac_entries: number of valid mac entry in @ct_peer_mac_table
* @magic: magic
* @tx_queue: tx frame queue
*/
struct tdls_vdev_priv_obj {
struct wlan_objmgr_vdev *vdev;
qdf_list_t peer_list[WLAN_TDLS_PEER_LIST_SIZE];
qdf_mc_timer_t peer_update_timer;
qdf_mc_timer_t peer_discovery_timer;
struct tdls_config_params threshold_config;
int32_t discovery_peer_cnt;
uint32_t discovery_sent_cnt;
int8_t ap_rssi;
struct tdls_peer *curr_candidate;
struct tdls_conn_tracker_mac_table
ct_peer_table[WLAN_TDLS_CT_TABLE_SIZE];
uint8_t valid_mac_entries;
uint32_t magic;
uint8_t session_id;
qdf_list_t tx_queue;
};
/**
* struct tdls_peer_mlme_info - tdls peer mlme info
**/
struct tdls_peer_mlme_info {
};
/**
* struct tdls_peer - tdls peer data
* @node: node
* @vdev_priv: tdls vdev priv obj
* @peer_mac: peer mac address
* @sta_id: station identifier
* @rssi: rssi
* @tdls_support: tdls support
* @link_status: tdls link status
* @is_responder: is responder
* @discovery_processed: dicovery processed
* @discovery_attempt: discovery attempt
* @tx_pkt: tx packet
* @rx_pkt: rx packet
* @uapsd_queues: uapsd queues
* @max_sp: max sp
* @buf_sta_capable: is buffer sta
* @off_channel_capable: is offchannel supported flag
* @supported_channels_len: supported channels length
* @supported_channels: supported channels
* @supported_oper_classes_len: supported operation classes length
* @supported_oper_classes: supported operation classes
* @is_forced_peer: is forced peer
* @op_class_for_pref_off_chan: op class for preferred off channel
* @pref_off_chan_num: preferred off channel number
* @op_class_for_pref_off_chan_is_set: op class for preferred off channel set
* @peer_idle_timer: time to check idle traffic in tdls peers
* @is_peer_idle_timer_initialised: Flag to check idle timer init
* @spatial_streams: Number of TX/RX spatial streams for TDLS
* @reason: reason
* @state_change_notification: state change notification
* @qos: QOS capability of TDLS link
*/
struct tdls_peer {
qdf_list_node_t node;
struct tdls_vdev_priv_obj *vdev_priv;
struct qdf_mac_addr peer_mac;
uint16_t sta_id;
int8_t rssi;
enum tdls_peer_capab tdls_support;
enum tdls_link_state link_status;
uint8_t is_responder;
uint8_t discovery_processed;
uint16_t discovery_attempt;
uint16_t tx_pkt;
uint16_t rx_pkt;
uint8_t uapsd_queues;
uint8_t max_sp;
uint8_t buf_sta_capable;
uint8_t off_channel_capable;
uint8_t supported_channels_len;
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_forced_peer;
uint8_t op_class_for_pref_off_chan;
uint8_t pref_off_chan_num;
uint8_t op_class_for_pref_off_chan_is_set;
qdf_mc_timer_t peer_idle_timer;
bool is_peer_idle_timer_initialised;
uint8_t spatial_streams;
enum tdls_link_state_reason reason;
tdls_state_change_callback state_change_notification;
uint8_t qos;
struct tdls_peer_mlme_info *tdls_info;
};
/**
* struct tdls_os_if_event - TDLS os event info
* @type: type of event
* @info: pointer to event information
*/
struct tdls_os_if_event {
uint32_t type;
void *info;
};
/**
* enum tdls_os_if_notification - TDLS notification from OS IF
* @TDLS_NOTIFY_STA_SESSION_INCREMENT: sta session count incremented
* @TDLS_NOTIFY_STA_SESSION_DECREMENT: sta session count decremented
*/
enum tdls_os_if_notification {
TDLS_NOTIFY_STA_SESSION_INCREMENT,
TDLS_NOTIFY_STA_SESSION_DECREMENT
};
/**
* wlan_vdev_get_tdls_soc_obj - private API to get tdls soc object from vdev
* @vdev: vdev object
*
* Return: tdls soc object
*/
static inline struct tdls_soc_priv_obj *
wlan_vdev_get_tdls_soc_obj(struct wlan_objmgr_vdev *vdev)
{
struct wlan_objmgr_psoc *psoc;
struct tdls_soc_priv_obj *soc_obj;
if (!vdev) {
tdls_err("NULL vdev");
return NULL;
}
psoc = wlan_vdev_get_psoc(vdev);
if (!psoc) {
tdls_err("can't get psoc");
return NULL;
}
soc_obj = (struct tdls_soc_priv_obj *)
wlan_objmgr_psoc_get_comp_private_obj(psoc,
WLAN_UMAC_COMP_TDLS);
return soc_obj;
}
/**
* wlan_psoc_get_tdls_soc_obj - private API to get tdls soc object from psoc
* @psoc: psoc object
*
* Return: tdls soc object
*/
static inline struct tdls_soc_priv_obj *
wlan_psoc_get_tdls_soc_obj(struct wlan_objmgr_psoc *psoc)
{
struct tdls_soc_priv_obj *soc_obj;
if (!psoc) {
tdls_err("NULL psoc");
return NULL;
}
soc_obj = (struct tdls_soc_priv_obj *)
wlan_objmgr_psoc_get_comp_private_obj(psoc,
WLAN_UMAC_COMP_TDLS);
return soc_obj;
}
/**
* wlan_vdev_get_tdls_vdev_obj - private API to get tdls vdev object from vdev
* @vdev: vdev object
*
* Return: tdls vdev object
*/
static inline struct tdls_vdev_priv_obj *
wlan_vdev_get_tdls_vdev_obj(struct wlan_objmgr_vdev *vdev)
{
struct tdls_vdev_priv_obj *vdev_obj;
if (!vdev) {
tdls_err("NULL vdev");
return NULL;
}
vdev_obj = (struct tdls_vdev_priv_obj *)
wlan_objmgr_vdev_get_comp_private_obj(vdev,
WLAN_UMAC_COMP_TDLS);
return vdev_obj;
}
/**
* tdls_set_link_status - tdls set link status
* @vdev: vdev object
* @mac: mac address of tdls peer
* @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_state link_state,
enum tdls_link_state_reason link_reason);
/**
* tdls_psoc_obj_create_notification() - tdls psoc create notification handler
* @psoc: psoc object
* @arg_list: Argument list
*
* Return: QDF_STATUS
*/
QDF_STATUS tdls_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc,
void *arg_list);
/**
* tdls_psoc_obj_destroy_notification() - tdls psoc destroy notification handler
* @psoc: psoc object
* @arg_list: Argument list
*
* Return: QDF_STATUS
*/
QDF_STATUS tdls_psoc_obj_destroy_notification(struct wlan_objmgr_psoc *psoc,
void *arg_list);
/**
* tdls_vdev_obj_create_notification() - tdls vdev create notification handler
* @vdev: vdev object
* @arg_list: Argument list
*
* Return: QDF_STATUS
*/
QDF_STATUS tdls_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev,
void *arg_list);
/**
* tdls_vdev_obj_destroy_notification() - tdls vdev destroy notification handler
* @vdev: vdev object
* @arg_list: Argument list
*
* Return: QDF_STATUS
*/
QDF_STATUS tdls_vdev_obj_destroy_notification(struct wlan_objmgr_vdev *vdev,
void *arg_list);
/**
* tdls_process_cmd() - tdls main command process function
* @msg: scheduler msg
*
* Return: QDF_STATUS
*/
QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg);
/**
* tdls_process_evt() - tdls main event process function
* @msg: scheduler msg
*
* Return: QDF_STATUS
*/
QDF_STATUS tdls_process_evt(struct scheduler_msg *msg);
/**
* tdls_timer_restart() - restart TDLS timer
* @vdev: VDEV object manager
* @timer: timer to restart
* @expiration_time: new expiration time to set for the timer
*
* Return: Void
*/
void tdls_timer_restart(struct wlan_objmgr_vdev *vdev,
qdf_mc_timer_t *timer,
uint32_t expiration_time);
/**
* wlan_hdd_tdls_timers_stop() - stop all the tdls timers running
* @tdls_vdev: TDLS vdev
*
* Return: none
*/
void tdls_timers_stop(struct tdls_vdev_priv_obj *tdls_vdev);
/**
* tdls_get_vdev_objects() - Get TDLS private objects
* @vdev: VDEV object manager
* @tdls_vdev_obj: tdls vdev object
* @tdls_soc_obj: tdls soc object
*
* Return: QDF_STATUS
*/
QDF_STATUS tdls_get_vdev_objects(struct wlan_objmgr_vdev *vdev,
struct tdls_vdev_priv_obj **tdls_vdev_obj,
struct tdls_soc_priv_obj **tdls_soc_obj);
/**
* cds_set_tdls_ct_mode() - Set the tdls connection tracker mode
* @hdd_ctx: hdd context
*
* This routine is called to set the tdls connection tracker operation status
*
* Return: NONE
*/
void tdls_set_ct_mode(struct wlan_objmgr_psoc *psoc);
/**
* tdls_set_operation_mode() - set tdls operating mode
* @tdls_set_mode: tdls mode set params
*
* Return: QDF_STATUS
*/
QDF_STATUS tdls_set_operation_mode(struct tdls_set_mode_params *tdls_set_mode);
/**
* tdls_notify_sta_connect() - Update tdls state for every
* connect event.
* @notify: sta connect params
*
* After every connect event in the system, check whether TDLS
* can be enabled in the system. If TDLS can be enabled, update the
* TDLS state as needed.
*
* Return: QDF_STATUS
*/
QDF_STATUS tdls_notify_sta_connect(struct tdls_sta_notify_params *notify);
/**
* tdls_notify_sta_disconnect() - Update tdls state for every
* disconnect event.
* @notify: sta disconnect params
*
* After every disconnect event in the system, check whether TDLS
* can be disabled/enabled in the system and update the
* TDLS state as needed.
*
* Return: QDF_STATUS
*/
QDF_STATUS tdls_notify_sta_disconnect(struct tdls_sta_notify_params *notify);
/**
* tdls_notify_reset_adapter() - notify reset adapter
* @vdev: vdev object
*
* Notify TDLS about the adapter reset
*
* Return: None
*/
void tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev);
/**
* tdls_peers_deleted_notification() - peer delete notification
* @psoc: soc object
* @vdev_id: vdev id
*
* Legacy lim layer will delete tdls peers for roaming and heart beat failures
* and notify the component about the delete event to update the tdls.
* state.
*
* Return: QDF_STATUS
*/
QDF_STATUS tdls_peers_deleted_notification(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id);
/**
* tdls_notify_decrement_session() - Notify the session decrement
* @psoc: psoc object manager
*
* Policy manager notify TDLS about session decrement
*
* Return: None
*/
void tdls_notify_decrement_session(struct wlan_objmgr_psoc *psoc);
/**
* tdls_send_update_to_fw - update tdls status info
* @tdls_vdev_obj: tdls vdev private object.
* @tdls_prohibited: indicates whether tdls is prohibited.
* @tdls_chan_swit_prohibited: indicates whether tdls channel switch
* is prohibited.
* @sta_connect_event: indicate sta connect or disconnect event
* @session_id: session id
*
* Normally an AP does not influence TDLS connection between STAs
* associated to it. But AP may set bits for TDLS Prohibited or
* TDLS Channel Switch Prohibited in Extended Capability IE in
* Assoc/Re-assoc response to STA. So after STA is connected to
* an AP, call this function to update TDLS status as per those
* bits set in Ext Cap IE in received Assoc/Re-assoc response
* from AP.
*
* Return: None.
*/
void tdls_send_update_to_fw(struct tdls_vdev_priv_obj *tdls_vdev_obj,
struct tdls_soc_priv_obj *tdls_soc_obj,
bool tdls_prohibited,
bool tdls_chan_swit_prohibited,
bool sta_connect_event,
uint8_t session_id);
/**
* tdls_notify_increment_session() - Notify the session increment
* @psoc: psoc object manager
*
* Policy manager notify TDLS about session increment
*
* Return: None
*/
void tdls_notify_increment_session(struct wlan_objmgr_psoc *psoc);
/**
* tdls_check_is_tdls_allowed() - check is tdls allowed or not
* @vdev: vdev object
*
* Function determines the whether TDLS allowed in the system
*
* Return: true or false
*/
bool tdls_check_is_tdls_allowed(struct wlan_objmgr_vdev *vdev);
/**
* tdls_get_vdev() - Get tdls specific vdev object manager
* @psoc: wlan psoc object manager
* @dbg_id: debug id
*
* If TDLS possible, return the corresponding vdev
* to enable TDLS in the system.
*
* Return: vdev manager pointer or NULL.
*/
struct wlan_objmgr_vdev *tdls_get_vdev(struct wlan_objmgr_psoc *psoc,
wlan_objmgr_ref_dbgid dbg_id);
/**
* tdls_process_policy_mgr_notification() - process policy manager notification
* @psoc: soc object manager
*
* Return: QDF_STATUS
*/
QDF_STATUS
tdls_process_policy_mgr_notification(struct wlan_objmgr_psoc *psoc);
/**
* tdls_scan_complete_event_handler() - scan complete event handler for tdls
* @vdev: vdev object
* @event: scan event
* @arg: tdls soc object
*
* Return: None
*/
void tdls_scan_complete_event_handler(struct wlan_objmgr_vdev *vdev,
struct scan_event *event,
void *arg);
/**
* tdls_scan_callback() - callback for TDLS scan operation
* @soc: tdls soc pvt object
*
* Return: QDF_STATUS
*/
QDF_STATUS tdls_scan_callback(struct tdls_soc_priv_obj *tdls_soc);
/**
* wlan_hdd_tdls_scan_done_callback() - callback for tdls scan done event
* @tdls_soc: tdls soc object
*
* Return: Void
*/
void tdls_scan_done_callback(struct tdls_soc_priv_obj *tdls_soc);
/**
* tdls_scan_serialization_comp_info_cb() - callback for scan start
* @vdev: VDEV on which the scan command is being processed
* @comp_info: serialize rules info
*
* Return: negative = caller should stop and return error code immediately
* 1 = caller can continue to scan
*/
void tdls_scan_serialization_comp_info_cb(struct wlan_objmgr_vdev *vdev,
union wlan_serialization_rules_info *comp_info);
/**
* tdls_set_offchan_mode() - update tdls status info
* @psoc: soc object
* @param: channel switch params
*
* send message to WMI to set TDLS off channel in f/w
*
* Return: QDF_STATUS.
*/
QDF_STATUS tdls_set_offchan_mode(struct wlan_objmgr_psoc *psoc,
struct tdls_channel_switch_params *param);
/**
* tdls_delete_all_peers_indication() - update tdls status info
* @psoc: soc object
* @vdev_id: vdev id
*
* Notify tdls component to cleanup all peers
*
* Return: QDF_STATUS.
*/
QDF_STATUS tdls_delete_all_peers_indication(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id);
#endif

View File

@@ -0,0 +1,449 @@
/*
* Copyright (c) 2017-2018 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_mgmt.c
*
* 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:%pK, frame_len:%d, rx_chan:%d, vdev_id:%d, frm_type:%d, rx_rssi:%d, buf:%pK",
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_ADDR_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_cfg80211_tdls_rx_callback() */
if (tdls_soc_obj && tdls_soc_obj->tdls_rx_cb)
tdls_soc_obj->tdls_rx_cb(tdls_soc_obj->tdls_rx_cb_data,
rx_mgmt);
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;
QDF_STATUS status;
int num_of_entries;
tdls_debug("psoc:%pK, is register rx:%d", psoc, isregister);
frm_cb_info.frm_type = MGMT_ACTION_TDLS_DISCRESP;
frm_cb_info.mgmt_rx_cb = tgt_tdls_mgmt_frame_rx_cb;
num_of_entries = 1;
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_flush_cb(
struct scheduler_msg *msg)
{
struct tdls_send_mgmt_request *tdls_mgmt_req;
tdls_mgmt_req = msg->bodyptr;
qdf_mem_free(tdls_mgmt_req);
msg->bodyptr = NULL;
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 = {0};
struct tdls_send_mgmt_request *tdls_mgmt_req;
if (!action_req || !action_req->vdev)
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_cmd;
}
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_cmd;
}
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);
status = wlan_objmgr_peer_try_get_ref(peer, WLAN_TDLS_SB_ID);
if (QDF_IS_STATUS_ERROR(status)) {
qdf_mem_free(tdls_mgmt_req);
goto release_cmd;
}
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) {
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;
if (action_req->use_default_ac)
tdls_mgmt_req->ac = WIFI_AC_VI;
else
tdls_mgmt_req->ac = WIFI_AC_BK;
/* 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;
msg.flush_callback = tdls_activate_send_mgmt_request_flush_cb;
status = scheduler_post_message(QDF_MODULE_ID_TDLS,
QDF_MODULE_ID_TDLS,
QDF_MODULE_ID_PE, &msg);
if (QDF_IS_STATUS_ERROR(status)) {
tdls_err("failed to post msg, status %d", status);
qdf_mem_free(tdls_mgmt_req);
}
wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_SB_ID);
release_cmd:
/*update tdls nss infornation based on action code */
tdls_reset_nss(tdls_soc_obj, action_req->chk_frame->action_code);
if (QDF_IS_STATUS_ERROR(status)) {
tdls_internal_send_mgmt_tx_done(action_req, status);
tdls_release_serialization_command(action_req->vdev,
WLAN_SER_CMD_TDLS_SEND_MGMT);
}
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: %pK, ", 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);
break;
case WLAN_SER_CB_RELEASE_MEM_CMD:
/* command successfully completed.
* release tdls_action_frame_request memory
*/
wlan_objmgr_vdev_release_ref(req->vdev, WLAN_TDLS_NB_ID);
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);
if (status != QDF_STATUS_SUCCESS) {
status = tdls_internal_send_mgmt_tx_done(tdls_mgmt_req,
status);
goto error_mgmt;
}
/* 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;
cmd.is_blocking = true;
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:
status = QDF_STATUS_E_FAILURE;
goto error_mgmt;
default:
QDF_ASSERT(0);
status = QDF_STATUS_E_INVAL;
goto error_mgmt;
}
return status;
error_mgmt:
wlan_objmgr_vdev_release_ref(tdls_mgmt_req->vdev, WLAN_TDLS_NB_ID);
qdf_mem_free(tdls_mgmt_req);
return status;
}

View File

@@ -0,0 +1,111 @@
/*
* Copyright (c) 2017-2018 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_mgmt.h
*
* TDLS management frames include file
*/
#ifndef _WLAN_TDLS_MGMT_H_
#define _WLAN_TDLS_MGMT_H_
#define TDLS_PUBLIC_ACTION_FRAME_OFFSET 24
#define TDLS_PUBLIC_ACTION_FRAME 4
#define TDLS_PUBLIC_ACTION_DISC_RESP 14
#define TDLS_ACTION_FRAME 12
#define TDLS_80211_PEER_ADDR_OFFSET (TDLS_PUBLIC_ACTION_FRAME + \
QDF_MAC_ADDR_SIZE)
#define TDLS_ACTION_FRAME_TYPE_MAX 11
/**
* struct tdls_rx_mgmt_event - tdls rx mgmt frame event
* @tdls_soc_obj: tdls soc private object
* @rx_mgmt: tdls rx mgmt frame structure
*/
struct tdls_rx_mgmt_event {
struct tdls_soc_priv_obj *tdls_soc_obj;
struct tdls_rx_mgmt_frame *rx_mgmt;
};
/*
* struct tdls_send_mgmt_request - tdls management request
* @message_type: type of pe message
* @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;
enum wifi_traffic_ac ac;
/* 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);
/**
* tdls_mgmt_rx_ops() - register or unregister rx callback
* @psoc: psoc object
* @isregister: register if true, unregister if false
*
* This function registers or unregisters rx callback to mgmt txrx
* component.
*
* Return: QDF_STATUS
*/
QDF_STATUS tdls_mgmt_rx_ops(struct wlan_objmgr_psoc *psoc,
bool isregister);
/**
* tdls_process_rx_frame() - process tdls rx frames
* @msg: scheduler msg
*
* Return: QDF_STATUS
*/
QDF_STATUS tdls_process_rx_frame(struct scheduler_msg *msg);
#endif

View File

@@ -0,0 +1,819 @@
/*
* Copyright (c) 2017-2018 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_ADDR_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;
}
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);
peer->sta_id = INVALID_TDLS_PEER_ID;
qdf_list_insert_back(head, &peer->node);
tdls_debug("add tdls peer: " QDF_MAC_ADDR_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_ADDR_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;
}
psoc = wlan_vdev_get_psoc(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_ADDR_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 QDF_OPMODE 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) {
vdev_id = wlan_vdev_get_id(vdev_obj->vdev);
opmode = wlan_vdev_mlme_get_opmode(vdev_obj->vdev);
*channel = policy_mgr_get_channel(soc_obj->soc,
policy_mgr_convert_device_mode_to_qdf_type(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: %pK, pdev: %pK", soc_obj, pdev);
return;
}
qdf_mem_zero(peer_param, sizeof(*peer_param));
peer_param->vdev_id = wlan_vdev_get_id(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.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_reg_is_dsrc_chan(pdev, 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;
peer_param->peer_cap.peer_chanlen++;
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 = 0;
uint8_t is_off_channel_supported = 0;
uint8_t is_qos_wmm_sta = 0;
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 = 1;
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_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 = INVALID_TDLS_PEER_ID;
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_ADDR_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);
}
}

View File

@@ -0,0 +1,246 @@
/*
* Copyright (c) 2017-2018 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_all_peer() - find peer matching the input MACaddr in soc range
* @soc_obj: TDLS soc object
* @channel:channel number
* @bw_offset: offset to bandwidth
*
* This is in scheduler thread context, no lock required.
*
* Return: Operating class
*/
uint8_t tdls_find_opclass(struct wlan_objmgr_psoc *psoc,
uint8_t channel,
uint8_t bw_offset);
/**
* tdls_find_first_connected_peer() - find the 1st connected tdls peer from vdev
* @vdev_obj: tdls vdev object
*
* 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_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

View File

@@ -0,0 +1,23 @@
/*
* 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_txrx.c
*
* TDLS txrx function definitions
*/

View File

@@ -0,0 +1,23 @@
/*
* 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_txrx.h
*
* TDLS txrx api declaration
*/

View File

@@ -0,0 +1,759 @@
/*
* Copyright (c) 2018 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.
*/
#if !defined(CONFIG_TDLS_H__)
#define CONFIG_TDLS_H__
#include "cfg_define.h"
#include "cfg_converged.h"
#include "qdf_types.h"
/*
* <ini>
* gTDLSUapsdMask - ACs to setup U-APSD for TDLS Sta.
* @Min: 0
* @Max: 0x0F
* @Default: 0x0F
*
* This ini is used to configure the ACs for which mask needs to be enabled.
* 0x1: Background 0x2: Best effort
* 0x4: Video 0x8: Voice
*
* Related: gEnableTDLSSupport.
*
* Supported Feature: TDLS
*
* Usage: Internal/External
*
* </ini>
*/
#define CFG_TDLS_QOS_WMM_UAPSD_MASK CFG_INI_UINT( \
"gTDLSUapsdMask", \
0, \
0x0F, \
0x0F, \
CFG_VALUE_OR_DEFAULT, \
"ACs to setup U-APSD for TDLS Sta")
/*
* <ini>
* gEnableTDLSBufferSta - Controls the TDLS buffer.
* @Min: 0
* @Max: 1
* @Default: 1
*
* This ini is used to control the TDLS buffer.
* Buffer STA is not enabled in CLD 2.0 yet.
*
* Related: gEnableTDLSSupport.
*
* Supported Feature: TDLS
*
* Usage: Internal/External
*
* </ini>
*/
#define CFG_TDLS_BUF_STA_ENABLED CFG_INI_BOOL( \
"gEnableTDLSBufferSta", \
1, \
"Controls the TDLS buffer")
/*
* <ini>
* gTDLSPuapsdInactivityTime - Peer UAPSD Inactivity time.
* @Min: 0
* @Max: 10
* @Default: 0
*
* This ini is used to configure peer uapsd inactivity time.
*
* Related: gEnableTDLSSupport.
*
* Supported Feature: TDLS
*
* Usage: Internal/External
*
* </ini>
*/
#define CFG_TDLS_PUAPSD_INACT_TIME CFG_INI_UINT( \
"gTDLSPuapsdInactivityTime", \
0, \
10, \
0, \
CFG_VALUE_OR_DEFAULT, \
"Peer UAPSD Inactivity time")
/*
* <ini>
* gTDLSPuapsdRxFrameThreshold - Peer UAPSD Rx frame threshold.
* @Min: 10
* @Max: 20
* @Default: 10
*
* This ini is used to configure maximum Rx frame during SP.
*
* Related: gEnableTDLSSupport.
*
* Supported Feature: TDLS
*
* Usage: Internal/External
*
* </ini>
*/
#define CFG_TDLS_RX_FRAME_THRESHOLD CFG_INI_UINT( \
"gTDLSPuapsdRxFrameThreshold", \
10, \
20, \
10, \
CFG_VALUE_OR_DEFAULT, \
"Peer UAPSD Rx frame threshold")
/*
* <ini>
* gEnableTDLSOffChannel - Enables off-channel support for TDLS link.
* @Min: 0
* @Max: 1
* @Default: 0
*
* This ini is used to enable/disable off-channel support for TDLS link.
*
* Related: gEnableTDLSSupport.
*
* Supported Feature: TDLS
*
* Usage: Internal/External
*
* </ini>
*/
#define CFG_TDLS_OFF_CHANNEL_ENABLED CFG_INI_BOOL( \
"gEnableTDLSOffChannel", \
0, \
"Enables off-channel support for TDLS")
/*
* <ini>
* gEnableTDLSSupport - Enable support for TDLS.
* @Min: 0
* @Max: 1
* @Default: 0
*
* This ini is used to enable/disable TDLS support.
*
* Related: None.
*
* Supported Feature: TDLS
*
* Usage: Internal/External
*
* </ini>
*/
#define CFG_TDLS_SUPPORT_ENABLE CFG_INI_BOOL( \
"gEnableTDLSSupport", \
0, \
"enable/disable TDLS support")
/*
* <ini>
* gEnableTDLSImplicitTrigger - Enable Implicit TDLS.
* @Min: 0
* @Max: 1
* @Default: 0
*
* This ini is used to enable/disable implicit TDLS.
* CLD driver initiates TDLS Discovery towards a peer whenever TDLS Setup
* criteria (throughput and RSSI thresholds) is met and then it tears down
* TDLS when teardown criteria (idle packet count and RSSI) is met.
*
* Related: gEnableTDLSSupport.
*
* Supported Feature: TDLS
*
* Usage: Internal/External
*
* </ini>
*/
#define CFG_TDLS_IMPLICIT_TRIGGER CFG_INI_BOOL( \
"gEnableTDLSImplicitTrigger", \
0, \
"enable/disable implicit TDLS")
/*
* <ini>
* gTDLSTxStatsPeriod - TDLS TX statistics time period.
* @Min: 1000
* @Max: 4294967295
* @Default: 2000
*
* This ini is used to configure the time period (in ms) to evaluate whether
* the number of Tx/Rx packets exceeds TDLSTxPacketThreshold and triggers a
* TDLS Discovery request.
*
* Related: gEnableTDLSSupport.
*
* Supported Feature: TDLS
*
* Usage: Internal/External
*
* </ini>
*/
#define CFG_TDLS_TX_STATS_PERIOD CFG_INI_UINT( \
"gTDLSTxStatsPeriod", \
1000, \
4294967295UL, \
2000, \
CFG_VALUE_OR_DEFAULT, \
"TDLS TX statistics time period")
/*
* <ini>
* gTDLSTxPacketThreshold - Tx/Rx Packet threshold for initiating TDLS.
* @Min: 0
* @Max: 4294967295
* @Default: 40
*
* This ini is used to configure the number of Tx/Rx packets during the
* period of gTDLSTxStatsPeriod when exceeded, a TDLS Discovery request
* is triggered.
* Related: gEnableTDLSSupport.
*
* Supported Feature: TDLS
*
* Usage: Internal/External
*
* </ini>
*/
#define CFG_TDLS_TX_PACKET_THRESHOLD CFG_INI_UINT( \
"gTDLSTxPacketThreshold", \
0, \
4294967295UL, \
40, \
CFG_VALUE_OR_DEFAULT, \
"Tx/Rx Packet threshold for initiating TDLS")
/*
* <ini>
* gTDLSMaxDiscoveryAttempt - Attempts for sending TDLS discovery requests.
* @Min: 1
* @Max: 100
* @Default: 5
*
* This ini is used to configure the number of failures of discover request,
* when exceeded, the peer is assumed to be not TDLS capable and no further
* TDLS Discovery request is made.
*
* Related: gEnableTDLSSupport.
*
* Supported Feature: TDLS
*
* Usage: Internal/External
*
* </ini>
*/
#define CFG_TDLS_MAX_DISCOVERY_ATTEMPT CFG_INI_UINT( \
"gTDLSMaxDiscoveryAttempt", \
1, \
100, \
5, \
CFG_VALUE_OR_DEFAULT, \
"Attempts for sending TDLS discovery requests")
/*
* <ini>
* gTDLSIdleTimeout - Duration within which number of TX / RX frames meet the
* criteria for TDLS teardown.
* @Min: 500
* @Max: 40000
* @Default: 5000
*
* This ini is used to configure the time period (in ms) to evaluate whether
* the number of Tx/Rx packets exceeds gTDLSIdlePacketThreshold and thus meets
* criteria for TDLS teardown.
* Teardown notification interval (gTDLSIdleTimeout) should be multiple of
* setup notification (gTDLSTxStatsPeriod) interval.
* e.g.
* if setup notification (gTDLSTxStatsPeriod) interval = 500, then
* teardown notification (gTDLSIdleTimeout) interval should be 1000,
* 1500, 2000, 2500...
*
* Related: gEnableTDLSSupport.
*
* Supported Feature: TDLS
*
* Usage: Internal/External
*
*/
#define CFG_TDLS_IDLE_TIMEOUT CFG_INI_UINT( \
"gTDLSIdleTimeout", \
500, \
40000, \
5000, \
CFG_VALUE_OR_DEFAULT, \
"this is idle time period")
/*
* <ini>
* gTDLSIdlePacketThreshold - Number of idle packet.
* @Min: 0
* @Max: 40000
* @Default: 3
*
* This ini is used to configure the number of Tx/Rx packet, below which
* within last gTDLSTxStatsPeriod period is considered as idle condition.
*
* Related: gEnableTDLSSupport.
*
* Supported Feature: TDLS
*
* Usage: Internal/External
*
* </ini>
*/
#define CFG_TDLS_IDLE_PACKET_THRESHOLD CFG_INI_UINT( \
"gTDLSIdlePacketThreshold", \
0, \
40000, \
3, \
CFG_VALUE_OR_DEFAULT, \
"Number of idle packet")
/*
* <ini>
* gTDLSRSSITriggerThreshold - RSSI threshold for TDLS connection.
* @Min: -120
* @Max: 0
* @Default: -75
*
* This ini is used to configure the absolute value (in dB) of the peer RSSI,
* below which a TDLS setup request is triggered.
*
* Related: gEnableTDLSSupport.
*
* Supported Feature: TDLS
*
* Usage: Internal/External
*
* </ini>
*/
#define CFG_TDLS_RSSI_TRIGGER_THRESHOLD CFG_INI_INT( \
"gTDLSRSSITriggerThreshold", \
-120, \
0, \
-75, \
CFG_VALUE_OR_DEFAULT, \
"RSSI threshold for TDLS connection")
/*
* <ini>
* gTDLSRSSITeardownThreshold - RSSI threshold for TDLS teardown.
* @Min: -120
* @Max: 0
* @Default: -75
*
* This ini is used to configure the absolute value (in dB) of the peer RSSI,
* when exceed, a TDLS teardown is triggered.
*
* Related: gEnableTDLSSupport.
*
* Supported Feature: TDLS
*
* Usage: Internal/External
*
* </ini>
*/
#define CFG_TDLS_RSSI_TEARDOWN_THRESHOLD CFG_INI_INT( \
"gTDLSRSSITeardownThreshold", \
-120, \
0, \
-75, \
CFG_VALUE_OR_DEFAULT, \
"RSSI threshold for TDLS teardown")
/*
* <ini>
* gTDLSRSSITeardownThreshold - RSSI threshold for TDLS teardown.
* @Min: -120
* @Max: 0
* @Default: -75
*
* This ini is used to configure the absolute value (in dB) of the peer RSSI,
* when exceed, a TDLS teardown is triggered.
*
* Related: gEnableTDLSSupport.
*
* Supported Feature: TDLS
*
* Usage: Internal/External
*
* </ini>
*/
#define CFG_TDLS_RSSI_DELTA CFG_INI_INT( \
"gTDLSRSSIDelta", \
-30, \
0, \
-20, \
CFG_VALUE_OR_DEFAULT, \
"Delta value for the peer RSSI that can trigger teardown")
/*
* <ini>
* gTDLSPrefOffChanNum - Preferred TDLS channel number when off-channel support
* is enabled.
* @Min: 1
* @Max: 165
* @Default: 36
*
* This ini is used to configure preferred TDLS channel number when off-channel
* support is enabled.
*
* Related: gEnableTDLSSupport, gEnableTDLSOffChannel.
*
* Supported Feature: TDLS
*
* Usage: Internal/External
*
* </ini>
*/
#define CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM CFG_INI_UINT( \
"gTDLSPrefOffChanNum", \
1, \
165, \
36, \
CFG_VALUE_OR_DEFAULT, \
"Preferred TDLS channel number")
/*
* <ini>
* gTDLSPrefOffChanBandwidth - Preferred TDLS channel bandwidth when
* off-channel support is enabled.
* @Min: 0x01
* @Max: 0x0F
* @Default: 0x07
*
* This ini is used to configure preferred TDLS channel bandwidth when
* off-channel support is enabled.
* 0x1: 20 MHz 0x2: 40 MHz 0x4: 80 MHz 0x8: 160 MHz
* When more than one bits are set then firmware starts from the highest and
* selects one based on capability of peer.
*
* Related: gEnableTDLSSupport, gEnableTDLSOffChannel.
*
* Supported Feature: TDLS
*
* Usage: Internal/External
*
* </ini>
*/
#define CFG_TDLS_PREFERRED_OFF_CHANNEL_BW CFG_INI_UINT( \
"gTDLSPrefOffChanBandwidth", \
1, \
15, \
7, \
CFG_VALUE_OR_DEFAULT, \
"Preferred TDLS channel bandwidth")
/*
* <ini>
* gTDLSPuapsdInactivityTime - Peer UAPSD Inactivity time.
* @Min: 0
* @Max: 10
* @Default: 0
*
* This ini is used to configure peer uapsd inactivity time.
*
* Related: gEnableTDLSSupport.
*
* Supported Feature: TDLS
*
* Usage: Internal/External
*
* </ini>
*/
#define CFG_TDLS_PUAPSD_INACTIVITY_TIME CFG_INI_UINT( \
"gTDLSPuapsdInactivityTime", \
0, \
10, \
0, \
CFG_VALUE_OR_DEFAULT, \
"Peer UAPSD Inactivity time")
/*
* <ini>
* gTDLSPuapsdInactivityTime - Peer UAPSD Inactivity time.
* @Min: 0
* @Max: 10
* @Default: 0
*
* This ini is used to configure peer uapsd inactivity time.
*
* Related: gEnableTDLSSupport.
*
* Supported Feature: TDLS
*
* Usage: Internal/External
*
* </ini>
*/
#define CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD CFG_INI_UINT( \
"gTDLSPuapsdRxFrameThreshold", \
10, \
20, \
10, \
CFG_VALUE_OR_DEFAULT, \
"Peer UAPSD Rx frame threshold")
/*
* <ini>
* gTDLSPuapsdPTIWindow - This ini is used to configure peer traffic indication
* window.
* @Min: 1
* @Max: 5
* @Default: 2
*
* This ini is used to configure buffering time in number of beacon intervals.
*
* Related: gEnableTDLSSupport.
*
* Supported Feature: TDLS
*
* Usage: Internal/External
*
* </ini>
*/
#define CFG_TDLS_PUAPSD_PEER_TRAFFIC_IND_WINDOW CFG_INI_UINT( \
"gTDLSPuapsdPTIWindow", \
1, \
5, \
2, \
CFG_VALUE_OR_DEFAULT, \
"This ini is used to configure peer traffic indication")
/*
* <ini>
* gTDLSPuapsdPTIWindow - This ini is used to configure peer traffic indication
* window.
* @Min: 1
* @Max: 5
* @Default: 2
*
* This ini is used to configure buffering time in number of beacon intervals.
*
* Related: gEnableTDLSSupport.
*
* Supported Feature: TDLS
*
* Usage: Internal/External
*
* </ini>
*/
#define CFG_TDLS_PUAPSD_PEER_TRAFFIC_RSP_TIMEOUT CFG_INI_UINT( \
"gTDLSPuapsdPTRTimeout", \
0, \
10000, \
5000, \
CFG_VALUE_OR_DEFAULT, \
"Peer Traffic Response timer duration in ms")
/*
* <ini>
* gTDLSPuapsdPTIWindow - This ini is used to configure peer traffic indication
* window.
* @Min: 1
* @Max: 5
* @Default: 2
*
* This ini is used to configure buffering time in number of beacon intervals.
*
* Related: gEnableTDLSSupport.
*
* Supported Feature: TDLS
*
* Usage: Internal/External
*
* </ini>
*/
#define CFG_TDLS_EXTERNAL_CONTROL CFG_INI_BOOL( \
"gTDLSExternalControl", \
1, \
"Enable external TDLS control")
/*
* <ini>
* gEnableTDLSWmmMode - Enables WMM support over TDLS link.
* @Min: 0
* @Max: 1
* @Default: 1
*
* This ini is used to enable/disable WMM support over TDLS link.
* This is required to be set to 1 for any TDLS and uAPSD functionality.
*
* Related: gEnableTDLSSupport.
*
* Supported Feature: TDLS
*
* Usage: Internal/External
*
* </ini>
*/
#define CFG_TDLS_WMM_MODE_ENABLE CFG_INI_BOOL( \
"gEnableTDLSWmmMode", \
1, \
"Enables WMM support over TDLS link")
/*
* <ini>
* gEnableTDLSScan - Allow scan and maintain TDLS link.
* @Min: 0
* @Max: 1
* @Default: 0
*
* This ini is used to enable/disable TDLS scan.
* 0: If peer is not buffer STA capable and device is not sleep STA
* capable, then teardown TDLS link when scan is initiated. If peer
* is buffer STA and we can be sleep STA then TDLS link is maintained
* during scan.
* 1: Maintain TDLS link and allow scan even if peer is not buffer STA
* capable and device is not sleep STA capable. There will be loss of
* Rx pkts since peer would not know when device moves away from tdls
* channel. Tx on TDLS link would stop when device moves away from tdls
* channel.
*
* Related: gEnableTDLSSupport.
*
* Supported Feature: TDLS
*
* Usage: Internal/External
*
* </ini>
*/
#define CFG_TDLS_SCAN_ENABLE CFG_INI_BOOL( \
"gEnableTDLSScan", \
0, \
"Allow scan and maintain TDLS link")
/*
* <ini>
* gTDLSPeerKickoutThreshold - TDLS peer kick out threshold to firmware.
* @Min: 10
* @Max: 5000
* @Default: 96
*
* This ini is used to configure TDLS peer kick out threshold to firmware.
* Firmware will use this value to determine, when to send TDLS
* peer kick out event to host.
* E.g.
* if peer kick out threshold is 10, then firmware will wait for 10
* consecutive packet failures and then send TDLS kick out
* notification to host driver
*
* Related: gEnableTDLSSupport.
*
* Supported Feature: TDLS
*
* Usage: Internal/External
*
* </ini>
*/
#define CFG_TDLS_PEER_KICKOUT_THRESHOLD CFG_INI_UINT( \
"gTDLSPeerKickoutThreshold", \
10, \
5000, \
96, \
CFG_VALUE_OR_DEFAULT, \
"TDLS peer kick out threshold to firmware")
/*
* <ini>
* gTDLSEnableDeferTime - Timer to defer for enabling TDLS on P2P listen.
* @Min: 500
* @Max: 6000
* @Default: 2000
*
* This ini is used to set the timer to defer for enabling TDLS on P2P
* listen (value in milliseconds).
*
* Related: gEnableTDLSSupport.
*
* Supported Feature: TDLS
*
* Usage: Internal/External
*
* </ini>
*/
#define CFG_TDLS_ENABLE_DEFER_TIMER CFG_INI_UINT( \
"gTDLSEnableDeferTime", \
500, \
6000, \
2000, \
CFG_VALUE_OR_DEFAULT, \
"Timer to defer for enabling TDLS on P2P listen")
/*
* <ini>
* DelayedTriggerFrmInt - delayed trigger frame interval.
* @Min: 500
* @Max: 6000
* @Default: 2000
*
* This ini is used to set the delayed trigger frame interval.
*
* Related: gEnableTDLSSupport.
*
* Supported Feature: TDLS
*
* Usage: Internal/External
*
* </ini>
*/
#define CFG_TDLS_DELAYED_TRGR_FRM_INT CFG_INI_UINT( \
"DelayedTriggerFrmInt", \
1, \
4294967295UL, \
3000, \
CFG_VALUE_OR_DEFAULT, \
"delayed trigger frame interval")
#define CFG_TDLS_ALL \
CFG(CFG_TDLS_QOS_WMM_UAPSD_MASK) \
CFG(CFG_TDLS_BUF_STA_ENABLED) \
CFG(CFG_TDLS_PUAPSD_INACT_TIME) \
CFG(CFG_TDLS_RX_FRAME_THRESHOLD) \
CFG(CFG_TDLS_OFF_CHANNEL_ENABLED) \
CFG(CFG_TDLS_SUPPORT_ENABLE) \
CFG(CFG_TDLS_IMPLICIT_TRIGGER) \
CFG(CFG_TDLS_TX_STATS_PERIOD) \
CFG(CFG_TDLS_TX_PACKET_THRESHOLD) \
CFG(CFG_TDLS_MAX_DISCOVERY_ATTEMPT) \
CFG(CFG_TDLS_IDLE_TIMEOUT) \
CFG(CFG_TDLS_IDLE_PACKET_THRESHOLD) \
CFG(CFG_TDLS_RSSI_TRIGGER_THRESHOLD) \
CFG(CFG_TDLS_RSSI_TEARDOWN_THRESHOLD) \
CFG(CFG_TDLS_RSSI_DELTA) \
CFG(CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM) \
CFG(CFG_TDLS_PREFERRED_OFF_CHANNEL_BW) \
CFG(CFG_TDLS_PUAPSD_INACTIVITY_TIME) \
CFG(CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD) \
CFG(CFG_TDLS_PUAPSD_PEER_TRAFFIC_IND_WINDOW) \
CFG(CFG_TDLS_PUAPSD_PEER_TRAFFIC_RSP_TIMEOUT) \
CFG(CFG_TDLS_EXTERNAL_CONTROL) \
CFG(CFG_TDLS_WMM_MODE_ENABLE) \
CFG(CFG_TDLS_SCAN_ENABLE) \
CFG(CFG_TDLS_PEER_KICKOUT_THRESHOLD) \
CFG(CFG_TDLS_ENABLE_DEFER_TIMER) \
CFG(CFG_TDLS_DELAYED_TRGR_FRM_INT)
#endif

View File

@@ -0,0 +1,217 @@
/*
* Copyright (c) 2018 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: Contains p2p configures interface definitions
*/
#ifndef _WLAN_TDLS_CFG_API_H_
#define _WLAN_TDLS_CFG_API_H_
#include <qdf_types.h>
struct wlan_objmgr_psoc;
/**
* cfg_tdls_get_support_enable() - get tdls support enable
* @psoc: pointer to psoc object
* @val: pointer to tdls support enable/disable
*
* This function gets tdls support enable
*/
QDF_STATUS
cfg_tdls_get_support_enable(struct wlan_objmgr_psoc *psoc,
bool *val);
/**
* cfg_tdls_set_support_enable() - set tdls support enable
* @psoc: pointer to psoc object
* @val: set tdls support enable/disable
*
* This function sets tdls support enable
*/
QDF_STATUS
cfg_tdls_set_support_enable(struct wlan_objmgr_psoc *psoc,
bool val);
/**
* cfg_tdls_get_external_control() - get tdls external control
* @psoc: pointer to psoc object
* @val: pointer to tdls external control enable/disable
*
* This function gets tdls external control
*/
QDF_STATUS
cfg_tdls_get_external_control(struct wlan_objmgr_psoc *psoc,
bool *val);
/**
* cfg_tdls_get_uapsd_mask() - get tdls uapsd mask
* @psoc: pointer to psoc object
* @val: pointer to tdls uapsd mask
*
* This function gets tdls uapsd mask
*/
QDF_STATUS
cfg_tdls_get_uapsd_mask(struct wlan_objmgr_psoc *psoc,
uint32_t *val);
/**
* cfg_tdls_get_buffer_sta_enable() - get tdls buffer sta enable
* @psoc: pointer to psoc object
* @val: pointer to tdls buffer sta enable
*
* This function gets tdls buffer sta enable
*/
QDF_STATUS
cfg_tdls_get_buffer_sta_enable(struct wlan_objmgr_psoc *psoc,
bool *val);
/**
* cfg_tdls_set_buffer_sta_enable() - set tdls buffer sta enable
* @psoc: pointer to psoc object
* @val: tdls buffer sta enable
*
* This function sets tdls buffer sta enable
*/
QDF_STATUS
cfg_tdls_set_buffer_sta_enable(struct wlan_objmgr_psoc *psoc,
bool val);
/**
* cfg_tdls_get_uapsd_inactivity_time() - get tdls uapsd inactivity time
* @psoc: pointer to psoc object
* @val: pointer to tdls uapsd inactivity time
*
* This function gets tdls uapsd inactivity time
*/
QDF_STATUS
cfg_tdls_get_uapsd_inactivity_time(struct wlan_objmgr_psoc *psoc,
uint32_t *val);
/**
* cfg_tdls_get_rx_pkt_threshold() - get tdls rx pkt threshold
* @psoc: pointer to psoc object
* @val: pointer to tdls tdls rx pkt threshold
*
* This function gets tdls rx pkt threshold
*/
QDF_STATUS
cfg_tdls_get_rx_pkt_threshold(struct wlan_objmgr_psoc *psoc,
uint32_t *val);
/**
* cfg_tdls_get_off_channel_enable() - get tdls off channel enable
* @psoc: pointer to psoc object
* @val: pointer to tdls off channel enable
*
* This function gets tdls off channel enable
*/
QDF_STATUS
cfg_tdls_get_off_channel_enable(struct wlan_objmgr_psoc *psoc,
bool *val);
/**
* cfg_tdls_set_off_channel_enable() - set tdls off channel enable
* @psoc: pointer to psoc object
* @val: tdls off channel enable
*
* This function sets tdls off channel enable
*/
QDF_STATUS
cfg_tdls_set_off_channel_enable(struct wlan_objmgr_psoc *psoc,
bool val);
/**
* cfg_tdls_get_wmm_mode_enable() - get tdls wmm mode enable
* @psoc: pointer to psoc object
* @val: pointer to tdls wmm mode enable
*
* This function gets tdls wmm mode enable
*/
QDF_STATUS
cfg_tdls_get_wmm_mode_enable(struct wlan_objmgr_psoc *psoc,
bool *val);
/**
* cfg_tdls_set_vdev_nss_2g() - set tdls vdev nss 2g
* @psoc: pointer to psoc object
* @val: tdls vdev nss 2g
*
* This function sets tdls vdev nss 2g
*/
QDF_STATUS
cfg_tdls_set_vdev_nss_2g(struct wlan_objmgr_psoc *psoc,
uint8_t val);
/**
* cfg_tdls_set_vdev_nss_5g() - set tdls vdev nss 5g
* @psoc: pointer to psoc object
* @val: tdls vdev nss 5g
*
* This function sets tdls vdev nss 5g
*/
QDF_STATUS
cfg_tdls_set_vdev_nss_5g(struct wlan_objmgr_psoc *psoc,
uint8_t val);
/**
* cfg_tdls_get_sleep_sta_enable() - get tdls sleep sta enable
* @psoc: pointer to psoc object
* @val: pointer to tdls sleep sta enable
*
* This function gets tdls sleep sta enable
*/
QDF_STATUS
cfg_tdls_get_sleep_sta_enable(struct wlan_objmgr_psoc *psoc,
bool *val);
/**
* cfg_tdls_set_sleep_sta_enable() - set tdls sleep sta enable
* @psoc: pointer to psoc object
* @val: tdls sleep sta enable
*
* This function sets tdls sleep sta enable
*/
QDF_STATUS
cfg_tdls_set_sleep_sta_enable(struct wlan_objmgr_psoc *psoc,
bool val);
/**
* cfg_tdls_get_scan_enable() - get tdls scan enable
* @psoc: pointer to psoc object
* @val: pointer to tdls scan enable
*
* This function gets tdls scan enable
*/
QDF_STATUS
cfg_tdls_get_scan_enable(struct wlan_objmgr_psoc *psoc,
bool *val);
/**
* cfg_tdls_set_scan_enable() - set tdls scan enable
* @psoc: pointer to psoc object
* @val: tdls scan enable
*
* This function sets tdls scan enable
*/
QDF_STATUS
cfg_tdls_set_scan_enable(struct wlan_objmgr_psoc *psoc,
bool val);
#endif /* _WLAN_TDLS_CFG_API_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,173 @@
/*
* Copyright (c) 2018 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_tgt_api.h
*
* TDLS south bound interface declaration
*/
#ifndef _WLAN_TDLS_TGT_API_H_
#define _WLAN_TDLS_TGT_API_H_
#include <wlan_tdls_public_structs.h>
#include "../../core/src/wlan_tdls_main.h"
/**
* tgt_tdls_set_fw_state() - invoke lmac tdls update fw
* @psoc: soc object
* @tdls_param: update tdls state parameters
*
* Return: QDF_STATUS
*/
QDF_STATUS tgt_tdls_set_fw_state(struct wlan_objmgr_psoc *psoc,
struct tdls_info *tdls_param);
/**
* tgt_tdls_set_peer_state() - invoke lmac tdls update peer state
* @psoc: soc object
* @peer_param: update tdls peer parameters
*
* Return: QDF_STATUS
*/
QDF_STATUS tgt_tdls_set_peer_state(struct wlan_objmgr_psoc *psoc,
struct tdls_peer_update_state *peer_param);
/**
* tgt_tdls_set_offchan_mode() - invoke lmac tdls set off-channel mode
* @psoc: soc object
* @param: set tdls off channel parameters
*
* Return: QDF_STATUS
*/
QDF_STATUS tgt_tdls_set_offchan_mode(struct wlan_objmgr_psoc *psoc,
struct tdls_channel_switch_params *param);
/**
* tgt_tdls_set_uapsd()- invoke lamc tdls set uapsd function
* @psoc: soc object
* @params: uapsd parameters
*
* Return: QDF_STATUS
*/
QDF_STATUS tgt_tdls_set_uapsd(struct wlan_objmgr_psoc *psoc,
struct sta_uapsd_trig_params *params);
/**
* tgt_tdls_send_mgmt_rsp() - process tdls mgmt response
* @pmsg: sheduler msg
*
* Return: QDF_STATUS
*/
QDF_STATUS tgt_tdls_send_mgmt_rsp(struct scheduler_msg *pmsg);
/**
* tgt_tdls_send_mgmt_tx_completion() -process tx completion message
* @pmsg: sheduler msg
*
* Return: QDF_STATUS
*/
QDF_STATUS tgt_tdls_send_mgmt_tx_completion(struct scheduler_msg *pmsg);
/**
* tgt_tdls_del_peer_rsp() - handle TDLS del peer response
* @pmsg: sheduler msg
*
* Return: QDF_STATUS
*/
QDF_STATUS tgt_tdls_del_peer_rsp(struct scheduler_msg *pmsg);
/**
* tgt_tdls_add_peer_rsp() - handle TDLS add peer response
* @pmsg: sheduler msg
*
* Return: QDF_STATUS
*/
QDF_STATUS tgt_tdls_add_peer_rsp(struct scheduler_msg *pmsg);
/**
* tgt_tdls_register_ev_handler() - invoke lmac register tdls event handler
* @psoc: soc object
*
* Return: QDF_STATUS_SUCCESS for success or error code.
*/
QDF_STATUS tgt_tdls_register_ev_handler(struct wlan_objmgr_psoc *psoc);
/**
* tgt_tdls_unregister_ev_handler() - invoke lmac unregister tdls event handler
* @psoc: soc object
*
* Return: QDF_STATUS_SUCCESS for success or error code.
*/
QDF_STATUS tgt_tdls_unregister_ev_handler(struct wlan_objmgr_psoc *psoc);
/**
* tgt_tdls_event_handler() - The callback registered to WMI for tdls events
* @psoc: psoc object
* @info: tdls event info
*
* The callback is registered by tgt as tdls rx ops handler.
*
* Return: 0 for success or err code.
*/
QDF_STATUS
tgt_tdls_event_handler(struct wlan_objmgr_psoc *psoc,
struct tdls_event_info *info);
/**
* tgt_tdls_mgmt_frame_rx_cb() - callback for rx mgmt frame
* @psoc: soc context
* @peer: peer context
* @buf: rx buffer
* @mgmt_rx_params: mgmt rx parameters
* @frm_type: frame type
*
* This function gets called from mgmt tx/rx component when rx mgmt
* received.
*
* Return: QDF_STATUS_SUCCESS
*/
QDF_STATUS tgt_tdls_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_peer *peer, qdf_nbuf_t buf,
struct mgmt_rx_event_params *mgmt_rx_params,
enum mgmt_frame_type frm_type);
/**
* tgt_tdls_peers_deleted_notification()- notification from legacy lim
* @psoc: soc object
* @session_id: session id
*
* This function called from legacy lim to notify tdls peer deletion
*
* Return: None
*/
void tgt_tdls_peers_deleted_notification(struct wlan_objmgr_psoc *psoc,
uint32_t session_id);
/**
* tgt_tdls_delete_all_peers_indication()- Indication to tdls component
* @psoc: soc object
* @session_id: session id
*
* This function called from legacy lim to tdls component to delete tdls peers.
*
* Return: None
*/
void tgt_tdls_delete_all_peers_indication(struct wlan_objmgr_psoc *psoc,
uint32_t session_id);
#endif

View File

@@ -0,0 +1,254 @@
/*
* Copyright (c) 2017-2018 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_ucfg_api.h
*
* TDLS north bound interface declaration
*/
#if !defined(_WLAN_TDLS_UCFG_API_H_)
#define _WLAN_TDLS_UCFG_API_H_
#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
*
* Return: QDF_STATUS
*/
QDF_STATUS ucfg_tdls_init(void);
/**
* ucfg_tdls_deinit() - TDLS module deinitialization API
*
* Return: QDF_STATUS
*/
QDF_STATUS ucfg_tdls_deinit(void);
/**
* ucfg_tdls_psoc_open() - TDLS module psoc open API
* @psoc: psoc object
*
* Return: QDF_STATUS
*/
QDF_STATUS ucfg_tdls_psoc_open(struct wlan_objmgr_psoc *psoc);
/**
* ucfg_tdls_psoc_close() - TDLS module psoc close API
* @psoc: psoc object
*
* Return: QDF_STATUS
*/
QDF_STATUS ucfg_tdls_psoc_close(struct wlan_objmgr_psoc *psoc);
/**
* ucfg_tdls_psoc_start() - TDLS module start
* @psoc: psoc object
* @req: tdls start paramets
*
* Return: QDF_STATUS
*/
QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc,
struct tdls_start_params *req);
/**
* ucfg_tdls_psoc_enable() - TDLS module enable API
* @psoc: psoc object
*
* Return: QDF_STATUS
*/
QDF_STATUS ucfg_tdls_psoc_enable(struct wlan_objmgr_psoc *psoc);
/**
* ucfg_tdls_psoc_disable() - TDLS moudle disable API
* @psoc: psoc object
*
* Return: QDF_STATUS
*/
QDF_STATUS ucfg_tdls_psoc_disable(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);
/**
* ucfg_tdls_oper() - handle TDLS oper functions
* @vdev: vdev object
* @macaddr: MAC address of TDLS peer
* @cmd: oper cmd
*
* Return: QDF_STATUS
*/
QDF_STATUS ucfg_tdls_oper(struct wlan_objmgr_vdev *vdev,
const uint8_t *macaddr, enum tdls_command_type cmd);
/**
* ucfg_tdls_get_all_peers() - get all tdls peers from the list
* @vdev: vdev object
* @buf: output buffer
* @buflen: length of written data
*
* Return: QDF_STATUS
*/
QDF_STATUS ucfg_tdls_get_all_peers(struct wlan_objmgr_vdev *vdev,
char *buf, int buflen);
/**
* 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);
/**
* ucfg_tdls_responder() - set responder in TDLS peer
* @msg_req: responder msg
*
* Return: QDF_STATUS
*/
QDF_STATUS ucfg_tdls_responder(struct tdls_set_responder_req *msg_req);
/**
* ucfg_tdls_teardown_links() - teardown all TDLS links
* @vdev: vdev object manager
*
* Return: None
*/
QDF_STATUS ucfg_tdls_teardown_links(struct wlan_objmgr_vdev *vdev);
/**
* ucfg_tdls_notify_reset_adapter() - notify reset adapter
* @vdev: vdev object manager
*
* Return: QDF_STATUS
*/
QDF_STATUS ucfg_tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev);
/**
* ucfg_tdls_notify_sta_connect() - notify sta connect
* @notify_info: sta notification info
*
* Return: QDF_STATUS
*/
QDF_STATUS ucfg_tdls_notify_sta_connect(
struct tdls_sta_notify_params *notify_info);
/**
* ucfg_tdls_notify_sta_disconnect() - notify sta disconnect
* @notify_info: sta notification info
*
* Return: QDF_STATUS
*/
QDF_STATUS ucfg_tdls_notify_sta_disconnect(
struct tdls_sta_notify_params *notify_info);
/**
* ucfg_tdls_set_operating_mode() - set operating mode
* @set_mode_params: set mode params
*
* Return: QDF_STATUS
*/
QDF_STATUS ucfg_tdls_set_operating_mode(
struct tdls_set_mode_params *set_mode_params);
/**
* ucfg_tdls_update_rx_pkt_cnt() - update rx pkt count
* @vdev: tdls vdev object
* @mac_addr: peer mac address
*
* Return: None
*/
void ucfg_tdls_update_rx_pkt_cnt(struct wlan_objmgr_vdev *vdev,
struct qdf_mac_addr *mac_addr);
/**
* ucfg_tdls_update_tx_pkt_cnt() - update tx pkt count
* @vdev: tdls vdev object
* @mac_addr: peer mac address
*
* Return: None
*/
void ucfg_tdls_update_tx_pkt_cnt(struct wlan_objmgr_vdev *vdev,
struct qdf_mac_addr *mac_addr);
/**
* ucfg_tdls_antenna_switch() - tdls antenna switch
* @vdev: tdls vdev object
* @mode: antenna mode
*
* Return: QDF_STATUS
*/
QDF_STATUS ucfg_tdls_antenna_switch(struct wlan_objmgr_vdev *vdev,
uint32_t mode);
/**
* ucfg_set_tdls_offchannel() - Handle TDLS set offchannel
* @vdev: vdev object
* @offchannel: updated offchannel
*
* Return: QDF_STATUS
*/
QDF_STATUS ucfg_set_tdls_offchannel(struct wlan_objmgr_vdev *vdev,
int offchannel);
/**
* ucfg_set_tdls_offchan_mode() - Handle TDLS set offchannel mode
* @vdev: vdev object
* @offchanmode: updated off-channel mode
*
* Return: QDF_STATUS
*/
QDF_STATUS ucfg_set_tdls_offchan_mode(struct wlan_objmgr_vdev *vdev,
int offchanmode);
/**
* ucfg_set_tdls_secoffchanneloffset() - Handle TDLS set offchannel offset
* @vdev: vdev object
* @offchanoffset: tdls off-channel offset
*
* Return: QDF_STATUS
*/
QDF_STATUS ucfg_set_tdls_secoffchanneloffset(struct wlan_objmgr_vdev *vdev,
int offchanoffset);
#endif

View File

@@ -0,0 +1,324 @@
/*
* Copyright (c) 2018 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: This file contains TDLS configures interface definitions
*/
#include <wlan_objmgr_psoc_obj.h>
#include "wlan_tdls_cfg_api.h"
#include "../../core/src/wlan_tdls_main.h"
QDF_STATUS
cfg_tdls_get_support_enable(struct wlan_objmgr_psoc *psoc,
bool *val)
{
struct tdls_soc_priv_obj *soc_obj;
soc_obj = wlan_psoc_get_tdls_soc_obj(psoc);
if (!soc_obj) {
*val = false;
tdls_err("tdls soc null");
return QDF_STATUS_E_INVAL;
}
*val = soc_obj->tdls_configs.tdls_support_enable;
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
cfg_tdls_set_support_enable(struct wlan_objmgr_psoc *psoc,
bool val)
{
struct tdls_soc_priv_obj *soc_obj;
soc_obj = wlan_psoc_get_tdls_soc_obj(psoc);
if (!soc_obj) {
tdls_err("tdls soc null");
return QDF_STATUS_E_INVAL;
}
soc_obj->tdls_configs.tdls_support_enable = val;
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
cfg_tdls_get_external_control(struct wlan_objmgr_psoc *psoc,
bool *val)
{
struct tdls_soc_priv_obj *soc_obj;
soc_obj = wlan_psoc_get_tdls_soc_obj(psoc);
if (!soc_obj) {
*val = false;
tdls_err("tdls soc null");
return QDF_STATUS_E_INVAL;
}
*val = soc_obj->tdls_configs.tdls_external_control;
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
cfg_tdls_get_uapsd_mask(struct wlan_objmgr_psoc *psoc,
uint32_t *val)
{
struct tdls_soc_priv_obj *soc_obj;
soc_obj = wlan_psoc_get_tdls_soc_obj(psoc);
if (!soc_obj) {
*val = 0;
tdls_err("tdls soc null");
return QDF_STATUS_E_INVAL;
}
*val = soc_obj->tdls_configs.tdls_uapsd_mask;
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
cfg_tdls_get_buffer_sta_enable(struct wlan_objmgr_psoc *psoc,
bool *val)
{
struct tdls_soc_priv_obj *soc_obj;
soc_obj = wlan_psoc_get_tdls_soc_obj(psoc);
if (!soc_obj) {
*val = false;
tdls_err("tdls soc null");
return QDF_STATUS_E_INVAL;
}
*val = soc_obj->tdls_configs.tdls_buffer_sta_enable;
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
cfg_tdls_set_buffer_sta_enable(struct wlan_objmgr_psoc *psoc,
bool val)
{
struct tdls_soc_priv_obj *soc_obj;
soc_obj = wlan_psoc_get_tdls_soc_obj(psoc);
if (!soc_obj) {
tdls_err("tdls soc null");
return QDF_STATUS_E_INVAL;
}
soc_obj->tdls_configs.tdls_buffer_sta_enable = val;
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
cfg_tdls_get_uapsd_inactivity_time(struct wlan_objmgr_psoc *psoc,
uint32_t *val)
{
struct tdls_soc_priv_obj *soc_obj;
soc_obj = wlan_psoc_get_tdls_soc_obj(psoc);
if (!soc_obj) {
*val = 0;
tdls_err("tdls soc null");
return QDF_STATUS_E_INVAL;
}
*val = soc_obj->tdls_configs.tdls_uapsd_inactivity_time;
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
cfg_tdls_get_rx_pkt_threshold(struct wlan_objmgr_psoc *psoc,
uint32_t *val)
{
struct tdls_soc_priv_obj *soc_obj;
soc_obj = wlan_psoc_get_tdls_soc_obj(psoc);
if (!soc_obj) {
*val = 0;
tdls_err("tdls soc null");
return QDF_STATUS_E_INVAL;
}
*val = soc_obj->tdls_configs.tdls_rx_pkt_threshold;
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
cfg_tdls_get_off_channel_enable(struct wlan_objmgr_psoc *psoc,
bool *val)
{
struct tdls_soc_priv_obj *soc_obj;
soc_obj = wlan_psoc_get_tdls_soc_obj(psoc);
if (!soc_obj) {
*val = false;
tdls_err("tdls soc null");
return QDF_STATUS_E_INVAL;
}
*val = soc_obj->tdls_configs.tdls_off_chan_enable;
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
cfg_tdls_set_off_channel_enable(struct wlan_objmgr_psoc *psoc,
bool val)
{
struct tdls_soc_priv_obj *soc_obj;
soc_obj = wlan_psoc_get_tdls_soc_obj(psoc);
if (!soc_obj) {
tdls_err("tdls soc null");
return QDF_STATUS_E_INVAL;
}
soc_obj->tdls_configs.tdls_off_chan_enable = val;
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
cfg_tdls_get_wmm_mode_enable(struct wlan_objmgr_psoc *psoc,
bool *val)
{
struct tdls_soc_priv_obj *soc_obj;
soc_obj = wlan_psoc_get_tdls_soc_obj(psoc);
if (!soc_obj) {
*val = false;
tdls_err("tdls soc null");
return QDF_STATUS_E_INVAL;
}
*val = soc_obj->tdls_configs.tdls_wmm_mode_enable;
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
cfg_tdls_set_vdev_nss_2g(struct wlan_objmgr_psoc *psoc,
uint8_t val)
{
struct tdls_soc_priv_obj *soc_obj;
soc_obj = wlan_psoc_get_tdls_soc_obj(psoc);
if (!soc_obj) {
tdls_err("tdls soc null");
return QDF_STATUS_E_INVAL;
}
soc_obj->tdls_configs.tdls_vdev_nss_2g = val;
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
cfg_tdls_set_vdev_nss_5g(struct wlan_objmgr_psoc *psoc,
uint8_t val)
{
struct tdls_soc_priv_obj *soc_obj;
soc_obj = wlan_psoc_get_tdls_soc_obj(psoc);
if (!soc_obj) {
tdls_err("tdls soc null");
return QDF_STATUS_E_INVAL;
}
soc_obj->tdls_configs.tdls_vdev_nss_5g = val;
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
cfg_tdls_get_sleep_sta_enable(struct wlan_objmgr_psoc *psoc,
bool *val)
{
struct tdls_soc_priv_obj *soc_obj;
soc_obj = wlan_psoc_get_tdls_soc_obj(psoc);
if (!soc_obj) {
*val = false;
tdls_err("tdls soc null");
return QDF_STATUS_E_INVAL;
}
*val = soc_obj->tdls_configs.tdls_sleep_sta_enable;
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
cfg_tdls_set_sleep_sta_enable(struct wlan_objmgr_psoc *psoc,
bool val)
{
struct tdls_soc_priv_obj *soc_obj;
soc_obj = wlan_psoc_get_tdls_soc_obj(psoc);
if (!soc_obj) {
tdls_err("tdls soc null");
return QDF_STATUS_E_INVAL;
}
soc_obj->tdls_configs.tdls_sleep_sta_enable = val;
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
cfg_tdls_get_scan_enable(struct wlan_objmgr_psoc *psoc,
bool *val)
{
struct tdls_soc_priv_obj *soc_obj;
soc_obj = wlan_psoc_get_tdls_soc_obj(psoc);
if (!soc_obj) {
*val = false;
tdls_err("tdls soc null");
return QDF_STATUS_E_INVAL;
}
*val = soc_obj->tdls_configs.tdls_scan_enable;
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
cfg_tdls_set_scan_enable(struct wlan_objmgr_psoc *psoc,
bool val)
{
struct tdls_soc_priv_obj *soc_obj;
soc_obj = wlan_psoc_get_tdls_soc_obj(psoc);
if (!soc_obj) {
tdls_err("tdls soc null");
return QDF_STATUS_E_INVAL;
}
soc_obj->tdls_configs.tdls_scan_enable = val;
return QDF_STATUS_SUCCESS;
}

View File

@@ -0,0 +1,383 @@
/*
* Copyright (c) 2017-2018 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_tgt_api.c
*
* TDLS south bound interface definitions
*/
#include "qdf_status.h"
#include <wlan_tdls_tgt_api.h>
#include "../../core/src/wlan_tdls_main.h"
#include "../../core/src/wlan_tdls_cmds_process.h"
#include "../../core/src/wlan_tdls_mgmt.h"
static inline struct wlan_lmac_if_tdls_tx_ops *
wlan_psoc_get_tdls_txops(struct wlan_objmgr_psoc *psoc)
{
return &psoc->soc_cb.tx_ops.tdls_tx_ops;
}
static inline struct wlan_lmac_if_tdls_rx_ops *
wlan_psoc_get_tdls_rxops(struct wlan_objmgr_psoc *psoc)
{
return &psoc->soc_cb.rx_ops.tdls_rx_ops;
}
QDF_STATUS tgt_tdls_set_fw_state(struct wlan_objmgr_psoc *psoc,
struct tdls_info *tdls_param)
{
struct wlan_lmac_if_tdls_tx_ops *tdls_ops = NULL;
tdls_ops = wlan_psoc_get_tdls_txops(psoc);
if (tdls_ops && tdls_ops->update_fw_state)
return tdls_ops->update_fw_state(psoc, tdls_param);
else
return QDF_STATUS_SUCCESS;
}
QDF_STATUS tgt_tdls_set_peer_state(struct wlan_objmgr_psoc *psoc,
struct tdls_peer_update_state *peer_param)
{
struct wlan_lmac_if_tdls_tx_ops *tdls_ops = NULL;
tdls_ops = wlan_psoc_get_tdls_txops(psoc);
if (tdls_ops && tdls_ops->update_peer_state)
return tdls_ops->update_peer_state(psoc, peer_param);
else
return QDF_STATUS_SUCCESS;
}
QDF_STATUS tgt_tdls_set_offchan_mode(struct wlan_objmgr_psoc *psoc,
struct tdls_channel_switch_params *param)
{
struct wlan_lmac_if_tdls_tx_ops *tdls_ops = NULL;
tdls_ops = wlan_psoc_get_tdls_txops(psoc);
if (tdls_ops && tdls_ops->set_offchan_mode)
return tdls_ops->set_offchan_mode(psoc, param);
else
return QDF_STATUS_SUCCESS;
}
QDF_STATUS tgt_tdls_set_uapsd(struct wlan_objmgr_psoc *psoc,
struct sta_uapsd_trig_params *params)
{
struct wlan_lmac_if_tdls_tx_ops *tdls_ops = NULL;
tdls_ops = wlan_psoc_get_tdls_txops(psoc);
if (tdls_ops && tdls_ops->tdls_set_uapsd)
return tdls_ops->tdls_set_uapsd(psoc, params);
else
return QDF_STATUS_SUCCESS;
}
QDF_STATUS tgt_tdls_send_mgmt_tx_completion(struct scheduler_msg *pmsg)
{
QDF_STATUS status = QDF_STATUS_SUCCESS;
if (!pmsg || !pmsg->bodyptr) {
tdls_err("msg: 0x%pK", pmsg);
QDF_ASSERT(0);
return QDF_STATUS_E_NULL_VALUE;
}
status = tdls_send_mgmt_tx_completion(pmsg->bodyptr);
return status;
}
QDF_STATUS tgt_tdls_send_mgmt_rsp(struct scheduler_msg *pmsg)
{
QDF_STATUS status = QDF_STATUS_SUCCESS;
if (!pmsg || !pmsg->bodyptr) {
tdls_err("msg: 0x%pK", pmsg);
QDF_ASSERT(0);
return QDF_STATUS_E_NULL_VALUE;
}
status = tdls_process_send_mgmt_rsp(pmsg->bodyptr);
return status;
}
QDF_STATUS tgt_tdls_add_peer_rsp(struct scheduler_msg *pmsg)
{
QDF_STATUS status = QDF_STATUS_SUCCESS;
if (!pmsg || !pmsg->bodyptr) {
tdls_err("msg: 0x%pK", pmsg);
QDF_ASSERT(0);
return QDF_STATUS_E_NULL_VALUE;
}
status = tdls_process_add_peer_rsp(pmsg->bodyptr);
return status;
}
QDF_STATUS tgt_tdls_del_peer_rsp(struct scheduler_msg *pmsg)
{
QDF_STATUS status = QDF_STATUS_SUCCESS;
if (!pmsg || !pmsg->bodyptr) {
tdls_err("msg: 0x%pK", pmsg);
QDF_ASSERT(0);
return QDF_STATUS_E_NULL_VALUE;
}
status = tdls_process_del_peer_rsp(pmsg->bodyptr);
return status;
}
QDF_STATUS tgt_tdls_register_ev_handler(struct wlan_objmgr_psoc *psoc)
{
struct wlan_lmac_if_tdls_tx_ops *tdls_ops = NULL;
tdls_ops = wlan_psoc_get_tdls_txops(psoc);
if (tdls_ops && tdls_ops->tdls_reg_ev_handler)
return tdls_ops->tdls_reg_ev_handler(psoc, NULL);
else
return QDF_STATUS_SUCCESS;
}
QDF_STATUS tgt_tdls_unregister_ev_handler(struct wlan_objmgr_psoc *psoc)
{
struct wlan_lmac_if_tdls_tx_ops *tdls_ops = NULL;
tdls_ops = wlan_psoc_get_tdls_txops(psoc);
if (tdls_ops->tdls_unreg_ev_handler)
return tdls_ops->tdls_unreg_ev_handler(psoc, NULL);
else
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS tgt_tdls_event_flush_cb(struct scheduler_msg *msg)
{
struct tdls_event_notify *notify;
notify = msg->bodyptr;
if (notify && notify->vdev) {
wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_SB_ID);
qdf_mem_free(notify);
}
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
tgt_tdls_event_handler(struct wlan_objmgr_psoc *psoc,
struct tdls_event_info *info)
{
struct scheduler_msg msg = {0,};
struct tdls_event_notify *notify;
uint8_t vdev_id;
QDF_STATUS status;
if (!psoc || !info) {
tdls_err("psoc: 0x%pK, info: 0x%pK", psoc, info);
return QDF_STATUS_E_NULL_VALUE;
}
tdls_debug("vdev: %d, type: %d, reason: %d" QDF_MAC_ADDR_STR,
info->vdev_id, info->message_type, info->peer_reason,
QDF_MAC_ADDR_ARRAY(info->peermac.bytes));
notify = qdf_mem_malloc(sizeof(*notify));
if (!notify) {
tdls_err("mem allocate fail");
return QDF_STATUS_E_NOMEM;
}
vdev_id = info->vdev_id;
notify->vdev =
wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
vdev_id, WLAN_TDLS_SB_ID);
if (!notify->vdev) {
tdls_err("null vdev, vdev_id: %d, psoc: 0x%pK", vdev_id, psoc);
return QDF_STATUS_E_INVAL;
}
qdf_mem_copy(&notify->event, info, sizeof(*info));
msg.bodyptr = notify;
msg.callback = tdls_process_evt;
msg.flush_callback = tgt_tdls_event_flush_cb;
status = scheduler_post_message(QDF_MODULE_ID_TDLS,
QDF_MODULE_ID_TDLS,
QDF_MODULE_ID_TARGET_IF, &msg);
if (QDF_IS_STATUS_ERROR(status)) {
tdls_err("can't post msg to handle tdls event");
wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_SB_ID);
qdf_mem_free(notify);
}
return status;
}
static QDF_STATUS tgt_tdls_mgmt_frame_rx_flush_cb(struct scheduler_msg *msg)
{
struct tdls_rx_mgmt_event *rx_mgmt_event;
rx_mgmt_event = msg->bodyptr;
if (rx_mgmt_event) {
if (rx_mgmt_event->rx_mgmt)
qdf_mem_free(rx_mgmt_event->rx_mgmt);
qdf_mem_free(rx_mgmt_event);
}
msg->bodyptr = NULL;
return QDF_STATUS_SUCCESS;
}
static
QDF_STATUS tgt_tdls_mgmt_frame_process_rx_cb(
struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_peer *peer,
qdf_nbuf_t buf,
struct mgmt_rx_event_params *mgmt_rx_params,
enum mgmt_frame_type frm_type)
{
struct tdls_rx_mgmt_frame *rx_mgmt;
struct tdls_rx_mgmt_event *rx_mgmt_event;
struct tdls_soc_priv_obj *tdls_soc_obj;
struct scheduler_msg msg = {0};
struct wlan_objmgr_vdev *vdev;
uint32_t vdev_id;
uint8_t *pdata;
QDF_STATUS status;
tdls_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
WLAN_UMAC_COMP_TDLS);
if (!tdls_soc_obj) {
tdls_err("tdls ctx is NULL, drop this frame");
return QDF_STATUS_E_FAILURE;
}
if (!peer) {
vdev = tdls_get_vdev(psoc, WLAN_TDLS_SB_ID);
if (!vdev) {
tdls_err("current tdls vdev is null, can't get vdev id");
return QDF_STATUS_E_FAILURE;
}
vdev_id = wlan_vdev_get_id(vdev);
wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID);
} else {
vdev = wlan_peer_get_vdev(peer);
if (!vdev) {
tdls_err("vdev is NULL in peer, drop this frame");
return QDF_STATUS_E_FAILURE;
}
vdev_id = wlan_vdev_get_id(vdev);
}
rx_mgmt_event = qdf_mem_malloc(sizeof(*rx_mgmt_event));
if (!rx_mgmt_event) {
tdls_err("Failed to allocate rx mgmt event");
return QDF_STATUS_E_NOMEM;
}
rx_mgmt = qdf_mem_malloc(sizeof(*rx_mgmt) +
mgmt_rx_params->buf_len);
if (!rx_mgmt) {
tdls_err("Failed to allocate rx mgmt frame");
qdf_mem_free(rx_mgmt_event);
return QDF_STATUS_E_NOMEM;
}
pdata = (uint8_t *)qdf_nbuf_data(buf);
rx_mgmt->frame_len = mgmt_rx_params->buf_len;
rx_mgmt->rx_chan = mgmt_rx_params->channel;
rx_mgmt->vdev_id = vdev_id;
rx_mgmt->frm_type = frm_type;
rx_mgmt->rx_rssi = mgmt_rx_params->rssi;
rx_mgmt_event->rx_mgmt = rx_mgmt;
rx_mgmt_event->tdls_soc_obj = tdls_soc_obj;
qdf_mem_copy(rx_mgmt->buf, pdata, mgmt_rx_params->buf_len);
msg.type = TDLS_EVENT_RX_MGMT;
msg.bodyptr = rx_mgmt_event;
msg.callback = tdls_process_rx_frame;
msg.flush_callback = tgt_tdls_mgmt_frame_rx_flush_cb;
status = scheduler_post_message(QDF_MODULE_ID_TDLS,
QDF_MODULE_ID_TDLS,
QDF_MODULE_ID_TARGET_IF, &msg);
if (QDF_IS_STATUS_ERROR(status)) {
qdf_mem_free(rx_mgmt);
qdf_mem_free(rx_mgmt_event);
}
qdf_nbuf_free(buf);
return status;
}
QDF_STATUS tgt_tdls_mgmt_frame_rx_cb(
struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_peer *peer,
qdf_nbuf_t buf,
struct mgmt_rx_event_params *mgmt_rx_params,
enum mgmt_frame_type frm_type)
{
QDF_STATUS status;
tdls_debug("psoc:%pK, peer:%pK, type:%d", psoc, peer, frm_type);
if (!buf) {
tdls_err("rx frame buff is null buf:%pK", buf);
return QDF_STATUS_E_INVAL;
}
if (!mgmt_rx_params || !psoc) {
tdls_err("input is NULL mgmt_rx_params:%pK psoc:%pK, peer:%pK",
mgmt_rx_params, psoc, peer);
status = QDF_STATUS_E_INVAL;
goto release_nbuf;
}
status = wlan_objmgr_peer_try_get_ref(peer, WLAN_TDLS_SB_ID);
if (QDF_STATUS_SUCCESS != status)
goto release_nbuf;
status = tgt_tdls_mgmt_frame_process_rx_cb(psoc, peer, buf,
mgmt_rx_params, frm_type);
wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_SB_ID);
if (QDF_STATUS_SUCCESS != status)
release_nbuf:
qdf_nbuf_free(buf);
return status;
}
void tgt_tdls_peers_deleted_notification(struct wlan_objmgr_psoc *psoc,
uint32_t session_id)
{
tdls_peers_deleted_notification(psoc, session_id);
}
void tgt_tdls_delete_all_peers_indication(struct wlan_objmgr_psoc *psoc,
uint32_t session_id)
{
tdls_delete_all_peers_indication(psoc, session_id);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,23 @@
/*
* 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_utils_api.c
*
* TDLS utility functions definitions
*/