From 3050ccd014a8ba5b7e657ecb24f633863040852e Mon Sep 17 00:00:00 2001 From: Paul Zhang Date: Wed, 24 May 2023 18:43:08 +0800 Subject: [PATCH] qcacld-3.0: Create API for TDLS configure link id Create API to set link id and used in wlan_hdd_cfg80211_tdls_mgmt function for MLO TDLS. Change-Id: I39814db1646362585cb9c3258d7e71c3cabe4204 CRs-Fixed: 3491950 --- .../tdls/dispatcher/inc/wlan_tdls_cfg_api.h | 35 +++++++ .../dispatcher/inc/wlan_tdls_public_structs.h | 2 + .../tdls/dispatcher/src/wlan_tdls_cfg.c | 30 ++++++ core/hdd/inc/wlan_hdd_tdls.h | 28 ++++++ core/hdd/src/wlan_hdd_cfg80211.c | 2 +- core/hdd/src/wlan_hdd_tdls.c | 93 +++++++++++++++++++ 6 files changed, 189 insertions(+), 1 deletion(-) diff --git a/components/tdls/dispatcher/inc/wlan_tdls_cfg_api.h b/components/tdls/dispatcher/inc/wlan_tdls_cfg_api.h index cd85ceb4d2..6468d739c3 100644 --- a/components/tdls/dispatcher/inc/wlan_tdls_cfg_api.h +++ b/components/tdls/dispatcher/inc/wlan_tdls_cfg_api.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2018-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 @@ -233,6 +234,28 @@ QDF_STATUS cfg_tdls_get_scan_enable(struct wlan_objmgr_psoc *psoc, bool *val); +/** + * cfg_tdls_get_link_id() - get tdls link id + * @psoc: pointer to psoc object + * + * This function gets tdls link id + * + * Return: int + */ +int cfg_tdls_get_link_id(struct wlan_objmgr_psoc *psoc); + +/** + * cfg_tdls_set_link_id() - get tdls link id + * @psoc: pointer to psoc object + * @val: the value of link id + * + * This function gets tdls link id + * + * Return: QDF_STATUS + */ +QDF_STATUS +cfg_tdls_set_link_id(struct wlan_objmgr_psoc *psoc, + int val); /** * cfg_tdls_set_scan_enable() - set tdls scan enable * @psoc: pointer to psoc object @@ -410,6 +433,18 @@ cfg_tdls_set_scan_enable(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +static inline int +cfg_tdls_get_link_id(struct wlan_objmgr_psoc *psoc) +{ + return 0; +} + +static inline QDF_STATUS +cfg_tdls_set_link_id(struct wlan_objmgr_psoc *psoc, + int val) +{ + return QDF_STATUS_SUCCESS; +} static inline uint16_t cfg_tdls_get_max_peer_count(struct wlan_objmgr_psoc *psoc) { diff --git a/components/tdls/dispatcher/inc/wlan_tdls_public_structs.h b/components/tdls/dispatcher/inc/wlan_tdls_public_structs.h index 030cce202c..ab7b8db340 100644 --- a/components/tdls/dispatcher/inc/wlan_tdls_public_structs.h +++ b/components/tdls/dispatcher/inc/wlan_tdls_public_structs.h @@ -505,6 +505,7 @@ enum tdls_feature_bit { * @tdls_scan_enable: tdls scan enable * @tdls_sleep_sta_enable: tdls sleep sta enable * @tdls_support_enable: tdls support enable + * @tdls_link_id: mlo link id */ struct tdls_user_config { uint32_t tdls_tx_states_period; @@ -538,6 +539,7 @@ struct tdls_user_config { bool tdls_scan_enable; bool tdls_sleep_sta_enable; bool tdls_support_enable; + int tdls_link_id; }; /** diff --git a/components/tdls/dispatcher/src/wlan_tdls_cfg.c b/components/tdls/dispatcher/src/wlan_tdls_cfg.c index 413ebc24cc..c66e60864c 100644 --- a/components/tdls/dispatcher/src/wlan_tdls_cfg.c +++ b/components/tdls/dispatcher/src/wlan_tdls_cfg.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2018-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 @@ -370,6 +371,35 @@ cfg_tdls_set_scan_enable(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +int cfg_tdls_get_link_id(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 QDF_STATUS_E_INVAL; + } + + return soc_obj->tdls_configs.tdls_link_id; +} + +QDF_STATUS +cfg_tdls_set_link_id(struct wlan_objmgr_psoc *psoc, int 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_link_id = val; + + return QDF_STATUS_SUCCESS; +} + uint16_t cfg_tdls_get_max_peer_count(struct wlan_objmgr_psoc *psoc) { diff --git a/core/hdd/inc/wlan_hdd_tdls.h b/core/hdd/inc/wlan_hdd_tdls.h index 9aa620fe90..9c5726c6c4 100644 --- a/core/hdd/inc/wlan_hdd_tdls.h +++ b/core/hdd/inc/wlan_hdd_tdls.h @@ -34,6 +34,10 @@ extern const struct nla_policy wlan_hdd_tdls_mode_configuration_policy [QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_MAX + 1]; +extern const struct nla_policy + wlan_hdd_tdls_disc_rsp_policy + [QCA_WLAN_VENDOR_ATTR_TDLS_DISC_RSP_EXT_MAX + 1]; + #define FEATURE_TDLS_VENDOR_COMMANDS \ { \ .info.vendor_id = QCA_NL80211_VENDOR_ID, \ @@ -70,6 +74,15 @@ extern const struct nla_policy WIPHY_VENDOR_CMD_NEED_NETDEV, \ .doit = wlan_hdd_cfg80211_exttdls_get_status, \ vendor_command_policy(VENDOR_CMD_RAW_DATA, 0) \ +}, \ +{ \ + .info.vendor_id = QCA_NL80211_VENDOR_ID, \ + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISC_RSP_EXT, \ + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | \ + WIPHY_VENDOR_CMD_NEED_NETDEV, \ + .doit = wlan_hdd_cfg80211_exttdls_set_link_id, \ + vendor_command_policy(wlan_hdd_tdls_disc_rsp_policy, \ + QCA_WLAN_VENDOR_ATTR_TDLS_DISC_RSP_EXT_TX_LINK) \ }, /* Bit mask flag for tdls_option to FW */ @@ -95,6 +108,21 @@ int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy, const void *data, int data_len); +/** + * wlan_hdd_cfg80211_exttdls_set_link_id() - set link id + * @wiphy: pointer to wireless wiphy structure. + * @wdev: pointer to wireless_dev structure. + * @data: Pointer to the data to be passed via vendor interface + * @data_len:Length of the data to be passed + * + * Return: Return the Success or Failure code. + */ +int +wlan_hdd_cfg80211_exttdls_set_link_id(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len); + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)) int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 93fe0369c6..69b8109f66 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -24097,7 +24097,7 @@ int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev, } #endif -#ifdef TDLS_MGMT_VERSION5 +#ifdef CFG80211_LINK_STA_PARAMS_PRESENT static inline uint8_t wlan_hdd_get_link_id(struct station_parameters *params) { diff --git a/core/hdd/src/wlan_hdd_tdls.c b/core/hdd/src/wlan_hdd_tdls.c index 77398f082e..209530deaf 100644 --- a/core/hdd/src/wlan_hdd_tdls.c +++ b/core/hdd/src/wlan_hdd_tdls.c @@ -159,6 +159,13 @@ static const struct nla_policy .type = NLA_U32}, }; +const struct nla_policy + wlan_hdd_tdls_disc_rsp_policy + [QCA_WLAN_VENDOR_ATTR_TDLS_DISC_RSP_EXT_MAX + 1] = { + [QCA_WLAN_VENDOR_ATTR_TDLS_DISC_RSP_EXT_TX_LINK] = { + .type = NLA_U8}, +}; + const struct nla_policy wlan_hdd_tdls_mode_configuration_policy [QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_MAX + 1] = { @@ -199,6 +206,55 @@ __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy, return 0; } +static int +__wlan_hdd_cfg80211_exttdls_set_link_id(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + struct net_device *dev = wdev->netdev; + struct hdd_context *hdd_ctx = wiphy_priv(wiphy); + struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISC_RSP_EXT_MAX + 1]; + int ret; + uint32_t link_id; + + hdd_enter_dev(dev); + + if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) { + hdd_err("Command not allowed in FTM mode"); + return -EPERM; + } + + ret = wlan_hdd_validate_context(hdd_ctx); + if (0 != ret) + return -EINVAL; + + if (!adapter) + return -EINVAL; + + if (wlan_cfg80211_nla_parse(tb, + QCA_WLAN_VENDOR_ATTR_TDLS_DISC_RSP_EXT_MAX, + data, data_len, + wlan_hdd_tdls_disc_rsp_policy)) { + hdd_err("Invalid attribute"); + return -EINVAL; + } + + if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISC_RSP_EXT_TX_LINK]) { + hdd_err("attr tdls link id failed"); + return -EINVAL; + } + + link_id = + nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISC_RSP_EXT_TX_LINK]); + hdd_debug("TDLS link id %d", link_id); + + ret = cfg_tdls_set_link_id(hdd_ctx->psoc, link_id); + + return ret; +} + /** * __wlan_hdd_cfg80211_configure_tdls_mode() - configure the tdls mode * @wiphy: wiphy @@ -320,6 +376,26 @@ int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy, return errno; } +int wlan_hdd_cfg80211_exttdls_set_link_id(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, + int data_len) +{ + int errno; + struct osif_vdev_sync *vdev_sync; + + errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync); + if (errno) + return errno; + + errno = __wlan_hdd_cfg80211_exttdls_set_link_id(wiphy, wdev, + data, data_len); + + osif_vdev_sync_op_stop(vdev_sync); + + return errno; +} + /** * __wlan_hdd_cfg80211_exttdls_enable() - enable an externally controllable * TDLS peer and set parameters @@ -421,6 +497,22 @@ int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy, return errno; } +#ifdef TDLS_MGMT_VERSION5 +static int wlan_hdd_get_tdls_link_id(struct hdd_context *hdd_ctx, int id) +{ + return id; +} +#else +static int wlan_hdd_get_tdls_link_id(struct hdd_context *hdd_ctx, int id) +{ + int link_id; + + link_id = cfg_tdls_get_link_id(hdd_ctx->psoc); + + return link_id; +} +#endif + #ifdef TDLS_MGMT_VERSION5 /** * __wlan_hdd_cfg80211_tdls_mgmt() - handle management actions on a given peer @@ -510,6 +602,7 @@ static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, if (hdd_ctx->tdls_umac_comp_active) { int ret; + link_id = wlan_hdd_get_tdls_link_id(hdd_ctx, link_id); ret = wlan_cfg80211_tdls_mgmt_mlo(adapter, peer, action_code, dialog_token, status_code, peer_capability,