130 lines
3.8 KiB
C
130 lines
3.8 KiB
C
|
/****************************************************************************
|
||
|
*
|
||
|
* Copyright (c) 2012 - 2016 Samsung Electronics Co., Ltd. All rights reserved
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
#ifndef __SLSI_UNITTEST_H__
|
||
|
#define __SLSI_UNITTEST_H__
|
||
|
|
||
|
#include "dev.h"
|
||
|
|
||
|
struct slsi_test_dev;
|
||
|
struct slsi_test_bh_work {
|
||
|
bool available;
|
||
|
struct slsi_test_dev *uftestdev;
|
||
|
struct workqueue_struct *workqueue;
|
||
|
struct work_struct work;
|
||
|
struct slsi_spinlock spinlock;
|
||
|
};
|
||
|
|
||
|
struct slsi_test_data_route {
|
||
|
bool configured;
|
||
|
u16 test_device_minor_number; /* index into slsi_test_devices[] */
|
||
|
u8 mac[ETH_ALEN];
|
||
|
u16 vif;
|
||
|
u8 ipsubnet;
|
||
|
u16 sequence_number;
|
||
|
};
|
||
|
|
||
|
struct slsi_test_dev {
|
||
|
/* This is used for:
|
||
|
* 1) The uf6kunittesthip<n> chardevice number
|
||
|
* 2) The uf6kunittest<n> chardevice number
|
||
|
* 3) The /procf/devices/unifi<n> number
|
||
|
*/
|
||
|
int device_minor_number;
|
||
|
|
||
|
void *uf_cdev;
|
||
|
struct device *dev;
|
||
|
struct slsi_dev *sdev;
|
||
|
|
||
|
struct workqueue_struct *attach_detach_work_queue;
|
||
|
/* a std mutex */
|
||
|
struct mutex attach_detach_mutex;
|
||
|
struct work_struct attach_work;
|
||
|
struct work_struct detach_work;
|
||
|
bool attached;
|
||
|
|
||
|
u8 hw_addr[ETH_ALEN];
|
||
|
struct slsi_test_bh_work bh_work;
|
||
|
|
||
|
/* a std spinlock */
|
||
|
spinlock_t route_spinlock;
|
||
|
struct slsi_test_data_route route[SLSI_AP_PEER_CONNECTIONS_MAX];
|
||
|
};
|
||
|
|
||
|
void slsi_test_dev_attach(struct slsi_test_dev *uftestdev);
|
||
|
void slsi_test_dev_detach(struct slsi_test_dev *uftestdev);
|
||
|
bool slsi_test_process_signal(struct slsi_test_dev *uftestdev, struct sk_buff *skb);
|
||
|
|
||
|
int slsi_test_udi_node_init(struct slsi_test_dev *uftestdev, struct device *parent);
|
||
|
int slsi_test_udi_node_reregister(struct slsi_test_dev *uftestdev);
|
||
|
int slsi_test_udi_node_deinit(struct slsi_test_dev *uftestdev);
|
||
|
|
||
|
int slsi_test_udi_init(void);
|
||
|
int slsi_test_udi_deinit(void);
|
||
|
|
||
|
void slsi_test_bh_work_f(struct work_struct *work);
|
||
|
static inline int slsi_test_bh_init(struct slsi_test_dev *uftestdev)
|
||
|
{
|
||
|
uftestdev->bh_work.available = false;
|
||
|
uftestdev->bh_work.uftestdev = uftestdev;
|
||
|
slsi_spinlock_create(&uftestdev->bh_work.spinlock);
|
||
|
INIT_WORK(&uftestdev->bh_work.work, slsi_test_bh_work_f);
|
||
|
uftestdev->bh_work.workqueue = alloc_ordered_workqueue("slsi_wlan_unittest_bh", 0);
|
||
|
if (!uftestdev->bh_work.workqueue)
|
||
|
return -ENOMEM;
|
||
|
uftestdev->bh_work.available = true;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static inline void slsi_test_bh_start(struct slsi_test_dev *uftestdev)
|
||
|
{
|
||
|
slsi_spinlock_lock(&uftestdev->bh_work.spinlock);
|
||
|
uftestdev->bh_work.available = true;
|
||
|
slsi_spinlock_unlock(&uftestdev->bh_work.spinlock);
|
||
|
}
|
||
|
|
||
|
static inline void slsi_test_bh_run(struct slsi_test_dev *uftestdev)
|
||
|
{
|
||
|
slsi_spinlock_lock(&uftestdev->bh_work.spinlock);
|
||
|
if (!uftestdev->bh_work.available)
|
||
|
goto exit;
|
||
|
queue_work(uftestdev->bh_work.workqueue, &uftestdev->bh_work.work);
|
||
|
exit:
|
||
|
slsi_spinlock_unlock(&uftestdev->bh_work.spinlock);
|
||
|
}
|
||
|
|
||
|
static inline void slsi_test_bh_stop(struct slsi_test_dev *uftestdev)
|
||
|
{
|
||
|
struct workqueue_struct *workqueue = NULL;
|
||
|
|
||
|
slsi_spinlock_lock(&uftestdev->bh_work.spinlock);
|
||
|
uftestdev->bh_work.available = false;
|
||
|
workqueue = uftestdev->bh_work.workqueue;
|
||
|
uftestdev->bh_work.workqueue = NULL;
|
||
|
slsi_spinlock_unlock(&uftestdev->bh_work.spinlock);
|
||
|
|
||
|
if (workqueue)
|
||
|
flush_workqueue(workqueue);
|
||
|
}
|
||
|
|
||
|
static inline void slsi_test_bh_deinit(struct slsi_test_dev *uftestdev)
|
||
|
{
|
||
|
struct workqueue_struct *workqueue = NULL;
|
||
|
|
||
|
slsi_spinlock_lock(&uftestdev->bh_work.spinlock);
|
||
|
WARN_ON(uftestdev->bh_work.available);
|
||
|
uftestdev->bh_work.available = false;
|
||
|
workqueue = uftestdev->bh_work.workqueue;
|
||
|
uftestdev->bh_work.workqueue = NULL;
|
||
|
slsi_spinlock_unlock(&uftestdev->bh_work.spinlock);
|
||
|
if (workqueue) {
|
||
|
flush_workqueue(workqueue);
|
||
|
destroy_workqueue(workqueue);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endif
|