qcacld-3.0: Move hdd_dsc to osif/sync
Move the contents of hdd_dsc to the new files added in osif/sync as part of Ica94d32028d10d344294d6cc12d91a06efe1ab6c. Change-Id: I556e9d2833edd2bd26266496b6000347649c5fbe CRs-Fixed: 2396512
This commit is contained in:
1
Kbuild
1
Kbuild
@@ -53,7 +53,6 @@ HDD_OBJS := $(HDD_SRC_DIR)/wlan_hdd_assoc.o \
|
||||
$(HDD_SRC_DIR)/wlan_hdd_cfg80211.o \
|
||||
$(HDD_SRC_DIR)/wlan_hdd_data_stall_detection.o \
|
||||
$(HDD_SRC_DIR)/wlan_hdd_driver_ops.o \
|
||||
$(HDD_SRC_DIR)/wlan_hdd_dsc.o \
|
||||
$(HDD_SRC_DIR)/wlan_hdd_ext_scan.o \
|
||||
$(HDD_SRC_DIR)/wlan_hdd_ftm.o \
|
||||
$(HDD_SRC_DIR)/wlan_hdd_hostapd.o \
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2018-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
|
||||
@@ -24,6 +24,7 @@
|
||||
#define __WLAN_DSC_PSOC_H
|
||||
|
||||
#include "qdf_status.h"
|
||||
#include "wlan_dsc_driver.h"
|
||||
|
||||
/**
|
||||
* struct dsc_psoc - opaque dsc psoc context
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2018-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
|
||||
@@ -24,6 +24,7 @@
|
||||
#define __WLAN_DSC_VDEV_H
|
||||
|
||||
#include "qdf_status.h"
|
||||
#include "wlan_dsc_psoc.h"
|
||||
|
||||
/**
|
||||
* struct dsc_vdev - opaque dsc vdev context
|
||||
|
@@ -1,340 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018-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
|
||||
* above copyright notice and this permission notice appear in all
|
||||
* copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __WLAN_HDD_DSC_H__
|
||||
#define __WLAN_HDD_DSC_H__
|
||||
|
||||
#include "qdf_types.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);
|
||||
|
||||
/**
|
||||
* struct hdd_psoc_sync - opaque synchronization handle for a psoc
|
||||
*/
|
||||
struct hdd_psoc_sync;
|
||||
|
||||
/**
|
||||
* hdd_psoc_sync_create() - create a psoc synchronization context
|
||||
* @dsc_driver: parent dsc_driver to the psoc
|
||||
* @out_psoc_sync: out parameter for the new synchronization context
|
||||
*
|
||||
* Return: Errno
|
||||
*/
|
||||
qdf_must_check int
|
||||
hdd_psoc_sync_create(struct dsc_driver *dsc_driver,
|
||||
struct hdd_psoc_sync **out_psoc_sync);
|
||||
|
||||
/**
|
||||
* hdd_psoc_sync_create_with_trans() - create a psoc synchronization context
|
||||
* @dsc_driver: parent dsc_driver to the psoc
|
||||
* @out_psoc_sync: out parameter for the new synchronization context
|
||||
*
|
||||
* For protecting the device creation process.
|
||||
*
|
||||
* Return: Errno
|
||||
*/
|
||||
#define hdd_psoc_sync_create_with_trans(dsc_driver, out_psoc_sync) \
|
||||
__hdd_psoc_sync_create_with_trans(dsc_driver, out_psoc_sync, __func__)
|
||||
|
||||
qdf_must_check int
|
||||
__hdd_psoc_sync_create_with_trans(struct dsc_driver *dsc_driver,
|
||||
struct hdd_psoc_sync **out_psoc_sync,
|
||||
const char *desc);
|
||||
|
||||
/**
|
||||
* hdd_psoc_sync_destroy() - destroy a psoc synchronization context
|
||||
* @psoc_sync: the context to destroy
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void hdd_psoc_sync_destroy(struct hdd_psoc_sync *psoc_sync);
|
||||
|
||||
/**
|
||||
* hdd_psoc_sync_register() - register a psoc for operations/transitions
|
||||
* @dev: the device to use as the operation/transition lookup key
|
||||
* @psoc_sync: the psoc synchronization context to register
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void hdd_psoc_sync_register(struct device *dev,
|
||||
struct hdd_psoc_sync *psoc_sync);
|
||||
|
||||
/**
|
||||
* hdd_psoc_sync_unregister() - unregister a psoc for operations/transitions
|
||||
* @dev: the device originally used to register the psoc_sync context
|
||||
*
|
||||
* Return: the psoc synchronization context that was registered for @dev
|
||||
*/
|
||||
struct hdd_psoc_sync *hdd_psoc_sync_unregister(struct device *dev);
|
||||
|
||||
/**
|
||||
* hdd_psoc_sync_trans_start() - attempt to start a transition on @dev
|
||||
* @dev: the device to transition
|
||||
* @out_psoc_sync: out parameter for the synchronization context registered with
|
||||
* @dev, populated on success
|
||||
*
|
||||
* Return: Errno
|
||||
*/
|
||||
#define hdd_psoc_sync_trans_start(dev, out_psoc_sync) \
|
||||
__hdd_psoc_sync_trans_start(dev, out_psoc_sync, __func__)
|
||||
|
||||
qdf_must_check int
|
||||
__hdd_psoc_sync_trans_start(struct device *dev,
|
||||
struct hdd_psoc_sync **out_psoc_sync,
|
||||
const char *desc);
|
||||
|
||||
/**
|
||||
* hdd_psoc_sync_trans_start_wait() - attempt to start a transition on @dev,
|
||||
* blocking if a conflicting transition is in flight
|
||||
* @dev: the device to transition
|
||||
* @out_psoc_sync: out parameter for the synchronization context registered with
|
||||
* @dev, populated on success
|
||||
*
|
||||
* Return: Errno
|
||||
*/
|
||||
#define hdd_psoc_sync_trans_start_wait(dev, out_psoc_sync) \
|
||||
__hdd_psoc_sync_trans_start_wait(dev, out_psoc_sync, __func__)
|
||||
|
||||
qdf_must_check int
|
||||
__hdd_psoc_sync_trans_start_wait(struct device *dev,
|
||||
struct hdd_psoc_sync **out_psoc_sync,
|
||||
const char *desc);
|
||||
|
||||
/**
|
||||
* hdd_psoc_sync_trans_resume() - resume a transition on @dev
|
||||
* @dev: the device under transition
|
||||
* @out_psoc_sync: out parameter for the synchronization context registered with
|
||||
* @dev, populated on success
|
||||
*
|
||||
* Return: Errno
|
||||
*/
|
||||
int hdd_psoc_sync_trans_resume(struct device *dev,
|
||||
struct hdd_psoc_sync **out_psoc_sync);
|
||||
|
||||
/**
|
||||
* hdd_psoc_sync_trans_stop() - stop a transition associated with @psoc_sync
|
||||
* @psoc_sync: the synchonization context tracking the transition
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void hdd_psoc_sync_trans_stop(struct hdd_psoc_sync *psoc_sync);
|
||||
|
||||
/**
|
||||
* hdd_psoc_sync_assert_trans_protected() - assert that @dev is currently
|
||||
* protected by a transition
|
||||
* @dev: the device to check
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void hdd_psoc_sync_assert_trans_protected(struct device *dev);
|
||||
|
||||
/**
|
||||
* hdd_psoc_sync_op_start() - attempt to start an operation on @dev
|
||||
* @dev: the device to operate against
|
||||
* @out_psoc_sync: out parameter for the synchronization context registered with
|
||||
* @dev, populated on success
|
||||
*
|
||||
* Return: Errno
|
||||
*/
|
||||
#define hdd_psoc_sync_op_start(dev, out_psoc_sync) \
|
||||
__hdd_psoc_sync_op_start(dev, out_psoc_sync, __func__)
|
||||
|
||||
qdf_must_check int
|
||||
__hdd_psoc_sync_op_start(struct device *dev,
|
||||
struct hdd_psoc_sync **out_psoc_sync,
|
||||
const char *func);
|
||||
|
||||
/**
|
||||
* hdd_psoc_sync_op_stop() - stop an operation associated with @psoc_sync
|
||||
* @psoc_sync: the synchonization context tracking the operation
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
#define hdd_psoc_sync_op_stop(dev) \
|
||||
__hdd_psoc_sync_op_stop(dev, __func__)
|
||||
|
||||
void __hdd_psoc_sync_op_stop(struct hdd_psoc_sync *psoc_sync,
|
||||
const char *func);
|
||||
|
||||
/**
|
||||
* hdd_psoc_sync_wait_for_ops() - wait until all @psoc_sync operations complete
|
||||
* @psoc_sync: the synchonization context tracking the operations
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void hdd_psoc_sync_wait_for_ops(struct hdd_psoc_sync *psoc_sync);
|
||||
|
||||
/**
|
||||
* struct hdd_vdev_sync - opaque synchronization handle for a vdev
|
||||
*/
|
||||
struct hdd_vdev_sync;
|
||||
|
||||
/**
|
||||
* hdd_vdev_sync_create() - create a vdev synchronization context
|
||||
* @dev: parent device to the vdev
|
||||
* @out_vdev_sync: out parameter for the new synchronization context
|
||||
*
|
||||
* Return: Errno
|
||||
*/
|
||||
qdf_must_check int
|
||||
hdd_vdev_sync_create(struct device *dev, struct hdd_vdev_sync **out_vdev_sync);
|
||||
|
||||
/**
|
||||
* hdd_vdev_sync_create_with_trans() - create a vdev synchronization context
|
||||
* @dev: parent device to the vdev
|
||||
* @out_vdev_sync: out parameter for the new synchronization context
|
||||
*
|
||||
* For protecting the net_device creation process.
|
||||
*
|
||||
* Return: Errno
|
||||
*/
|
||||
#define hdd_vdev_sync_create_with_trans(dev, out_vdev_sync) \
|
||||
__hdd_vdev_sync_create_with_trans(dev, out_vdev_sync, __func__)
|
||||
|
||||
qdf_must_check int
|
||||
__hdd_vdev_sync_create_with_trans(struct device *dev,
|
||||
struct hdd_vdev_sync **out_vdev_sync,
|
||||
const char *desc);
|
||||
|
||||
/**
|
||||
* hdd_vdev_sync_destroy() - destroy a vdev synchronization context
|
||||
* @vdev_sync: the context to destroy
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void hdd_vdev_sync_destroy(struct hdd_vdev_sync *vdev_sync);
|
||||
|
||||
/**
|
||||
* hdd_vdev_sync_register() - register a vdev for operations/transitions
|
||||
* @net_dev: the net_device to use as the operation/transition lookup key
|
||||
* @vdev_sync: the vdev synchronization context to register
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void hdd_vdev_sync_register(struct net_device *net_dev,
|
||||
struct hdd_vdev_sync *vdev_sync);
|
||||
|
||||
/**
|
||||
* hdd_vdev_sync_unregister() - unregister a vdev for operations/transitions
|
||||
* @net_dev: the net_device originally used to register the vdev_sync context
|
||||
*
|
||||
* Return: the vdev synchronization context that was registered for @net_dev
|
||||
*/
|
||||
struct hdd_vdev_sync *hdd_vdev_sync_unregister(struct net_device *net_dev);
|
||||
|
||||
/**
|
||||
* hdd_vdev_sync_trans_start() - attempt to start a transition on @net_dev
|
||||
* @net_dev: the net_device to transition
|
||||
* @out_vdev_sync: out parameter for the synchronization context registered with
|
||||
* @net_dev, populated on success
|
||||
*
|
||||
* Return: Errno
|
||||
*/
|
||||
#define hdd_vdev_sync_trans_start(net_dev, out_vdev_sync) \
|
||||
__hdd_vdev_sync_trans_start(net_dev, out_vdev_sync, __func__)
|
||||
|
||||
qdf_must_check int
|
||||
__hdd_vdev_sync_trans_start(struct net_device *net_dev,
|
||||
struct hdd_vdev_sync **out_vdev_sync,
|
||||
const char *desc);
|
||||
|
||||
/**
|
||||
* hdd_vdev_sync_trans_start_wait() - attempt to start a transition on @net_dev,
|
||||
* blocking if a conflicting transition is in flight
|
||||
* @net_dev: the net_device to transition
|
||||
* @out_vdev_sync: out parameter for the synchronization context registered with
|
||||
* @net_dev, populated on success
|
||||
*
|
||||
* Return: Errno
|
||||
*/
|
||||
#define hdd_vdev_sync_trans_start_wait(net_dev, out_vdev_sync) \
|
||||
__hdd_vdev_sync_trans_start_wait(net_dev, out_vdev_sync, __func__)
|
||||
|
||||
qdf_must_check int
|
||||
__hdd_vdev_sync_trans_start_wait(struct net_device *net_dev,
|
||||
struct hdd_vdev_sync **out_vdev_sync,
|
||||
const char *desc);
|
||||
|
||||
/**
|
||||
* hdd_vdev_sync_trans_stop() - stop a transition associated with @vdev_sync
|
||||
* @vdev_sync: the synchonization context tracking the transition
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void hdd_vdev_sync_trans_stop(struct hdd_vdev_sync *vdev_sync);
|
||||
|
||||
/**
|
||||
* hdd_vdev_sync_assert_trans_protected() - assert that @net_dev is currently
|
||||
* protected by a transition
|
||||
* @net_dev: the net_device to check
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void hdd_vdev_sync_assert_trans_protected(struct net_device *net_dev);
|
||||
|
||||
/**
|
||||
* hdd_vdev_sync_op_start() - attempt to start an operation on @net_dev
|
||||
* @net_dev: the net_device to operate against
|
||||
* @out_vdev_sync: out parameter for the synchronization context registered with
|
||||
* @net_dev, populated on success
|
||||
*
|
||||
* Return: Errno
|
||||
*/
|
||||
#define hdd_vdev_sync_op_start(net_dev, out_vdev_sync) \
|
||||
__hdd_vdev_sync_op_start(net_dev, out_vdev_sync, __func__)
|
||||
|
||||
qdf_must_check int
|
||||
__hdd_vdev_sync_op_start(struct net_device *net_dev,
|
||||
struct hdd_vdev_sync **out_vdev_sync,
|
||||
const char *func);
|
||||
|
||||
/**
|
||||
* hdd_vdev_sync_op_stop() - stop an operation associated with @vdev_sync
|
||||
* @vdev_sync: the synchonization context tracking the operation
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
#define hdd_vdev_sync_op_stop(net_dev) \
|
||||
__hdd_vdev_sync_op_stop(net_dev, __func__)
|
||||
|
||||
void __hdd_vdev_sync_op_stop(struct hdd_vdev_sync *vdev_sync,
|
||||
const char *func);
|
||||
|
||||
/**
|
||||
* hdd_vdev_sync_wait_for_ops() - wait until all @vdev_sync operations complete
|
||||
* @vdev_sync: the synchonization context tracking the operations
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void hdd_vdev_sync_wait_for_ops(struct hdd_vdev_sync *vdev_sync);
|
||||
|
||||
#endif
|
@@ -118,7 +118,7 @@
|
||||
#include <wlan_hdd_sar_limits.h>
|
||||
#include <wlan_hdd_ota_test.h>
|
||||
#include "wlan_policy_mgr_ucfg.h"
|
||||
#include <wlan_hdd_dsc.h>
|
||||
#include "osif_sync.h"
|
||||
#include "wlan_mlme_ucfg_api.h"
|
||||
#include "wlan_mlme_public_struct.h"
|
||||
#include "wlan_extscan_ucfg_api.h"
|
||||
|
@@ -26,7 +26,7 @@
|
||||
#include "hif.h"
|
||||
#include "htc.h"
|
||||
#include "epping_main.h"
|
||||
#include "wlan_hdd_dsc.h"
|
||||
#include "osif_sync.h"
|
||||
#include "wlan_hdd_main.h"
|
||||
#include "wlan_hdd_power.h"
|
||||
#include "wlan_logging_sock_svc.h"
|
||||
|
@@ -1,607 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018-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
|
||||
* above copyright notice and this permission notice appear in all
|
||||
* copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "qdf_lock.h"
|
||||
#include "qdf_status.h"
|
||||
#include "qdf_types.h"
|
||||
#include "wlan_dsc.h"
|
||||
#include "wlan_hdd_dsc.h"
|
||||
|
||||
/**
|
||||
* struct hdd_psoc_sync - a psoc synchronization context
|
||||
* @dev: the device used as a lookup key
|
||||
* @dsc_psoc: the dsc_psoc used for synchronization
|
||||
* @in_use: indicates if the context is being used
|
||||
*/
|
||||
struct hdd_psoc_sync {
|
||||
struct device *dev;
|
||||
struct dsc_psoc *dsc_psoc;
|
||||
bool in_use;
|
||||
};
|
||||
|
||||
#define WLAN_MAX_PSOCS 1
|
||||
static struct hdd_psoc_sync __hdd_psoc_sync_arr[WLAN_MAX_PSOCS];
|
||||
static qdf_spinlock_t __hdd_psoc_sync_lock;
|
||||
|
||||
#define hdd_psoc_sync_lock_create() qdf_spinlock_create(&__hdd_psoc_sync_lock)
|
||||
#define hdd_psoc_sync_lock_destroy() qdf_spinlock_destroy(&__hdd_psoc_sync_lock)
|
||||
#define hdd_psoc_sync_lock() qdf_spin_lock_bh(&__hdd_psoc_sync_lock)
|
||||
#define hdd_psoc_sync_unlock() qdf_spin_unlock_bh(&__hdd_psoc_sync_lock)
|
||||
#define hdd_psoc_sync_lock_assert() \
|
||||
QDF_BUG(qdf_spin_is_locked(&__hdd_psoc_sync_lock))
|
||||
|
||||
static struct hdd_psoc_sync *hdd_psoc_sync_lookup(struct device *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
hdd_psoc_sync_lock_assert();
|
||||
|
||||
for (i = 0; i < QDF_ARRAY_SIZE(__hdd_psoc_sync_arr); i++) {
|
||||
struct hdd_psoc_sync *psoc_sync = __hdd_psoc_sync_arr + i;
|
||||
|
||||
if (psoc_sync->dev == dev)
|
||||
return psoc_sync;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct hdd_psoc_sync *hdd_psoc_sync_get(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
hdd_psoc_sync_lock_assert();
|
||||
|
||||
for (i = 0; i < QDF_ARRAY_SIZE(__hdd_psoc_sync_arr); i++) {
|
||||
struct hdd_psoc_sync *psoc_sync = __hdd_psoc_sync_arr + i;
|
||||
|
||||
if (!psoc_sync->in_use) {
|
||||
psoc_sync->in_use = true;
|
||||
return psoc_sync;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void hdd_psoc_sync_put(struct hdd_psoc_sync *psoc_sync)
|
||||
{
|
||||
hdd_psoc_sync_lock_assert();
|
||||
|
||||
qdf_mem_zero(psoc_sync, sizeof(*psoc_sync));
|
||||
}
|
||||
|
||||
int hdd_psoc_sync_create(struct dsc_driver *dsc_driver,
|
||||
struct hdd_psoc_sync **out_psoc_sync)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
struct hdd_psoc_sync *psoc_sync;
|
||||
|
||||
QDF_BUG(dsc_driver);
|
||||
if (!dsc_driver)
|
||||
return -EINVAL;
|
||||
|
||||
QDF_BUG(out_psoc_sync);
|
||||
if (!out_psoc_sync)
|
||||
return -EINVAL;
|
||||
|
||||
hdd_psoc_sync_lock();
|
||||
psoc_sync = hdd_psoc_sync_get();
|
||||
hdd_psoc_sync_unlock();
|
||||
if (!psoc_sync)
|
||||
return -ENOMEM;
|
||||
|
||||
status = dsc_psoc_create(dsc_driver, &psoc_sync->dsc_psoc);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
goto sync_put;
|
||||
|
||||
*out_psoc_sync = psoc_sync;
|
||||
|
||||
return 0;
|
||||
|
||||
sync_put:
|
||||
hdd_psoc_sync_lock();
|
||||
hdd_psoc_sync_put(psoc_sync);
|
||||
hdd_psoc_sync_unlock();
|
||||
|
||||
return qdf_status_to_os_return(status);
|
||||
}
|
||||
|
||||
int __hdd_psoc_sync_create_with_trans(struct dsc_driver *dsc_driver,
|
||||
struct hdd_psoc_sync **out_psoc_sync,
|
||||
const char *desc)
|
||||
{
|
||||
struct hdd_psoc_sync *psoc_sync;
|
||||
QDF_STATUS status;
|
||||
int errno;
|
||||
|
||||
errno = hdd_psoc_sync_create(dsc_driver, &psoc_sync);
|
||||
if (errno)
|
||||
return errno;
|
||||
|
||||
status = dsc_psoc_trans_start(psoc_sync->dsc_psoc, desc);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
goto sync_destroy;
|
||||
|
||||
*out_psoc_sync = psoc_sync;
|
||||
|
||||
return 0;
|
||||
|
||||
sync_destroy:
|
||||
hdd_psoc_sync_destroy(psoc_sync);
|
||||
|
||||
return qdf_status_to_os_return(status);
|
||||
}
|
||||
|
||||
void hdd_psoc_sync_destroy(struct hdd_psoc_sync *psoc_sync)
|
||||
{
|
||||
QDF_BUG(psoc_sync);
|
||||
if (!psoc_sync)
|
||||
return;
|
||||
|
||||
dsc_psoc_destroy(&psoc_sync->dsc_psoc);
|
||||
|
||||
hdd_psoc_sync_lock();
|
||||
hdd_psoc_sync_put(psoc_sync);
|
||||
hdd_psoc_sync_unlock();
|
||||
}
|
||||
|
||||
void hdd_psoc_sync_register(struct device *dev,
|
||||
struct hdd_psoc_sync *psoc_sync)
|
||||
{
|
||||
QDF_BUG(dev);
|
||||
QDF_BUG(psoc_sync);
|
||||
if (!psoc_sync)
|
||||
return;
|
||||
|
||||
hdd_psoc_sync_lock();
|
||||
psoc_sync->dev = dev;
|
||||
hdd_psoc_sync_unlock();
|
||||
}
|
||||
|
||||
struct hdd_psoc_sync *hdd_psoc_sync_unregister(struct device *dev)
|
||||
{
|
||||
struct hdd_psoc_sync *psoc_sync;
|
||||
|
||||
QDF_BUG(dev);
|
||||
if (!dev)
|
||||
return NULL;
|
||||
|
||||
hdd_psoc_sync_lock();
|
||||
psoc_sync = hdd_psoc_sync_lookup(dev);
|
||||
if (psoc_sync)
|
||||
psoc_sync->dev = NULL;
|
||||
hdd_psoc_sync_unlock();
|
||||
|
||||
return psoc_sync;
|
||||
}
|
||||
|
||||
typedef QDF_STATUS (*psoc_start_func)(struct dsc_psoc *, const char *);
|
||||
|
||||
static int __hdd_psoc_sync_start_callback(struct device *dev,
|
||||
struct hdd_psoc_sync **out_psoc_sync,
|
||||
const char *desc,
|
||||
psoc_start_func psoc_start_cb)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
struct hdd_psoc_sync *psoc_sync;
|
||||
|
||||
hdd_psoc_sync_lock_assert();
|
||||
|
||||
*out_psoc_sync = NULL;
|
||||
|
||||
psoc_sync = hdd_psoc_sync_lookup(dev);
|
||||
if (!psoc_sync)
|
||||
return -EAGAIN;
|
||||
|
||||
status = psoc_start_cb(psoc_sync->dsc_psoc, desc);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
return qdf_status_to_os_return(status);
|
||||
|
||||
*out_psoc_sync = psoc_sync;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __hdd_psoc_sync_trans_start(struct device *dev,
|
||||
struct hdd_psoc_sync **out_psoc_sync,
|
||||
const char *desc)
|
||||
{
|
||||
int errno;
|
||||
|
||||
hdd_psoc_sync_lock();
|
||||
errno = __hdd_psoc_sync_start_callback(dev, out_psoc_sync, desc,
|
||||
dsc_psoc_trans_start);
|
||||
hdd_psoc_sync_unlock();
|
||||
|
||||
return errno;
|
||||
}
|
||||
|
||||
int __hdd_psoc_sync_trans_start_wait(struct device *dev,
|
||||
struct hdd_psoc_sync **out_psoc_sync,
|
||||
const char *desc)
|
||||
{
|
||||
int errno;
|
||||
|
||||
hdd_psoc_sync_lock();
|
||||
errno = __hdd_psoc_sync_start_callback(dev, out_psoc_sync, desc,
|
||||
dsc_psoc_trans_start_wait);
|
||||
hdd_psoc_sync_unlock();
|
||||
|
||||
return errno;
|
||||
}
|
||||
|
||||
static QDF_STATUS __assert_trans_cb(struct dsc_psoc *dsc_psoc, const char *desc)
|
||||
{
|
||||
dsc_psoc_assert_trans_protected(dsc_psoc);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
int hdd_psoc_sync_trans_resume(struct device *dev,
|
||||
struct hdd_psoc_sync **out_psoc_sync)
|
||||
{
|
||||
int errno;
|
||||
|
||||
hdd_psoc_sync_lock();
|
||||
errno = __hdd_psoc_sync_start_callback(dev, out_psoc_sync, NULL,
|
||||
__assert_trans_cb);
|
||||
hdd_psoc_sync_unlock();
|
||||
|
||||
return errno;
|
||||
}
|
||||
|
||||
void hdd_psoc_sync_trans_stop(struct hdd_psoc_sync *psoc_sync)
|
||||
{
|
||||
dsc_psoc_trans_stop(psoc_sync->dsc_psoc);
|
||||
}
|
||||
|
||||
void hdd_psoc_sync_assert_trans_protected(struct device *dev)
|
||||
{
|
||||
struct hdd_psoc_sync *psoc_sync;
|
||||
|
||||
hdd_psoc_sync_lock();
|
||||
|
||||
psoc_sync = hdd_psoc_sync_lookup(dev);
|
||||
QDF_BUG(psoc_sync);
|
||||
if (psoc_sync)
|
||||
dsc_psoc_assert_trans_protected(psoc_sync->dsc_psoc);
|
||||
|
||||
hdd_psoc_sync_unlock();
|
||||
}
|
||||
|
||||
int __hdd_psoc_sync_op_start(struct device *dev,
|
||||
struct hdd_psoc_sync **out_psoc_sync,
|
||||
const char *func)
|
||||
{
|
||||
int errno;
|
||||
|
||||
hdd_psoc_sync_lock();
|
||||
errno = __hdd_psoc_sync_start_callback(dev, out_psoc_sync, func,
|
||||
_dsc_psoc_op_start);
|
||||
hdd_psoc_sync_unlock();
|
||||
|
||||
return errno;
|
||||
}
|
||||
|
||||
void __hdd_psoc_sync_op_stop(struct hdd_psoc_sync *psoc_sync,
|
||||
const char *func)
|
||||
{
|
||||
_dsc_psoc_op_stop(psoc_sync->dsc_psoc, func);
|
||||
}
|
||||
|
||||
void hdd_psoc_sync_wait_for_ops(struct hdd_psoc_sync *psoc_sync)
|
||||
{
|
||||
dsc_psoc_wait_for_ops(psoc_sync->dsc_psoc);
|
||||
}
|
||||
|
||||
/**
|
||||
* struct hdd_vdev_sync - a vdev synchronization context
|
||||
* @net_dev: the net_device used as a lookup key
|
||||
* @dsc_vdev: the dsc_vdev used for synchronization
|
||||
* @in_use: indicates if the context is being used
|
||||
*/
|
||||
struct hdd_vdev_sync {
|
||||
struct net_device *net_dev;
|
||||
struct dsc_vdev *dsc_vdev;
|
||||
bool in_use;
|
||||
};
|
||||
|
||||
static struct hdd_vdev_sync __hdd_vdev_sync_arr[WLAN_MAX_VDEVS];
|
||||
static qdf_spinlock_t __hdd_vdev_sync_lock;
|
||||
|
||||
#define hdd_vdev_sync_lock_create() qdf_spinlock_create(&__hdd_vdev_sync_lock)
|
||||
#define hdd_vdev_sync_lock_destroy() qdf_spinlock_destroy(&__hdd_vdev_sync_lock)
|
||||
#define hdd_vdev_sync_lock() qdf_spin_lock_bh(&__hdd_vdev_sync_lock)
|
||||
#define hdd_vdev_sync_unlock() qdf_spin_unlock_bh(&__hdd_vdev_sync_lock)
|
||||
#define hdd_vdev_sync_lock_assert() \
|
||||
QDF_BUG(qdf_spin_is_locked(&__hdd_vdev_sync_lock))
|
||||
|
||||
static struct hdd_vdev_sync *hdd_vdev_sync_lookup(struct net_device *net_dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
hdd_vdev_sync_lock_assert();
|
||||
|
||||
for (i = 0; i < QDF_ARRAY_SIZE(__hdd_vdev_sync_arr); i++) {
|
||||
struct hdd_vdev_sync *vdev_sync = __hdd_vdev_sync_arr + i;
|
||||
|
||||
if (vdev_sync->net_dev == net_dev)
|
||||
return vdev_sync;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct hdd_vdev_sync *hdd_vdev_sync_get(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
hdd_vdev_sync_lock_assert();
|
||||
|
||||
for (i = 0; i < QDF_ARRAY_SIZE(__hdd_vdev_sync_arr); i++) {
|
||||
struct hdd_vdev_sync *vdev_sync = __hdd_vdev_sync_arr + i;
|
||||
|
||||
if (!vdev_sync->in_use) {
|
||||
vdev_sync->in_use = true;
|
||||
return vdev_sync;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void hdd_vdev_sync_put(struct hdd_vdev_sync *vdev_sync)
|
||||
{
|
||||
hdd_vdev_sync_lock_assert();
|
||||
|
||||
qdf_mem_zero(vdev_sync, sizeof(*vdev_sync));
|
||||
}
|
||||
|
||||
static QDF_STATUS hdd_vdev_dsc_create(struct device *dev,
|
||||
struct dsc_vdev **out_dsc_vdev)
|
||||
{
|
||||
struct hdd_psoc_sync *psoc_sync;
|
||||
|
||||
hdd_psoc_sync_lock_assert();
|
||||
|
||||
psoc_sync = hdd_psoc_sync_lookup(dev);
|
||||
if (!psoc_sync)
|
||||
return QDF_STATUS_E_INVAL;
|
||||
|
||||
return dsc_vdev_create(psoc_sync->dsc_psoc, out_dsc_vdev);
|
||||
}
|
||||
|
||||
int hdd_vdev_sync_create(struct device *dev,
|
||||
struct hdd_vdev_sync **out_vdev_sync)
|
||||
{
|
||||
struct hdd_vdev_sync *vdev_sync;
|
||||
QDF_STATUS status;
|
||||
|
||||
QDF_BUG(dev);
|
||||
if (!dev)
|
||||
return -EINVAL;
|
||||
|
||||
QDF_BUG(out_vdev_sync);
|
||||
if (!out_vdev_sync)
|
||||
return -EINVAL;
|
||||
|
||||
hdd_vdev_sync_lock();
|
||||
vdev_sync = hdd_vdev_sync_get();
|
||||
hdd_vdev_sync_unlock();
|
||||
if (!vdev_sync)
|
||||
return -ENOMEM;
|
||||
|
||||
hdd_psoc_sync_lock();
|
||||
status = hdd_vdev_dsc_create(dev, &vdev_sync->dsc_vdev);
|
||||
hdd_psoc_sync_unlock();
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
goto sync_put;
|
||||
|
||||
*out_vdev_sync = vdev_sync;
|
||||
|
||||
return 0;
|
||||
|
||||
sync_put:
|
||||
hdd_vdev_sync_lock();
|
||||
hdd_vdev_sync_put(vdev_sync);
|
||||
hdd_vdev_sync_unlock();
|
||||
|
||||
return qdf_status_to_os_return(status);
|
||||
}
|
||||
|
||||
int __hdd_vdev_sync_create_with_trans(struct device *dev,
|
||||
struct hdd_vdev_sync **out_vdev_sync,
|
||||
const char *desc)
|
||||
{
|
||||
struct hdd_vdev_sync *vdev_sync;
|
||||
QDF_STATUS status;
|
||||
int errno;
|
||||
|
||||
errno = hdd_vdev_sync_create(dev, &vdev_sync);
|
||||
if (errno)
|
||||
return errno;
|
||||
|
||||
status = dsc_vdev_trans_start(vdev_sync->dsc_vdev, desc);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
goto sync_destroy;
|
||||
|
||||
*out_vdev_sync = vdev_sync;
|
||||
|
||||
return 0;
|
||||
|
||||
sync_destroy:
|
||||
hdd_vdev_sync_destroy(vdev_sync);
|
||||
|
||||
return qdf_status_to_os_return(status);
|
||||
}
|
||||
|
||||
void hdd_vdev_sync_destroy(struct hdd_vdev_sync *vdev_sync)
|
||||
{
|
||||
QDF_BUG(vdev_sync);
|
||||
if (!vdev_sync)
|
||||
return;
|
||||
|
||||
dsc_vdev_destroy(&vdev_sync->dsc_vdev);
|
||||
|
||||
hdd_vdev_sync_lock();
|
||||
hdd_vdev_sync_put(vdev_sync);
|
||||
hdd_vdev_sync_unlock();
|
||||
}
|
||||
|
||||
void hdd_vdev_sync_register(struct net_device *net_dev,
|
||||
struct hdd_vdev_sync *vdev_sync)
|
||||
{
|
||||
QDF_BUG(net_dev);
|
||||
QDF_BUG(vdev_sync);
|
||||
if (!vdev_sync)
|
||||
return;
|
||||
|
||||
hdd_vdev_sync_lock();
|
||||
vdev_sync->net_dev = net_dev;
|
||||
hdd_vdev_sync_unlock();
|
||||
}
|
||||
|
||||
struct hdd_vdev_sync *hdd_vdev_sync_unregister(struct net_device *net_dev)
|
||||
{
|
||||
struct hdd_vdev_sync *vdev_sync;
|
||||
|
||||
QDF_BUG(net_dev);
|
||||
if (!net_dev)
|
||||
return NULL;
|
||||
|
||||
hdd_vdev_sync_lock();
|
||||
vdev_sync = hdd_vdev_sync_lookup(net_dev);
|
||||
if (vdev_sync)
|
||||
vdev_sync->net_dev = NULL;
|
||||
hdd_vdev_sync_unlock();
|
||||
|
||||
return vdev_sync;
|
||||
}
|
||||
|
||||
typedef QDF_STATUS (*vdev_start_func)(struct dsc_vdev *, const char *);
|
||||
|
||||
static int __hdd_vdev_sync_start_callback(struct net_device *net_dev,
|
||||
struct hdd_vdev_sync **out_vdev_sync,
|
||||
const char *desc,
|
||||
vdev_start_func vdev_start_cb)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
struct hdd_vdev_sync *vdev_sync;
|
||||
|
||||
hdd_vdev_sync_lock_assert();
|
||||
|
||||
*out_vdev_sync = NULL;
|
||||
|
||||
vdev_sync = hdd_vdev_sync_lookup(net_dev);
|
||||
if (!vdev_sync)
|
||||
return -EAGAIN;
|
||||
|
||||
status = vdev_start_cb(vdev_sync->dsc_vdev, desc);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
return qdf_status_to_os_return(status);
|
||||
|
||||
*out_vdev_sync = vdev_sync;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __hdd_vdev_sync_trans_start(struct net_device *net_dev,
|
||||
struct hdd_vdev_sync **out_vdev_sync,
|
||||
const char *desc)
|
||||
{
|
||||
int errno;
|
||||
|
||||
hdd_vdev_sync_lock();
|
||||
errno = __hdd_vdev_sync_start_callback(net_dev, out_vdev_sync, desc,
|
||||
dsc_vdev_trans_start);
|
||||
hdd_vdev_sync_unlock();
|
||||
|
||||
return errno;
|
||||
}
|
||||
|
||||
int __hdd_vdev_sync_trans_start_wait(struct net_device *net_dev,
|
||||
struct hdd_vdev_sync **out_vdev_sync,
|
||||
const char *desc)
|
||||
{
|
||||
int errno;
|
||||
|
||||
hdd_vdev_sync_lock();
|
||||
errno = __hdd_vdev_sync_start_callback(net_dev, out_vdev_sync, desc,
|
||||
dsc_vdev_trans_start_wait);
|
||||
hdd_vdev_sync_unlock();
|
||||
|
||||
return errno;
|
||||
}
|
||||
|
||||
void hdd_vdev_sync_trans_stop(struct hdd_vdev_sync *vdev_sync)
|
||||
{
|
||||
dsc_vdev_trans_stop(vdev_sync->dsc_vdev);
|
||||
}
|
||||
|
||||
void hdd_vdev_sync_assert_trans_protected(struct net_device *net_dev)
|
||||
{
|
||||
struct hdd_vdev_sync *vdev_sync;
|
||||
|
||||
hdd_vdev_sync_lock();
|
||||
|
||||
vdev_sync = hdd_vdev_sync_lookup(net_dev);
|
||||
QDF_BUG(vdev_sync);
|
||||
if (vdev_sync)
|
||||
dsc_vdev_assert_trans_protected(vdev_sync->dsc_vdev);
|
||||
|
||||
hdd_vdev_sync_unlock();
|
||||
}
|
||||
|
||||
int __hdd_vdev_sync_op_start(struct net_device *net_dev,
|
||||
struct hdd_vdev_sync **out_vdev_sync,
|
||||
const char *func)
|
||||
{
|
||||
int errno;
|
||||
|
||||
hdd_vdev_sync_lock();
|
||||
errno = __hdd_vdev_sync_start_callback(net_dev, out_vdev_sync, func,
|
||||
_dsc_vdev_op_start);
|
||||
hdd_vdev_sync_unlock();
|
||||
|
||||
return errno;
|
||||
}
|
||||
|
||||
void __hdd_vdev_sync_op_stop(struct hdd_vdev_sync *vdev_sync,
|
||||
const char *func)
|
||||
{
|
||||
_dsc_vdev_op_stop(vdev_sync->dsc_vdev, func);
|
||||
}
|
||||
|
||||
void hdd_vdev_sync_wait_for_ops(struct hdd_vdev_sync *vdev_sync)
|
||||
{
|
||||
dsc_vdev_wait_for_ops(vdev_sync->dsc_vdev);
|
||||
}
|
||||
|
||||
void hdd_dsc_init(void)
|
||||
{
|
||||
hdd_psoc_sync_lock_create();
|
||||
hdd_vdev_sync_lock_create();
|
||||
}
|
||||
|
||||
void hdd_dsc_deinit(void)
|
||||
{
|
||||
hdd_vdev_sync_lock_destroy();
|
||||
hdd_psoc_sync_lock_destroy();
|
||||
}
|
||||
|
@@ -27,7 +27,7 @@
|
||||
|
||||
#include "wlan_hdd_ext_scan.h"
|
||||
#include "wlan_hdd_regulatory.h"
|
||||
#include <wlan_hdd_dsc.h>
|
||||
#include "osif_sync.h"
|
||||
#include "cds_utils.h"
|
||||
#include "cds_sched.h"
|
||||
#include <qca_vendor.h>
|
||||
|
@@ -25,7 +25,7 @@
|
||||
|
||||
#include "wlan_hdd_main.h"
|
||||
#include "wlan_hdd_he.h"
|
||||
#include <wlan_hdd_dsc.h>
|
||||
#include "osif_sync.h"
|
||||
#include "wma_he.h"
|
||||
#include "wlan_utility.h"
|
||||
#include "wlan_mlme_ucfg_api.h"
|
||||
|
@@ -40,7 +40,7 @@
|
||||
#include <dbglog_host.h>
|
||||
#include <wlan_logging_sock_svc.h>
|
||||
#include <wlan_roam_debug.h>
|
||||
#include "wlan_hdd_dsc.h"
|
||||
#include "osif_sync.h"
|
||||
#include <wlan_hdd_wowl.h>
|
||||
#include <wlan_hdd_misc.h>
|
||||
#include <wlan_hdd_wext.h>
|
||||
|
@@ -30,7 +30,7 @@
|
||||
#include "sme_api.h"
|
||||
#include "wlan_hdd_main.h"
|
||||
#include "wlan_hdd_nan.h"
|
||||
#include <wlan_hdd_dsc.h>
|
||||
#include "osif_sync.h"
|
||||
#include <qca_vendor.h>
|
||||
#include "cfg_nan_api.h"
|
||||
#include "os_if_nan.h"
|
||||
|
@@ -28,7 +28,7 @@
|
||||
#include <linux/etherdevice.h>
|
||||
#include "wlan_hdd_includes.h"
|
||||
#include "wlan_hdd_p2p.h"
|
||||
#include <wlan_hdd_dsc.h>
|
||||
#include "osif_sync.h"
|
||||
#include "wma_api.h"
|
||||
#include "wlan_hdd_assoc.h"
|
||||
#include "sme_nan_datapath.h"
|
||||
|
@@ -24,7 +24,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "wlan_hdd_dsc.h"
|
||||
#include "osif_sync.h"
|
||||
#include <wlan_hdd_includes.h>
|
||||
#include <wlan_hdd_hostapd.h>
|
||||
#include <net/cfg80211.h>
|
||||
|
@@ -78,7 +78,7 @@
|
||||
#include <wlan_cfg80211_mc_cp_stats.h>
|
||||
#include "wlan_p2p_ucfg_api.h"
|
||||
#include "wlan_mlme_ucfg_api.h"
|
||||
#include "wlan_hdd_dsc.h"
|
||||
#include "osif_sync.h"
|
||||
|
||||
/* Preprocessor definitions and constants */
|
||||
#ifdef QCA_WIFI_NAPIER_EMULATION
|
||||
|
@@ -34,7 +34,7 @@
|
||||
#include "wlan_hdd_p2p.h"
|
||||
#include "wlan_hdd_trace.h"
|
||||
#include "wlan_hdd_scan.h"
|
||||
#include <wlan_hdd_dsc.h>
|
||||
#include "osif_sync.h"
|
||||
#include "wlan_policy_mgr_api.h"
|
||||
#include "wlan_hdd_power.h"
|
||||
#include "wma_api.h"
|
||||
|
@@ -34,7 +34,7 @@
|
||||
#include <wlan_osif_request_manager.h>
|
||||
#include <qdf_mem.h>
|
||||
#include <sir_api.h>
|
||||
#include <wlan_hdd_dsc.h>
|
||||
#include "osif_sync.h"
|
||||
|
||||
#define MAX_PSOC_ID_SIZE 10
|
||||
|
||||
|
@@ -19,5 +19,165 @@
|
||||
#ifndef __OSIF_PSOC_SYNC_H
|
||||
#define __OSIF_PSOC_SYNC_H
|
||||
|
||||
#include "linux/device.h"
|
||||
#include "wlan_dsc_driver.h"
|
||||
#include "qdf_types.h"
|
||||
|
||||
/**
|
||||
* struct hdd_psoc_sync - opaque synchronization handle for a psoc
|
||||
*/
|
||||
struct hdd_psoc_sync;
|
||||
|
||||
/**
|
||||
* hdd_psoc_sync_create() - create a psoc synchronization context
|
||||
* @dsc_driver: parent dsc_driver to the psoc
|
||||
* @out_psoc_sync: out parameter for the new synchronization context
|
||||
*
|
||||
* Return: Errno
|
||||
*/
|
||||
qdf_must_check int
|
||||
hdd_psoc_sync_create(struct dsc_driver *dsc_driver,
|
||||
struct hdd_psoc_sync **out_psoc_sync);
|
||||
|
||||
/**
|
||||
* hdd_psoc_sync_create_with_trans() - create a psoc synchronization context
|
||||
* @dsc_driver: parent dsc_driver to the psoc
|
||||
* @out_psoc_sync: out parameter for the new synchronization context
|
||||
*
|
||||
* For protecting the device creation process.
|
||||
*
|
||||
* Return: Errno
|
||||
*/
|
||||
#define hdd_psoc_sync_create_with_trans(dsc_driver, out_psoc_sync) \
|
||||
__hdd_psoc_sync_create_with_trans(dsc_driver, out_psoc_sync, __func__)
|
||||
|
||||
qdf_must_check int
|
||||
__hdd_psoc_sync_create_with_trans(struct dsc_driver *dsc_driver,
|
||||
struct hdd_psoc_sync **out_psoc_sync,
|
||||
const char *desc);
|
||||
|
||||
/**
|
||||
* hdd_psoc_sync_destroy() - destroy a psoc synchronization context
|
||||
* @psoc_sync: the context to destroy
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void hdd_psoc_sync_destroy(struct hdd_psoc_sync *psoc_sync);
|
||||
|
||||
/**
|
||||
* hdd_psoc_sync_register() - register a psoc for operations/transitions
|
||||
* @dev: the device to use as the operation/transition lookup key
|
||||
* @psoc_sync: the psoc synchronization context to register
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void hdd_psoc_sync_register(struct device *dev,
|
||||
struct hdd_psoc_sync *psoc_sync);
|
||||
|
||||
/**
|
||||
* hdd_psoc_sync_unregister() - unregister a psoc for operations/transitions
|
||||
* @dev: the device originally used to register the psoc_sync context
|
||||
*
|
||||
* Return: the psoc synchronization context that was registered for @dev
|
||||
*/
|
||||
struct hdd_psoc_sync *hdd_psoc_sync_unregister(struct device *dev);
|
||||
|
||||
/**
|
||||
* hdd_psoc_sync_trans_start() - attempt to start a transition on @dev
|
||||
* @dev: the device to transition
|
||||
* @out_psoc_sync: out parameter for the synchronization context registered with
|
||||
* @dev, populated on success
|
||||
*
|
||||
* Return: Errno
|
||||
*/
|
||||
#define hdd_psoc_sync_trans_start(dev, out_psoc_sync) \
|
||||
__hdd_psoc_sync_trans_start(dev, out_psoc_sync, __func__)
|
||||
|
||||
qdf_must_check int
|
||||
__hdd_psoc_sync_trans_start(struct device *dev,
|
||||
struct hdd_psoc_sync **out_psoc_sync,
|
||||
const char *desc);
|
||||
|
||||
/**
|
||||
* hdd_psoc_sync_trans_start_wait() - attempt to start a transition on @dev,
|
||||
* blocking if a conflicting transition is in flight
|
||||
* @dev: the device to transition
|
||||
* @out_psoc_sync: out parameter for the synchronization context registered with
|
||||
* @dev, populated on success
|
||||
*
|
||||
* Return: Errno
|
||||
*/
|
||||
#define hdd_psoc_sync_trans_start_wait(dev, out_psoc_sync) \
|
||||
__hdd_psoc_sync_trans_start_wait(dev, out_psoc_sync, __func__)
|
||||
|
||||
qdf_must_check int
|
||||
__hdd_psoc_sync_trans_start_wait(struct device *dev,
|
||||
struct hdd_psoc_sync **out_psoc_sync,
|
||||
const char *desc);
|
||||
|
||||
/**
|
||||
* hdd_psoc_sync_trans_resume() - resume a transition on @dev
|
||||
* @dev: the device under transition
|
||||
* @out_psoc_sync: out parameter for the synchronization context registered with
|
||||
* @dev, populated on success
|
||||
*
|
||||
* Return: Errno
|
||||
*/
|
||||
int hdd_psoc_sync_trans_resume(struct device *dev,
|
||||
struct hdd_psoc_sync **out_psoc_sync);
|
||||
|
||||
/**
|
||||
* hdd_psoc_sync_trans_stop() - stop a transition associated with @psoc_sync
|
||||
* @psoc_sync: the synchonization context tracking the transition
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void hdd_psoc_sync_trans_stop(struct hdd_psoc_sync *psoc_sync);
|
||||
|
||||
/**
|
||||
* hdd_psoc_sync_assert_trans_protected() - assert that @dev is currently
|
||||
* protected by a transition
|
||||
* @dev: the device to check
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void hdd_psoc_sync_assert_trans_protected(struct device *dev);
|
||||
|
||||
/**
|
||||
* hdd_psoc_sync_op_start() - attempt to start an operation on @dev
|
||||
* @dev: the device to operate against
|
||||
* @out_psoc_sync: out parameter for the synchronization context registered with
|
||||
* @dev, populated on success
|
||||
*
|
||||
* Return: Errno
|
||||
*/
|
||||
#define hdd_psoc_sync_op_start(dev, out_psoc_sync) \
|
||||
__hdd_psoc_sync_op_start(dev, out_psoc_sync, __func__)
|
||||
|
||||
qdf_must_check int
|
||||
__hdd_psoc_sync_op_start(struct device *dev,
|
||||
struct hdd_psoc_sync **out_psoc_sync,
|
||||
const char *func);
|
||||
|
||||
/**
|
||||
* hdd_psoc_sync_op_stop() - stop an operation associated with @psoc_sync
|
||||
* @psoc_sync: the synchonization context tracking the operation
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
#define hdd_psoc_sync_op_stop(dev) \
|
||||
__hdd_psoc_sync_op_stop(dev, __func__)
|
||||
|
||||
void __hdd_psoc_sync_op_stop(struct hdd_psoc_sync *psoc_sync,
|
||||
const char *func);
|
||||
|
||||
/**
|
||||
* hdd_psoc_sync_wait_for_ops() - wait until all @psoc_sync operations complete
|
||||
* @psoc_sync: the synchonization context tracking the operations
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void hdd_psoc_sync_wait_for_ops(struct hdd_psoc_sync *psoc_sync);
|
||||
|
||||
#endif /* __OSIF_PSOC_SYNC_H */
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2018-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
|
||||
@@ -23,5 +23,19 @@
|
||||
#include "osif_psoc_sync.h"
|
||||
#include "osif_vdev_sync.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);
|
||||
|
||||
#endif /* __OSIF_SYNC_H */
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2018-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
|
||||
@@ -19,5 +19,153 @@
|
||||
#ifndef __OSIF_VDEV_SYNC_H
|
||||
#define __OSIF_VDEV_SYNC_H
|
||||
|
||||
#include "linux/device.h"
|
||||
#include "linux/netdevice.h"
|
||||
#include "qdf_types.h"
|
||||
|
||||
/**
|
||||
* struct hdd_vdev_sync - opaque synchronization handle for a vdev
|
||||
*/
|
||||
struct hdd_vdev_sync;
|
||||
|
||||
/**
|
||||
* hdd_vdev_sync_create() - create a vdev synchronization context
|
||||
* @dev: parent device to the vdev
|
||||
* @out_vdev_sync: out parameter for the new synchronization context
|
||||
*
|
||||
* Return: Errno
|
||||
*/
|
||||
qdf_must_check int
|
||||
hdd_vdev_sync_create(struct device *dev, struct hdd_vdev_sync **out_vdev_sync);
|
||||
|
||||
/**
|
||||
* hdd_vdev_sync_create_with_trans() - create a vdev synchronization context
|
||||
* @dev: parent device to the vdev
|
||||
* @out_vdev_sync: out parameter for the new synchronization context
|
||||
*
|
||||
* For protecting the net_device creation process.
|
||||
*
|
||||
* Return: Errno
|
||||
*/
|
||||
#define hdd_vdev_sync_create_with_trans(dev, out_vdev_sync) \
|
||||
__hdd_vdev_sync_create_with_trans(dev, out_vdev_sync, __func__)
|
||||
|
||||
qdf_must_check int
|
||||
__hdd_vdev_sync_create_with_trans(struct device *dev,
|
||||
struct hdd_vdev_sync **out_vdev_sync,
|
||||
const char *desc);
|
||||
|
||||
/**
|
||||
* hdd_vdev_sync_destroy() - destroy a vdev synchronization context
|
||||
* @vdev_sync: the context to destroy
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void hdd_vdev_sync_destroy(struct hdd_vdev_sync *vdev_sync);
|
||||
|
||||
/**
|
||||
* hdd_vdev_sync_register() - register a vdev for operations/transitions
|
||||
* @net_dev: the net_device to use as the operation/transition lookup key
|
||||
* @vdev_sync: the vdev synchronization context to register
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void hdd_vdev_sync_register(struct net_device *net_dev,
|
||||
struct hdd_vdev_sync *vdev_sync);
|
||||
|
||||
/**
|
||||
* hdd_vdev_sync_unregister() - unregister a vdev for operations/transitions
|
||||
* @net_dev: the net_device originally used to register the vdev_sync context
|
||||
*
|
||||
* Return: the vdev synchronization context that was registered for @net_dev
|
||||
*/
|
||||
struct hdd_vdev_sync *hdd_vdev_sync_unregister(struct net_device *net_dev);
|
||||
|
||||
/**
|
||||
* hdd_vdev_sync_trans_start() - attempt to start a transition on @net_dev
|
||||
* @net_dev: the net_device to transition
|
||||
* @out_vdev_sync: out parameter for the synchronization context registered with
|
||||
* @net_dev, populated on success
|
||||
*
|
||||
* Return: Errno
|
||||
*/
|
||||
#define hdd_vdev_sync_trans_start(net_dev, out_vdev_sync) \
|
||||
__hdd_vdev_sync_trans_start(net_dev, out_vdev_sync, __func__)
|
||||
|
||||
qdf_must_check int
|
||||
__hdd_vdev_sync_trans_start(struct net_device *net_dev,
|
||||
struct hdd_vdev_sync **out_vdev_sync,
|
||||
const char *desc);
|
||||
|
||||
/**
|
||||
* hdd_vdev_sync_trans_start_wait() - attempt to start a transition on @net_dev,
|
||||
* blocking if a conflicting transition is in flight
|
||||
* @net_dev: the net_device to transition
|
||||
* @out_vdev_sync: out parameter for the synchronization context registered with
|
||||
* @net_dev, populated on success
|
||||
*
|
||||
* Return: Errno
|
||||
*/
|
||||
#define hdd_vdev_sync_trans_start_wait(net_dev, out_vdev_sync) \
|
||||
__hdd_vdev_sync_trans_start_wait(net_dev, out_vdev_sync, __func__)
|
||||
|
||||
qdf_must_check int
|
||||
__hdd_vdev_sync_trans_start_wait(struct net_device *net_dev,
|
||||
struct hdd_vdev_sync **out_vdev_sync,
|
||||
const char *desc);
|
||||
|
||||
/**
|
||||
* hdd_vdev_sync_trans_stop() - stop a transition associated with @vdev_sync
|
||||
* @vdev_sync: the synchonization context tracking the transition
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void hdd_vdev_sync_trans_stop(struct hdd_vdev_sync *vdev_sync);
|
||||
|
||||
/**
|
||||
* hdd_vdev_sync_assert_trans_protected() - assert that @net_dev is currently
|
||||
* protected by a transition
|
||||
* @net_dev: the net_device to check
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void hdd_vdev_sync_assert_trans_protected(struct net_device *net_dev);
|
||||
|
||||
/**
|
||||
* hdd_vdev_sync_op_start() - attempt to start an operation on @net_dev
|
||||
* @net_dev: the net_device to operate against
|
||||
* @out_vdev_sync: out parameter for the synchronization context registered with
|
||||
* @net_dev, populated on success
|
||||
*
|
||||
* Return: Errno
|
||||
*/
|
||||
#define hdd_vdev_sync_op_start(net_dev, out_vdev_sync) \
|
||||
__hdd_vdev_sync_op_start(net_dev, out_vdev_sync, __func__)
|
||||
|
||||
qdf_must_check int
|
||||
__hdd_vdev_sync_op_start(struct net_device *net_dev,
|
||||
struct hdd_vdev_sync **out_vdev_sync,
|
||||
const char *func);
|
||||
|
||||
/**
|
||||
* hdd_vdev_sync_op_stop() - stop an operation associated with @vdev_sync
|
||||
* @vdev_sync: the synchonization context tracking the operation
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
#define hdd_vdev_sync_op_stop(net_dev) \
|
||||
__hdd_vdev_sync_op_stop(net_dev, __func__)
|
||||
|
||||
void __hdd_vdev_sync_op_stop(struct hdd_vdev_sync *vdev_sync,
|
||||
const char *func);
|
||||
|
||||
/**
|
||||
* hdd_vdev_sync_wait_for_ops() - wait until all @vdev_sync operations complete
|
||||
* @vdev_sync: the synchonization context tracking the operations
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void hdd_vdev_sync_wait_for_ops(struct hdd_vdev_sync *vdev_sync);
|
||||
|
||||
#endif /* __OSIF_VDEV_SYNC_H */
|
||||
|
||||
|
@@ -19,5 +19,34 @@
|
||||
#ifndef ____OSIF_PSOC_SYNC_H
|
||||
#define ____OSIF_PSOC_SYNC_H
|
||||
|
||||
#include "linux/device.h"
|
||||
#include "qdf_status.h"
|
||||
#include "wlan_dsc_vdev.h"
|
||||
|
||||
/**
|
||||
* osif_psoc_sync_init() - global initializer
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void osif_psoc_sync_init(void);
|
||||
|
||||
/**
|
||||
* osif_psoc_sync_deinit() - global de-initializer
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void osif_psoc_sync_deinit(void);
|
||||
|
||||
/**
|
||||
* osif_psoc_sync_dsc_vdev_create() - create a dsc_vdev and attach it to a
|
||||
* dsc_psoc keyed by @dev
|
||||
* @dev: the device to key off of
|
||||
* @out_dsc_vdev: output pointer parameter for the new dsc_vdev
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS osif_psoc_sync_dsc_vdev_create(struct device *dev,
|
||||
struct dsc_vdev **out_dsc_vdev);
|
||||
|
||||
#endif /* ____OSIF_PSOC_SYNC_H */
|
||||
|
||||
|
@@ -19,5 +19,19 @@
|
||||
#ifndef ____OSIF_VDEV_SYNC_H
|
||||
#define ____OSIF_VDEV_SYNC_H
|
||||
|
||||
/**
|
||||
* osif_vdev_sync_init() - global initializer
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void osif_vdev_sync_init(void);
|
||||
|
||||
/**
|
||||
* osif_vdev_sync_deinit() - global de-initializer
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void osif_vdev_sync_deinit(void);
|
||||
|
||||
#endif /* ____OSIF_VDEV_SYNC_H */
|
||||
|
||||
|
@@ -16,5 +16,338 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "linux/device.h"
|
||||
#include "__osif_psoc_sync.h"
|
||||
#include "osif_psoc_sync.h"
|
||||
#include "qdf_lock.h"
|
||||
#include "qdf_status.h"
|
||||
#include "qdf_types.h"
|
||||
#include "qdf_util.h"
|
||||
#include "wlan_dsc_driver.h"
|
||||
#include "wlan_dsc_psoc.h"
|
||||
#include "wlan_dsc_vdev.h"
|
||||
|
||||
/**
|
||||
* struct hdd_psoc_sync - a psoc synchronization context
|
||||
* @dev: the device used as a lookup key
|
||||
* @dsc_psoc: the dsc_psoc used for synchronization
|
||||
* @in_use: indicates if the context is being used
|
||||
*/
|
||||
struct hdd_psoc_sync {
|
||||
struct device *dev;
|
||||
struct dsc_psoc *dsc_psoc;
|
||||
bool in_use;
|
||||
};
|
||||
|
||||
static struct hdd_psoc_sync __hdd_psoc_sync_arr[WLAN_MAX_PSOCS];
|
||||
static qdf_spinlock_t __hdd_psoc_sync_lock;
|
||||
|
||||
#define hdd_psoc_sync_lock_create() qdf_spinlock_create(&__hdd_psoc_sync_lock)
|
||||
#define hdd_psoc_sync_lock_destroy() qdf_spinlock_destroy(&__hdd_psoc_sync_lock)
|
||||
#define hdd_psoc_sync_lock() qdf_spin_lock_bh(&__hdd_psoc_sync_lock)
|
||||
#define hdd_psoc_sync_unlock() qdf_spin_unlock_bh(&__hdd_psoc_sync_lock)
|
||||
#define hdd_psoc_sync_lock_assert() \
|
||||
QDF_BUG(qdf_spin_is_locked(&__hdd_psoc_sync_lock))
|
||||
|
||||
static struct hdd_psoc_sync *hdd_psoc_sync_lookup(struct device *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
hdd_psoc_sync_lock_assert();
|
||||
|
||||
for (i = 0; i < QDF_ARRAY_SIZE(__hdd_psoc_sync_arr); i++) {
|
||||
struct hdd_psoc_sync *psoc_sync = __hdd_psoc_sync_arr + i;
|
||||
|
||||
if (psoc_sync->dev == dev)
|
||||
return psoc_sync;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct hdd_psoc_sync *hdd_psoc_sync_get(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
hdd_psoc_sync_lock_assert();
|
||||
|
||||
for (i = 0; i < QDF_ARRAY_SIZE(__hdd_psoc_sync_arr); i++) {
|
||||
struct hdd_psoc_sync *psoc_sync = __hdd_psoc_sync_arr + i;
|
||||
|
||||
if (!psoc_sync->in_use) {
|
||||
psoc_sync->in_use = true;
|
||||
return psoc_sync;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void hdd_psoc_sync_put(struct hdd_psoc_sync *psoc_sync)
|
||||
{
|
||||
hdd_psoc_sync_lock_assert();
|
||||
|
||||
qdf_mem_zero(psoc_sync, sizeof(*psoc_sync));
|
||||
}
|
||||
|
||||
int hdd_psoc_sync_create(struct dsc_driver *dsc_driver,
|
||||
struct hdd_psoc_sync **out_psoc_sync)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
struct hdd_psoc_sync *psoc_sync;
|
||||
|
||||
QDF_BUG(dsc_driver);
|
||||
if (!dsc_driver)
|
||||
return -EINVAL;
|
||||
|
||||
QDF_BUG(out_psoc_sync);
|
||||
if (!out_psoc_sync)
|
||||
return -EINVAL;
|
||||
|
||||
hdd_psoc_sync_lock();
|
||||
psoc_sync = hdd_psoc_sync_get();
|
||||
hdd_psoc_sync_unlock();
|
||||
if (!psoc_sync)
|
||||
return -ENOMEM;
|
||||
|
||||
status = dsc_psoc_create(dsc_driver, &psoc_sync->dsc_psoc);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
goto sync_put;
|
||||
|
||||
*out_psoc_sync = psoc_sync;
|
||||
|
||||
return 0;
|
||||
|
||||
sync_put:
|
||||
hdd_psoc_sync_lock();
|
||||
hdd_psoc_sync_put(psoc_sync);
|
||||
hdd_psoc_sync_unlock();
|
||||
|
||||
return qdf_status_to_os_return(status);
|
||||
}
|
||||
|
||||
int __hdd_psoc_sync_create_with_trans(struct dsc_driver *dsc_driver,
|
||||
struct hdd_psoc_sync **out_psoc_sync,
|
||||
const char *desc)
|
||||
{
|
||||
struct hdd_psoc_sync *psoc_sync;
|
||||
QDF_STATUS status;
|
||||
int errno;
|
||||
|
||||
errno = hdd_psoc_sync_create(dsc_driver, &psoc_sync);
|
||||
if (errno)
|
||||
return errno;
|
||||
|
||||
status = dsc_psoc_trans_start(psoc_sync->dsc_psoc, desc);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
goto sync_destroy;
|
||||
|
||||
*out_psoc_sync = psoc_sync;
|
||||
|
||||
return 0;
|
||||
|
||||
sync_destroy:
|
||||
hdd_psoc_sync_destroy(psoc_sync);
|
||||
|
||||
return qdf_status_to_os_return(status);
|
||||
}
|
||||
|
||||
void hdd_psoc_sync_destroy(struct hdd_psoc_sync *psoc_sync)
|
||||
{
|
||||
QDF_BUG(psoc_sync);
|
||||
if (!psoc_sync)
|
||||
return;
|
||||
|
||||
dsc_psoc_destroy(&psoc_sync->dsc_psoc);
|
||||
|
||||
hdd_psoc_sync_lock();
|
||||
hdd_psoc_sync_put(psoc_sync);
|
||||
hdd_psoc_sync_unlock();
|
||||
}
|
||||
|
||||
void hdd_psoc_sync_register(struct device *dev,
|
||||
struct hdd_psoc_sync *psoc_sync)
|
||||
{
|
||||
QDF_BUG(dev);
|
||||
QDF_BUG(psoc_sync);
|
||||
if (!psoc_sync)
|
||||
return;
|
||||
|
||||
hdd_psoc_sync_lock();
|
||||
psoc_sync->dev = dev;
|
||||
hdd_psoc_sync_unlock();
|
||||
}
|
||||
|
||||
struct hdd_psoc_sync *hdd_psoc_sync_unregister(struct device *dev)
|
||||
{
|
||||
struct hdd_psoc_sync *psoc_sync;
|
||||
|
||||
QDF_BUG(dev);
|
||||
if (!dev)
|
||||
return NULL;
|
||||
|
||||
hdd_psoc_sync_lock();
|
||||
psoc_sync = hdd_psoc_sync_lookup(dev);
|
||||
if (psoc_sync)
|
||||
psoc_sync->dev = NULL;
|
||||
hdd_psoc_sync_unlock();
|
||||
|
||||
return psoc_sync;
|
||||
}
|
||||
|
||||
typedef QDF_STATUS (*psoc_start_func)(struct dsc_psoc *, const char *);
|
||||
|
||||
static int __hdd_psoc_sync_start_callback(struct device *dev,
|
||||
struct hdd_psoc_sync **out_psoc_sync,
|
||||
const char *desc,
|
||||
psoc_start_func psoc_start_cb)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
struct hdd_psoc_sync *psoc_sync;
|
||||
|
||||
hdd_psoc_sync_lock_assert();
|
||||
|
||||
*out_psoc_sync = NULL;
|
||||
|
||||
psoc_sync = hdd_psoc_sync_lookup(dev);
|
||||
if (!psoc_sync)
|
||||
return -EAGAIN;
|
||||
|
||||
status = psoc_start_cb(psoc_sync->dsc_psoc, desc);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
return qdf_status_to_os_return(status);
|
||||
|
||||
*out_psoc_sync = psoc_sync;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __hdd_psoc_sync_trans_start(struct device *dev,
|
||||
struct hdd_psoc_sync **out_psoc_sync,
|
||||
const char *desc)
|
||||
{
|
||||
int errno;
|
||||
|
||||
hdd_psoc_sync_lock();
|
||||
errno = __hdd_psoc_sync_start_callback(dev, out_psoc_sync, desc,
|
||||
dsc_psoc_trans_start);
|
||||
hdd_psoc_sync_unlock();
|
||||
|
||||
return errno;
|
||||
}
|
||||
|
||||
int __hdd_psoc_sync_trans_start_wait(struct device *dev,
|
||||
struct hdd_psoc_sync **out_psoc_sync,
|
||||
const char *desc)
|
||||
{
|
||||
int errno;
|
||||
|
||||
hdd_psoc_sync_lock();
|
||||
errno = __hdd_psoc_sync_start_callback(dev, out_psoc_sync, desc,
|
||||
dsc_psoc_trans_start_wait);
|
||||
hdd_psoc_sync_unlock();
|
||||
|
||||
return errno;
|
||||
}
|
||||
|
||||
static QDF_STATUS __assert_trans_cb(struct dsc_psoc *dsc_psoc, const char *desc)
|
||||
{
|
||||
dsc_psoc_assert_trans_protected(dsc_psoc);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
int hdd_psoc_sync_trans_resume(struct device *dev,
|
||||
struct hdd_psoc_sync **out_psoc_sync)
|
||||
{
|
||||
int errno;
|
||||
|
||||
hdd_psoc_sync_lock();
|
||||
errno = __hdd_psoc_sync_start_callback(dev, out_psoc_sync, NULL,
|
||||
__assert_trans_cb);
|
||||
hdd_psoc_sync_unlock();
|
||||
|
||||
return errno;
|
||||
}
|
||||
|
||||
void hdd_psoc_sync_trans_stop(struct hdd_psoc_sync *psoc_sync)
|
||||
{
|
||||
dsc_psoc_trans_stop(psoc_sync->dsc_psoc);
|
||||
}
|
||||
|
||||
void hdd_psoc_sync_assert_trans_protected(struct device *dev)
|
||||
{
|
||||
struct hdd_psoc_sync *psoc_sync;
|
||||
|
||||
hdd_psoc_sync_lock();
|
||||
|
||||
psoc_sync = hdd_psoc_sync_lookup(dev);
|
||||
QDF_BUG(psoc_sync);
|
||||
if (psoc_sync)
|
||||
dsc_psoc_assert_trans_protected(psoc_sync->dsc_psoc);
|
||||
|
||||
hdd_psoc_sync_unlock();
|
||||
}
|
||||
|
||||
int __hdd_psoc_sync_op_start(struct device *dev,
|
||||
struct hdd_psoc_sync **out_psoc_sync,
|
||||
const char *func)
|
||||
{
|
||||
int errno;
|
||||
|
||||
hdd_psoc_sync_lock();
|
||||
errno = __hdd_psoc_sync_start_callback(dev, out_psoc_sync, func,
|
||||
_dsc_psoc_op_start);
|
||||
hdd_psoc_sync_unlock();
|
||||
|
||||
return errno;
|
||||
}
|
||||
|
||||
void __hdd_psoc_sync_op_stop(struct hdd_psoc_sync *psoc_sync,
|
||||
const char *func)
|
||||
{
|
||||
_dsc_psoc_op_stop(psoc_sync->dsc_psoc, func);
|
||||
}
|
||||
|
||||
void hdd_psoc_sync_wait_for_ops(struct hdd_psoc_sync *psoc_sync)
|
||||
{
|
||||
dsc_psoc_wait_for_ops(psoc_sync->dsc_psoc);
|
||||
}
|
||||
|
||||
void osif_psoc_sync_init(void)
|
||||
{
|
||||
hdd_psoc_sync_lock_create();
|
||||
}
|
||||
|
||||
void osif_psoc_sync_deinit(void)
|
||||
{
|
||||
hdd_psoc_sync_lock_destroy();
|
||||
}
|
||||
|
||||
static QDF_STATUS
|
||||
__osif_psoc_sync_dsc_vdev_create(struct device *dev,
|
||||
struct dsc_vdev **out_dsc_vdev)
|
||||
{
|
||||
struct hdd_psoc_sync *psoc_sync;
|
||||
|
||||
hdd_psoc_sync_lock_assert();
|
||||
|
||||
psoc_sync = hdd_psoc_sync_lookup(dev);
|
||||
if (!psoc_sync)
|
||||
return QDF_STATUS_E_INVAL;
|
||||
|
||||
return dsc_vdev_create(psoc_sync->dsc_psoc, out_dsc_vdev);
|
||||
}
|
||||
|
||||
QDF_STATUS osif_psoc_sync_dsc_vdev_create(struct device *dev,
|
||||
struct dsc_vdev **out_dsc_vdev)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
|
||||
hdd_psoc_sync_lock();
|
||||
status = __osif_psoc_sync_dsc_vdev_create(dev, out_dsc_vdev);
|
||||
hdd_psoc_sync_unlock();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2018-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
|
||||
@@ -16,5 +16,19 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "__osif_psoc_sync.h"
|
||||
#include "__osif_vdev_sync.h"
|
||||
#include "osif_sync.h"
|
||||
|
||||
void hdd_dsc_init(void)
|
||||
{
|
||||
osif_psoc_sync_init();
|
||||
osif_vdev_sync_init();
|
||||
}
|
||||
|
||||
void hdd_dsc_deinit(void)
|
||||
{
|
||||
osif_vdev_sync_deinit();
|
||||
osif_psoc_sync_deinit();
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2018-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
|
||||
@@ -16,5 +16,290 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "linux/device.h"
|
||||
#include "linux/netdevice.h"
|
||||
#include "__osif_psoc_sync.h"
|
||||
#include "__osif_vdev_sync.h"
|
||||
#include "osif_vdev_sync.h"
|
||||
#include "qdf_lock.h"
|
||||
#include "qdf_status.h"
|
||||
#include "qdf_types.h"
|
||||
#include "qdf_util.h"
|
||||
|
||||
/**
|
||||
* struct hdd_vdev_sync - a vdev synchronization context
|
||||
* @net_dev: the net_device used as a lookup key
|
||||
* @dsc_vdev: the dsc_vdev used for synchronization
|
||||
* @in_use: indicates if the context is being used
|
||||
*/
|
||||
struct hdd_vdev_sync {
|
||||
struct net_device *net_dev;
|
||||
struct dsc_vdev *dsc_vdev;
|
||||
bool in_use;
|
||||
};
|
||||
|
||||
static struct hdd_vdev_sync __hdd_vdev_sync_arr[WLAN_MAX_VDEVS];
|
||||
static qdf_spinlock_t __hdd_vdev_sync_lock;
|
||||
|
||||
#define hdd_vdev_sync_lock_create() qdf_spinlock_create(&__hdd_vdev_sync_lock)
|
||||
#define hdd_vdev_sync_lock_destroy() qdf_spinlock_destroy(&__hdd_vdev_sync_lock)
|
||||
#define hdd_vdev_sync_lock() qdf_spin_lock_bh(&__hdd_vdev_sync_lock)
|
||||
#define hdd_vdev_sync_unlock() qdf_spin_unlock_bh(&__hdd_vdev_sync_lock)
|
||||
#define hdd_vdev_sync_lock_assert() \
|
||||
QDF_BUG(qdf_spin_is_locked(&__hdd_vdev_sync_lock))
|
||||
|
||||
static struct hdd_vdev_sync *hdd_vdev_sync_lookup(struct net_device *net_dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
hdd_vdev_sync_lock_assert();
|
||||
|
||||
for (i = 0; i < QDF_ARRAY_SIZE(__hdd_vdev_sync_arr); i++) {
|
||||
struct hdd_vdev_sync *vdev_sync = __hdd_vdev_sync_arr + i;
|
||||
|
||||
if (vdev_sync->net_dev == net_dev)
|
||||
return vdev_sync;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct hdd_vdev_sync *hdd_vdev_sync_get(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
hdd_vdev_sync_lock_assert();
|
||||
|
||||
for (i = 0; i < QDF_ARRAY_SIZE(__hdd_vdev_sync_arr); i++) {
|
||||
struct hdd_vdev_sync *vdev_sync = __hdd_vdev_sync_arr + i;
|
||||
|
||||
if (!vdev_sync->in_use) {
|
||||
vdev_sync->in_use = true;
|
||||
return vdev_sync;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void hdd_vdev_sync_put(struct hdd_vdev_sync *vdev_sync)
|
||||
{
|
||||
hdd_vdev_sync_lock_assert();
|
||||
|
||||
qdf_mem_zero(vdev_sync, sizeof(*vdev_sync));
|
||||
}
|
||||
|
||||
int hdd_vdev_sync_create(struct device *dev,
|
||||
struct hdd_vdev_sync **out_vdev_sync)
|
||||
{
|
||||
struct hdd_vdev_sync *vdev_sync;
|
||||
QDF_STATUS status;
|
||||
|
||||
QDF_BUG(dev);
|
||||
if (!dev)
|
||||
return -EINVAL;
|
||||
|
||||
QDF_BUG(out_vdev_sync);
|
||||
if (!out_vdev_sync)
|
||||
return -EINVAL;
|
||||
|
||||
hdd_vdev_sync_lock();
|
||||
vdev_sync = hdd_vdev_sync_get();
|
||||
hdd_vdev_sync_unlock();
|
||||
if (!vdev_sync)
|
||||
return -ENOMEM;
|
||||
|
||||
status = osif_psoc_sync_dsc_vdev_create(dev, &vdev_sync->dsc_vdev);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
goto sync_put;
|
||||
|
||||
*out_vdev_sync = vdev_sync;
|
||||
|
||||
return 0;
|
||||
|
||||
sync_put:
|
||||
hdd_vdev_sync_lock();
|
||||
hdd_vdev_sync_put(vdev_sync);
|
||||
hdd_vdev_sync_unlock();
|
||||
|
||||
return qdf_status_to_os_return(status);
|
||||
}
|
||||
|
||||
int __hdd_vdev_sync_create_with_trans(struct device *dev,
|
||||
struct hdd_vdev_sync **out_vdev_sync,
|
||||
const char *desc)
|
||||
{
|
||||
struct hdd_vdev_sync *vdev_sync;
|
||||
QDF_STATUS status;
|
||||
int errno;
|
||||
|
||||
errno = hdd_vdev_sync_create(dev, &vdev_sync);
|
||||
if (errno)
|
||||
return errno;
|
||||
|
||||
status = dsc_vdev_trans_start(vdev_sync->dsc_vdev, desc);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
goto sync_destroy;
|
||||
|
||||
*out_vdev_sync = vdev_sync;
|
||||
|
||||
return 0;
|
||||
|
||||
sync_destroy:
|
||||
hdd_vdev_sync_destroy(vdev_sync);
|
||||
|
||||
return qdf_status_to_os_return(status);
|
||||
}
|
||||
|
||||
void hdd_vdev_sync_destroy(struct hdd_vdev_sync *vdev_sync)
|
||||
{
|
||||
QDF_BUG(vdev_sync);
|
||||
if (!vdev_sync)
|
||||
return;
|
||||
|
||||
dsc_vdev_destroy(&vdev_sync->dsc_vdev);
|
||||
|
||||
hdd_vdev_sync_lock();
|
||||
hdd_vdev_sync_put(vdev_sync);
|
||||
hdd_vdev_sync_unlock();
|
||||
}
|
||||
|
||||
void hdd_vdev_sync_register(struct net_device *net_dev,
|
||||
struct hdd_vdev_sync *vdev_sync)
|
||||
{
|
||||
QDF_BUG(net_dev);
|
||||
QDF_BUG(vdev_sync);
|
||||
if (!vdev_sync)
|
||||
return;
|
||||
|
||||
hdd_vdev_sync_lock();
|
||||
vdev_sync->net_dev = net_dev;
|
||||
hdd_vdev_sync_unlock();
|
||||
}
|
||||
|
||||
struct hdd_vdev_sync *hdd_vdev_sync_unregister(struct net_device *net_dev)
|
||||
{
|
||||
struct hdd_vdev_sync *vdev_sync;
|
||||
|
||||
QDF_BUG(net_dev);
|
||||
if (!net_dev)
|
||||
return NULL;
|
||||
|
||||
hdd_vdev_sync_lock();
|
||||
vdev_sync = hdd_vdev_sync_lookup(net_dev);
|
||||
if (vdev_sync)
|
||||
vdev_sync->net_dev = NULL;
|
||||
hdd_vdev_sync_unlock();
|
||||
|
||||
return vdev_sync;
|
||||
}
|
||||
|
||||
typedef QDF_STATUS (*vdev_start_func)(struct dsc_vdev *, const char *);
|
||||
|
||||
static int __hdd_vdev_sync_start_callback(struct net_device *net_dev,
|
||||
struct hdd_vdev_sync **out_vdev_sync,
|
||||
const char *desc,
|
||||
vdev_start_func vdev_start_cb)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
struct hdd_vdev_sync *vdev_sync;
|
||||
|
||||
hdd_vdev_sync_lock_assert();
|
||||
|
||||
*out_vdev_sync = NULL;
|
||||
|
||||
vdev_sync = hdd_vdev_sync_lookup(net_dev);
|
||||
if (!vdev_sync)
|
||||
return -EAGAIN;
|
||||
|
||||
status = vdev_start_cb(vdev_sync->dsc_vdev, desc);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
return qdf_status_to_os_return(status);
|
||||
|
||||
*out_vdev_sync = vdev_sync;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __hdd_vdev_sync_trans_start(struct net_device *net_dev,
|
||||
struct hdd_vdev_sync **out_vdev_sync,
|
||||
const char *desc)
|
||||
{
|
||||
int errno;
|
||||
|
||||
hdd_vdev_sync_lock();
|
||||
errno = __hdd_vdev_sync_start_callback(net_dev, out_vdev_sync, desc,
|
||||
dsc_vdev_trans_start);
|
||||
hdd_vdev_sync_unlock();
|
||||
|
||||
return errno;
|
||||
}
|
||||
|
||||
int __hdd_vdev_sync_trans_start_wait(struct net_device *net_dev,
|
||||
struct hdd_vdev_sync **out_vdev_sync,
|
||||
const char *desc)
|
||||
{
|
||||
int errno;
|
||||
|
||||
hdd_vdev_sync_lock();
|
||||
errno = __hdd_vdev_sync_start_callback(net_dev, out_vdev_sync, desc,
|
||||
dsc_vdev_trans_start_wait);
|
||||
hdd_vdev_sync_unlock();
|
||||
|
||||
return errno;
|
||||
}
|
||||
|
||||
void hdd_vdev_sync_trans_stop(struct hdd_vdev_sync *vdev_sync)
|
||||
{
|
||||
dsc_vdev_trans_stop(vdev_sync->dsc_vdev);
|
||||
}
|
||||
|
||||
void hdd_vdev_sync_assert_trans_protected(struct net_device *net_dev)
|
||||
{
|
||||
struct hdd_vdev_sync *vdev_sync;
|
||||
|
||||
hdd_vdev_sync_lock();
|
||||
|
||||
vdev_sync = hdd_vdev_sync_lookup(net_dev);
|
||||
QDF_BUG(vdev_sync);
|
||||
if (vdev_sync)
|
||||
dsc_vdev_assert_trans_protected(vdev_sync->dsc_vdev);
|
||||
|
||||
hdd_vdev_sync_unlock();
|
||||
}
|
||||
|
||||
int __hdd_vdev_sync_op_start(struct net_device *net_dev,
|
||||
struct hdd_vdev_sync **out_vdev_sync,
|
||||
const char *func)
|
||||
{
|
||||
int errno;
|
||||
|
||||
hdd_vdev_sync_lock();
|
||||
errno = __hdd_vdev_sync_start_callback(net_dev, out_vdev_sync, func,
|
||||
_dsc_vdev_op_start);
|
||||
hdd_vdev_sync_unlock();
|
||||
|
||||
return errno;
|
||||
}
|
||||
|
||||
void __hdd_vdev_sync_op_stop(struct hdd_vdev_sync *vdev_sync,
|
||||
const char *func)
|
||||
{
|
||||
_dsc_vdev_op_stop(vdev_sync->dsc_vdev, func);
|
||||
}
|
||||
|
||||
void hdd_vdev_sync_wait_for_ops(struct hdd_vdev_sync *vdev_sync)
|
||||
{
|
||||
dsc_vdev_wait_for_ops(vdev_sync->dsc_vdev);
|
||||
}
|
||||
|
||||
void osif_vdev_sync_init(void)
|
||||
{
|
||||
hdd_vdev_sync_lock_create();
|
||||
}
|
||||
|
||||
void osif_vdev_sync_deinit(void)
|
||||
{
|
||||
hdd_vdev_sync_lock_destroy();
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user