qcacld-3.0: Add support for get twt capabilities

Add support for get twt capabilities.

Change-Id: I5ac2ac597b92fd683afe97604b4e7dcda518ec39
CRs-Fixed: 3085572
This commit is contained in:
Srinivas Girigowda 2021-12-13 18:07:46 -08:00 committed by Madan Koyyalamudi
parent 297fb98ed9
commit d7e3efed33
8 changed files with 256 additions and 10 deletions

View File

@ -119,6 +119,10 @@ QDF_STATUS wlan_twt_cfg_update(struct wlan_objmgr_psoc *psoc)
tgt_caps->legacy_bcast_twt_support),
(enable_twt &&
twt_cfg->bcast_responder_enabled));
twt_debug("req: %d resp: %d bcast_req: %d bcast_resp: %d",
twt_cfg->twt_requestor, twt_cfg->twt_responder,
twt_cfg->bcast_requestor_enabled,
twt_cfg->bcast_responder_enabled);
return QDF_STATUS_SUCCESS;
}

View File

@ -242,6 +242,7 @@ static int hdd_twt_configure(struct hdd_adapter *adapter,
case QCA_WLAN_TWT_NUDGE:
break;
case QCA_WLAN_TWT_GET_CAPABILITIES:
ret = osif_twt_get_capabilities(vdev);
break;
case QCA_WLAN_TWT_GET_STATS:
break;

View File

@ -494,11 +494,34 @@ enum ani_akm_type lim_translate_rsn_oui_to_akm_type(uint8_t auth_suite[4]);
*/
void lim_fill_roamed_peer_twt_caps(struct mac_context *mac_ctx, uint8_t vdev_id,
struct roam_offload_synch_ind *roam_synch);
/**
* lim_set_twt_peer_capabilities() - Update Peer TWT capabilities
* @mac_ctx: Pointer to mac context
* @peer_mac: peer mac address
* @he_cap: pointer to HE capabilities IE
* @he_op: pointer to HE IE
*
* Based on the peer IE capabilities, update the TWT peer private object
*
* Return: None
*/
void lim_set_twt_peer_capabilities(struct mac_context *mac_ctx,
struct qdf_mac_addr *peer_mac,
tDot11fIEhe_cap *he_cap,
tDot11fIEhe_op *he_op);
#else
static inline
void lim_fill_roamed_peer_twt_caps(struct mac_context *mac_ctx, uint8_t vdev_id,
struct roam_offload_synch_ind *roam_synch)
{}
static inline
void lim_set_twt_peer_capabilities(struct mac_context *mac_ctx,
struct qdf_mac_addr *peer_mac,
tDot11fIEhe_cap *he_cap,
tDot11fIEhe_op *he_op)
{}
#endif
/**

View File

@ -85,6 +85,7 @@
#include "utils_mlo.h"
#include "wlan_mlo_mgr_sta.h"
#include "wlan_mlo_mgr_peer.h"
#include <wlan_twt_api.h>
struct pe_hang_event_fixed_param {
uint16_t tlv_header;
@ -1759,6 +1760,44 @@ bool lim_is_sb_disconnect_allowed_fl(struct pe_session *session,
return false;
}
#ifdef WLAN_SUPPORT_TWT
#ifdef WLAN_TWT_CONV_SUPPORTED
void lim_set_twt_peer_capabilities(struct mac_context *mac_ctx,
struct qdf_mac_addr *peer_mac,
tDot11fIEhe_cap *he_cap,
tDot11fIEhe_op *he_op)
{
uint8_t caps = 0;
if (he_cap->twt_request)
caps |= WLAN_TWT_CAPA_REQUESTOR;
if (he_cap->twt_responder)
caps |= WLAN_TWT_CAPA_RESPONDER;
if (he_cap->broadcast_twt)
caps |= WLAN_TWT_CAPA_BROADCAST;
if (he_cap->flex_twt_sched)
caps |= WLAN_TWT_CAPA_FLEXIBLE;
if (he_op->twt_required)
caps |= WLAN_TWT_CAPA_REQUIRED;
wlan_set_peer_twt_capabilities(mac_ctx->psoc, peer_mac, caps);
}
#else
void lim_set_twt_peer_capabilities(struct mac_context *mac_ctx,
struct qdf_mac_addr *peer_mac,
tDot11fIEhe_cap *he_cap,
tDot11fIEhe_op *he_op)
{
mlme_set_twt_peer_capabilities(mac_ctx->psoc, peer_mac,
he_cap, he_op);
}
#endif /* WLAN_TWT_CONV_SUPPORTED */
#endif /* WLAN_SUPPORT_TWT */
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
static void pe_set_rmf_caps(struct mac_context *mac_ctx,
struct pe_session *ft_session,
@ -2458,10 +2497,10 @@ lim_fill_roamed_peer_twt_caps(struct mac_context *mac_ctx,
}
if (lim_is_session_he_capable(pe_session))
mlme_set_twt_peer_capabilities(mac_ctx->psoc,
&roam_synch->bssid,
&reassoc_rsp->he_cap,
&reassoc_rsp->he_op);
lim_set_twt_peer_capabilities(mac_ctx,
&roam_synch->bssid,
&reassoc_rsp->he_cap,
&reassoc_rsp->he_op);
qdf_mem_free(reassoc_rsp);
}
#endif

View File

@ -1111,8 +1111,8 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info,
&assoc_rsp->obss_scanparams);
if (lim_is_session_he_capable(session_entry))
mlme_set_twt_peer_capabilities(
mac_ctx->psoc,
lim_set_twt_peer_capabilities(
mac_ctx,
(struct qdf_mac_addr *)current_bssid,
&assoc_rsp->he_cap,
&assoc_rsp->he_op);

View File

@ -92,6 +92,41 @@ int osif_twt_sap_teardown_req(struct wlan_objmgr_vdev *vdev,
void
osif_twt_handle_renego_failure(struct wlan_objmgr_psoc *psoc,
struct twt_add_dialog_complete_event *add_dialog_event);
/**
* osif_twt_get_capabilities() - Process TWT get capabilities
* in the received vendor command.
* @vdev: vdev
*
* Handles QCA_WLAN_TWT_GET_CAPABILITIES
*
* Return: 0 on success, negative value on failure
*/
int osif_twt_get_capabilities(struct wlan_objmgr_vdev *vdev);
/**
* osif_twt_send_get_capabilities_response - TWT pack and send response to
* userspace for get capabilities command
* @psoc: pointer to global psoc
* @vdev: pointer to vdev
*
* Return: QDF_STATUS
*/
QDF_STATUS
osif_twt_send_get_capabilities_response(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_vdev *vdev);
/**
* osif_fill_peer_macaddr - find peer from vdev and fill mac address
* @vdev: vdev pointer
* @mac_addr: output buffer to copy mac address
*
* This is the utility function, which finds peer bss info from the vdev
* and fill the output buffer with mac address
*
* Return: errno
*/
int osif_fill_peer_macaddr(struct wlan_objmgr_vdev *vdev, uint8_t *mac_addr);
#else
static inline
int osif_twt_setup_req(struct wlan_objmgr_vdev *vdev,
@ -100,6 +135,12 @@ int osif_twt_setup_req(struct wlan_objmgr_vdev *vdev,
return 0;
}
static inline
int osif_twt_get_capabilities(struct wlan_objmgr_vdev *vdev)
{
return 0;
}
static inline
int osif_twt_sta_teardown_req(struct wlan_objmgr_vdev *vdev,
struct nlattr *twt_param_attr)

View File

@ -363,8 +363,7 @@ osif_twt_parse_del_dialog_attrs(struct nlattr **tb,
return 0;
}
static int osif_fill_peer_macaddr(struct wlan_objmgr_vdev *vdev,
uint8_t *mac_addr)
int osif_fill_peer_macaddr(struct wlan_objmgr_vdev *vdev, uint8_t *mac_addr)
{
struct wlan_objmgr_peer *peer;
@ -374,8 +373,7 @@ static int osif_fill_peer_macaddr(struct wlan_objmgr_vdev *vdev,
return -EINVAL;
}
wlan_peer_obj_lock(peer);
qdf_mem_copy(mac_addr, wlan_peer_get_macaddr(peer),
QDF_MAC_ADDR_SIZE);
qdf_mem_copy(mac_addr, wlan_peer_get_macaddr(peer), QDF_MAC_ADDR_SIZE);
wlan_peer_obj_unlock(peer);
wlan_objmgr_peer_release_ref(peer, WLAN_TWT_ID);
@ -627,6 +625,37 @@ int osif_twt_send_responder_disable_cmd(struct wlan_objmgr_psoc *psoc,
return osif_twt_responder_disable(psoc, &req);
}
int osif_twt_get_capabilities(struct wlan_objmgr_vdev *vdev)
{
struct wlan_objmgr_psoc *psoc;
enum QDF_OPMODE mode;
QDF_STATUS status;
uint8_t vdev_id;
psoc = wlan_vdev_get_psoc(vdev);
if (!psoc)
return -EINVAL;
vdev_id = wlan_vdev_get_id(vdev);
mode = wlan_vdev_mlme_get_opmode(vdev);
if (mode != QDF_STA_MODE && mode != QDF_P2P_CLIENT_MODE)
return -EOPNOTSUPP;
if (!wlan_cm_is_vdev_connected(vdev)) {
osif_err_rl("Not associated!, vdev %d mode %d", vdev_id, mode);
return -EAGAIN;
}
if (wlan_cm_host_roam_in_progress(psoc, vdev_id))
return -EBUSY;
status = osif_twt_send_get_capabilities_response(psoc, vdev);
if (QDF_IS_STATUS_ERROR(status))
osif_err_rl("TWT: Get capabilities failed");
return qdf_status_to_os_return(status);
}
int osif_twt_setup_req(struct wlan_objmgr_vdev *vdev,
struct nlattr *twt_param_attr)
{

View File

@ -25,6 +25,12 @@
#include <wlan_objmgr_psoc_obj.h>
#include <wlan_osif_priv.h>
#include <wlan_osif_request_manager.h>
#include <wlan_cm_api.h>
#include <wlan_twt_ucfg_api.h>
#include <wlan_cm_ucfg_api.h>
#include <wlan_reg_ucfg_api.h>
#include <wlan_twt_ucfg_ext_api.h>
#include <wlan_twt_ucfg_ext_cfg.h>
/**
* osif_twt_get_setup_event_len() - Calculates the length of twt
@ -441,6 +447,109 @@ osif_twt_teardown_pack_resp_nlmsg(struct sk_buff *reply_skb,
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
osif_twt_send_get_capabilities_response(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_vdev *vdev)
{
struct vdev_osif_priv *osif_priv;
struct nlattr *config_attr;
struct sk_buff *reply_skb;
size_t skb_len = NLMSG_HDRLEN;
QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
enum band_info connected_band;
uint8_t peer_cap = 0, self_cap = 0;
bool twt_req = false, twt_bcast_req = false;
bool is_twt_24ghz_allowed = true, val;
struct qdf_mac_addr peer_mac;
int ret;
/*
* Userspace will query the TWT get capabilities before
* issuing a get capabilities request. If the STA is
* connected, then check the "enable_twt_24ghz" ini
* value to advertise the TWT requestor capability.
*/
connected_band = ucfg_cm_get_connected_band(vdev);
ucfg_twt_cfg_get_24ghz_enabled(psoc, &val);
osif_debug("connected_band: %d val: %d", connected_band, val);
if (connected_band == BAND_2G && !val)
is_twt_24ghz_allowed = false;
/* fill the self_capability bitmap */
ucfg_twt_cfg_get_requestor(psoc, &twt_req);
osif_debug("is_twt_24ghz_allowed: %d twt_req: %d",
is_twt_24ghz_allowed, twt_req);
if (twt_req && is_twt_24ghz_allowed)
self_cap |= QCA_WLAN_TWT_CAPA_REQUESTOR;
ucfg_twt_cfg_get_bcast_requestor(psoc, &twt_bcast_req);
osif_debug("twt_bcast_req: %d", twt_bcast_req);
self_cap |= (twt_bcast_req ? QCA_WLAN_TWT_CAPA_BROADCAST : 0);
ucfg_twt_cfg_get_flex_sched(psoc, &val);
osif_debug("flex sched: %d", val);
if (val)
self_cap |= QCA_WLAN_TWT_CAPA_FLEXIBLE;
ret = osif_fill_peer_macaddr(vdev, peer_mac.bytes);
if (ret)
return QDF_STATUS_E_INVAL;
qdf_status = ucfg_twt_get_peer_capabilities(psoc, &peer_mac, &peer_cap);
if (QDF_IS_STATUS_ERROR(qdf_status))
return qdf_status;
osif_debug("self_cap: 0x%x peer_cap: 0x%x", self_cap, peer_cap);
osif_priv = wlan_vdev_get_ospriv(vdev);
/*
* Length of attribute QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_SELF &
* QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_PEER
*/
skb_len += 2 * nla_total_size(sizeof(u16)) + NLA_HDRLEN;
reply_skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(
osif_priv->wdev->wiphy,
skb_len);
if (!reply_skb) {
osif_err("TWT: get_caps alloc reply skb failed");
return QDF_STATUS_E_NOMEM;
}
config_attr = nla_nest_start(reply_skb,
QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS);
if (!config_attr) {
osif_err("TWT: nla_nest_start error");
qdf_status = QDF_STATUS_E_FAILURE;
goto free_skb;
}
if (nla_put_u16(reply_skb, QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_SELF,
self_cap)) {
osif_err("TWT: Failed to fill capabilities");
qdf_status = QDF_STATUS_E_FAILURE;
goto free_skb;
}
if (nla_put_u16(reply_skb, QCA_WLAN_VENDOR_ATTR_TWT_CAPABILITIES_PEER,
peer_cap)) {
osif_err("TWT: Failed to fill capabilities");
qdf_status = QDF_STATUS_E_FAILURE;
goto free_skb;
}
nla_nest_end(reply_skb, config_attr);
if (cfg80211_vendor_cmd_reply(reply_skb))
qdf_status = QDF_STATUS_E_INVAL;
free_skb:
if (QDF_IS_STATUS_ERROR(qdf_status) && reply_skb)
kfree_skb(reply_skb);
return qdf_status;
}
static void
osif_twt_setup_response(struct wlan_objmgr_psoc *psoc,
struct twt_add_dialog_complete_event *event)