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:
parent
297fb98ed9
commit
d7e3efed33
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user