qcacld-3.0: Add logic to support tdls on MLO
Since for MLD device, it can only choice one link for tdls, add logic like this: 1\ As initiator, it needs to send discovery request on each link, before send the frame, it needs to force active the link; 2\ As responder, it sends the discovery response the link id, before send the frame, it needs to force active the link; 3\ For other tdls management and tdls operation, it needs to find out which link(vdev) is used as tdls link first. Change-Id: I64e27219eb6c6b3fef62e541423aa8e5d84b1560 CRs-Fixed: 3439568
This commit is contained in:

committed by
Madan Koyyalamudi

parent
7d518a4ab9
commit
0752365a21
@@ -1008,6 +1008,7 @@ static void tdls_ct_process_handler(struct wlan_objmgr_vdev *vdev)
|
|||||||
void tdls_ct_handler(void *user_data)
|
void tdls_ct_handler(void *user_data)
|
||||||
{
|
{
|
||||||
struct wlan_objmgr_vdev *vdev;
|
struct wlan_objmgr_vdev *vdev;
|
||||||
|
struct wlan_objmgr_vdev *link_vdev;
|
||||||
|
|
||||||
if (!user_data)
|
if (!user_data)
|
||||||
return;
|
return;
|
||||||
@@ -1016,7 +1017,17 @@ void tdls_ct_handler(void *user_data)
|
|||||||
if (!vdev)
|
if (!vdev)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tdls_ct_process_handler(vdev);
|
link_vdev = tdls_mlo_get_tdls_link_vdev(vdev);
|
||||||
|
if (link_vdev) {
|
||||||
|
if (wlan_objmgr_vdev_try_get_ref(link_vdev, WLAN_TDLS_NB_ID) ==
|
||||||
|
QDF_STATUS_SUCCESS) {
|
||||||
|
tdls_ct_process_handler(link_vdev);
|
||||||
|
wlan_objmgr_vdev_release_ref(link_vdev,
|
||||||
|
WLAN_TDLS_NB_ID);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tdls_ct_process_handler(vdev);
|
||||||
|
}
|
||||||
|
|
||||||
wlan_objmgr_vdev_release_ref(vdev,
|
wlan_objmgr_vdev_release_ref(vdev,
|
||||||
WLAN_TDLS_NB_ID);
|
WLAN_TDLS_NB_ID);
|
||||||
|
@@ -634,14 +634,15 @@ static QDF_STATUS tdls_activate_send_mgmt_request_flush_cb(
|
|||||||
return QDF_STATUS_SUCCESS;
|
return QDF_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QDF_STATUS tdls_activate_send_mgmt_request(
|
static QDF_STATUS
|
||||||
struct tdls_action_frame_request *action_req)
|
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;
|
struct tdls_soc_priv_obj *tdls_soc_obj;
|
||||||
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
QDF_STATUS status;
|
||||||
struct scheduler_msg msg = {0};
|
|
||||||
struct tdls_send_mgmt_request *tdls_mgmt_req;
|
struct tdls_send_mgmt_request *tdls_mgmt_req;
|
||||||
|
struct wlan_objmgr_peer *peer;
|
||||||
|
struct scheduler_msg msg = {0};
|
||||||
|
struct tdls_vdev_priv_obj *tdls_vdev;
|
||||||
|
|
||||||
if (!action_req || !action_req->vdev)
|
if (!action_req || !action_req->vdev)
|
||||||
return QDF_STATUS_E_NULL_VALUE;
|
return QDF_STATUS_E_NULL_VALUE;
|
||||||
@@ -684,6 +685,7 @@ static QDF_STATUS tdls_activate_send_mgmt_request(
|
|||||||
if (!peer) {
|
if (!peer) {
|
||||||
tdls_err("bss peer is null");
|
tdls_err("bss peer is null");
|
||||||
qdf_mem_free(tdls_mgmt_req);
|
qdf_mem_free(tdls_mgmt_req);
|
||||||
|
status = QDF_STATUS_E_NULL_VALUE;
|
||||||
goto release_cmd;
|
goto release_cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -707,6 +709,25 @@ static QDF_STATUS tdls_activate_send_mgmt_request(
|
|||||||
else
|
else
|
||||||
tdls_mgmt_req->ac = WIFI_AC_BK;
|
tdls_mgmt_req->ac = WIFI_AC_BK;
|
||||||
|
|
||||||
|
if (wlan_vdev_mlme_is_mlo_vdev(action_req->vdev) &&
|
||||||
|
!tdls_mlo_get_tdls_link_vdev(action_req->vdev) &&
|
||||||
|
tdls_mgmt_req->req_type == TDLS_DISCOVERY_REQUEST) {
|
||||||
|
tdls_vdev = wlan_vdev_get_tdls_vdev_obj(action_req->vdev);
|
||||||
|
if (QDF_TIMER_STATE_RUNNING !=
|
||||||
|
qdf_mc_timer_get_current_state(
|
||||||
|
&tdls_vdev->peer_discovery_timer)) {
|
||||||
|
tdls_timer_restart(tdls_vdev->vdev,
|
||||||
|
&tdls_vdev->peer_discovery_timer,
|
||||||
|
tdls_vdev->threshold_config.tx_period_t -
|
||||||
|
TDLS_DISCOVERY_TIMEOUT_ERE_UPDATE);
|
||||||
|
qdf_atomic_inc(&tdls_soc_obj->timer_cnt);
|
||||||
|
} else {
|
||||||
|
qdf_mem_free(tdls_mgmt_req);
|
||||||
|
status = QDF_STATUS_E_NULL_VALUE;
|
||||||
|
goto release_cmd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Send the request to PE. */
|
/* Send the request to PE. */
|
||||||
qdf_mem_zero(&msg, sizeof(msg));
|
qdf_mem_zero(&msg, sizeof(msg));
|
||||||
|
|
||||||
@@ -781,6 +802,52 @@ tdls_send_mgmt_serialize_callback(struct wlan_serialization_command *cmd,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WLAN_FEATURE_11BE_MLO
|
||||||
|
static QDF_STATUS tdls_set_link_mode(struct tdls_action_frame_request *req)
|
||||||
|
{
|
||||||
|
uint8_t mlo_vdev_lst[WLAN_UMAC_MLO_MAX_VDEVS] = {-1};
|
||||||
|
struct wlan_objmgr_psoc *psoc;
|
||||||
|
struct wlan_objmgr_vdev *mlo_tdls_vdev;
|
||||||
|
uint8_t vdev_count = 0;
|
||||||
|
bool is_mlo_vdev;
|
||||||
|
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
is_mlo_vdev = wlan_vdev_mlme_is_mlo_vdev(req->vdev);
|
||||||
|
if (!is_mlo_vdev)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
mlo_tdls_vdev = wlan_mlo_get_tdls_link_vdev(req->vdev);
|
||||||
|
if (mlo_tdls_vdev)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
psoc = wlan_vdev_get_psoc(req->vdev);
|
||||||
|
if (!psoc) {
|
||||||
|
tdls_err("psoc is NULL");
|
||||||
|
return QDF_STATUS_E_NULL_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req->tdls_mgmt.frame_type == TDLS_DISCOVERY_RESPONSE ||
|
||||||
|
req->tdls_mgmt.frame_type == TDLS_DISCOVERY_REQUEST) {
|
||||||
|
mlo_vdev_lst[0] = wlan_vdev_get_id(req->vdev);
|
||||||
|
vdev_count = 1;
|
||||||
|
|
||||||
|
status = policy_mgr_mlo_sta_set_link(psoc,
|
||||||
|
MLO_LINK_FORCE_REASON_TDLS,
|
||||||
|
MLO_LINK_FORCE_MODE_ACTIVE,
|
||||||
|
vdev_count, mlo_vdev_lst);
|
||||||
|
if (status == QDF_STATUS_SUCCESS)
|
||||||
|
req->link_active = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static QDF_STATUS tdls_set_link_mode(struct tdls_action_frame_request *req)
|
||||||
|
{
|
||||||
|
return QDF_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
QDF_STATUS tdls_process_mgmt_req(
|
QDF_STATUS tdls_process_mgmt_req(
|
||||||
struct tdls_action_frame_request *tdls_mgmt_req)
|
struct tdls_action_frame_request *tdls_mgmt_req)
|
||||||
{
|
{
|
||||||
@@ -796,6 +863,14 @@ QDF_STATUS tdls_process_mgmt_req(
|
|||||||
goto error_mgmt;
|
goto error_mgmt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status = tdls_set_link_mode(tdls_mgmt_req);
|
||||||
|
if (status != QDF_STATUS_SUCCESS) {
|
||||||
|
tdls_err("failed to set link active");
|
||||||
|
status = tdls_internal_send_mgmt_tx_done(tdls_mgmt_req,
|
||||||
|
status);
|
||||||
|
goto error_mgmt;
|
||||||
|
}
|
||||||
|
|
||||||
/* update the responder, status code information
|
/* update the responder, status code information
|
||||||
* after the cmd validation
|
* after the cmd validation
|
||||||
*/
|
*/
|
||||||
|
@@ -1176,20 +1176,24 @@ struct tdls_get_all_peers {
|
|||||||
* @vdev: vdev object
|
* @vdev: vdev object
|
||||||
* @chk_frame: This struct used to validate mgmt frame
|
* @chk_frame: This struct used to validate mgmt frame
|
||||||
* @session_id: session id
|
* @session_id: session id
|
||||||
|
* @link_id: link id
|
||||||
* @vdev_id: vdev id
|
* @vdev_id: vdev id
|
||||||
* @cmd_buf: cmd buffer
|
* @cmd_buf: cmd buffer
|
||||||
* @len: length of the frame
|
* @len: length of the frame
|
||||||
* @use_default_ac: access category
|
* @use_default_ac: access category
|
||||||
|
* @link_active: whether link active command send successfully
|
||||||
* @tdls_mgmt: tdls management
|
* @tdls_mgmt: tdls management
|
||||||
*/
|
*/
|
||||||
struct tdls_action_frame_request {
|
struct tdls_action_frame_request {
|
||||||
struct wlan_objmgr_vdev *vdev;
|
struct wlan_objmgr_vdev *vdev;
|
||||||
struct tdls_validate_action_req chk_frame;
|
struct tdls_validate_action_req chk_frame;
|
||||||
uint8_t session_id;
|
uint8_t session_id;
|
||||||
|
uint8_t link_id;
|
||||||
uint8_t vdev_id;
|
uint8_t vdev_id;
|
||||||
const uint8_t *cmd_buf;
|
const uint8_t *cmd_buf;
|
||||||
uint8_t len;
|
uint8_t len;
|
||||||
bool use_default_ac;
|
bool use_default_ac;
|
||||||
|
bool link_active;
|
||||||
/* Variable length, do not add anything after this */
|
/* Variable length, do not add anything after this */
|
||||||
struct tdls_send_mgmt tdls_mgmt;
|
struct tdls_send_mgmt tdls_mgmt;
|
||||||
};
|
};
|
||||||
|
@@ -181,6 +181,35 @@ void ucfg_tdls_update_fw_mlo_capability(struct wlan_objmgr_psoc *psoc,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ucfg_tdls_link_vdev_is_matching() - check whether vdev is matching link vdev
|
||||||
|
* @vdev: vdev object
|
||||||
|
*
|
||||||
|
* Return: bool
|
||||||
|
*/
|
||||||
|
bool ucfg_tdls_link_vdev_is_matching(struct wlan_objmgr_vdev *vdev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ucfg_tdls_get_tdls_link_vdev() - get tdls link vdev
|
||||||
|
* @vdev: vdev object
|
||||||
|
* @dbg_id: debug id
|
||||||
|
*
|
||||||
|
* Return: vdev pointer
|
||||||
|
*/
|
||||||
|
struct wlan_objmgr_vdev *
|
||||||
|
ucfg_tdls_get_tdls_link_vdev(struct wlan_objmgr_vdev *vdev,
|
||||||
|
wlan_objmgr_ref_dbgid dbg_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ucfg_tdls_put_tdls_link_vdev() - put tdls link vdev
|
||||||
|
* @vdev: vdev odject
|
||||||
|
* @dbg_id: debug id
|
||||||
|
*
|
||||||
|
* Return: void
|
||||||
|
*/
|
||||||
|
void ucfg_tdls_put_tdls_link_vdev(struct wlan_objmgr_vdev *vdev,
|
||||||
|
wlan_objmgr_ref_dbgid dbg_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ucfg_tdls_psoc_enable() - TDLS module enable API
|
* ucfg_tdls_psoc_enable() - TDLS module enable API
|
||||||
* @psoc: psoc object
|
* @psoc: psoc object
|
||||||
@@ -429,6 +458,25 @@ struct wlan_objmgr_vdev *ucfg_get_tdls_vdev(struct wlan_objmgr_psoc *psoc,
|
|||||||
wlan_objmgr_ref_dbgid dbg_id);
|
wlan_objmgr_ref_dbgid dbg_id);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
static inline
|
||||||
|
bool ucfg_tdls_link_vdev_is_matching(struct wlan_objmgr_vdev *vdev)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
struct wlan_objmgr_vdev *
|
||||||
|
ucfg_tdls_get_tdls_link_vdev(struct wlan_objmgr_vdev *vdev,
|
||||||
|
wlan_objmgr_ref_dbgid dbg_id)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
void ucfg_tdls_put_tdls_link_vdev(struct wlan_objmgr_vdev *vdev,
|
||||||
|
wlan_objmgr_ref_dbgid dbg_id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
QDF_STATUS ucfg_tdls_init(void)
|
QDF_STATUS ucfg_tdls_init(void)
|
||||||
|
@@ -34,6 +34,7 @@
|
|||||||
#include "wlan_policy_mgr_api.h"
|
#include "wlan_policy_mgr_api.h"
|
||||||
#include "wlan_scan_ucfg_api.h"
|
#include "wlan_scan_ucfg_api.h"
|
||||||
#include "cfg_tdls.h"
|
#include "cfg_tdls.h"
|
||||||
|
#include "wlan_mlo_mgr_sta.h"
|
||||||
#include "cfg_ucfg_api.h"
|
#include "cfg_ucfg_api.h"
|
||||||
#include "wlan_tdls_api.h"
|
#include "wlan_tdls_api.h"
|
||||||
|
|
||||||
@@ -519,6 +520,49 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc,
|
|||||||
return QDF_STATUS_SUCCESS;
|
return QDF_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ucfg_tdls_link_vdev_is_matching(struct wlan_objmgr_vdev *vdev)
|
||||||
|
{
|
||||||
|
struct wlan_objmgr_vdev *tdls_link_vdev;
|
||||||
|
|
||||||
|
tdls_link_vdev = tdls_mlo_get_tdls_link_vdev(vdev);
|
||||||
|
if (!tdls_link_vdev) {
|
||||||
|
wlan_vdev_mlme_feat_ext2_cap_set(vdev,
|
||||||
|
WLAN_VDEV_FEXT2_MLO_STA_TDLS);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tdls_link_vdev && tdls_link_vdev != vdev) {
|
||||||
|
tdls_debug("tdls vdev has been created on vdev %d",
|
||||||
|
wlan_vdev_get_id(tdls_link_vdev));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlan_objmgr_vdev *
|
||||||
|
ucfg_tdls_get_tdls_link_vdev(struct wlan_objmgr_vdev *vdev,
|
||||||
|
wlan_objmgr_ref_dbgid dbg_id)
|
||||||
|
{
|
||||||
|
struct wlan_objmgr_vdev *link_vdev;
|
||||||
|
|
||||||
|
link_vdev = tdls_mlo_get_tdls_link_vdev(vdev);
|
||||||
|
if (!link_vdev)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (wlan_objmgr_vdev_try_get_ref(link_vdev, dbg_id) !=
|
||||||
|
QDF_STATUS_SUCCESS)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return link_vdev;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ucfg_tdls_put_tdls_link_vdev(struct wlan_objmgr_vdev *vdev,
|
||||||
|
wlan_objmgr_ref_dbgid dbg_id)
|
||||||
|
{
|
||||||
|
wlan_objmgr_vdev_release_ref(vdev, dbg_id);
|
||||||
|
}
|
||||||
|
|
||||||
QDF_STATUS ucfg_tdls_psoc_enable(struct wlan_objmgr_psoc *psoc)
|
QDF_STATUS ucfg_tdls_psoc_enable(struct wlan_objmgr_psoc *psoc)
|
||||||
{
|
{
|
||||||
QDF_STATUS status;
|
QDF_STATUS status;
|
||||||
|
@@ -21684,12 +21684,34 @@ static int wlan_hdd_add_key_mlo_vdev(mac_handle_t mac_handle,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pairwise && link_id == -1)
|
link_vdev = ucfg_tdls_get_tdls_link_vdev(vdev, WLAN_OSIF_TDLS_ID);
|
||||||
|
if (pairwise && link_id == -1 && !link_vdev)
|
||||||
return wlan_hdd_add_key_all_mlo_vdev(mac_handle, vdev,
|
return wlan_hdd_add_key_all_mlo_vdev(mac_handle, vdev,
|
||||||
key_index, pairwise,
|
key_index, pairwise,
|
||||||
mac_addr, params,
|
mac_addr, params,
|
||||||
link_id, adapter);
|
link_id, adapter);
|
||||||
|
|
||||||
|
if (pairwise && link_id == -1 && link_vdev) {
|
||||||
|
hdd_ctx = WLAN_HDD_GET_CTX(adapter);
|
||||||
|
link_adapter =
|
||||||
|
hdd_get_adapter_by_vdev(hdd_ctx,
|
||||||
|
wlan_vdev_get_id(link_vdev));
|
||||||
|
link_id = wlan_vdev_get_link_id(link_vdev);
|
||||||
|
if (!link_adapter) {
|
||||||
|
ucfg_tdls_put_tdls_link_vdev(link_vdev,
|
||||||
|
WLAN_OSIF_TDLS_ID);
|
||||||
|
hdd_err("couldn't set tdls key, link_id %d", link_id);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
errno = wlan_hdd_add_key_vdev(mac_handle, link_vdev, key_index,
|
||||||
|
pairwise, mac_addr, params,
|
||||||
|
link_id, link_adapter);
|
||||||
|
ucfg_tdls_put_tdls_link_vdev(link_vdev, WLAN_OSIF_TDLS_ID);
|
||||||
|
|
||||||
|
return errno;
|
||||||
|
}
|
||||||
|
|
||||||
if (wlan_vdev_get_link_id(adapter->deflink->vdev) == link_id) {
|
if (wlan_vdev_get_link_id(adapter->deflink->vdev) == link_id) {
|
||||||
hdd_debug("add_key for same vdev: %d",
|
hdd_debug("add_key for same vdev: %d",
|
||||||
adapter->deflink->vdev_id);
|
adapter->deflink->vdev_id);
|
||||||
@@ -23234,6 +23256,19 @@ int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef TDLS_MGMT_VERSION5
|
||||||
|
static inline
|
||||||
|
uint8_t wlan_hdd_get_link_id(struct station_parameters *params)
|
||||||
|
{
|
||||||
|
return params->link_sta_params.link_id;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static inline
|
||||||
|
uint8_t wlan_hdd_get_link_id(struct station_parameters *params)
|
||||||
|
{
|
||||||
|
return 255;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
/**
|
/**
|
||||||
* __wlan_hdd_cfg80211_add_station() - add station
|
* __wlan_hdd_cfg80211_add_station() - add station
|
||||||
* @wiphy: Pointer to wiphy
|
* @wiphy: Pointer to wiphy
|
||||||
@@ -23253,6 +23288,7 @@ static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
|
|||||||
struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
|
struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
|
||||||
struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
|
struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
|
||||||
u32 mask, set;
|
u32 mask, set;
|
||||||
|
uint8_t link_id;
|
||||||
|
|
||||||
hdd_enter();
|
hdd_enter();
|
||||||
|
|
||||||
@@ -23272,24 +23308,15 @@ static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
mask = params->sta_flags_mask;
|
mask = params->sta_flags_mask;
|
||||||
|
|
||||||
set = params->sta_flags_set;
|
set = params->sta_flags_set;
|
||||||
|
link_id = wlan_hdd_get_link_id(params);
|
||||||
hdd_debug("mask 0x%x set 0x%x " QDF_MAC_ADDR_FMT, mask, set,
|
hdd_debug("mask 0x%x set 0x%x link_id %d " QDF_MAC_ADDR_FMT, mask, set,
|
||||||
QDF_MAC_ADDR_REF(mac));
|
link_id, QDF_MAC_ADDR_REF(mac));
|
||||||
|
|
||||||
if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
|
if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
|
||||||
if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
|
if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
|
||||||
struct wlan_objmgr_vdev *vdev;
|
status = wlan_cfg80211_tdls_add_peer_mlo(adapter,
|
||||||
|
mac, link_id);
|
||||||
vdev = hdd_objmgr_get_vdev_by_user(adapter,
|
|
||||||
WLAN_OSIF_TDLS_ID);
|
|
||||||
if (vdev) {
|
|
||||||
status = wlan_cfg80211_tdls_add_peer(vdev,
|
|
||||||
mac);
|
|
||||||
hdd_objmgr_put_vdev_by_user(vdev,
|
|
||||||
WLAN_OSIF_TDLS_ID);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -80,6 +80,7 @@ int wlan_hdd_tdls_get_all_peers(struct hdd_adapter *adapter,
|
|||||||
int len;
|
int len;
|
||||||
struct hdd_context *hdd_ctx;
|
struct hdd_context *hdd_ctx;
|
||||||
struct wlan_objmgr_vdev *vdev;
|
struct wlan_objmgr_vdev *vdev;
|
||||||
|
struct wlan_objmgr_vdev *link_vdev;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
hdd_enter();
|
hdd_enter();
|
||||||
@@ -103,7 +104,15 @@ int wlan_hdd_tdls_get_all_peers(struct hdd_adapter *adapter,
|
|||||||
len = scnprintf(buf, buflen, "\nVDEV is NULL\n");
|
len = scnprintf(buf, buflen, "\nVDEV is NULL\n");
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
ret = wlan_cfg80211_tdls_get_all_peers(vdev, buf, buflen);
|
|
||||||
|
link_vdev = ucfg_tdls_get_tdls_link_vdev(vdev, WLAN_OSIF_TDLS_ID);
|
||||||
|
if (link_vdev) {
|
||||||
|
ret = wlan_cfg80211_tdls_get_all_peers(link_vdev, buf, buflen);
|
||||||
|
ucfg_tdls_put_tdls_link_vdev(link_vdev, WLAN_OSIF_TDLS_ID);
|
||||||
|
} else {
|
||||||
|
ret = wlan_cfg80211_tdls_get_all_peers(vdev, buf, buflen);
|
||||||
|
}
|
||||||
|
|
||||||
hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_TDLS_ID);
|
hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_TDLS_ID);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@@ -467,6 +476,9 @@ static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
|
|||||||
struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
|
struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
|
||||||
struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
|
struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
|
||||||
bool tdls_support;
|
bool tdls_support;
|
||||||
|
#ifndef TDLS_MGMT_VERSION5
|
||||||
|
int link_id = -1;
|
||||||
|
#endif
|
||||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0))
|
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0))
|
||||||
#if !(TDLS_MGMT_VERSION2)
|
#if !(TDLS_MGMT_VERSION2)
|
||||||
u32 peer_capability;
|
u32 peer_capability;
|
||||||
@@ -498,17 +510,12 @@ static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hdd_ctx->tdls_umac_comp_active) {
|
if (hdd_ctx->tdls_umac_comp_active) {
|
||||||
struct wlan_objmgr_vdev *vdev;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
vdev = hdd_objmgr_get_vdev_by_user(adapter, WLAN_OSIF_TDLS_ID);
|
ret = wlan_cfg80211_tdls_mgmt_mlo(adapter, peer,
|
||||||
if (!vdev)
|
action_code, dialog_token,
|
||||||
return -EINVAL;
|
status_code, peer_capability,
|
||||||
ret = wlan_cfg80211_tdls_mgmt(vdev, peer,
|
buf, len, link_id);
|
||||||
action_code, dialog_token,
|
|
||||||
status_code, peer_capability,
|
|
||||||
buf, len);
|
|
||||||
hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_TDLS_ID);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
|
* Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
|
||||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and/or distribute this software for
|
* Permission to use, copy, modify, and/or distribute this software for
|
||||||
* any purpose with or without fee is hereby granted, provided that the
|
* any purpose with or without fee is hereby granted, provided that the
|
||||||
@@ -32,6 +32,7 @@
|
|||||||
#include <wlan_tdls_public_structs.h>
|
#include <wlan_tdls_public_structs.h>
|
||||||
#include <qdf_list.h>
|
#include <qdf_list.h>
|
||||||
#include <qdf_types.h>
|
#include <qdf_types.h>
|
||||||
|
#include <wlan_hdd_main.h>
|
||||||
#include <wlan_tdls_ucfg_api.h>
|
#include <wlan_tdls_ucfg_api.h>
|
||||||
|
|
||||||
#ifdef FEATURE_WLAN_TDLS
|
#ifdef FEATURE_WLAN_TDLS
|
||||||
@@ -110,14 +111,15 @@ QDF_STATUS wlan_cfg80211_tdls_osif_priv_init(struct wlan_objmgr_vdev *vdev);
|
|||||||
void wlan_cfg80211_tdls_osif_priv_deinit(struct wlan_objmgr_vdev *vdev);
|
void wlan_cfg80211_tdls_osif_priv_deinit(struct wlan_objmgr_vdev *vdev);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* wlan_cfg80211_tdls_add_peer() - process cfg80211 add TDLS peer request
|
* wlan_cfg80211_tdls_add_peer_mlo() - process cfg80211 add TDLS peer request
|
||||||
* @vdev: vdev object
|
* @adapter: adapter pointer
|
||||||
* @mac: MAC address for TDLS peer
|
* @mac: MAC address for TDLS peer
|
||||||
|
* @link_id: link id
|
||||||
*
|
*
|
||||||
* Return: 0 for success; negative errno otherwise
|
* Return: 0 for success; negative errno otherwise
|
||||||
*/
|
*/
|
||||||
int wlan_cfg80211_tdls_add_peer(struct wlan_objmgr_vdev *vdev,
|
int wlan_cfg80211_tdls_add_peer_mlo(struct hdd_adapter *adapter,
|
||||||
const uint8_t *mac);
|
const uint8_t *mac, uint8_t link_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* wlan_cfg80211_tdls_update_peer() - process cfg80211 update TDLS peer request
|
* wlan_cfg80211_tdls_update_peer() - process cfg80211 update TDLS peer request
|
||||||
@@ -185,8 +187,9 @@ bool wlan_cfg80211_tdls_is_fw_6ghz_capable(struct wlan_objmgr_vdev *vdev);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* wlan_cfg80211_tdls_mgmt() - process TDLS management frames from the supplicant
|
* wlan_cfg80211_tdls_mgmt_mlo() - process TDLS management frames from
|
||||||
* @vdev: vdev object
|
* the supplicant
|
||||||
|
* @adapter: adapter object
|
||||||
* @peer: MAC address of the TDLS peer
|
* @peer: MAC address of the TDLS peer
|
||||||
* @action_code: type of TDLS mgmt frame to be sent
|
* @action_code: type of TDLS mgmt frame to be sent
|
||||||
* @dialog_token: dialog token used in the frame
|
* @dialog_token: dialog token used in the frame
|
||||||
@@ -194,14 +197,15 @@ bool wlan_cfg80211_tdls_is_fw_6ghz_capable(struct wlan_objmgr_vdev *vdev);
|
|||||||
* @peer_capability: peer capability information
|
* @peer_capability: peer capability information
|
||||||
* @buf: additional IEs to be included
|
* @buf: additional IEs to be included
|
||||||
* @len: length of additional Ies
|
* @len: length of additional Ies
|
||||||
|
* @link_id: link id
|
||||||
*
|
*
|
||||||
* Return: 0 on success; negative errno otherwise
|
* Return: 0 on success; negative errno otherwise
|
||||||
*/
|
*/
|
||||||
int wlan_cfg80211_tdls_mgmt(struct wlan_objmgr_vdev *vdev,
|
int wlan_cfg80211_tdls_mgmt_mlo(struct hdd_adapter *adapter,
|
||||||
const uint8_t *peer,
|
const uint8_t *peer,
|
||||||
uint8_t action_code, uint8_t dialog_token,
|
uint8_t action_code, uint8_t dialog_token,
|
||||||
uint16_t status_code, uint32_t peer_capability,
|
uint16_t status_code, uint32_t peer_capability,
|
||||||
const uint8_t *buf, size_t len);
|
const uint8_t *buf, size_t len, int link_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* wlan_tdls_antenna_switch() - process TDLS antenna switch
|
* wlan_tdls_antenna_switch() - process TDLS antenna switch
|
||||||
|
@@ -39,6 +39,8 @@
|
|||||||
#include "wlan_tdls_ucfg_api.h"
|
#include "wlan_tdls_ucfg_api.h"
|
||||||
#include "wlan_cm_roam_api.h"
|
#include "wlan_cm_roam_api.h"
|
||||||
#include "wlan_mlo_mgr_sta.h"
|
#include "wlan_mlo_mgr_sta.h"
|
||||||
|
#include "wlan_hdd_main.h"
|
||||||
|
#include "wlan_hdd_object_manager.h"
|
||||||
|
|
||||||
static int wlan_cfg80211_tdls_validate_mac_addr(const uint8_t *mac)
|
static int wlan_cfg80211_tdls_validate_mac_addr(const uint8_t *mac)
|
||||||
{
|
{
|
||||||
@@ -104,8 +106,8 @@ void hdd_notify_tdls_reset_adapter(struct wlan_objmgr_vdev *vdev)
|
|||||||
ucfg_tdls_notify_reset_adapter(vdev);
|
ucfg_tdls_notify_reset_adapter(vdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
int wlan_cfg80211_tdls_add_peer(struct wlan_objmgr_vdev *vdev,
|
static int wlan_cfg80211_tdls_add_peer(struct wlan_objmgr_vdev *vdev,
|
||||||
const uint8_t *mac)
|
const uint8_t *mac)
|
||||||
{
|
{
|
||||||
struct tdls_add_peer_params *add_peer_req;
|
struct tdls_add_peer_params *add_peer_req;
|
||||||
int status;
|
int status;
|
||||||
@@ -163,6 +165,42 @@ error:
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int wlan_cfg80211_tdls_add_peer_mlo(struct hdd_adapter *adapter,
|
||||||
|
const uint8_t *mac, uint8_t link_id)
|
||||||
|
{
|
||||||
|
struct wlan_objmgr_vdev *vdev;
|
||||||
|
bool is_mlo_vdev;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
vdev = hdd_objmgr_get_vdev_by_user(adapter, WLAN_OSIF_TDLS_ID);
|
||||||
|
if (!vdev)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
is_mlo_vdev = wlan_vdev_mlme_is_mlo_vdev(vdev);
|
||||||
|
if (is_mlo_vdev) {
|
||||||
|
hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_TDLS_ID);
|
||||||
|
|
||||||
|
vdev = wlan_key_get_link_vdev(adapter, WLAN_OSIF_TDLS_ID,
|
||||||
|
link_id);
|
||||||
|
if (!vdev)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (!ucfg_tdls_link_vdev_is_matching(vdev)) {
|
||||||
|
wlan_key_put_link_vdev(vdev, WLAN_OSIF_TDLS_ID);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
osif_debug("tdls add peer for vdev %d", wlan_vdev_get_id(vdev));
|
||||||
|
status = wlan_cfg80211_tdls_add_peer(vdev, mac);
|
||||||
|
wlan_key_put_link_vdev(vdev, WLAN_OSIF_TDLS_ID);
|
||||||
|
} else {
|
||||||
|
status = wlan_cfg80211_tdls_add_peer(vdev, mac);
|
||||||
|
hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_TDLS_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
is_duplicate_freq(qdf_freq_t *arr, uint8_t index, qdf_freq_t freq)
|
is_duplicate_freq(qdf_freq_t *arr, uint8_t index, qdf_freq_t freq)
|
||||||
{
|
{
|
||||||
@@ -623,6 +661,7 @@ int wlan_cfg80211_tdls_update_peer(struct wlan_objmgr_vdev *vdev,
|
|||||||
struct wlan_objmgr_psoc *psoc;
|
struct wlan_objmgr_psoc *psoc;
|
||||||
bool tdls_11ax_support = false;
|
bool tdls_11ax_support = false;
|
||||||
bool tdls_6g_support = false;
|
bool tdls_6g_support = false;
|
||||||
|
bool is_mlo_vdev;
|
||||||
|
|
||||||
status = wlan_cfg80211_tdls_validate_mac_addr(mac);
|
status = wlan_cfg80211_tdls_validate_mac_addr(mac);
|
||||||
|
|
||||||
@@ -632,14 +671,25 @@ int wlan_cfg80211_tdls_update_peer(struct wlan_objmgr_vdev *vdev,
|
|||||||
osif_debug("Update TDLS peer " QDF_MAC_ADDR_FMT,
|
osif_debug("Update TDLS peer " QDF_MAC_ADDR_FMT,
|
||||||
QDF_MAC_ADDR_REF(mac));
|
QDF_MAC_ADDR_REF(mac));
|
||||||
|
|
||||||
req_info = qdf_mem_malloc(sizeof(*req_info));
|
is_mlo_vdev = wlan_vdev_mlme_is_mlo_vdev(vdev);
|
||||||
if (!req_info)
|
if (is_mlo_vdev) {
|
||||||
return -EINVAL;
|
vdev = ucfg_tdls_get_tdls_link_vdev(vdev, WLAN_OSIF_TDLS_ID);
|
||||||
|
if (!vdev) {
|
||||||
|
osif_err("no tdls link vdev");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
psoc = wlan_vdev_get_psoc(vdev);
|
psoc = wlan_vdev_get_psoc(vdev);
|
||||||
if (!psoc) {
|
if (!psoc) {
|
||||||
osif_err_rl("Invalid psoc");
|
osif_err_rl("Invalid psoc");
|
||||||
return -EINVAL;
|
goto relref;
|
||||||
|
}
|
||||||
|
|
||||||
|
req_info = qdf_mem_malloc(sizeof(*req_info));
|
||||||
|
if (!req_info) {
|
||||||
|
status = -EINVAL;
|
||||||
|
goto relref;
|
||||||
}
|
}
|
||||||
|
|
||||||
tdls_11ax_support = ucfg_tdls_is_fw_11ax_capable(psoc);
|
tdls_11ax_support = ucfg_tdls_is_fw_11ax_capable(psoc);
|
||||||
@@ -682,6 +732,9 @@ int wlan_cfg80211_tdls_update_peer(struct wlan_objmgr_vdev *vdev,
|
|||||||
}
|
}
|
||||||
error:
|
error:
|
||||||
qdf_mem_free(req_info);
|
qdf_mem_free(req_info);
|
||||||
|
relref:
|
||||||
|
if (is_mlo_vdev)
|
||||||
|
ucfg_tdls_put_tdls_link_vdev(vdev, WLAN_OSIF_TDLS_ID);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -759,6 +812,7 @@ int wlan_cfg80211_tdls_oper(struct wlan_objmgr_vdev *vdev,
|
|||||||
int status;
|
int status;
|
||||||
unsigned long rc;
|
unsigned long rc;
|
||||||
enum tdls_command_type cmd;
|
enum tdls_command_type cmd;
|
||||||
|
bool is_mlo_vdev;
|
||||||
|
|
||||||
status = wlan_cfg80211_tdls_validate_mac_addr(peer);
|
status = wlan_cfg80211_tdls_validate_mac_addr(peer);
|
||||||
|
|
||||||
@@ -771,6 +825,15 @@ int wlan_cfg80211_tdls_oper(struct wlan_objmgr_vdev *vdev,
|
|||||||
return -ENOTSUPP;
|
return -ENOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is_mlo_vdev = wlan_vdev_mlme_is_mlo_vdev(vdev);
|
||||||
|
if (is_mlo_vdev) {
|
||||||
|
vdev = ucfg_tdls_get_tdls_link_vdev(vdev, WLAN_OSIF_TDLS_ID);
|
||||||
|
if (!vdev) {
|
||||||
|
osif_err("no tdls link vdev");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
osif_debug("%s start", tdls_oper_to_str(oper));
|
osif_debug("%s start", tdls_oper_to_str(oper));
|
||||||
cmd = tdls_oper_to_cmd(oper);
|
cmd = tdls_oper_to_cmd(oper);
|
||||||
switch (oper) {
|
switch (oper) {
|
||||||
@@ -786,6 +849,9 @@ int wlan_cfg80211_tdls_oper(struct wlan_objmgr_vdev *vdev,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NL80211_TDLS_DISABLE_LINK:
|
case NL80211_TDLS_DISABLE_LINK:
|
||||||
|
wlan_vdev_mlme_feat_ext2_cap_clear(vdev,
|
||||||
|
WLAN_VDEV_FEXT2_MLO_STA_TDLS);
|
||||||
|
|
||||||
osif_priv = wlan_vdev_get_ospriv(vdev);
|
osif_priv = wlan_vdev_get_ospriv(vdev);
|
||||||
|
|
||||||
if (!osif_priv || !osif_priv->osif_tdls) {
|
if (!osif_priv || !osif_priv->osif_tdls) {
|
||||||
@@ -816,6 +882,8 @@ int wlan_cfg80211_tdls_oper(struct wlan_objmgr_vdev *vdev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
if (is_mlo_vdev)
|
||||||
|
ucfg_tdls_put_tdls_link_vdev(vdev, WLAN_OSIF_TDLS_ID);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -844,7 +912,8 @@ void wlan_cfg80211_tdls_rx_callback(void *user_data,
|
|||||||
assoc_vdev = vdev;
|
assoc_vdev = vdev;
|
||||||
opmode = wlan_vdev_mlme_get_opmode(vdev);
|
opmode = wlan_vdev_mlme_get_opmode(vdev);
|
||||||
|
|
||||||
if (opmode == QDF_STA_MODE && wlan_vdev_mlme_is_mlo_vdev(vdev)) {
|
if ((opmode == QDF_STA_MODE || opmode == QDF_TDLS_MODE) &&
|
||||||
|
wlan_vdev_mlme_is_mlo_vdev(vdev)) {
|
||||||
assoc_vdev = ucfg_mlo_get_assoc_link_vdev(vdev);
|
assoc_vdev = ucfg_mlo_get_assoc_link_vdev(vdev);
|
||||||
if (!assoc_vdev) {
|
if (!assoc_vdev) {
|
||||||
osif_err("assoc vdev is null");
|
osif_err("assoc vdev is null");
|
||||||
@@ -1000,11 +1069,12 @@ bool wlan_cfg80211_tdls_is_fw_6ghz_capable(struct wlan_objmgr_vdev *vdev)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int wlan_cfg80211_tdls_mgmt(struct wlan_objmgr_vdev *vdev,
|
static int
|
||||||
const uint8_t *peer_mac,
|
wlan_cfg80211_tdls_mgmt(struct wlan_objmgr_vdev *vdev,
|
||||||
uint8_t action_code, uint8_t dialog_token,
|
const uint8_t *peer_mac,
|
||||||
uint16_t status_code, uint32_t peer_capability,
|
uint8_t action_code, uint8_t dialog_token,
|
||||||
const uint8_t *buf, size_t len)
|
uint16_t status_code, uint32_t peer_capability,
|
||||||
|
const uint8_t *buf, size_t len, int link_id)
|
||||||
{
|
{
|
||||||
struct tdls_action_frame_request mgmt_req;
|
struct tdls_action_frame_request mgmt_req;
|
||||||
struct vdev_osif_priv *osif_priv;
|
struct vdev_osif_priv *osif_priv;
|
||||||
@@ -1060,6 +1130,8 @@ int wlan_cfg80211_tdls_mgmt(struct wlan_objmgr_vdev *vdev,
|
|||||||
mgmt_req.tdls_mgmt.peer_capability = peer_capability;
|
mgmt_req.tdls_mgmt.peer_capability = peer_capability;
|
||||||
mgmt_req.tdls_mgmt.status_code = mgmt_req.chk_frame.status_code;
|
mgmt_req.tdls_mgmt.status_code = mgmt_req.chk_frame.status_code;
|
||||||
|
|
||||||
|
mgmt_req.link_active = false;
|
||||||
|
mgmt_req.link_id = link_id;
|
||||||
/*populate the additional IE's */
|
/*populate the additional IE's */
|
||||||
mgmt_req.cmd_buf = buf;
|
mgmt_req.cmd_buf = buf;
|
||||||
mgmt_req.len = len;
|
mgmt_req.len = len;
|
||||||
@@ -1111,6 +1183,88 @@ error_mgmt_req:
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
wlan_cfg80211_tdls_mgmt_mlo(struct hdd_adapter *adapter, const uint8_t *peer,
|
||||||
|
uint8_t action_code, uint8_t dialog_token,
|
||||||
|
uint16_t status_code, uint32_t peer_capability,
|
||||||
|
const uint8_t *buf, size_t len, int link_id)
|
||||||
|
{
|
||||||
|
struct wlan_objmgr_vdev *tdls_link_vdev = NULL;
|
||||||
|
struct wlan_objmgr_vdev *mlo_vdev = NULL;
|
||||||
|
struct wlan_objmgr_vdev *vdev;
|
||||||
|
bool is_mlo_vdev;
|
||||||
|
bool link_id_vdev = false;
|
||||||
|
bool dis_req_more = false;
|
||||||
|
uint8_t i;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
vdev = hdd_objmgr_get_vdev_by_user(adapter, WLAN_OSIF_TDLS_ID);
|
||||||
|
if (!vdev)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
is_mlo_vdev = wlan_vdev_mlme_is_mlo_vdev(vdev);
|
||||||
|
if (is_mlo_vdev) {
|
||||||
|
tdls_link_vdev =
|
||||||
|
ucfg_tdls_get_tdls_link_vdev(vdev, WLAN_OSIF_TDLS_ID);
|
||||||
|
if (!tdls_link_vdev) {
|
||||||
|
if (action_code == TDLS_DISCOVERY_RESPONSE) {
|
||||||
|
hdd_objmgr_put_vdev_by_user(vdev,
|
||||||
|
WLAN_OSIF_TDLS_ID);
|
||||||
|
if (link_id < 0) {
|
||||||
|
osif_err("link id is invalid");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
/* Get the candidate vdev per link id */
|
||||||
|
link_id_vdev = true;
|
||||||
|
vdev = wlan_key_get_link_vdev(adapter,
|
||||||
|
WLAN_OSIF_TDLS_ID,
|
||||||
|
link_id);
|
||||||
|
} else if (action_code == TDLS_DISCOVERY_REQUEST) {
|
||||||
|
if (ucfg_tdls_discovery_on_going(vdev)) {
|
||||||
|
osif_err("discovery request is going");
|
||||||
|
hdd_objmgr_put_vdev_by_user(vdev,
|
||||||
|
WLAN_OSIF_TDLS_ID);
|
||||||
|
return -EAGAIN;
|
||||||
|
}
|
||||||
|
dis_req_more = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_TDLS_ID);
|
||||||
|
vdev = tdls_link_vdev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dis_req_more) {
|
||||||
|
/* it needs to send discovery request on each vdev */
|
||||||
|
for (i = 0 ; i < WLAN_UMAC_MLO_MAX_VDEVS; i++) {
|
||||||
|
mlo_vdev = ucfg_tdls_get_mlo_vdev(vdev, i,
|
||||||
|
WLAN_OSIF_TDLS_ID);
|
||||||
|
if (!mlo_vdev) {
|
||||||
|
osif_err("mlo vdev is NULL");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ret = wlan_cfg80211_tdls_mgmt(mlo_vdev, peer,
|
||||||
|
action_code,
|
||||||
|
dialog_token, status_code,
|
||||||
|
peer_capability, buf, len,
|
||||||
|
link_id);
|
||||||
|
ucfg_tdls_release_mlo_vdev(mlo_vdev, WLAN_OSIF_TDLS_ID);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ret = wlan_cfg80211_tdls_mgmt(vdev, peer,
|
||||||
|
action_code, dialog_token,
|
||||||
|
status_code, peer_capability,
|
||||||
|
buf, len, link_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vdev && link_id_vdev)
|
||||||
|
wlan_key_put_link_vdev(vdev, WLAN_OSIF_TDLS_ID);
|
||||||
|
else if (!tdls_link_vdev)
|
||||||
|
ucfg_tdls_put_tdls_link_vdev(vdev, WLAN_OSIF_TDLS_ID);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int wlan_tdls_antenna_switch(struct wlan_objmgr_vdev *vdev, uint32_t mode)
|
int wlan_tdls_antenna_switch(struct wlan_objmgr_vdev *vdev, uint32_t mode)
|
||||||
{
|
{
|
||||||
struct vdev_osif_priv *osif_priv;
|
struct vdev_osif_priv *osif_priv;
|
||||||
|
Reference in New Issue
Block a user