qcacld-3.0: Add support to send TDLS avail and no. connected peer

Add support to send whether currently TDLS is available or not.

Vendor subcmd: QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS
Vendor attr: QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_AVAILABLE

Also add support to get the TDLS number of active sessions
using below vendor attr.

Vendor subcmd: QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS
Vendor attr: QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_NUM_SESSIONS

Change-Id: Ie9ad09de9593559c4d57599a9af58a95af99e60f
CRs-Fixed: 3554429
This commit is contained in:
Deeksha Gupta
2023-07-24 11:00:11 +05:30
committed by Rahul Choudhary
parent 35e5e0117e
commit 167488b437
6 changed files with 196 additions and 2 deletions

View File

@@ -30,6 +30,7 @@
#include <wlan_mlme_api.h>
#include <wlan_mlme_main.h>
#include "wma_tgt_cfg.h"
#include "wlan_mlme_vdev_mgr_interface.h"
/**
* ucfg_mlme_init() - initialize mlme_ctx context.
@@ -282,6 +283,19 @@ ucfg_mlme_peer_config_vlan(struct wlan_objmgr_vdev *vdev,
return wlan_mlme_peer_config_vlan(vdev, macaddr);
}
/**
* ucfg_mlme_get_tdls_prohibited() - get if TDLS prohibited is advertised by
* the connected AP.
* @vdev: vdev pointer
*
* Return: bool
*/
static inline
bool ucfg_mlme_get_tdls_prohibited(struct wlan_objmgr_vdev *vdev)
{
return mlme_get_tdls_prohibited(vdev);
}
#ifdef MULTI_CLIENT_LL_SUPPORT
/**
* ucfg_mlme_get_wlm_multi_client_ll_caps() - Get multi client latency level

View File

@@ -274,6 +274,14 @@ cfg_tdls_set_scan_enable(struct wlan_objmgr_psoc *psoc,
* This function gets tdls max peer count
*/
uint16_t cfg_tdls_get_max_peer_count(struct wlan_objmgr_psoc *psoc);
/**
* cfg_tdls_get_connected_peer_count() - get tdls connected peer count
* @psoc: pointer to psoc object
*
* This function gets tdls connected peer count
*/
uint16_t cfg_tdls_get_connected_peer_count(struct wlan_objmgr_psoc *psoc);
#else
static inline QDF_STATUS
cfg_tdls_get_support_enable(struct wlan_objmgr_psoc *psoc,
@@ -450,5 +458,12 @@ cfg_tdls_get_max_peer_count(struct wlan_objmgr_psoc *psoc)
{
return 0;
}
static inline uint16_t
cfg_tdls_get_connected_peer_count(struct wlan_objmgr_psoc *psoc)
{
return 0;
}
#endif /* FEATURE_WLAN_TDLS */
#endif /* _WLAN_TDLS_CFG_API_H_ */

View File

@@ -459,6 +459,16 @@ uint16_t ucfg_get_tdls_conn_peer_count(struct wlan_objmgr_vdev *vdev);
struct wlan_objmgr_vdev *ucfg_get_tdls_vdev(struct wlan_objmgr_psoc *psoc,
wlan_objmgr_ref_dbgid dbg_id);
/**
* ucfg_tdls_check_is_tdls_allowed() - Ucfg api to check is tdls allowed or not
* @vdev: vdev object
*
* Function determines the whether TDLS allowed in the system
*
* Return: true or false
*/
bool ucfg_tdls_check_is_tdls_allowed(struct wlan_objmgr_vdev *vdev);
#else
static inline
bool ucfg_tdls_link_vdev_is_matching(struct wlan_objmgr_vdev *vdev)
@@ -560,6 +570,12 @@ struct wlan_objmgr_vdev *ucfg_get_tdls_vdev(struct wlan_objmgr_psoc *psoc,
return NULL;
}
static inline
bool ucfg_tdls_check_is_tdls_allowed(struct wlan_objmgr_vdev *vdev)
{
return false;
}
static inline
void ucfg_tdls_update_fw_11ax_capability(struct wlan_objmgr_psoc *psoc,
bool is_fw_tdls_11ax_capable)

View File

@@ -413,3 +413,17 @@ cfg_tdls_get_max_peer_count(struct wlan_objmgr_psoc *psoc)
return soc_obj->max_num_tdls_sta;
}
uint16_t
cfg_tdls_get_connected_peer_count(struct wlan_objmgr_psoc *psoc)
{
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 0;
}
return soc_obj->connected_peer_count;
}

View File

@@ -1287,3 +1287,8 @@ struct wlan_objmgr_vdev *ucfg_get_tdls_vdev(struct wlan_objmgr_psoc *psoc,
{
return tdls_get_vdev(psoc, dbg_id);
}
bool ucfg_tdls_check_is_tdls_allowed(struct wlan_objmgr_vdev *vdev)
{
return tdls_check_is_tdls_allowed(vdev);
}

View File

@@ -189,6 +189,70 @@ const struct nla_policy
.type = NLA_S32},
};
static bool wlan_hdd_is_tdls_allowed(struct hdd_context *hdd_ctx,
struct wlan_objmgr_vdev *vdev)
{
bool tdls_support;
if ((cfg_tdls_get_support_enable(hdd_ctx->psoc, &tdls_support) ==
QDF_STATUS_SUCCESS) && !tdls_support) {
hdd_debug("TDLS feature not Enabled or Not supported in FW");
return false;
}
if (!wlan_cm_is_vdev_connected(vdev)) {
hdd_debug("Failed due to Not associated");
return false;
}
if (wlan_cm_roaming_in_progress(hdd_ctx->pdev,
wlan_vdev_get_id(vdev))) {
hdd_debug("Failed due to Roaming is in progress");
return false;
}
if (!ucfg_tdls_check_is_tdls_allowed(vdev)) {
hdd_debug("TDLS is not allowed");
return false;
}
if (ucfg_mlme_get_tdls_prohibited(vdev)) {
hdd_debug("TDLS is prohobited by AP");
return false;
}
return true;
}
static bool wlan_hdd_get_tdls_allowed(struct hdd_context *hdd_ctx,
struct hdd_adapter *adapter)
{
struct wlan_hdd_link_info *link_info;
struct wlan_objmgr_vdev *vdev;
bool is_tdls_avail = false;
hdd_adapter_for_each_active_link_info(adapter, link_info) {
vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_TDLS_NB_ID);
if (!vdev)
return false;
is_tdls_avail = wlan_hdd_is_tdls_allowed(hdd_ctx, vdev);
/* Return is_tdls_avail for non-MLO case */
if (!wlan_vdev_mlme_is_mlo_vdev(vdev)) {
hdd_objmgr_put_vdev_by_user(vdev, WLAN_TDLS_NB_ID);
return is_tdls_avail;
}
hdd_objmgr_put_vdev_by_user(vdev, WLAN_TDLS_NB_ID);
if (is_tdls_avail)
return is_tdls_avail;
}
return false;
}
/**
* __wlan_hdd_cfg80211_exttdls_get_status() - handle get status cfg80211 command
* @wiphy: wiphy
@@ -202,8 +266,74 @@ __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
const void *data,
int data_len)
{
/* TODO */
return 0;
struct net_device *dev = wdev->netdev;
struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
struct sk_buff *skb;
uint32_t connected_peer_count = 0;
int status;
bool is_tdls_avail = true;
int ret = 0;
int attr;
hdd_enter_dev(wdev->netdev);
if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
hdd_err("Command not allowed in FTM mode");
return -EPERM;
}
status = wlan_hdd_validate_context(hdd_ctx);
if (status)
return -EINVAL;
skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
sizeof(u32) + sizeof(bool) +
NLMSG_HDRLEN);
if (!skb) {
hdd_err("wlan_cfg80211_vendor_cmd_alloc_reply_skb failed");
return -ENOMEM;
}
if (adapter->device_mode != QDF_STA_MODE &&
adapter->device_mode != QDF_P2P_CLIENT_MODE) {
hdd_debug("Failed to get TDLS info due to opmode:%d",
adapter->device_mode);
ret = -EOPNOTSUPP;
goto fail;
}
connected_peer_count = cfg_tdls_get_connected_peer_count(hdd_ctx->psoc);
is_tdls_avail = wlan_hdd_get_tdls_allowed(hdd_ctx, adapter);
if (connected_peer_count >=
cfg_tdls_get_max_peer_count(hdd_ctx->psoc)) {
hdd_debug("Failed due to max no. of connected peer:%d reached",
connected_peer_count);
is_tdls_avail = false;
}
hdd_debug("Send TDLS_available: %d, no. of connected peer:%d to userspace",
is_tdls_avail, connected_peer_count);
attr = QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_NUM_SESSIONS;
if (nla_put_u32(skb, attr, connected_peer_count)) {
hdd_err("nla put fail");
ret = -EINVAL;
goto fail;
}
attr = QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_AVAILABLE;
if (is_tdls_avail && nla_put_flag(skb, attr)) {
hdd_err("nla put fail");
ret = -EINVAL;
goto fail;
}
return wlan_cfg80211_vendor_cmd_reply(skb);
fail:
wlan_cfg80211_vendor_free_skb(skb);
return ret;
}
static int