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:

committed by
Madan Koyyalamudi

parent
90da1d654b
commit
9e24d820d4
@@ -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;
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
|
||||
/**
|
||||
|
@@ -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);
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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)
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user