!66 btdev虚拟设备代合入

Merge pull request !66 from YangYanJun/master
This commit is contained in:
openharmony_ci
2023-03-15 06:26:39 +00:00
committed by Gitee
4 changed files with 1490 additions and 0 deletions
+3
View File
@@ -0,0 +1,3 @@
# enable btdev:
# kernel/linux/linux-5.10/drivers/net/Makefile add obj-y += bt/
obj-y += btdev.o
File diff suppressed because it is too large Load Diff
+252
View File
@@ -0,0 +1,252 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
*/
#ifndef _BTDEV_H_
#define _BTDEV_H_
#include <linux/skbuff.h>
#include <linux/list.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/ioport.h>
#include <linux/in.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/ip.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/poll.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/ktime.h>
#include <linux/rtnetlink.h>
/* must include btdev_user.h first before any macro definition */
#include "btdev_user.h"
#define OK 0
#define DELAY_100_MS 100
#define MACADDR_LEN (2 * ETH_ALEN)
#define BT_DEV_MAJOR 125
#define BT_DEV_MINOR 0
#define BT_RING_BUFFER_SIZE 4096
#define STRTOLL_BASE 10
#define BT_DEV_ID_OFFSET (sizeof(BT_DEV_PATH_PREFIX) - 1)
#define BT_STATISTIC_KTIME_MAX ULONG_MAX
/**
* for debug
*/
#define DEBUG
/**
* ring buffer
*/
struct bt_ring {
u32 head;
u32 tail;
u32 size;
void **data;
};
/**
* one char device
*/
struct bt_cdev {
struct cdev *cdev;
struct class *bt_class;
char dev_filename[BT_PATHNAME_MAX];
};
struct bt_mng_file {
struct bt_cdev *bt_cdev;
atomic_t open_limit;
};
struct bt_io_file {
struct bt_cdev *bt_cdev;
atomic_t read_open_limit;
atomic_t write_open_limit;
};
/**
* virnet list
*/
struct bt_table {
struct list_head head;
struct mutex tbl_lock; // lock for table
u32 num;
};
/**
* bt virnet state
*/
enum bt_virnet_state {
BT_VIRNET_STATE_CREATED,
BT_VIRNET_STATE_CONNECTED,
BT_VIRNET_STATE_DISCONNECTED,
BT_VIRNET_STATE_DISABLED,
BT_VIRNET_STATE_DELETED,
BT_VIRNET_STAET_NUM
};
/**
* one virnet device
*/
struct bt_virnet {
struct bt_ring *tx_ring;
struct bt_io_file *io_file;
struct net_device *ndev;
struct list_head virnet_entry;
struct bt_table *bt_table_head;
enum bt_virnet_state state;
struct semaphore sem;
wait_queue_head_t rx_queue, tx_queue;
};
/**
* instance of the module
*/
struct bt_drv {
struct bt_table *devices_table;
struct bt_mng_file *mng_file;
struct bt_io_file **io_files;
u32 bitmap;
struct mutex bitmap_lock; // lock for bitmap
struct class *bt_class;
};
/**
* state to string
*/
static const char *bt_virnet_state_rep[BT_VIRNET_STAET_NUM] = {
"CREATED",
"CONNECTED",
"DISCONNECTED",
"DISABLED",
"ENABLED"};
/**
* inline functions
*/
static inline int bt_get_unused_id(const u32 *bitmap)
{
int i;
WARN_ON(!bitmap);
for (i = 0; i < BT_VIRNET_MAX_NUM + 1; ++i) {
if (!(*bitmap & (1 << i)))
return i;
}
return -1; // all used
}
static inline void bt_set_bit(u32 *bitmap, u32 idx)
{
WARN_ON(!bitmap);
*bitmap |= (1 << idx);
}
static inline void bt_clear_bit(u32 *bitmap, u32 idx)
{
WARN_ON(!bitmap);
*bitmap &= ~(1 << idx);
}
#define SET_STATE(vn, st) bt_virnet_set_state(vn, st)
static inline void bt_virnet_set_state(struct bt_virnet *vn,
enum bt_virnet_state state)
{
WARN_ON(!vn);
vn->state = state;
}
static inline const struct cdev *bt_virnet_get_cdev(const struct bt_virnet *vn)
{
WARN_ON(!vn);
return vn->io_file->bt_cdev->cdev;
}
static inline const dev_t bt_virnet_get_cdev_number(const struct bt_virnet *vn)
{
WARN_ON(!vn);
return vn->io_file->bt_cdev->cdev->dev;
}
static inline const char *bt_virnet_get_cdev_name(const struct bt_virnet *vn)
{
WARN_ON(!vn);
return vn->io_file->bt_cdev->dev_filename;
}
static inline struct net_device *bt_virnet_get_ndev(const struct bt_virnet *vn)
{
WARN_ON(!vn);
return vn->ndev;
}
static inline const char *bt_virnet_get_ndev_name(const struct bt_virnet *vn)
{
WARN_ON(!vn);
return vn->ndev->name;
}
static inline const char *bt_virnet_get_state_rep(const struct bt_virnet *vn)
{
WARN_ON(!vn);
return bt_virnet_state_rep[vn->state];
}
static inline int bt_get_total_device(const struct bt_drv *bt_drv)
{
WARN_ON(!bt_drv);
return bt_drv->devices_table->num;
}
static inline int bt_virnet_get_ring_packets(const struct bt_virnet *vn)
{
int packets = 0;
WARN_ON(!vn);
packets = vn->tx_ring->head - vn->tx_ring->tail;
if (unlikely(packets < 0))
packets += BT_RING_BUFFER_SIZE;
return packets;
}
static struct bt_table *bt_table_init(void);
static int bt_table_add_device(struct bt_table *tbl, struct bt_virnet *vn);
static void bt_table_remove_device(struct bt_table *tbl, struct bt_virnet *vn);
static void bt_table_delete_all(struct bt_drv *drv);
static struct bt_virnet *bt_table_find(struct bt_table *tbl, const char *ifa_name);
static void bt_table_destroy(struct bt_drv *drv);
static void bt_delete_io_files(struct bt_drv *drv);
static struct bt_io_file **bt_create_io_files(void);
static struct bt_ring *bt_ring_create(void);
static int bt_ring_is_empty(const struct bt_ring *ring);
static int bt_ring_is_full(const struct bt_ring *ring);
static void *bt_ring_current(struct bt_ring *ring);
static void bt_ring_produce(struct bt_ring *ring, void *data);
static void bt_ring_consume(struct bt_ring *ring);
static void bt_ring_destroy(struct bt_ring *ring);
static int bt_virnet_produce_data(struct bt_virnet *dev, void *data);
static struct bt_virnet *bt_virnet_create(struct bt_drv *drv, u32 id);
static void bt_virnet_destroy(struct bt_virnet *dev);
#endif
+49
View File
@@ -0,0 +1,49 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
*/
#ifndef _BTDEV_USER_H_
#define _BTDEV_USER_H_
#include <linux/if.h>
#include <linux/ioctl.h>
#define BT_VIRNET_NAME_PREFIX "btn"
#define BT_DEV_NAME_PREFIX "btdev"
#define BT_DEV_PATH_PREFIX "/dev/" BT_DEV_NAME_PREFIX
#define BT_DEV_PATH(idx) (BT_DEV_PATH_PREFIX#idx)
#define BT_DEV_NAME(idx) (BT_DEV_NAME_PREFIX#idx)
#define BT_DEV_NAME_MNG_FILE BT_DEV_NAME(0)
#define BT_DEV_PATH_MNG_FILE BT_DEV_PATH(0)
#define BT_DEV_NAME_IO_FILE(idx) BT_DEV_NAME(idx)
#define BT_DEV_PATH_IO_FILE(idx) BT_DEV_PATH(idx)
#define BT_VIRNET_NAME(idx) (BT_VIRNET_NAME_PREFIX#idx)
#define BT_PATHNAME_MAX 256
#define BT_VIRNET_MAX_NUM 16
#define BT_VIRNET_DATA_HEAD_LEN 2
/**
* ioctl cmd
*/
#define BT_IOC_CREATE _IO('b', 1)
#define BT_IOC_DELETE _IO('b', 2)
#define BT_IOC_CHANGE_MTU _IO('b', 3)
#define BT_IOC_QUERY_ALL _IO('b', 4)
#define BT_IOC_DELETE_ALL _IO('b', 5)
#define BT_IOC_ENABLE _IO('b', 6)
#define BT_IOC_DISABLE _IO('b', 7)
#define BT_IOC_PEEK_PACKET _IO('b', 8)
/**
* user space ioctl arguments
*/
struct bt_uioc_args {
char ifa_name[IFNAMSIZ];
char cfile_name[BT_PATHNAME_MAX];
};
#endif