qcacld-3.0: Handle STA + TDLS + P2P CLI concurrencies

When P2P CLI is connected first and then STA is connected,
disable TDLS on existing interface and enable TDLS on the STA
vdev.

When existing STA + TDLS exists, disable off channel when P2P
connection is started and re-enable off channel for TDLS once
connection is complete. Don't teardown TDLS peers once the
P2P client connection is successful.

Change-Id: I91d152a3a052706289c06cebc932c84a69fdbc00
CRs-Fixed: 3455639
This commit is contained in:
Pragaspathi Thilagaraj
2023-04-04 23:10:43 +05:30
committed by Madan Koyyalamudi
parent 90da1d654b
commit 9e24d820d4
9 changed files with 154 additions and 35 deletions

View File

@@ -31,6 +31,7 @@
#include "wlan_mlme_vdev_mgr_interface.h"
#include "wlan_p2p_ucfg_api.h"
#include "wlan_vdev_mgr_utils_api.h"
#include "wlan_tdls_tgt_api.h"
QDF_STATUS if_mgr_ap_start_bss(struct wlan_objmgr_vdev *vdev,
struct if_mgr_event_data *event_data)
@@ -113,6 +114,11 @@ if_mgr_ap_start_bss_complete(struct wlan_objmgr_vdev *vdev,
ifmgr_debug("check for SAP restart");
policy_mgr_check_concurrent_intf_and_restart_sap(psoc,
wlan_util_vdev_mgr_get_acs_mode_for_vdev(vdev));
/*
* Enable TDLS again on concurrent STA
*/
if (event_data && QDF_IS_STATUS_ERROR(event_data->status))
wlan_tdls_notify_start_bss_failure(psoc);
return QDF_STATUS_SUCCESS;
}

View File

@@ -1656,18 +1656,40 @@ tdls_process_sta_disconnect(struct tdls_sta_notify_params *notify)
QDF_STATUS tdls_notify_sta_disconnect(struct tdls_sta_notify_params *notify)
{
QDF_STATUS status;
struct wlan_objmgr_vdev *vdev;
enum QDF_OPMODE opmode;
struct wlan_objmgr_psoc *psoc;
uint8_t sta_count;
if (!notify) {
tdls_err("invalid param");
return QDF_STATUS_E_INVAL;
}
if (!notify->vdev) {
vdev = notify->vdev;
if (!vdev) {
tdls_err("invalid param");
qdf_mem_free(notify);
return QDF_STATUS_E_INVAL;
}
psoc = wlan_vdev_get_psoc(vdev);
if (!psoc) {
wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID);
qdf_mem_free(notify);
return QDF_STATUS_E_INVAL;
}
opmode = wlan_vdev_mlme_get_opmode(vdev);
sta_count = policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE,
NULL);
if (opmode == QDF_P2P_CLIENT_MODE && sta_count) {
tdls_debug("STA + P2P concurrency. No action on P2P vdev");
wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID);
qdf_mem_free(notify);
return QDF_STATUS_E_INVAL;
}
status = tdls_process_sta_disconnect(notify);
wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID);
@@ -1750,6 +1772,7 @@ QDF_STATUS tdls_peers_deleted_notification(struct wlan_objmgr_psoc *psoc,
return QDF_STATUS_SUCCESS;
}
static
QDF_STATUS tdls_delete_all_peers_indication(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id)
{
@@ -1762,13 +1785,10 @@ QDF_STATUS tdls_delete_all_peers_indication(struct wlan_objmgr_psoc *psoc,
if (!indication)
return QDF_STATUS_E_NULL_VALUE;
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
vdev_id,
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
WLAN_TDLS_SB_ID);
if (!vdev) {
tdls_err("vdev not exist for the session id %d",
vdev_id);
tdls_err("vdev:%d does not exist", vdev_id);
qdf_mem_free(indication);
return QDF_STATUS_E_INVAL;
}
@@ -1793,6 +1813,40 @@ QDF_STATUS tdls_delete_all_peers_indication(struct wlan_objmgr_psoc *psoc,
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
tdls_check_and_indicate_delete_all_peers(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id)
{
struct wlan_objmgr_pdev *pdev;
uint32_t pdev_id;
enum QDF_OPMODE opmode;
uint8_t sta_count =
policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE,
NULL);
pdev_id = wlan_get_pdev_id_from_vdev_id(psoc, vdev_id, WLAN_TDLS_SB_ID);
if (pdev_id == WLAN_INVALID_PDEV_ID) {
tdls_debug("Invalid pdev id");
return QDF_STATUS_E_INVAL;
}
pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, WLAN_TDLS_SB_ID);
if (!pdev) {
tdls_debug("pdev is NULL");
return QDF_STATUS_E_INVAL;
}
opmode = wlan_get_opmode_from_vdev_id(pdev, vdev_id);
wlan_objmgr_pdev_release_ref(pdev, WLAN_TDLS_SB_ID);
if (opmode == QDF_P2P_CLIENT_MODE && sta_count) {
tdls_debug("STA + P2P concurrency. No action on P2P vdev");
return QDF_STATUS_E_INVAL;
}
return tdls_delete_all_peers_indication(psoc, vdev_id);
}
/**
* tdls_set_mode_in_vdev() - set TDLS mode
* @tdls_vdev: tdls vdev object

View File

@@ -840,16 +840,18 @@ 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
* tdls_check_and_indicate_delete_all_peers() - Check if delete all peers is
* allowed for the vdev based on current concurrency.
* @psoc: soc object
* @vdev_id: vdev id
*
* Notify tdls component to cleanup all peers
* Notify tdls component to cleanup all peers based on current concurrency
* combination.
*
* Return: QDF_STATUS.
* Return: QDF_STATUS
*/
QDF_STATUS tdls_delete_all_peers_indication(struct wlan_objmgr_psoc *psoc,
QDF_STATUS
tdls_check_and_indicate_delete_all_peers(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id);
/**

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2017-2021 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
* any purpose with or without fee is hereby granted, provided that the
@@ -29,6 +29,7 @@
#include <wlan_policy_mgr_api.h>
#include "wlan_reg_ucfg_api.h"
#include <host_diag_core_event.h>
#include "wlan_policy_mgr_api.h"
static uint8_t calculate_hash_key(const uint8_t *macaddr)
{
@@ -574,6 +575,46 @@ static void tdls_get_wifi_hal_state(struct tdls_peer *peer, uint32_t *state,
}
}
#ifdef WLAN_FEATURE_TDLS_CONCURRENCIES
/**
* tdls_get_allowed_off_channel_for_concurrency() - Get allowed off-channel
* frequency based on current concurrency. Return 0 if all frequencies are
* allowed
* @pdev: Pointer to PDEV object
* @vdev: Pointer to vdev object
*
* Return: Frequency
*/
static inline qdf_freq_t
tdls_get_allowed_off_channel_for_concurrency(struct wlan_objmgr_pdev *pdev,
struct wlan_objmgr_vdev *vdev)
{
struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
qdf_freq_t freq = 0;
if (!psoc)
return 0;
if (!wlan_psoc_nif_fw_ext2_cap_get(psoc,
WLAN_TDLS_CONCURRENCIES_SUPPORT))
return 0;
if (!policy_mgr_get_allowed_tdls_offchannel_freq(psoc, vdev, &freq)) {
tdls_debug("off channel not allowed for current concurrency");
return 0;
}
return freq;
}
#else
static inline qdf_freq_t
tdls_get_allowed_off_channel_for_concurrency(struct wlan_objmgr_pdev *pdev,
struct wlan_objmgr_vdev *vdev)
{
return 0;
}
#endif
/**
* tdls_extract_peer_state_param() - extract peer update params from TDLS peer
* @peer_param: output peer update params
@@ -592,7 +633,7 @@ void tdls_extract_peer_state_param(struct tdls_peer_update_state *peer_param,
enum channel_state ch_state;
struct wlan_objmgr_pdev *pdev;
uint32_t cur_band;
qdf_freq_t ch_freq;
qdf_freq_t ch_freq, allowed_freq;
uint32_t tx_power = 0;
vdev_obj = peer->vdev_priv;
@@ -654,8 +695,16 @@ void tdls_extract_peer_state_param(struct tdls_peer_update_state *peer_param,
}
num = 0;
allowed_freq =
tdls_get_allowed_off_channel_for_concurrency(pdev,
vdev_obj->vdev);
tdls_debug("allowed freq:%u", allowed_freq);
for (i = 0; i < peer->supported_channels_len; i++) {
ch_freq = peer->supported_chan_freq[i];
if (allowed_freq && allowed_freq != ch_freq)
continue;
ch_state = wlan_reg_get_channel_state_for_pwrmode(
pdev, ch_freq,
REG_CURRENT_PWR_MODE);

View File

@@ -125,6 +125,14 @@ void wlan_tdls_update_tx_pkt_cnt(struct wlan_objmgr_vdev *vdev,
void wlan_tdls_update_rx_pkt_cnt(struct wlan_objmgr_vdev *vdev,
struct qdf_mac_addr *mac_addr,
struct qdf_mac_addr *dest_mac_addr);
/**
* wlan_tdls_notify_start_bss_failure() - Notify TDLS module on start bss
* failure
* @psoc: Pointer to PSOC object
*
* Return: None
*/
void wlan_tdls_notify_start_bss_failure(struct wlan_objmgr_psoc *psoc);
/**
* wlan_tdls_notify_start_bss() - Notify TDLS module on start bss
@@ -255,5 +263,9 @@ static inline
void wlan_tdls_handle_p2p_client_connect(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_vdev *vdev)
{}
static inline
void wlan_tdls_notify_start_bss_failure(struct wlan_objmgr_psoc *psoc)
{}
#endif
#endif

View File

@@ -269,7 +269,7 @@ void wlan_tdls_notify_channel_switch_start(struct wlan_objmgr_psoc *psoc,
void wlan_tdls_handle_p2p_client_connect(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_vdev *vdev)
{
if (policy_mgr_get_connection_count(psoc) < 2)
if (!policy_mgr_get_connection_count(psoc))
return;
/*
@@ -296,6 +296,11 @@ void wlan_tdls_notify_start_bss(struct wlan_objmgr_psoc *psoc,
wlan_tdls_check_and_teardown_links_sync(psoc, vdev);
}
void wlan_tdls_notify_start_bss_failure(struct wlan_objmgr_psoc *psoc)
{
tdls_notify_decrement_session(psoc);
}
static QDF_STATUS tdls_notify_flush_cb(struct scheduler_msg *msg)
{
struct tdls_sta_notify_params *notify = msg->bodyptr;

View File

@@ -1,5 +1,6 @@
/*
* Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. 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
@@ -362,6 +363,5 @@ void tgt_tdls_peers_deleted_notification(struct wlan_objmgr_psoc *psoc,
void tgt_tdls_delete_all_peers_indication(struct wlan_objmgr_psoc *psoc,
uint32_t session_id)
{
tdls_delete_all_peers_indication(psoc, session_id);
tdls_check_and_indicate_delete_all_peers(psoc, session_id);
}

View File

@@ -1272,23 +1272,9 @@ QDF_STATUS ucfg_tdls_set_rssi(struct wlan_objmgr_vdev *vdev,
return tdls_set_rssi(vdev, mac, rssi);
}
/**
* wlan_tdls_notify_connect_failure() - This api is called if STA/P2P
* connection fails on one iface and to enable/disable TDLS on the other
* STA/P2P iface which is already connected.
* @psoc: psoc object
*
* Return: void
*/
static inline
void wlan_tdls_notify_connect_failure(struct wlan_objmgr_psoc *psoc)
{
return tdls_notify_decrement_session(psoc);
}
void ucfg_tdls_notify_connect_failure(struct wlan_objmgr_psoc *psoc)
{
return wlan_tdls_notify_connect_failure(psoc);
return tdls_notify_decrement_session(psoc);
}
uint16_t ucfg_get_tdls_conn_peer_count(struct wlan_objmgr_vdev *vdev)

View File

@@ -6813,10 +6813,15 @@ error:
free:
wlan_twt_concurrency_update(hdd_ctx);
if (deliver_start_evt) {
struct if_mgr_event_data evt_data;
evt_data.status = QDF_STATUS_SUCCESS;
if (ret < 0)
evt_data.status = QDF_STATUS_E_FAILURE;
status = ucfg_if_mgr_deliver_event(
vdev,
WLAN_IF_MGR_EV_AP_START_BSS_COMPLETE,
NULL);
vdev, WLAN_IF_MGR_EV_AP_START_BSS_COMPLETE,
&evt_data);
if (!QDF_IS_STATUS_SUCCESS(status)) {
hdd_err("start bss complete failed!!");
ret = -EINVAL;