1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3 * Copyright (c) 2023 Huawei Device Co., Ltd.
4 *
5 * Description: Bluetooth virtual network device used in
6 * the NewIP over Bluetooth communication scenario.
7 *
8 * Author: Yang Yanjun <yangyanjun@huawei.com>
9 *
10 * Data: 2023-03-14
11 */
12
13 #ifndef _BTDEV_H_
14 #define _BTDEV_H_
15
16 #include <linux/skbuff.h>
17 #include <linux/list.h>
18 #include <linux/errno.h>
19 #include <linux/netdevice.h>
20 #include <linux/etherdevice.h>
21 #include <linux/kernel.h>
22 #include <linux/types.h>
23 #include <linux/fcntl.h>
24 #include <linux/ioport.h>
25 #include <linux/in.h>
26 #include <linux/slab.h>
27 #include <linux/spinlock.h>
28 #include <linux/string.h>
29 #include <linux/bitops.h>
30 #include <linux/delay.h>
31 #include <linux/ip.h>
32 #include <linux/init.h>
33 #include <linux/module.h>
34 #include <linux/miscdevice.h>
35 #include <linux/fs.h>
36 #include <linux/cdev.h>
37 #include <linux/poll.h>
38 #include <linux/proc_fs.h>
39 #include <linux/seq_file.h>
40 #include <linux/ktime.h>
41 #include <linux/rtnetlink.h>
42 #include <linux/libfdt_env.h>
43
44 /* must include btdev_user.h first before any macro definition */
45 #include "btdev_user.h"
46
47 #define OK 0
48 #define TRUE 1
49 #define FALSE 0
50 #define DELAY_100_MS 100
51 #define MACADDR_LEN (2 * ETH_ALEN)
52
53 #define BT_DEV_MAJOR 125
54 #define BT_DEV_MINOR 0
55 #define BT_RING_BUFFER_SIZE 4096
56 #define STRTOLL_BASE 10
57 #define BT_DEV_ID_OFFSET (sizeof(BT_DEV_PATH_PREFIX) - 1)
58 #define BT_STATISTIC_KTIME_MAX ULONG_MAX
59 #define NEWIP_TYPE_SIZE 2 /* newip type eadd */
60 #define BT_MAX_MTU 65535
61 #define UNKNOWN_NAME "unknown"
62
63 /**
64 * ring buffer
65 */
66 struct bt_ring {
67 u32 head;
68 u32 tail;
69 u32 size;
70 void **data;
71 };
72
73 /**
74 * one char device
75 */
76 struct bt_cdev {
77 struct cdev *cdev;
78 struct class *bt_class;
79 char dev_filename[IFNAMSIZ];
80 };
81
82 struct bt_mng_file {
83 struct bt_cdev *bt_cdev;
84 atomic_t open_limit;
85 };
86
87 struct bt_io_file {
88 struct bt_cdev *bt_cdev;
89 atomic_t read_open_limit;
90 atomic_t write_open_limit;
91 };
92
93 /**
94 * virnet list
95 */
96 struct bt_table {
97 struct list_head head;
98 struct mutex tbl_lock; // lock for table
99 u32 num;
100 };
101
102 /**
103 * bt virnet state
104 */
105 enum bt_virnet_state {
106 BT_VIRNET_STATE_CREATED,
107 BT_VIRNET_STATE_CONNECTED,
108 BT_VIRNET_STATE_DISCONNECTED,
109 BT_VIRNET_STATE_DISABLED,
110 BT_VIRNET_STATE_DELETED,
111 BT_VIRNET_STAET_NUM
112 };
113
114 /**
115 * one virnet device
116 */
117 struct bt_virnet {
118 struct bt_ring *tx_ring;
119 struct bt_io_file *io_file;
120 struct net_device *ndev;
121 struct list_head virnet_entry;
122 enum bt_virnet_state state;
123 struct semaphore sem;
124 wait_queue_head_t rx_queue;
125 };
126
127 /**
128 * instance of the module
129 */
130 struct bt_drv {
131 struct bt_table *devices_table;
132 struct bt_mng_file *mng_file;
133 struct bt_io_file **io_files;
134 u32 bitmap;
135 struct mutex bitmap_lock; // lock for bitmap
136 struct class *bt_class;
137 };
138
139 /**
140 * state to string
141 */
142 static const char *g_bt_virnet_state_rep[BT_VIRNET_STAET_NUM] = {
143 "CREATED",
144 "CONNECTED",
145 "DISCONNECTED",
146 "DISABLED",
147 "ENABLED"};
148
149 /**
150 * inline functions
151 */
bt_get_unused_id(u32 bitmap)152 static inline int bt_get_unused_id(u32 bitmap)
153 {
154 int i;
155
156 for (i = 0; i < BT_VIRNET_MAX_NUM + 1; ++i) {
157 if (!(bitmap & (1 << i)))
158 return i;
159 }
160 return -1; // all used
161 }
162
bt_set_bit(u32 * bitmap,u32 idx)163 static inline void bt_set_bit(u32 *bitmap, u32 idx)
164 {
165 if (bitmap && idx <= BT_VIRNET_MAX_NUM)
166 *bitmap |= (1 << idx);
167 }
168
bt_clear_bit(u32 * bitmap,u32 idx)169 static inline void bt_clear_bit(u32 *bitmap, u32 idx)
170 {
171 if (bitmap && idx <= BT_VIRNET_MAX_NUM)
172 *bitmap &= ~(1 << idx);
173 }
174
175 #define set_state(vn, st) bt_virnet_set_state(vn, st)
bt_virnet_set_state(struct bt_virnet * vn,enum bt_virnet_state state)176 static inline void bt_virnet_set_state(struct bt_virnet *vn,
177 enum bt_virnet_state state)
178 {
179 vn->state = state;
180 }
181
bt_virnet_get_cdev(const struct bt_virnet * vn)182 static inline const struct cdev *bt_virnet_get_cdev(const struct bt_virnet *vn)
183 {
184 if (unlikely(!vn->io_file) || unlikely(!vn->io_file->bt_cdev))
185 return NULL;
186
187 return vn->io_file->bt_cdev->cdev;
188 }
189
bt_virnet_get_cdev_number(const struct bt_virnet * vn,dev_t * number)190 static inline const int bt_virnet_get_cdev_number(const struct bt_virnet *vn, dev_t *number)
191 {
192 if (unlikely(!vn->io_file) || unlikely(!vn->io_file->bt_cdev) ||
193 unlikely(!vn->io_file->bt_cdev->cdev) || unlikely(!number))
194 return -EINVAL;
195
196 *number = vn->io_file->bt_cdev->cdev->dev;
197 return OK;
198 }
199
bt_virnet_get_cdev_name(const struct bt_virnet * vn)200 static inline const char *bt_virnet_get_cdev_name(const struct bt_virnet *vn)
201 {
202 if (unlikely(!vn->io_file) || unlikely(!vn->io_file->bt_cdev) ||
203 unlikely(!vn->io_file->bt_cdev->dev_filename))
204 return UNKNOWN_NAME;
205
206 return vn->io_file->bt_cdev->dev_filename;
207 }
208
bt_virnet_get_ndev(const struct bt_virnet * vn)209 static inline struct net_device *bt_virnet_get_ndev(const struct bt_virnet *vn)
210 {
211 return vn->ndev;
212 }
213
bt_virnet_get_ndev_name(const struct bt_virnet * vn)214 static inline const char *bt_virnet_get_ndev_name(const struct bt_virnet *vn)
215 {
216 if (unlikely(!vn->ndev) || unlikely(!vn->ndev->name))
217 return UNKNOWN_NAME;
218
219 return vn->ndev->name;
220 }
221
bt_virnet_get_state_rep(const struct bt_virnet * vn)222 static inline const char *bt_virnet_get_state_rep(const struct bt_virnet *vn)
223 {
224 return g_bt_virnet_state_rep[vn->state];
225 }
226
bt_get_total_device(const struct bt_drv * drv)227 static inline int bt_get_total_device(const struct bt_drv *drv)
228 {
229 if (unlikely(!drv->devices_table))
230 return -EINVAL;
231
232 return drv->devices_table->num;
233 }
234
bt_virnet_get_ring_packets(const struct bt_virnet * vn)235 static inline int bt_virnet_get_ring_packets(const struct bt_virnet *vn)
236 {
237 int packets = 0;
238
239 if (unlikely(!vn->tx_ring) || unlikely(!vn->tx_ring->head) ||
240 unlikely(!vn->tx_ring->tail))
241 return 0;
242
243 packets = vn->tx_ring->head - vn->tx_ring->tail;
244 if (unlikely(packets < 0))
245 packets += BT_RING_BUFFER_SIZE;
246
247 return packets;
248 }
249
250 static struct bt_table *bt_table_init(void);
251 static int bt_table_add_device(struct bt_table *tbl, struct bt_virnet *vn);
252 static void bt_table_remove_device(struct bt_table *tbl, struct bt_virnet *vn);
253 static int bt_table_delete_all(struct bt_drv *drv);
254 static struct bt_virnet *bt_table_find(struct bt_table *tbl, const char *ifa_name);
255 static void bt_table_destroy(struct bt_drv *drv);
256 static void bt_delete_io_files(struct bt_drv *bt_mng);
257 static struct bt_io_file **bt_create_io_files(void);
258
259 static struct bt_ring *bt_ring_create(void);
260 static int bt_ring_is_empty(const struct bt_ring *ring);
261 static int bt_ring_is_full(const struct bt_ring *ring);
262 static void *bt_ring_current(struct bt_ring *ring);
263 static void bt_ring_produce(struct bt_ring *ring, void *data);
264 static void bt_ring_consume(struct bt_ring *ring);
265 static void bt_ring_destroy(struct bt_ring *ring);
266
267 static int bt_virnet_produce_data(struct bt_virnet *dev, void *data);
268 static struct bt_virnet *bt_virnet_create(struct bt_drv *bt_mng, u32 id);
269 static void bt_virnet_destroy(struct bt_virnet *vnet);
270
271 #endif
272