qcacmn: Add support for initiate pasn auth vendor command

Add support for initiate pasn authentication using the vendor
command: QCA_NL80211_VENDOR_SUBCMD_PASN
Fill the below required attributes to initiate PASN:
QCA_WLAN_VENDOR_ATTR_PASN_ACTION
QCA_WLAN_VENDOR_ATTR_PASN_PEERS
QCA_WLAN_VENDOR_ATTR_PASN_PEER_MAC_ADDR
QCA_WLAN_VENDOR_ATTR_PASN_PEER_SRC_ADDR

Change-Id: If33f54eafe5986b4571cc21a80fb0b61578db116
CRs-Fixed: 3232261
This commit is contained in:
Pragaspathi Thilagaraj
2022-06-22 18:28:59 +05:30
committed by Madan Koyyalamudi
parent 93bf7e1fb1
commit 38b8236ddc
9 changed files with 218 additions and 40 deletions

View File

@@ -28,6 +28,7 @@
#include "qdf_status.h" #include "qdf_status.h"
#include <wlan_objmgr_cmn.h> #include <wlan_objmgr_cmn.h>
#include "wifi_pos_public_struct.h" #include "wifi_pos_public_struct.h"
#include "wlan_cfg80211.h"
/* forward declaration */ /* forward declaration */
struct wifi_pos_ch_info; struct wifi_pos_ch_info;
@@ -35,6 +36,12 @@ struct wlan_objmgr_psoc;
struct wifi_pos_driver_caps; struct wifi_pos_driver_caps;
#ifdef WIFI_POS_CONVERGED #ifdef WIFI_POS_CONVERGED
#define FEATURE_WIFI_POS_11AZ_AUTH_EVENTS \
[QCA_NL80211_VENDOR_SUBCMD_PASN_AUTH_STATUS_INDEX] = { \
.vendor_id = QCA_NL80211_VENDOR_ID, \
.subcmd = QCA_NL80211_VENDOR_SUBCMD_PASN, \
},
/** /**
* os_if_wifi_pos_register_nl() - abstration API to register callback with GENL * os_if_wifi_pos_register_nl() - abstration API to register callback with GENL
* socket. * socket.
@@ -80,6 +87,8 @@ void os_if_wifi_pos_send_peer_status(struct qdf_mac_addr *peer_mac,
int os_if_wifi_pos_populate_caps(struct wlan_objmgr_psoc *psoc, int os_if_wifi_pos_populate_caps(struct wlan_objmgr_psoc *psoc,
struct wifi_pos_driver_caps *caps); struct wifi_pos_driver_caps *caps);
#else #else
#define FEATURE_WIFI_POS_11AZ_AUTH_EVENTS
static inline int os_if_wifi_pos_register_nl(void) static inline int os_if_wifi_pos_register_nl(void)
{ {
return 0; return 0;

View File

@@ -37,9 +37,7 @@ struct wifi_pos_osif_ops {
uint8_t num_pasn_peers, uint8_t num_pasn_peers,
bool is_initiate_pasn); bool is_initiate_pasn);
}; };
#endif
#if defined(WIFI_POS_CONVERGED) && defined(WLAN_FEATURE_RTT_11AZ_SUPPORT)
/** /**
* osif_wifi_pos_register_ops() - Register Wifi-Pos module OS_IF callbacks * osif_wifi_pos_register_ops() - Register Wifi-Pos module OS_IF callbacks
* @psoc: Pointer to PSOC obj * @psoc: Pointer to PSOC obj

View File

@@ -1093,9 +1093,14 @@ os_if_wifi_pos_initiate_pasn_auth(struct wlan_objmgr_vdev *vdev,
bool is_initiate_pasn) bool is_initiate_pasn)
{ {
struct net_device *netdev; struct net_device *netdev;
struct cfg80211_pasn_params *pasn_params;
struct vdev_osif_priv *osif_priv; struct vdev_osif_priv *osif_priv;
int i, ret; struct sk_buff *skb;
struct nlattr *attr, *nest_attr;
enum qca_wlan_vendor_pasn_action action;
int i;
int index = QCA_NL80211_VENDOR_SUBCMD_PASN_AUTH_STATUS_INDEX;
uint16_t record_size;
uint32_t len;
QDF_STATUS status = QDF_STATUS_SUCCESS; QDF_STATUS status = QDF_STATUS_SUCCESS;
osif_priv = wlan_vdev_get_ospriv(vdev); osif_priv = wlan_vdev_get_ospriv(vdev);
@@ -1106,43 +1111,79 @@ os_if_wifi_pos_initiate_pasn_auth(struct wlan_objmgr_vdev *vdev,
netdev = osif_priv->wdev->netdev; netdev = osif_priv->wdev->netdev;
pasn_params = qdf_mem_malloc(sizeof(*pasn_params) + len = NLMSG_HDRLEN;
(num_pasn_peers * /* QCA_WLAN_VENDOR_ATTR_PASN_ACTION */
sizeof(struct pasn_peer))); len += nla_total_size(sizeof(u32));
if (!pasn_params)
/*
* size of nest containing
* QCA_WLAN_VENDOR_ATTR_PASN_PEER_MAC_ADDR
* QCA_WLAN_VENDOR_ATTR_PASN_PEER_SRC_ADDR
*/
record_size = nla_total_size(2 * nla_total_size(ETH_ALEN));
/* QCA_WLAN_VENDOR_ATTR_PASN_PEERS nest */
len += nla_total_size(num_pasn_peers * record_size);
skb = wlan_cfg80211_vendor_event_alloc(osif_priv->wdev->wiphy,
osif_priv->wdev, len,
index, GFP_ATOMIC);
if (!skb)
return QDF_STATUS_E_NOMEM; return QDF_STATUS_E_NOMEM;
pasn_params->action = (is_initiate_pasn ? action = is_initiate_pasn ?
NL80211_PASN_ACTION_AUTH : NL80211_PASN_ACTION_DEAUTH); QCA_WLAN_VENDOR_PASN_ACTION_AUTH :
QCA_WLAN_VENDOR_PASN_ACTION_DELETE_SECURE_RANGING_CONTEXT;
if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_PASN_ACTION, action)) {
osif_err("NLA put failed");
goto nla_put_failure;
}
attr = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_PASN_PEERS);
if (!attr) {
osif_err("NLA nest failed");
status = QDF_STATUS_E_FAILURE;
goto nla_put_failure;
}
pasn_params->num_pasn_peers = num_pasn_peers;
for (i = 0; i < num_pasn_peers; i++) { for (i = 0; i < num_pasn_peers; i++) {
qdf_mem_copy(pasn_params->peer[i].peer_addr, osif_debug("PASN peer_mac[%d]:" QDF_MAC_ADDR_FMT "src_mac:" QDF_MAC_ADDR_FMT, i,
pasn_peer[i].peer_mac.bytes, QDF_MAC_ADDR_REF(pasn_peer[i].peer_mac.bytes),
QDF_MAC_ADDR_SIZE); QDF_MAC_ADDR_REF(pasn_peer[i].self_mac.bytes));
qdf_mem_copy(pasn_params->peer[i].src_addr, nest_attr = nla_nest_start(skb, i);
pasn_peer[i].self_mac.bytes, if (!nest_attr) {
QDF_MAC_ADDR_SIZE); osif_err("NLA nest failed for iter:%d", i);
if (pasn_peer[i].force_self_mac_usage) status = QDF_STATUS_E_FAILURE;
pasn_params->peer[i].flags = PASN_PEER_USE_SRC_MAC; goto nla_put_failure;
}
osif_debug("PASN peer_mac[%d]:" QDF_MAC_ADDR_FMT " src_mac:" QDF_MAC_ADDR_FMT, if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_PASN_PEER_MAC_ADDR,
i, ETH_ALEN, pasn_peer[i].peer_mac.bytes)) {
QDF_MAC_ADDR_REF(pasn_params->peer[i].peer_addr), osif_err("NLA put failed");
QDF_MAC_ADDR_REF(pasn_params->peer[i].src_addr)); status = QDF_STATUS_E_FAILURE;
goto nla_put_failure;
}
if (pasn_peer[i].force_self_mac_usage &&
nla_put(skb, QCA_WLAN_VENDOR_ATTR_PASN_PEER_SRC_ADDR,
ETH_ALEN, pasn_peer[i].self_mac.bytes)) {
osif_err("NLA put failed");
status = QDF_STATUS_E_FAILURE;
goto nla_put_failure;
}
nla_nest_end(skb, nest_attr);
} }
nla_nest_end(skb, attr);
osif_debug("action:%d num_pasn_peers:%d", pasn_params->action, osif_debug("action:%d num_pasn_peers:%d", action, num_pasn_peers);
pasn_params->num_pasn_peers);
ret = cfg80211_pasn_auth_request(netdev, pasn_params, wlan_cfg80211_vendor_event(skb, GFP_ATOMIC);
qdf_mem_malloc_flags());
if (ret) {
status = qdf_status_from_os_return(ret);
osif_err("PASN Auth request failed");
}
qdf_mem_free(pasn_params); return status;
nla_put_failure:
wlan_cfg80211_vendor_free_skb(skb);
return status; return status;
} }

View File

@@ -255,6 +255,7 @@ enum qca_nl80211_vendor_subcmds_index {
QCA_NL80211_VENDOR_SUBCMD_MCC_QUOTA_INDEX, QCA_NL80211_VENDOR_SUBCMD_MCC_QUOTA_INDEX,
QCA_NL80211_VENDOR_SUBCMD_PEER_FLUSH_PENDING_INDEX, QCA_NL80211_VENDOR_SUBCMD_PEER_FLUSH_PENDING_INDEX,
QCA_NL80211_VENDOR_SUBCMD_DRIVER_READY_INDEX, QCA_NL80211_VENDOR_SUBCMD_DRIVER_READY_INDEX,
QCA_NL80211_VENDOR_SUBCMD_PASN_AUTH_STATUS_INDEX,
#ifdef WLAN_SUPPORT_SCS #ifdef WLAN_SUPPORT_SCS
QCA_NL80211_VENDOR_SUBCMD_SCS_RULE_CONFIG_INDEX, QCA_NL80211_VENDOR_SUBCMD_SCS_RULE_CONFIG_INDEX,
#endif #endif

View File

@@ -164,6 +164,7 @@ void target_if_vdev_mgr_rsp_timer_cb(void *arg)
} else if (qdf_atomic_test_bit(PEER_DELETE_ALL_RESPONSE_BIT, } else if (qdf_atomic_test_bit(PEER_DELETE_ALL_RESPONSE_BIT,
&vdev_rsp->rsp_status)) { &vdev_rsp->rsp_status)) {
peer_del_all_rsp.vdev_id = vdev_id; peer_del_all_rsp.vdev_id = vdev_id;
peer_del_all_rsp.peer_type_bitmap = vdev_rsp->peer_type_bitmap;
rsp_pos = PEER_DELETE_ALL_RESPONSE_BIT; rsp_pos = PEER_DELETE_ALL_RESPONSE_BIT;
recovery_reason = QDF_VDEV_PEER_DELETE_ALL_RESPONSE_TIMED_OUT; recovery_reason = QDF_VDEV_PEER_DELETE_ALL_RESPONSE_TIMED_OUT;
target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, rsp_pos); target_if_vdev_mgr_rsp_timer_stop(psoc, vdev_rsp, rsp_pos);

View File

@@ -33,6 +33,7 @@
#endif #endif
#ifdef WIFI_POS_CONVERGED #ifdef WIFI_POS_CONVERGED
#include "target_if_wifi_pos.h" #include "target_if_wifi_pos.h"
#include "target_if_wifi_pos_rx_ops.h"
#endif /* WIFI_POS_CONVERGED */ #endif /* WIFI_POS_CONVERGED */
#include "wlan_reg_tgt_api.h" #include "wlan_reg_tgt_api.h"
#ifdef CONVERGED_P2P_ENABLE #ifdef CONVERGED_P2P_ENABLE

View File

@@ -154,6 +154,17 @@ wifi_pos_get_pasn_peer_count(struct wlan_objmgr_vdev *vdev);
void wifi_pos_update_pasn_peer_count(struct wlan_objmgr_vdev *vdev, void wifi_pos_update_pasn_peer_count(struct wlan_objmgr_vdev *vdev,
bool is_increment); bool is_increment);
/**
* wifi_pos_cleanup_pasn_peers - Delete all PASN peer objects for
* given vdev
* @vdev: Pointer to vdev object
*
* Return: QDF_STATUS
*/
QDF_STATUS
wifi_pos_cleanup_pasn_peers(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_vdev *vdev);
/** /**
* wifi_pos_vdev_delete_all_ranging_peers() - Delete all ranging peers * wifi_pos_vdev_delete_all_ranging_peers() - Delete all ranging peers
* associated with given vdev id * associated with given vdev id
@@ -176,6 +187,26 @@ wifi_pos_vdev_delete_all_ranging_peers(struct wlan_objmgr_vdev *vdev);
QDF_STATUS QDF_STATUS
wifi_pos_vdev_delete_all_ranging_peers_rsp(struct wlan_objmgr_psoc *psoc, wifi_pos_vdev_delete_all_ranging_peers_rsp(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id); uint8_t vdev_id);
/**
* wifi_pos_is_delete_all_peer_in_progress() - Check if delete all
* pasn peers command is already in progress for a given vdev
* @vdev: Vdev object pointer
*
* Return: True if delete all pasn peer is in progress
*/
bool wifi_pos_is_delete_all_peer_in_progress(struct wlan_objmgr_vdev *vdev);
/**
* wifi_pos_set_delete_all_peer_in_progress() - API to set/unset delete all
* ranging peers is in progress
* @vdev: Pointer to vdev object
* @flag: value to indicate set or unset the flag
*
* Return: None
*/
void wifi_pos_set_delete_all_peer_in_progress(struct wlan_objmgr_vdev *vdev,
bool flag);
#else #else
static inline static inline
QDF_STATUS wifi_pos_handle_ranging_peer_create(struct wlan_objmgr_psoc *psoc, QDF_STATUS wifi_pos_handle_ranging_peer_create(struct wlan_objmgr_psoc *psoc,
@@ -238,5 +269,23 @@ wifi_pos_vdev_delete_all_ranging_peers(struct wlan_objmgr_vdev *vdev)
{ {
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
} }
static inline
bool wifi_pos_is_delete_all_peer_in_progress(struct wlan_objmgr_vdev *vdev)
{
return false;
}
static inline QDF_STATUS
wifi_pos_cleanup_pasn_peers(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_vdev *vdev)
{
return QDF_STATUS_SUCCESS;
}
static inline
void wifi_pos_set_delete_all_peer_in_progress(struct wlan_objmgr_vdev *vdev,
bool flag)
{}
#endif /* WIFI_POS_CONVERGED && WLAN_FEATURE_RTT_11AZ_SUPPORT */ #endif /* WIFI_POS_CONVERGED && WLAN_FEATURE_RTT_11AZ_SUPPORT */
#endif /* _WIFI_POS_PASN_API_H_ */ #endif /* _WIFI_POS_PASN_API_H_ */

View File

@@ -177,7 +177,7 @@ void wifi_pos_move_peers_to_fail_list(struct wlan_objmgr_vdev *vdev,
uint8_t i; uint8_t i;
struct wifi_pos_vdev_priv_obj *vdev_pos_obj; struct wifi_pos_vdev_priv_obj *vdev_pos_obj;
struct wifi_pos_11az_context *pasn_context; struct wifi_pos_11az_context *pasn_context;
struct wlan_pasn_request *secure_list, *unsecure_list, *list; struct wlan_pasn_request *secure_list, *unsecure_list, *list = NULL;
struct qdf_mac_addr entry_to_copy; struct qdf_mac_addr entry_to_copy;
if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE) if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE)
@@ -201,7 +201,12 @@ void wifi_pos_move_peers_to_fail_list(struct wlan_objmgr_vdev *vdev,
if (peer_type == WLAN_WIFI_POS_PASN_SECURE_PEER) if (peer_type == WLAN_WIFI_POS_PASN_SECURE_PEER)
list = pasn_context->secure_peer_list; list = pasn_context->secure_peer_list;
else if (peer_type == WLAN_WIFI_POS_PASN_UNSECURE_PEER) else if (peer_type == WLAN_WIFI_POS_PASN_UNSECURE_PEER)
list = pasn_context->secure_peer_list; list = pasn_context->unsecure_peer_list;
if (!list) {
wifi_pos_err("No Valid list exists");
return;
}
for (i = 0; i < WLAN_MAX_11AZ_PEERS; i++) { for (i = 0; i < WLAN_MAX_11AZ_PEERS; i++) {
/* /*
@@ -478,6 +483,7 @@ wifi_pos_handle_ranging_peer_create_rsp(struct wlan_objmgr_psoc *psoc,
wifi_pos_debug("Received peer create response for " QDF_MAC_ADDR_FMT " status:%d pending_count:%d", wifi_pos_debug("Received peer create response for " QDF_MAC_ADDR_FMT " status:%d pending_count:%d",
QDF_MAC_ADDR_REF(peer_mac->bytes), peer_create_status, QDF_MAC_ADDR_REF(peer_mac->bytes), peer_create_status,
pasn_context->num_pending_peer_creation); pasn_context->num_pending_peer_creation);
if (peer_create_status) { if (peer_create_status) {
wifi_pos_move_peers_to_fail_list(vdev, peer_mac, wifi_pos_move_peers_to_fail_list(vdev, peer_mac,
WLAN_WIFI_POS_PASN_PEER_TYPE_MAX); WLAN_WIFI_POS_PASN_PEER_TYPE_MAX);
@@ -700,15 +706,55 @@ bool wifi_pos_is_ltf_keyseed_required_for_peer(struct wlan_objmgr_peer *peer)
} }
static static
void wifi_pos_delete_objmgr_ranging_peer(struct wlan_objmgr_vdev *vdev, void wifi_pos_delete_objmgr_ranging_peer(struct wlan_objmgr_psoc *psoc,
void *object, void *arg) void *object, void *arg)
{ {
struct wlan_objmgr_peer *peer = object; struct wlan_objmgr_peer *peer = object;
struct wlan_objmgr_vdev *vdev = arg;
uint8_t vdev_id, peer_vdev_id;
enum wlan_peer_type peer_type;
QDF_STATUS status; QDF_STATUS status;
if (!peer) {
wifi_pos_err("Peer is NULL");
return;
}
peer_type = wlan_peer_get_peer_type(peer);
if (peer_type != WLAN_PEER_RTT_PASN)
return;
if (!vdev) {
wifi_pos_err("VDEV is NULL");
return;
}
vdev_id = wlan_vdev_get_id(vdev);
peer_vdev_id = wlan_vdev_get_id(wlan_peer_get_vdev(peer));
if (vdev_id != peer_vdev_id)
return;
status = wlan_objmgr_peer_obj_delete(peer); status = wlan_objmgr_peer_obj_delete(peer);
if (QDF_IS_STATUS_ERROR(status)) if (QDF_IS_STATUS_ERROR(status))
wifi_pos_err("Failed to delete peer"); wifi_pos_err("Failed to delete peer");
wifi_pos_update_pasn_peer_count(vdev, false);
}
QDF_STATUS
wifi_pos_cleanup_pasn_peers(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_vdev *vdev)
{
QDF_STATUS status;
wifi_pos_debug("Iterate and delete PASN peers");
status = wlan_objmgr_iterate_obj_list(psoc, WLAN_PEER_OP,
wifi_pos_delete_objmgr_ranging_peer,
vdev, 0, WLAN_WIFI_POS_CORE_ID);
if (QDF_IS_STATUS_ERROR(status))
wifi_pos_err("Delete objmgr peers failed");
return status;
} }
QDF_STATUS QDF_STATUS
@@ -729,11 +775,6 @@ wifi_pos_vdev_delete_all_ranging_peers(struct wlan_objmgr_vdev *vdev)
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
vdev_pos_obj->is_delete_all_pasn_peer_in_progress = true; vdev_pos_obj->is_delete_all_pasn_peer_in_progress = true;
status = wlan_objmgr_iterate_peerobj_list(vdev,
wifi_pos_delete_objmgr_ranging_peer,
NULL, WLAN_WIFI_POS_CORE_ID);
if (QDF_IS_STATUS_ERROR(status))
wifi_pos_err("Delete objmgr peers failed");
vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev); vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
if (!vdev_mlme) { if (!vdev_mlme) {
@@ -774,6 +815,12 @@ wifi_pos_vdev_delete_all_ranging_peers_rsp(struct wlan_objmgr_psoc *psoc,
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
} }
status = wifi_pos_cleanup_pasn_peers(psoc, vdev);
if (QDF_IS_STATUS_ERROR(status)) {
wlan_objmgr_vdev_release_ref(vdev, WLAN_WIFI_POS_CORE_ID);
return status;
}
vdev_pos_obj->is_delete_all_pasn_peer_in_progress = false; vdev_pos_obj->is_delete_all_pasn_peer_in_progress = false;
legacy_cb = wifi_pos_get_legacy_ops(psoc); legacy_cb = wifi_pos_get_legacy_ops(psoc);
@@ -791,3 +838,30 @@ wifi_pos_vdev_delete_all_ranging_peers_rsp(struct wlan_objmgr_psoc *psoc,
return status; return status;
} }
bool wifi_pos_is_delete_all_peer_in_progress(struct wlan_objmgr_vdev *vdev)
{
struct wifi_pos_vdev_priv_obj *vdev_pos_obj;
vdev_pos_obj = wifi_pos_get_vdev_priv_obj(vdev);
if (!vdev_pos_obj) {
wifi_pos_err("Wifi pos vdev priv obj is null");
return false;
}
return vdev_pos_obj->is_delete_all_pasn_peer_in_progress;
}
void wifi_pos_set_delete_all_peer_in_progress(struct wlan_objmgr_vdev *vdev,
bool flag)
{
struct wifi_pos_vdev_priv_obj *vdev_pos_obj;
vdev_pos_obj = wifi_pos_get_vdev_priv_obj(vdev);
if (!vdev_pos_obj) {
wifi_pos_err("Wifi pos vdev priv obj is null");
return;
}
vdev_pos_obj->is_delete_all_pasn_peer_in_progress = flag;
}

View File

@@ -16486,6 +16486,10 @@ send_rtt_pasn_auth_status_cmd_tlv(wmi_unified_t wmi_handle,
WMI_CHAR_ARRAY_TO_MAC_ADDR(data->auth_status[i].self_mac.bytes, WMI_CHAR_ARRAY_TO_MAC_ADDR(data->auth_status[i].self_mac.bytes,
&auth_status_tlv->source_mac_addr); &auth_status_tlv->source_mac_addr);
auth_status_tlv->status = data->auth_status[i].status; auth_status_tlv->status = data->auth_status[i].status;
wmi_debug("peer_mac: " QDF_MAC_ADDR_FMT " self_mac:" QDF_MAC_ADDR_FMT " status:%d",
QDF_MAC_ADDR_REF(data->auth_status[i].peer_mac.bytes),
QDF_MAC_ADDR_REF(data->auth_status[i].self_mac.bytes),
auth_status_tlv->status);
buf_ptr += sizeof(wmi_rtt_pasn_auth_status_param); buf_ptr += sizeof(wmi_rtt_pasn_auth_status_param);
} }