qcacld-3.0: Add HDD DSC vdev operation start/stop
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. Add APIs in HDD for starting and stopping vdev-level operations. These APIs also provide a register/unregister capability to atomically enable and disable operation processing for a particular vdev. Change-Id: I8bfb7a9bc6c16d219eb74eeeb98591fe4fd7984a CRs-Fixed: 2365189
This commit is contained in:
@@ -19,7 +19,22 @@
|
||||
#ifndef __WLAN_HDD_DSC_H__
|
||||
#define __WLAN_HDD_DSC_H__
|
||||
|
||||
#include <wlan_hdd_main.h>
|
||||
#include "wlan_dsc.h"
|
||||
#include "wlan_hdd_main.h"
|
||||
|
||||
/**
|
||||
* hdd_dsc_init() - global initializer for HDD DSC
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void hdd_dsc_init(void);
|
||||
|
||||
/**
|
||||
* hdd_dsc_deinit() - global deinitializer for HDD DSC
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void hdd_dsc_deinit(void);
|
||||
|
||||
/**
|
||||
* hdd_dsc_psoc_from_wiphy() - get dsc psoc from wiphy
|
||||
@@ -28,4 +43,58 @@
|
||||
* Return: dsc_psoc on success, NULL on failure
|
||||
*/
|
||||
struct dsc_psoc *hdd_dsc_psoc_from_wiphy(struct wiphy *wiphy);
|
||||
|
||||
/**
|
||||
* hdd_vdev_ops_register() - register a dsc_vdev to accept new operations
|
||||
* @net_dev: the net_device which will be used for lookup during op start
|
||||
* @dsc_vdev: the dsc_vdev to use to protect operations on @net_dev
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void hdd_vdev_ops_register(struct net_device *net_dev,
|
||||
struct dsc_vdev *dsc_vdev);
|
||||
|
||||
/**
|
||||
* hdd_vdev_ops_unregister() - unregister a dsc_vdev to reject future operations
|
||||
* @net_dev: the net_device to use for lookup
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void hdd_vdev_ops_unregister(struct net_device *net_dev);
|
||||
|
||||
/**
|
||||
* struct hdd_vdev_op - opaque handle used to identify a specific vdev operation
|
||||
*/
|
||||
struct hdd_vdev_op;
|
||||
|
||||
/**
|
||||
* hdd_vdev_op_start() - attempt to start a vdev-level driver operation
|
||||
* @net_dev: the net_device to start the operation on
|
||||
*
|
||||
* Return: an operation handle on success, NULL on failure
|
||||
*/
|
||||
#define hdd_vdev_op_start(net_dev) __hdd_vdev_op_start(net_dev, __func__)
|
||||
|
||||
/**
|
||||
* hdd_vdev_op_start_with_wdev() - attempt to start a vdev-level driver
|
||||
* operation using a wireless_dev instance
|
||||
* @wdev: the wireless_dev to start the operation on
|
||||
*
|
||||
* Return: an operation handle on success, NULL on failure
|
||||
*/
|
||||
#define hdd_vdev_op_start_with_wdev(wdev) hdd_vdev_op_start((wdev)->netdev)
|
||||
|
||||
struct hdd_vdev_op *__hdd_vdev_op_start(struct net_device *net_dev,
|
||||
const char *func);
|
||||
|
||||
/**
|
||||
* hdd_vdev_op_stop() - stop a given vdev-level operation
|
||||
* @op: an operation handle identifying the operation to stop
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
#define hdd_vdev_op_stop(op) __hdd_vdev_op_stop(op, __func__)
|
||||
|
||||
void __hdd_vdev_op_stop(struct hdd_vdev_op *op, const char *func);
|
||||
|
||||
#endif
|
||||
|
@@ -15,6 +15,12 @@
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "sme_api.h"
|
||||
#include "qdf_lock.h"
|
||||
#include "qdf_status.h"
|
||||
#include "qdf_types.h"
|
||||
#include "wlan_dsc.h"
|
||||
#include "wlan_hdd_dsc.h"
|
||||
|
||||
struct dsc_psoc *hdd_dsc_psoc_from_wiphy(struct wiphy *wiphy)
|
||||
@@ -29,3 +35,132 @@ struct dsc_psoc *hdd_dsc_psoc_from_wiphy(struct wiphy *wiphy)
|
||||
|
||||
return hdd_ctx->hdd_psoc->dsc_psoc;
|
||||
}
|
||||
|
||||
/**
|
||||
* struct hdd_vdev_kvp - net_device/dsc_vdev key-value-pair for mapping a
|
||||
* net_device to a dsc_vdev
|
||||
* @net_dev: the net_device key
|
||||
* @dsc_vdev: the dsc_vdev value
|
||||
*/
|
||||
struct hdd_vdev_kvp {
|
||||
struct net_device *net_dev;
|
||||
struct dsc_vdev *dsc_vdev;
|
||||
};
|
||||
|
||||
static struct hdd_vdev_kvp __hdd_vdev_map[CSR_ROAM_SESSION_MAX];
|
||||
static qdf_spinlock_t __hdd_vdev_lock;
|
||||
|
||||
#define hdd_vdev_map_lock() qdf_spin_lock_bh(&__hdd_vdev_lock)
|
||||
#define hdd_vdev_map_unlock() qdf_spin_unlock_bh(&__hdd_vdev_lock)
|
||||
#define hdd_vdev_map_lock_assert() QDF_BUG(qdf_spin_is_locked(&__hdd_vdev_lock))
|
||||
|
||||
static struct hdd_vdev_kvp *hdd_vdev_kvp_get(struct net_device *net_dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
hdd_vdev_map_lock_assert();
|
||||
|
||||
for (i = 0; i < QDF_ARRAY_SIZE(__hdd_vdev_map); i++) {
|
||||
struct hdd_vdev_kvp *kvp = __hdd_vdev_map + i;
|
||||
|
||||
if (kvp->net_dev == net_dev)
|
||||
return kvp;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void hdd_vdev_ops_register(struct net_device *net_dev,
|
||||
struct dsc_vdev *dsc_vdev)
|
||||
{
|
||||
struct hdd_vdev_kvp *kvp;
|
||||
|
||||
QDF_BUG(net_dev);
|
||||
if (!net_dev)
|
||||
return;
|
||||
|
||||
QDF_BUG(dsc_vdev);
|
||||
if (!dsc_vdev)
|
||||
return;
|
||||
|
||||
hdd_vdev_map_lock();
|
||||
|
||||
kvp = hdd_vdev_kvp_get(NULL);
|
||||
QDF_BUG(kvp);
|
||||
if (kvp) {
|
||||
kvp->net_dev = net_dev;
|
||||
kvp->dsc_vdev = dsc_vdev;
|
||||
}
|
||||
|
||||
hdd_vdev_map_unlock();
|
||||
}
|
||||
|
||||
void hdd_vdev_ops_unregister(struct net_device *net_dev)
|
||||
{
|
||||
struct hdd_vdev_kvp *kvp;
|
||||
|
||||
QDF_BUG(net_dev);
|
||||
if (!net_dev)
|
||||
return;
|
||||
|
||||
hdd_vdev_map_lock();
|
||||
|
||||
kvp = hdd_vdev_kvp_get(net_dev);
|
||||
QDF_BUG(kvp);
|
||||
if (kvp) {
|
||||
kvp->net_dev = NULL;
|
||||
kvp->dsc_vdev = NULL;
|
||||
}
|
||||
|
||||
hdd_vdev_map_unlock();
|
||||
}
|
||||
|
||||
static struct hdd_vdev_op *hdd_vdev_to_op(struct dsc_vdev *dsc_vdev)
|
||||
{
|
||||
return (struct hdd_vdev_op *)dsc_vdev;
|
||||
}
|
||||
|
||||
static struct dsc_vdev *hdd_op_to_vdev(struct hdd_vdev_op *op)
|
||||
{
|
||||
return (struct dsc_vdev *)op;
|
||||
}
|
||||
|
||||
struct hdd_vdev_op *__hdd_vdev_op_start(struct net_device *net_dev,
|
||||
const char *func)
|
||||
{
|
||||
QDF_STATUS status = QDF_STATUS_E_NULL_VALUE;
|
||||
struct hdd_vdev_kvp *kvp;
|
||||
|
||||
QDF_BUG(net_dev);
|
||||
if (!net_dev)
|
||||
return NULL;
|
||||
|
||||
hdd_vdev_map_lock();
|
||||
|
||||
kvp = hdd_vdev_kvp_get(net_dev);
|
||||
if (kvp)
|
||||
status = _dsc_vdev_op_start(kvp->dsc_vdev, func);
|
||||
|
||||
hdd_vdev_map_unlock();
|
||||
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
return NULL;
|
||||
|
||||
return hdd_vdev_to_op(kvp->dsc_vdev);
|
||||
}
|
||||
|
||||
void __hdd_vdev_op_stop(struct hdd_vdev_op *op, const char *func)
|
||||
{
|
||||
_dsc_vdev_op_stop(hdd_op_to_vdev(op), func);
|
||||
}
|
||||
|
||||
void hdd_dsc_init(void)
|
||||
{
|
||||
qdf_spinlock_create(&__hdd_vdev_lock);
|
||||
}
|
||||
|
||||
void hdd_dsc_deinit(void)
|
||||
{
|
||||
qdf_spinlock_destroy(&__hdd_vdev_lock);
|
||||
}
|
||||
|
||||
|
@@ -40,6 +40,7 @@
|
||||
#include <dbglog_host.h>
|
||||
#include <wlan_logging_sock_svc.h>
|
||||
#include <wlan_roam_debug.h>
|
||||
#include "wlan_hdd_dsc.h"
|
||||
#include <wlan_hdd_wowl.h>
|
||||
#include <wlan_hdd_misc.h>
|
||||
#include <wlan_hdd_wext.h>
|
||||
@@ -12917,13 +12918,15 @@ static inline int hdd_state_query_cb(void)
|
||||
int hdd_init(void)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
hdd_dsc_init();
|
||||
|
||||
status = cds_init();
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
hdd_err("Failed to allocate CDS context");
|
||||
ret = -ENOMEM;
|
||||
goto err_out;
|
||||
goto deinit_dsc;
|
||||
}
|
||||
qdf_register_module_state_query_callback(hdd_state_query_cb);
|
||||
|
||||
@@ -12941,7 +12944,11 @@ int hdd_init(void)
|
||||
hdd_register_debug_callback();
|
||||
wlan_roam_debug_init();
|
||||
|
||||
err_out:
|
||||
return 0;
|
||||
|
||||
deinit_dsc:
|
||||
hdd_dsc_deinit();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -12963,6 +12970,8 @@ void hdd_deinit(void)
|
||||
|
||||
wlan_destroy_bug_report_lock();
|
||||
cds_deinit();
|
||||
|
||||
hdd_dsc_deinit();
|
||||
}
|
||||
|
||||
#ifdef QCA_WIFI_NAPIER_EMULATION
|
||||
|
Reference in New Issue
Block a user