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),
|
tgt_caps->legacy_bcast_twt_support),
|
||||||
(enable_twt &&
|
(enable_twt &&
|
||||||
twt_cfg->bcast_responder_enabled));
|
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;
|
return QDF_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,6 +242,7 @@ static int hdd_twt_configure(struct hdd_adapter *adapter,
|
|||||||
case QCA_WLAN_TWT_NUDGE:
|
case QCA_WLAN_TWT_NUDGE:
|
||||||
break;
|
break;
|
||||||
case QCA_WLAN_TWT_GET_CAPABILITIES:
|
case QCA_WLAN_TWT_GET_CAPABILITIES:
|
||||||
|
ret = osif_twt_get_capabilities(vdev);
|
||||||
break;
|
break;
|
||||||
case QCA_WLAN_TWT_GET_STATS:
|
case QCA_WLAN_TWT_GET_STATS:
|
||||||
break;
|
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,
|
void lim_fill_roamed_peer_twt_caps(struct mac_context *mac_ctx, uint8_t vdev_id,
|
||||||
struct roam_offload_synch_ind *roam_synch);
|
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
|
#else
|
||||||
static inline
|
static inline
|
||||||
void lim_fill_roamed_peer_twt_caps(struct mac_context *mac_ctx, uint8_t vdev_id,
|
void lim_fill_roamed_peer_twt_caps(struct mac_context *mac_ctx, uint8_t vdev_id,
|
||||||
struct roam_offload_synch_ind *roam_synch)
|
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
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -85,6 +85,7 @@
|
|||||||
#include "utils_mlo.h"
|
#include "utils_mlo.h"
|
||||||
#include "wlan_mlo_mgr_sta.h"
|
#include "wlan_mlo_mgr_sta.h"
|
||||||
#include "wlan_mlo_mgr_peer.h"
|
#include "wlan_mlo_mgr_peer.h"
|
||||||
|
#include <wlan_twt_api.h>
|
||||||
|
|
||||||
struct pe_hang_event_fixed_param {
|
struct pe_hang_event_fixed_param {
|
||||||
uint16_t tlv_header;
|
uint16_t tlv_header;
|
||||||
@ -1759,6 +1760,44 @@ bool lim_is_sb_disconnect_allowed_fl(struct pe_session *session,
|
|||||||
return false;
|
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
|
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
|
||||||
static void pe_set_rmf_caps(struct mac_context *mac_ctx,
|
static void pe_set_rmf_caps(struct mac_context *mac_ctx,
|
||||||
struct pe_session *ft_session,
|
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))
|
if (lim_is_session_he_capable(pe_session))
|
||||||
mlme_set_twt_peer_capabilities(mac_ctx->psoc,
|
lim_set_twt_peer_capabilities(mac_ctx,
|
||||||
&roam_synch->bssid,
|
&roam_synch->bssid,
|
||||||
&reassoc_rsp->he_cap,
|
&reassoc_rsp->he_cap,
|
||||||
&reassoc_rsp->he_op);
|
&reassoc_rsp->he_op);
|
||||||
qdf_mem_free(reassoc_rsp);
|
qdf_mem_free(reassoc_rsp);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1111,8 +1111,8 @@ lim_process_assoc_rsp_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info,
|
|||||||
&assoc_rsp->obss_scanparams);
|
&assoc_rsp->obss_scanparams);
|
||||||
|
|
||||||
if (lim_is_session_he_capable(session_entry))
|
if (lim_is_session_he_capable(session_entry))
|
||||||
mlme_set_twt_peer_capabilities(
|
lim_set_twt_peer_capabilities(
|
||||||
mac_ctx->psoc,
|
mac_ctx,
|
||||||
(struct qdf_mac_addr *)current_bssid,
|
(struct qdf_mac_addr *)current_bssid,
|
||||||
&assoc_rsp->he_cap,
|
&assoc_rsp->he_cap,
|
||||||
&assoc_rsp->he_op);
|
&assoc_rsp->he_op);
|
||||||
|
@ -92,6 +92,41 @@ int osif_twt_sap_teardown_req(struct wlan_objmgr_vdev *vdev,
|
|||||||
void
|
void
|
||||||
osif_twt_handle_renego_failure(struct wlan_objmgr_psoc *psoc,
|
osif_twt_handle_renego_failure(struct wlan_objmgr_psoc *psoc,
|
||||||
struct twt_add_dialog_complete_event *add_dialog_event);
|
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
|
#else
|
||||||
static inline
|
static inline
|
||||||
int osif_twt_setup_req(struct wlan_objmgr_vdev *vdev,
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
int osif_twt_get_capabilities(struct wlan_objmgr_vdev *vdev)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
int osif_twt_sta_teardown_req(struct wlan_objmgr_vdev *vdev,
|
int osif_twt_sta_teardown_req(struct wlan_objmgr_vdev *vdev,
|
||||||
struct nlattr *twt_param_attr)
|
struct nlattr *twt_param_attr)
|
||||||
|
@ -363,8 +363,7 @@ osif_twt_parse_del_dialog_attrs(struct nlattr **tb,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int osif_fill_peer_macaddr(struct wlan_objmgr_vdev *vdev,
|
int osif_fill_peer_macaddr(struct wlan_objmgr_vdev *vdev, uint8_t *mac_addr)
|
||||||
uint8_t *mac_addr)
|
|
||||||
{
|
{
|
||||||
struct wlan_objmgr_peer *peer;
|
struct wlan_objmgr_peer *peer;
|
||||||
|
|
||||||
@ -374,8 +373,7 @@ static int osif_fill_peer_macaddr(struct wlan_objmgr_vdev *vdev,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
wlan_peer_obj_lock(peer);
|
wlan_peer_obj_lock(peer);
|
||||||
qdf_mem_copy(mac_addr, wlan_peer_get_macaddr(peer),
|
qdf_mem_copy(mac_addr, wlan_peer_get_macaddr(peer), QDF_MAC_ADDR_SIZE);
|
||||||
QDF_MAC_ADDR_SIZE);
|
|
||||||
wlan_peer_obj_unlock(peer);
|
wlan_peer_obj_unlock(peer);
|
||||||
|
|
||||||
wlan_objmgr_peer_release_ref(peer, WLAN_TWT_ID);
|
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);
|
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,
|
int osif_twt_setup_req(struct wlan_objmgr_vdev *vdev,
|
||||||
struct nlattr *twt_param_attr)
|
struct nlattr *twt_param_attr)
|
||||||
{
|
{
|
||||||
|
@ -25,6 +25,12 @@
|
|||||||
#include <wlan_objmgr_psoc_obj.h>
|
#include <wlan_objmgr_psoc_obj.h>
|
||||||
#include <wlan_osif_priv.h>
|
#include <wlan_osif_priv.h>
|
||||||
#include <wlan_osif_request_manager.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
|
* 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;
|
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
|
static void
|
||||||
osif_twt_setup_response(struct wlan_objmgr_psoc *psoc,
|
osif_twt_setup_response(struct wlan_objmgr_psoc *psoc,
|
||||||
struct twt_add_dialog_complete_event *event)
|
struct twt_add_dialog_complete_event *event)
|
||||||
|
Loading…
Reference in New Issue
Block a user