mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-24 05:29:04 -04:00
qcacld-3.0: Integrate DSC (nan)
The Driver Synchronization Core (DSC) is a set of synchronization primitives for use by the driver's orchestration layer. It provides APIs for ensuring safe state transitions (including bring up and tear down) of major driver objects: a single driver, associated psocs, and their associated vdevs. As part of integrating the DSC APIs into OSIF, protect NAN datapath and NAN discovery. Change-Id: Icf24c8f7717cd1ca92616c781f06dacdd69c01f0 CRs-Fixed: 2398340
This commit is contained in:
parent
ecfefa92f9
commit
1b899ef904
3 changed files with 264 additions and 52 deletions
|
|
@ -157,11 +157,19 @@ int wlan_hdd_cfg80211_nan_ext_request(struct wiphy *wiphy,
|
|||
int data_len)
|
||||
|
||||
{
|
||||
int ret;
|
||||
struct osif_psoc_sync *psoc_sync;
|
||||
int errno;
|
||||
|
||||
errno = osif_psoc_sync_op_start(wiphy_dev(wiphy), &psoc_sync);
|
||||
if (errno)
|
||||
return errno;
|
||||
|
||||
cds_ssr_protect(__func__);
|
||||
ret = __wlan_hdd_cfg80211_nan_ext_request(wiphy, wdev, data, data_len);
|
||||
errno = __wlan_hdd_cfg80211_nan_ext_request(wiphy, wdev,
|
||||
data, data_len);
|
||||
cds_ssr_unprotect(__func__);
|
||||
|
||||
return ret;
|
||||
osif_psoc_sync_op_stop(psoc_sync);
|
||||
|
||||
return errno;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -408,20 +408,13 @@ static int __wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
|
|||
int wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
|
||||
struct wireless_dev *wdev, const void *data, int data_len)
|
||||
{
|
||||
struct osif_psoc_sync *psoc_sync;
|
||||
int errno;
|
||||
|
||||
errno = osif_psoc_sync_op_start(wiphy_dev(wiphy), &psoc_sync);
|
||||
if (errno)
|
||||
return errno;
|
||||
|
||||
cds_ssr_protect(__func__);
|
||||
errno = __wlan_hdd_cfg80211_process_ndp_cmd(wiphy, wdev,
|
||||
data, data_len);
|
||||
cds_ssr_unprotect(__func__);
|
||||
|
||||
osif_psoc_sync_op_stop(psoc_sync);
|
||||
|
||||
return errno;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2016-2019 The Linux Foundation. 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
|
||||
|
|
@ -20,6 +20,7 @@
|
|||
* DOC: defines nan component os interface APIs
|
||||
*/
|
||||
|
||||
#include "osif_sync.h"
|
||||
#include "qdf_str.h"
|
||||
#include "qdf_trace.h"
|
||||
#include "qdf_types.h"
|
||||
|
|
@ -168,22 +169,17 @@ vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1] = {
|
|||
},
|
||||
};
|
||||
|
||||
static int os_if_nan_process_ndi_create(struct wlan_objmgr_psoc *psoc,
|
||||
struct nlattr **tb)
|
||||
static int __os_if_nan_process_ndi_create(struct wlan_objmgr_psoc *psoc,
|
||||
char *iface_name,
|
||||
struct nlattr **tb)
|
||||
{
|
||||
int ret;
|
||||
char *iface_name;
|
||||
QDF_STATUS status;
|
||||
uint16_t transaction_id;
|
||||
struct wlan_objmgr_vdev *nan_vdev;
|
||||
struct nan_callbacks cb_obj;
|
||||
|
||||
cfg80211_debug("enter");
|
||||
if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
|
||||
cfg80211_err("Interface name string is unavailable");
|
||||
return -EINVAL;
|
||||
}
|
||||
iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
|
||||
|
||||
nan_vdev = wlan_util_get_vdev_by_ifname(psoc, iface_name, WLAN_NAN_ID);
|
||||
if (nan_vdev) {
|
||||
|
|
@ -215,6 +211,116 @@ static int os_if_nan_process_ndi_create(struct wlan_objmgr_psoc *psoc,
|
|||
return cb_obj.ndi_start(iface_name, transaction_id);
|
||||
}
|
||||
|
||||
static int
|
||||
osif_nla_str(struct nlattr **tb, size_t attr_id, char **out_str)
|
||||
{
|
||||
if (!tb || !tb[attr_id])
|
||||
return -EINVAL;
|
||||
|
||||
*out_str = nla_data(tb[attr_id]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
osif_device_from_psoc(struct wlan_objmgr_psoc *psoc, struct device **out_dev)
|
||||
{
|
||||
qdf_device_t qdf_dev;
|
||||
|
||||
if (!psoc)
|
||||
return -EINVAL;
|
||||
|
||||
qdf_dev = wlan_psoc_get_qdf_dev(psoc);
|
||||
if (!qdf_dev || !qdf_dev->dev)
|
||||
return -EINVAL;
|
||||
|
||||
*out_dev = qdf_dev->dev;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int osif_net_dev_from_vdev(struct wlan_objmgr_vdev *vdev,
|
||||
struct net_device **out_net_dev)
|
||||
{
|
||||
struct vdev_osif_priv *priv;
|
||||
|
||||
if (!vdev)
|
||||
return -EINVAL;
|
||||
|
||||
priv = wlan_vdev_get_ospriv(vdev);
|
||||
if (!priv || !priv->wdev || !priv->wdev->netdev)
|
||||
return -EINVAL;
|
||||
|
||||
*out_net_dev = priv->wdev->netdev;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int osif_net_dev_from_ifname(struct wlan_objmgr_psoc *psoc,
|
||||
char *iface_name,
|
||||
struct net_device **out_net_dev)
|
||||
{
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
struct net_device *net_dev;
|
||||
int errno;
|
||||
|
||||
vdev = wlan_util_get_vdev_by_ifname(psoc, iface_name, WLAN_NAN_ID);
|
||||
if (!vdev)
|
||||
return -EINVAL;
|
||||
|
||||
errno = osif_net_dev_from_vdev(vdev, &net_dev);
|
||||
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID);
|
||||
|
||||
if (errno)
|
||||
return errno;
|
||||
|
||||
*out_net_dev = net_dev;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int os_if_nan_process_ndi_create(struct wlan_objmgr_psoc *psoc,
|
||||
struct nlattr **tb)
|
||||
{
|
||||
struct device *dev;
|
||||
struct net_device *net_dev;
|
||||
struct osif_vdev_sync *vdev_sync;
|
||||
char *ifname;
|
||||
int errno;
|
||||
|
||||
errno = osif_nla_str(tb, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR, &ifname);
|
||||
if (errno)
|
||||
return errno;
|
||||
|
||||
errno = osif_device_from_psoc(psoc, &dev);
|
||||
if (errno)
|
||||
return errno;
|
||||
|
||||
errno = osif_vdev_sync_create_with_trans(dev, &vdev_sync);
|
||||
if (errno)
|
||||
return errno;
|
||||
|
||||
errno = __os_if_nan_process_ndi_create(psoc, ifname, tb);
|
||||
if (errno)
|
||||
goto destroy_sync;
|
||||
|
||||
errno = osif_net_dev_from_ifname(psoc, ifname, &net_dev);
|
||||
if (errno)
|
||||
goto destroy_sync;
|
||||
|
||||
osif_vdev_sync_register(net_dev, vdev_sync);
|
||||
osif_vdev_sync_trans_stop(vdev_sync);
|
||||
|
||||
return 0;
|
||||
|
||||
destroy_sync:
|
||||
osif_vdev_sync_trans_stop(vdev_sync);
|
||||
osif_vdev_sync_destroy(vdev_sync);
|
||||
|
||||
return errno;
|
||||
}
|
||||
|
||||
static void os_if_nan_vdev_delete_peer(struct wlan_objmgr_psoc *psoc,
|
||||
void *peer, void *nan_vdev)
|
||||
{
|
||||
|
|
@ -226,24 +332,17 @@ static void os_if_nan_vdev_delete_peer(struct wlan_objmgr_psoc *psoc,
|
|||
}
|
||||
}
|
||||
|
||||
static int os_if_nan_process_ndi_delete(struct wlan_objmgr_psoc *psoc,
|
||||
struct nlattr **tb)
|
||||
static int __os_if_nan_process_ndi_delete(struct wlan_objmgr_psoc *psoc,
|
||||
char *iface_name,
|
||||
struct nlattr **tb)
|
||||
{
|
||||
uint8_t vdev_id;
|
||||
char *iface_name;
|
||||
QDF_STATUS status;
|
||||
uint32_t num_peers;
|
||||
uint16_t transaction_id;
|
||||
struct nan_callbacks cb_obj;
|
||||
struct wlan_objmgr_vdev *nan_vdev = NULL;
|
||||
|
||||
if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
|
||||
cfg80211_err("Interface name string is unavailable");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
|
||||
|
||||
if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) {
|
||||
cfg80211_err("Transaction id is unavailable");
|
||||
return -EINVAL;
|
||||
|
|
@ -285,6 +384,45 @@ static int os_if_nan_process_ndi_delete(struct wlan_objmgr_psoc *psoc,
|
|||
return cb_obj.ndi_delete(vdev_id, iface_name, transaction_id);
|
||||
}
|
||||
|
||||
static int os_if_nan_process_ndi_delete(struct wlan_objmgr_psoc *psoc,
|
||||
struct nlattr **tb)
|
||||
{
|
||||
struct net_device *net_dev;
|
||||
struct osif_vdev_sync *vdev_sync;
|
||||
char *ifname;
|
||||
int errno;
|
||||
|
||||
errno = osif_nla_str(tb, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR, &ifname);
|
||||
if (errno)
|
||||
return errno;
|
||||
|
||||
errno = osif_net_dev_from_ifname(psoc, ifname, &net_dev);
|
||||
if (errno)
|
||||
return errno;
|
||||
|
||||
errno = osif_vdev_sync_trans_start_wait(net_dev, &vdev_sync);
|
||||
if (errno)
|
||||
return errno;
|
||||
|
||||
osif_vdev_sync_unregister(net_dev);
|
||||
osif_vdev_sync_wait_for_ops(vdev_sync);
|
||||
|
||||
errno = __os_if_nan_process_ndi_delete(psoc, ifname, tb);
|
||||
if (errno)
|
||||
goto reregister;
|
||||
|
||||
osif_vdev_sync_trans_stop(vdev_sync);
|
||||
osif_vdev_sync_destroy(vdev_sync);
|
||||
|
||||
return 0;
|
||||
|
||||
reregister:
|
||||
osif_vdev_sync_register(net_dev, vdev_sync);
|
||||
osif_vdev_sync_trans_stop(vdev_sync);
|
||||
|
||||
return errno;
|
||||
}
|
||||
|
||||
/**
|
||||
* os_if_nan_parse_security_params() - parse vendor attributes for security
|
||||
* params.
|
||||
|
|
@ -351,7 +489,7 @@ static int os_if_nan_parse_security_params(struct nlattr **tb,
|
|||
}
|
||||
|
||||
/**
|
||||
* os_if_nan_process_ndp_initiator_req() - NDP initiator request handler
|
||||
* __os_if_nan_process_ndp_initiator_req() - NDP initiator request handler
|
||||
* @ctx: hdd context
|
||||
* @tb: parsed NL attribute list
|
||||
*
|
||||
|
|
@ -371,22 +509,16 @@ static int os_if_nan_parse_security_params(struct nlattr **tb,
|
|||
*
|
||||
* Return: 0 on success or error code on failure
|
||||
*/
|
||||
static int os_if_nan_process_ndp_initiator_req(struct wlan_objmgr_psoc *psoc,
|
||||
struct nlattr **tb)
|
||||
static int __os_if_nan_process_ndp_initiator_req(struct wlan_objmgr_psoc *psoc,
|
||||
char *iface_name,
|
||||
struct nlattr **tb)
|
||||
{
|
||||
int ret = 0;
|
||||
char *iface_name;
|
||||
QDF_STATUS status;
|
||||
enum nan_datapath_state state;
|
||||
struct wlan_objmgr_vdev *nan_vdev;
|
||||
struct nan_datapath_initiator_req req = {0};
|
||||
|
||||
if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
|
||||
cfg80211_err("Interface name string is unavailable");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
|
||||
nan_vdev = wlan_util_get_vdev_by_ifname(psoc, iface_name, WLAN_NAN_ID);
|
||||
if (!nan_vdev) {
|
||||
cfg80211_err("NAN data interface %s not available", iface_name);
|
||||
|
|
@ -499,8 +631,35 @@ initiator_req_failed:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int os_if_nan_process_ndp_initiator_req(struct wlan_objmgr_psoc *psoc,
|
||||
struct nlattr **tb)
|
||||
{
|
||||
struct net_device *net_dev;
|
||||
struct osif_vdev_sync *vdev_sync;
|
||||
char *ifname;
|
||||
int errno;
|
||||
|
||||
errno = osif_nla_str(tb, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR, &ifname);
|
||||
if (errno)
|
||||
return errno;
|
||||
|
||||
errno = osif_net_dev_from_ifname(psoc, ifname, &net_dev);
|
||||
if (errno)
|
||||
return errno;
|
||||
|
||||
errno = osif_vdev_sync_op_start(net_dev, &vdev_sync);
|
||||
if (errno)
|
||||
return errno;
|
||||
|
||||
errno = __os_if_nan_process_ndp_initiator_req(psoc, ifname, tb);
|
||||
|
||||
osif_vdev_sync_op_stop(vdev_sync);
|
||||
|
||||
return errno;
|
||||
}
|
||||
|
||||
/**
|
||||
* os_if_nan_process_ndp_responder_req() - NDP responder request handler
|
||||
* __os_if_nan_process_ndp_responder_req() - NDP responder request handler
|
||||
* @nan_ctx: hdd context
|
||||
* @tb: parsed NL attribute list
|
||||
*
|
||||
|
|
@ -518,11 +677,11 @@ initiator_req_failed:
|
|||
*
|
||||
* Return: 0 on success or error code on failure
|
||||
*/
|
||||
static int os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc *psoc,
|
||||
struct nlattr **tb)
|
||||
static int __os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc *psoc,
|
||||
char *iface_name,
|
||||
struct nlattr **tb)
|
||||
{
|
||||
int ret = 0;
|
||||
char *iface_name;
|
||||
QDF_STATUS status;
|
||||
enum nan_datapath_state state;
|
||||
struct wlan_objmgr_vdev *nan_vdev = NULL;
|
||||
|
|
@ -535,12 +694,6 @@ static int os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc *psoc,
|
|||
req.ndp_rsp = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]);
|
||||
|
||||
if (req.ndp_rsp == NAN_DATAPATH_RESPONSE_ACCEPT) {
|
||||
if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
|
||||
cfg80211_err("Interface not provided");
|
||||
return -ENODEV;
|
||||
}
|
||||
iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
|
||||
|
||||
/* Check for an existing NAN interface */
|
||||
nan_vdev = wlan_util_get_vdev_by_ifname(psoc, iface_name,
|
||||
WLAN_NAN_ID);
|
||||
|
|
@ -662,8 +815,35 @@ responder_req_failed:
|
|||
|
||||
}
|
||||
|
||||
static int os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc *psoc,
|
||||
struct nlattr **tb)
|
||||
{
|
||||
struct net_device *net_dev;
|
||||
struct osif_vdev_sync *vdev_sync;
|
||||
char *ifname;
|
||||
int errno;
|
||||
|
||||
errno = osif_nla_str(tb, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR, &ifname);
|
||||
if (errno)
|
||||
return errno;
|
||||
|
||||
errno = osif_net_dev_from_ifname(psoc, ifname, &net_dev);
|
||||
if (errno)
|
||||
return errno;
|
||||
|
||||
errno = osif_vdev_sync_op_start(net_dev, &vdev_sync);
|
||||
if (errno)
|
||||
return errno;
|
||||
|
||||
errno = __os_if_nan_process_ndp_responder_req(psoc, ifname, tb);
|
||||
|
||||
osif_vdev_sync_op_stop(vdev_sync);
|
||||
|
||||
return errno;
|
||||
}
|
||||
|
||||
/**
|
||||
* os_if_nan_process_ndp_end_req() - NDP end request handler
|
||||
* __os_if_nan_process_ndp_end_req() - NDP end request handler
|
||||
* @psoc: pointer to psoc object
|
||||
*
|
||||
* @tb: parsed NL attribute list
|
||||
|
|
@ -672,8 +852,8 @@ responder_req_failed:
|
|||
*
|
||||
* Return: 0 on success or error code on failure
|
||||
*/
|
||||
static int os_if_nan_process_ndp_end_req(struct wlan_objmgr_psoc *psoc,
|
||||
struct nlattr **tb)
|
||||
static int __os_if_nan_process_ndp_end_req(struct wlan_objmgr_psoc *psoc,
|
||||
struct nlattr **tb)
|
||||
{
|
||||
int ret = 0;
|
||||
QDF_STATUS status;
|
||||
|
|
@ -722,6 +902,37 @@ static int os_if_nan_process_ndp_end_req(struct wlan_objmgr_psoc *psoc,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int os_if_nan_process_ndp_end_req(struct wlan_objmgr_psoc *psoc,
|
||||
struct nlattr **tb)
|
||||
{
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
struct net_device *net_dev;
|
||||
struct osif_vdev_sync *vdev_sync;
|
||||
int errno;
|
||||
|
||||
vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(psoc, QDF_NDI_MODE,
|
||||
WLAN_NAN_ID);
|
||||
if (!vdev)
|
||||
return -EINVAL;
|
||||
|
||||
errno = osif_net_dev_from_vdev(vdev, &net_dev);
|
||||
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_NAN_ID);
|
||||
|
||||
if (errno)
|
||||
return errno;
|
||||
|
||||
errno = osif_vdev_sync_op_start(net_dev, &vdev_sync);
|
||||
if (errno)
|
||||
return errno;
|
||||
|
||||
errno = __os_if_nan_process_ndp_end_req(psoc, tb);
|
||||
|
||||
osif_vdev_sync_op_stop(vdev_sync);
|
||||
|
||||
return errno;
|
||||
}
|
||||
|
||||
int os_if_nan_process_ndp_cmd(struct wlan_objmgr_psoc *psoc,
|
||||
const void *data, int data_len)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue