xref: /linux/drivers/net/wwan/wwan_hwsim.c (revision 1fd1dc41724319406b0aff221a352a400b0ddfc5)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * WWAN device simulator for WWAN framework testing.
4  *
5  * Copyright (c) 2021, 2025, Sergey Ryazanov <ryazanov.s.a@gmail.com>
6  */
7 
8 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
9 
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/slab.h>
13 #include <linux/device.h>
14 #include <linux/spinlock.h>
15 #include <linux/time.h>
16 #include <linux/list.h>
17 #include <linux/skbuff.h>
18 #include <linux/timer.h>
19 #include <linux/netdevice.h>
20 #include <linux/wwan.h>
21 #include <linux/debugfs.h>
22 #include <linux/workqueue.h>
23 
24 #include <net/arp.h>
25 
26 static int wwan_hwsim_devsnum = 2;
27 module_param_named(devices, wwan_hwsim_devsnum, int, 0444);
28 MODULE_PARM_DESC(devices, "Number of simulated devices");
29 
30 static const struct class wwan_hwsim_class = {
31 	.name = "wwan_hwsim",
32 };
33 
34 static struct dentry *wwan_hwsim_debugfs_topdir;
35 static struct dentry *wwan_hwsim_debugfs_devcreate;
36 
37 static DEFINE_SPINLOCK(wwan_hwsim_devs_lock);
38 static LIST_HEAD(wwan_hwsim_devs);
39 static unsigned int wwan_hwsim_dev_idx;
40 static struct workqueue_struct *wwan_wq;
41 
42 struct wwan_hwsim_dev {
43 	struct list_head list;
44 	unsigned int id;
45 	struct device dev;
46 	struct work_struct del_work;
47 	struct dentry *debugfs_topdir;
48 	struct dentry *debugfs_portcreate;
49 	spinlock_t ports_lock;	/* Serialize ports creation/deletion */
50 	unsigned int port_idx;
51 	struct list_head ports;
52 };
53 
54 struct wwan_hwsim_port {
55 	struct list_head list;
56 	unsigned int id;
57 	struct wwan_hwsim_dev *dev;
58 	struct wwan_port *wwan;
59 	struct work_struct del_work;
60 	struct dentry *debugfs_topdir;
61 	union {
62 		struct {
63 			enum {	/* AT command parser state */
64 				AT_PARSER_WAIT_A,
65 				AT_PARSER_WAIT_T,
66 				AT_PARSER_WAIT_TERM,
67 				AT_PARSER_SKIP_LINE,
68 			} pstate;
69 		} at_emul;
70 		struct {
71 			struct timer_list timer;
72 		} nmea_emul;
73 	};
74 };
75 
76 static const struct file_operations wwan_hwsim_debugfs_portdestroy_fops;
77 static const struct file_operations wwan_hwsim_debugfs_portcreate_fops;
78 static const struct file_operations wwan_hwsim_debugfs_devdestroy_fops;
79 static void wwan_hwsim_port_del_work(struct work_struct *work);
80 static void wwan_hwsim_dev_del_work(struct work_struct *work);
81 
82 static netdev_tx_t wwan_hwsim_netdev_xmit(struct sk_buff *skb,
83 					  struct net_device *ndev)
84 {
85 	ndev->stats.tx_packets++;
86 	ndev->stats.tx_bytes += skb->len;
87 	consume_skb(skb);
88 	return NETDEV_TX_OK;
89 }
90 
91 static const struct net_device_ops wwan_hwsim_netdev_ops = {
92 	.ndo_start_xmit = wwan_hwsim_netdev_xmit,
93 };
94 
95 static void wwan_hwsim_netdev_setup(struct net_device *ndev)
96 {
97 	ndev->netdev_ops = &wwan_hwsim_netdev_ops;
98 	ndev->needs_free_netdev = true;
99 
100 	ndev->mtu = ETH_DATA_LEN;
101 	ndev->min_mtu = ETH_MIN_MTU;
102 	ndev->max_mtu = ETH_MAX_MTU;
103 
104 	ndev->type = ARPHRD_NONE;
105 	ndev->flags = IFF_POINTOPOINT | IFF_NOARP;
106 }
107 
108 static const struct wwan_ops wwan_hwsim_wwan_rtnl_ops = {
109 	.priv_size = 0,			/* No private data */
110 	.setup = wwan_hwsim_netdev_setup,
111 };
112 
113 static int wwan_hwsim_at_emul_start(struct wwan_port *wport)
114 {
115 	struct wwan_hwsim_port *port = wwan_port_get_drvdata(wport);
116 
117 	port->at_emul.pstate = AT_PARSER_WAIT_A;
118 
119 	return 0;
120 }
121 
122 static void wwan_hwsim_at_emul_stop(struct wwan_port *wport)
123 {
124 }
125 
126 /* Implements a minimalistic AT commands parser that echo input back and
127  * reply with 'OK' to each input command. See AT command protocol details in the
128  * ITU-T V.250 recomendations document.
129  *
130  * Be aware that this processor is not fully V.250 compliant.
131  */
132 static int wwan_hwsim_at_emul_tx(struct wwan_port *wport, struct sk_buff *in)
133 {
134 	struct wwan_hwsim_port *port = wwan_port_get_drvdata(wport);
135 	struct sk_buff *out;
136 	int i, n, s;
137 
138 	/* Estimate a max possible number of commands by counting the number of
139 	 * termination chars (S3 param, CR by default). And then allocate the
140 	 * output buffer that will be enough to fit the echo and result codes of
141 	 * all commands.
142 	 */
143 	for (i = 0, n = 0; i < in->len; ++i)
144 		if (in->data[i] == '\r')
145 			n++;
146 	n = in->len + n * (2 + 2 + 2);	/* Output buffer size */
147 	out = alloc_skb(n, GFP_KERNEL);
148 	if (!out)
149 		return -ENOMEM;
150 
151 	for (i = 0, s = 0; i < in->len; ++i) {
152 		char c = in->data[i];
153 
154 		if (port->at_emul.pstate == AT_PARSER_WAIT_A) {
155 			if (c == 'A' || c == 'a')
156 				port->at_emul.pstate = AT_PARSER_WAIT_T;
157 			else if (c != '\n')	/* Ignore formating char */
158 				port->at_emul.pstate = AT_PARSER_SKIP_LINE;
159 		} else if (port->at_emul.pstate == AT_PARSER_WAIT_T) {
160 			if (c == 'T' || c == 't')
161 				port->at_emul.pstate = AT_PARSER_WAIT_TERM;
162 			else
163 				port->at_emul.pstate = AT_PARSER_SKIP_LINE;
164 		} else if (port->at_emul.pstate == AT_PARSER_WAIT_TERM) {
165 			if (c != '\r')
166 				continue;
167 			/* Consume the trailing formatting char as well */
168 			if ((i + 1) < in->len && in->data[i + 1] == '\n')
169 				i++;
170 			n = i - s + 1;
171 			skb_put_data(out, &in->data[s], n);/* Echo */
172 			skb_put_data(out, "\r\nOK\r\n", 6);
173 			s = i + 1;
174 			port->at_emul.pstate = AT_PARSER_WAIT_A;
175 		} else if (port->at_emul.pstate == AT_PARSER_SKIP_LINE) {
176 			if (c != '\r')
177 				continue;
178 			port->at_emul.pstate = AT_PARSER_WAIT_A;
179 		}
180 	}
181 
182 	if (i > s) {
183 		/* Echo the processed portion of a not yet completed command */
184 		n = i - s;
185 		skb_put_data(out, &in->data[s], n);
186 	}
187 
188 	consume_skb(in);
189 
190 	wwan_port_rx(wport, out);
191 
192 	return 0;
193 }
194 
195 static const struct wwan_port_ops wwan_hwsim_at_emul_port_ops = {
196 	.start = wwan_hwsim_at_emul_start,
197 	.stop = wwan_hwsim_at_emul_stop,
198 	.tx = wwan_hwsim_at_emul_tx,
199 };
200 
201 #if IS_ENABLED(CONFIG_GNSS)
202 #define NMEA_MAX_LEN		82	/* Max sentence length */
203 #define NMEA_TRAIL_LEN		5	/* '*' + Checksum + <CR><LF> */
204 #define NMEA_MAX_DATA_LEN	(NMEA_MAX_LEN - NMEA_TRAIL_LEN)
205 
206 static __printf(2, 3)
207 void wwan_hwsim_nmea_skb_push_sentence(struct sk_buff *skb,
208 				       const char *fmt, ...)
209 {
210 	unsigned char *s, *p;
211 	va_list ap;
212 	u8 cs = 0;
213 	int len;
214 
215 	s = skb_put(skb, NMEA_MAX_LEN + 1);	/* +'\0' */
216 	if (!s)
217 		return;
218 
219 	va_start(ap, fmt);
220 	len = vsnprintf(s, NMEA_MAX_DATA_LEN + 1, fmt, ap);
221 	va_end(ap);
222 	if (WARN_ON_ONCE(len > NMEA_MAX_DATA_LEN))/* No space for trailer */
223 		return;
224 
225 	for (p = s + 1; *p != '\0'; ++p)/* Skip leading '$' or '!' */
226 		cs ^= *p;
227 	p += snprintf(p, 5 + 1, "*%02X\r\n", cs);
228 
229 	len = (p - s) - (NMEA_MAX_LEN + 1);	/* exp. vs real length diff */
230 	skb->tail += len;			/* Adjust tail to real length */
231 	skb->len += len;
232 }
233 
234 static void wwan_hwsim_nmea_emul_timer(struct timer_list *t)
235 {
236 	/* 43.74754722298909 N 11.25759835922875 E in DMM format */
237 	static const unsigned int coord[4 * 2] = { 43, 44, 8528, 0,
238 						   11, 15, 4559, 0 };
239 	struct wwan_hwsim_port *port = timer_container_of(port, t, nmea_emul.timer);
240 	struct sk_buff *skb;
241 	struct tm tm;
242 
243 	time64_to_tm(ktime_get_real_seconds(), 0, &tm);
244 
245 	mod_timer(&port->nmea_emul.timer, jiffies + HZ);	/* 1 second */
246 
247 	skb = alloc_skb(NMEA_MAX_LEN * 2 + 2, GFP_ATOMIC);	/* GGA + RMC */
248 	if (!skb)
249 		return;
250 
251 	wwan_hwsim_nmea_skb_push_sentence(skb,
252 					  "$GPGGA,%02u%02u%02u.000,%02u%02u.%04u,%c,%03u%02u.%04u,%c,1,7,1.03,176.2,M,55.2,M,,",
253 					  tm.tm_hour, tm.tm_min, tm.tm_sec,
254 					  coord[0], coord[1], coord[2],
255 					  coord[3] ? 'S' : 'N',
256 					  coord[4], coord[5], coord[6],
257 					  coord[7] ? 'W' : 'E');
258 
259 	wwan_hwsim_nmea_skb_push_sentence(skb,
260 					  "$GPRMC,%02u%02u%02u.000,A,%02u%02u.%04u,%c,%03u%02u.%04u,%c,0.02,31.66,%02u%02u%02u,,,A",
261 					  tm.tm_hour, tm.tm_min, tm.tm_sec,
262 					  coord[0], coord[1], coord[2],
263 					  coord[3] ? 'S' : 'N',
264 					  coord[4], coord[5], coord[6],
265 					  coord[7] ? 'W' : 'E',
266 					  tm.tm_mday, tm.tm_mon + 1,
267 					  (unsigned int)tm.tm_year - 100);
268 
269 	wwan_port_rx(port->wwan, skb);
270 }
271 
272 static int wwan_hwsim_nmea_emul_start(struct wwan_port *wport)
273 {
274 	struct wwan_hwsim_port *port = wwan_port_get_drvdata(wport);
275 
276 	timer_setup(&port->nmea_emul.timer, wwan_hwsim_nmea_emul_timer, 0);
277 	wwan_hwsim_nmea_emul_timer(&port->nmea_emul.timer);
278 
279 	return 0;
280 }
281 
282 static void wwan_hwsim_nmea_emul_stop(struct wwan_port *wport)
283 {
284 	struct wwan_hwsim_port *port = wwan_port_get_drvdata(wport);
285 
286 	timer_delete_sync(&port->nmea_emul.timer);
287 }
288 
289 static int wwan_hwsim_nmea_emul_tx(struct wwan_port *wport, struct sk_buff *in)
290 {
291 	consume_skb(in);
292 
293 	return 0;
294 }
295 
296 static const struct wwan_port_ops wwan_hwsim_nmea_emul_port_ops = {
297 	.start = wwan_hwsim_nmea_emul_start,
298 	.stop = wwan_hwsim_nmea_emul_stop,
299 	.tx = wwan_hwsim_nmea_emul_tx,
300 };
301 #endif
302 
303 static struct wwan_hwsim_port *wwan_hwsim_port_new(struct wwan_hwsim_dev *dev,
304 						   enum wwan_port_type type)
305 {
306 	const struct wwan_port_ops *ops;
307 	struct wwan_hwsim_port *port;
308 	char name[0x10];
309 	int err;
310 
311 	if (type == WWAN_PORT_AT)
312 		ops = &wwan_hwsim_at_emul_port_ops;
313 #if IS_ENABLED(CONFIG_GNSS)
314 	else if (type == WWAN_PORT_NMEA)
315 		ops = &wwan_hwsim_nmea_emul_port_ops;
316 #endif
317 	else
318 		return ERR_PTR(-EINVAL);
319 
320 	port = kzalloc_obj(*port);
321 	if (!port)
322 		return ERR_PTR(-ENOMEM);
323 
324 	port->dev = dev;
325 
326 	spin_lock(&dev->ports_lock);
327 	port->id = dev->port_idx++;
328 	spin_unlock(&dev->ports_lock);
329 
330 	port->wwan = wwan_create_port(&dev->dev, type, ops, NULL, port);
331 	if (IS_ERR(port->wwan)) {
332 		err = PTR_ERR(port->wwan);
333 		goto err_free_port;
334 	}
335 
336 	INIT_WORK(&port->del_work, wwan_hwsim_port_del_work);
337 
338 	snprintf(name, sizeof(name), "port%u", port->id);
339 	port->debugfs_topdir = debugfs_create_dir(name, dev->debugfs_topdir);
340 	debugfs_create_file("destroy", 0200, port->debugfs_topdir, port,
341 			    &wwan_hwsim_debugfs_portdestroy_fops);
342 
343 	return port;
344 
345 err_free_port:
346 	kfree(port);
347 
348 	return ERR_PTR(err);
349 }
350 
351 static void wwan_hwsim_port_del(struct wwan_hwsim_port *port)
352 {
353 	debugfs_remove(port->debugfs_topdir);
354 
355 	/* Make sure that there is no pending deletion work */
356 	if (current_work() != &port->del_work)
357 		cancel_work_sync(&port->del_work);
358 
359 	wwan_remove_port(port->wwan);
360 	kfree(port);
361 }
362 
363 static void wwan_hwsim_port_del_work(struct work_struct *work)
364 {
365 	struct wwan_hwsim_port *port =
366 				container_of(work, typeof(*port), del_work);
367 	struct wwan_hwsim_dev *dev = port->dev;
368 
369 	spin_lock(&dev->ports_lock);
370 	if (list_empty(&port->list)) {
371 		/* Someone else deleting port at the moment */
372 		spin_unlock(&dev->ports_lock);
373 		return;
374 	}
375 	list_del_init(&port->list);
376 	spin_unlock(&dev->ports_lock);
377 
378 	wwan_hwsim_port_del(port);
379 }
380 
381 static void wwan_hwsim_dev_release(struct device *sysdev)
382 {
383 	struct wwan_hwsim_dev *dev = container_of(sysdev, typeof(*dev), dev);
384 
385 	kfree(dev);
386 }
387 
388 static struct wwan_hwsim_dev *wwan_hwsim_dev_new(void)
389 {
390 	struct wwan_hwsim_dev *dev;
391 	int err;
392 
393 	dev = kzalloc_obj(*dev);
394 	if (!dev)
395 		return ERR_PTR(-ENOMEM);
396 
397 	spin_lock(&wwan_hwsim_devs_lock);
398 	dev->id = wwan_hwsim_dev_idx++;
399 	spin_unlock(&wwan_hwsim_devs_lock);
400 
401 	dev->dev.release = wwan_hwsim_dev_release;
402 	dev->dev.class = &wwan_hwsim_class;
403 	dev_set_name(&dev->dev, "hwsim%u", dev->id);
404 
405 	spin_lock_init(&dev->ports_lock);
406 	INIT_LIST_HEAD(&dev->ports);
407 
408 	err = device_register(&dev->dev);
409 	if (err)
410 		goto err_free_dev;
411 
412 	INIT_WORK(&dev->del_work, wwan_hwsim_dev_del_work);
413 
414 	err = wwan_register_ops(&dev->dev, &wwan_hwsim_wwan_rtnl_ops, dev, 1);
415 	if (err)
416 		goto err_unreg_dev;
417 
418 	dev->debugfs_topdir = debugfs_create_dir(dev_name(&dev->dev),
419 						 wwan_hwsim_debugfs_topdir);
420 	debugfs_create_file("destroy", 0200, dev->debugfs_topdir, dev,
421 			    &wwan_hwsim_debugfs_devdestroy_fops);
422 	dev->debugfs_portcreate =
423 		debugfs_create_file("portcreate", 0200,
424 				    dev->debugfs_topdir, dev,
425 				    &wwan_hwsim_debugfs_portcreate_fops);
426 
427 	return dev;
428 
429 err_unreg_dev:
430 	device_unregister(&dev->dev);
431 	/* Memory will be freed in the device release callback */
432 
433 	return ERR_PTR(err);
434 
435 err_free_dev:
436 	put_device(&dev->dev);
437 
438 	return ERR_PTR(err);
439 }
440 
441 static void wwan_hwsim_dev_del(struct wwan_hwsim_dev *dev)
442 {
443 	debugfs_remove(dev->debugfs_portcreate);	/* Avoid new ports */
444 
445 	spin_lock(&dev->ports_lock);
446 	while (!list_empty(&dev->ports)) {
447 		struct wwan_hwsim_port *port;
448 
449 		port = list_first_entry(&dev->ports, struct wwan_hwsim_port,
450 					list);
451 		list_del_init(&port->list);
452 		spin_unlock(&dev->ports_lock);
453 		wwan_hwsim_port_del(port);
454 		spin_lock(&dev->ports_lock);
455 	}
456 	spin_unlock(&dev->ports_lock);
457 
458 	debugfs_remove(dev->debugfs_topdir);
459 
460 	/* This will remove all child netdev(s) */
461 	wwan_unregister_ops(&dev->dev);
462 
463 	/* Make sure that there is no pending deletion work */
464 	if (current_work() != &dev->del_work)
465 		cancel_work_sync(&dev->del_work);
466 
467 	device_unregister(&dev->dev);
468 	/* Memory will be freed in the device release callback */
469 }
470 
471 static void wwan_hwsim_dev_del_work(struct work_struct *work)
472 {
473 	struct wwan_hwsim_dev *dev = container_of(work, typeof(*dev), del_work);
474 
475 	spin_lock(&wwan_hwsim_devs_lock);
476 	if (list_empty(&dev->list)) {
477 		/* Someone else deleting device at the moment */
478 		spin_unlock(&wwan_hwsim_devs_lock);
479 		return;
480 	}
481 	list_del_init(&dev->list);
482 	spin_unlock(&wwan_hwsim_devs_lock);
483 
484 	wwan_hwsim_dev_del(dev);
485 }
486 
487 static ssize_t wwan_hwsim_debugfs_portdestroy_write(struct file *file,
488 						    const char __user *usrbuf,
489 						    size_t count, loff_t *ppos)
490 {
491 	struct wwan_hwsim_port *port = file->private_data;
492 
493 	/* We can not delete port here since it will cause a deadlock due to
494 	 * waiting this callback to finish in the debugfs_remove() call. So,
495 	 * use workqueue.
496 	 */
497 	queue_work(wwan_wq, &port->del_work);
498 
499 	return count;
500 }
501 
502 static const struct file_operations wwan_hwsim_debugfs_portdestroy_fops = {
503 	.write = wwan_hwsim_debugfs_portdestroy_write,
504 	.open = simple_open,
505 	.llseek = noop_llseek,
506 };
507 
508 static ssize_t wwan_hwsim_debugfs_portcreate_write(struct file *file,
509 						   const char __user *usrbuf,
510 						   size_t count, loff_t *ppos)
511 {
512 	struct wwan_hwsim_dev *dev = file->private_data;
513 	struct wwan_hwsim_port *port;
514 
515 	port = wwan_hwsim_port_new(dev, WWAN_PORT_AT);
516 	if (IS_ERR(port))
517 		return PTR_ERR(port);
518 
519 	spin_lock(&dev->ports_lock);
520 	list_add_tail(&port->list, &dev->ports);
521 	spin_unlock(&dev->ports_lock);
522 
523 	return count;
524 }
525 
526 static const struct file_operations wwan_hwsim_debugfs_portcreate_fops = {
527 	.write = wwan_hwsim_debugfs_portcreate_write,
528 	.open = simple_open,
529 	.llseek = noop_llseek,
530 };
531 
532 static ssize_t wwan_hwsim_debugfs_devdestroy_write(struct file *file,
533 						   const char __user *usrbuf,
534 						   size_t count, loff_t *ppos)
535 {
536 	struct wwan_hwsim_dev *dev = file->private_data;
537 
538 	/* We can not delete device here since it will cause a deadlock due to
539 	 * waiting this callback to finish in the debugfs_remove() call. So,
540 	 * use workqueue.
541 	 */
542 	queue_work(wwan_wq, &dev->del_work);
543 
544 	return count;
545 }
546 
547 static const struct file_operations wwan_hwsim_debugfs_devdestroy_fops = {
548 	.write = wwan_hwsim_debugfs_devdestroy_write,
549 	.open = simple_open,
550 	.llseek = noop_llseek,
551 };
552 
553 static ssize_t wwan_hwsim_debugfs_devcreate_write(struct file *file,
554 						  const char __user *usrbuf,
555 						  size_t count, loff_t *ppos)
556 {
557 	struct wwan_hwsim_dev *dev;
558 
559 	dev = wwan_hwsim_dev_new();
560 	if (IS_ERR(dev))
561 		return PTR_ERR(dev);
562 
563 	spin_lock(&wwan_hwsim_devs_lock);
564 	list_add_tail(&dev->list, &wwan_hwsim_devs);
565 	spin_unlock(&wwan_hwsim_devs_lock);
566 
567 	return count;
568 }
569 
570 static const struct file_operations wwan_hwsim_debugfs_devcreate_fops = {
571 	.write = wwan_hwsim_debugfs_devcreate_write,
572 	.open = simple_open,
573 	.llseek = noop_llseek,
574 };
575 
576 static int __init wwan_hwsim_init_devs(void)
577 {
578 	struct wwan_hwsim_dev *dev;
579 	int i, j;
580 
581 	for (i = 0; i < wwan_hwsim_devsnum; ++i) {
582 		struct wwan_hwsim_port *port;
583 
584 		dev = wwan_hwsim_dev_new();
585 		if (IS_ERR(dev))
586 			return PTR_ERR(dev);
587 
588 		spin_lock(&wwan_hwsim_devs_lock);
589 		list_add_tail(&dev->list, &wwan_hwsim_devs);
590 		spin_unlock(&wwan_hwsim_devs_lock);
591 
592 		/* Create a few various ports per each device to accelerate
593 		 * the simulator readiness time.
594 		 */
595 
596 		for (j = 0; j < 2; ++j) {
597 			port = wwan_hwsim_port_new(dev, WWAN_PORT_AT);
598 			if (IS_ERR(port))
599 				return PTR_ERR(port);
600 
601 			spin_lock(&dev->ports_lock);
602 			list_add_tail(&port->list, &dev->ports);
603 			spin_unlock(&dev->ports_lock);
604 		}
605 
606 #if IS_ENABLED(CONFIG_GNSS)
607 		port = wwan_hwsim_port_new(dev, WWAN_PORT_NMEA);
608 		if (IS_ERR(port)) {
609 			dev_warn(&dev->dev, "failed to create initial NMEA port: %d\n",
610 				 (int)PTR_ERR(port));
611 		} else {
612 			spin_lock(&dev->ports_lock);
613 			list_add_tail(&port->list, &dev->ports);
614 			spin_unlock(&dev->ports_lock);
615 		}
616 #endif
617 	}
618 
619 	return 0;
620 }
621 
622 static void wwan_hwsim_free_devs(void)
623 {
624 	struct wwan_hwsim_dev *dev;
625 
626 	spin_lock(&wwan_hwsim_devs_lock);
627 	while (!list_empty(&wwan_hwsim_devs)) {
628 		dev = list_first_entry(&wwan_hwsim_devs, struct wwan_hwsim_dev,
629 				       list);
630 		list_del_init(&dev->list);
631 		spin_unlock(&wwan_hwsim_devs_lock);
632 		wwan_hwsim_dev_del(dev);
633 		spin_lock(&wwan_hwsim_devs_lock);
634 	}
635 	spin_unlock(&wwan_hwsim_devs_lock);
636 }
637 
638 static int __init wwan_hwsim_init(void)
639 {
640 	int err;
641 
642 	if (wwan_hwsim_devsnum < 0 || wwan_hwsim_devsnum > 128)
643 		return -EINVAL;
644 
645 	wwan_wq = alloc_workqueue("wwan_wq", WQ_PERCPU, 0);
646 	if (!wwan_wq)
647 		return -ENOMEM;
648 
649 	err = class_register(&wwan_hwsim_class);
650 	if (err)
651 		goto err_wq_destroy;
652 
653 	wwan_hwsim_debugfs_topdir = debugfs_create_dir("wwan_hwsim", NULL);
654 	wwan_hwsim_debugfs_devcreate =
655 			debugfs_create_file("devcreate", 0200,
656 					    wwan_hwsim_debugfs_topdir, NULL,
657 					    &wwan_hwsim_debugfs_devcreate_fops);
658 
659 	err = wwan_hwsim_init_devs();
660 	if (err)
661 		goto err_clean_devs;
662 
663 	return 0;
664 
665 err_clean_devs:
666 	debugfs_remove(wwan_hwsim_debugfs_devcreate);	/* Avoid new devs */
667 	wwan_hwsim_free_devs();
668 	flush_workqueue(wwan_wq);	/* Wait deletion works completion */
669 	debugfs_remove(wwan_hwsim_debugfs_topdir);
670 	class_unregister(&wwan_hwsim_class);
671 err_wq_destroy:
672 	destroy_workqueue(wwan_wq);
673 
674 	return err;
675 }
676 
677 static void __exit wwan_hwsim_exit(void)
678 {
679 	debugfs_remove(wwan_hwsim_debugfs_devcreate);	/* Avoid new devs */
680 	wwan_hwsim_free_devs();
681 	flush_workqueue(wwan_wq);	/* Wait deletion works completion */
682 	debugfs_remove(wwan_hwsim_debugfs_topdir);
683 	class_unregister(&wwan_hwsim_class);
684 	destroy_workqueue(wwan_wq);
685 }
686 
687 module_init(wwan_hwsim_init);
688 module_exit(wwan_hwsim_exit);
689 
690 MODULE_AUTHOR("Sergey Ryazanov");
691 MODULE_DESCRIPTION("Device simulator for WWAN framework");
692 MODULE_LICENSE("GPL");
693