1 // SPDX-License-Identifier: GPL-2.0-only
3 * WWAN device simulator for WWAN framework testing.
8 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
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/list.h>
16 #include <linux/skbuff.h>
17 #include <linux/netdevice.h>
18 #include <linux/wwan.h>
19 #include <linux/debugfs.h>
20 #include <linux/workqueue.h>
24 static int wwan_hwsim_devsnum = 2;
25 module_param_named(devices, wwan_hwsim_devsnum, int, 0444);
26 MODULE_PARM_DESC(devices, "Number of simulated devices");
28 static struct class *wwan_hwsim_class;
30 static struct dentry *wwan_hwsim_debugfs_topdir;
31 static struct dentry *wwan_hwsim_debugfs_devcreate;
33 static DEFINE_SPINLOCK(wwan_hwsim_devs_lock);
34 static LIST_HEAD(wwan_hwsim_devs);
35 static unsigned int wwan_hwsim_dev_idx;
36 static struct workqueue_struct *wwan_wq;
38 struct wwan_hwsim_dev {
39 struct list_head list;
42 struct work_struct del_work;
43 struct dentry *debugfs_topdir;
44 struct dentry *debugfs_portcreate;
45 spinlock_t ports_lock; /* Serialize ports creation/deletion */
46 unsigned int port_idx;
47 struct list_head ports;
50 struct wwan_hwsim_port {
51 struct list_head list;
53 struct wwan_hwsim_dev *dev;
54 struct wwan_port *wwan;
55 struct work_struct del_work;
56 struct dentry *debugfs_topdir;
57 enum { /* AT command parser state */
65 static const struct file_operations wwan_hwsim_debugfs_portdestroy_fops;
66 static const struct file_operations wwan_hwsim_debugfs_portcreate_fops;
67 static const struct file_operations wwan_hwsim_debugfs_devdestroy_fops;
68 static void wwan_hwsim_port_del_work(struct work_struct *work);
69 static void wwan_hwsim_dev_del_work(struct work_struct *work);
71 static netdev_tx_t wwan_hwsim_netdev_xmit(struct sk_buff *skb,
72 struct net_device *ndev)
74 ndev->stats.tx_packets++;
75 ndev->stats.tx_bytes += skb->len;
80 static const struct net_device_ops wwan_hwsim_netdev_ops = {
81 .ndo_start_xmit = wwan_hwsim_netdev_xmit,
84 static void wwan_hwsim_netdev_setup(struct net_device *ndev)
86 ndev->netdev_ops = &wwan_hwsim_netdev_ops;
87 ndev->needs_free_netdev = true;
89 ndev->mtu = ETH_DATA_LEN;
90 ndev->min_mtu = ETH_MIN_MTU;
91 ndev->max_mtu = ETH_MAX_MTU;
93 ndev->type = ARPHRD_NONE;
94 ndev->flags = IFF_POINTOPOINT | IFF_NOARP;
97 static const struct wwan_ops wwan_hwsim_wwan_rtnl_ops = {
98 .priv_size = 0, /* No private data */
99 .setup = wwan_hwsim_netdev_setup,
102 static int wwan_hwsim_port_start(struct wwan_port *wport)
104 struct wwan_hwsim_port *port = wwan_port_get_drvdata(wport);
106 port->pstate = AT_PARSER_WAIT_A;
111 static void wwan_hwsim_port_stop(struct wwan_port *wport)
115 /* Implements a minimalistic AT commands parser that echo input back and
116 * reply with 'OK' to each input command. See AT command protocol details in the
117 * ITU-T V.250 recomendations document.
119 * Be aware that this processor is not fully V.250 compliant.
121 static int wwan_hwsim_port_tx(struct wwan_port *wport, struct sk_buff *in)
123 struct wwan_hwsim_port *port = wwan_port_get_drvdata(wport);
127 /* Estimate a max possible number of commands by counting the number of
128 * termination chars (S3 param, CR by default). And then allocate the
129 * output buffer that will be enough to fit the echo and result codes of
132 for (i = 0, n = 0; i < in->len; ++i)
133 if (in->data[i] == '\r')
135 n = in->len + n * (2 + 2 + 2); /* Output buffer size */
136 out = alloc_skb(n, GFP_KERNEL);
140 for (i = 0, s = 0; i < in->len; ++i) {
141 char c = in->data[i];
143 if (port->pstate == AT_PARSER_WAIT_A) {
144 if (c == 'A' || c == 'a')
145 port->pstate = AT_PARSER_WAIT_T;
146 else if (c != '\n') /* Ignore formating char */
147 port->pstate = AT_PARSER_SKIP_LINE;
148 } else if (port->pstate == AT_PARSER_WAIT_T) {
149 if (c == 'T' || c == 't')
150 port->pstate = AT_PARSER_WAIT_TERM;
152 port->pstate = AT_PARSER_SKIP_LINE;
153 } else if (port->pstate == AT_PARSER_WAIT_TERM) {
156 /* Consume the trailing formatting char as well */
157 if ((i + 1) < in->len && in->data[i + 1] == '\n')
160 skb_put_data(out, &in->data[s], n);/* Echo */
161 skb_put_data(out, "\r\nOK\r\n", 6);
163 port->pstate = AT_PARSER_WAIT_A;
164 } else if (port->pstate == AT_PARSER_SKIP_LINE) {
167 port->pstate = AT_PARSER_WAIT_A;
172 /* Echo the processed portion of a not yet completed command */
174 skb_put_data(out, &in->data[s], n);
179 wwan_port_rx(wport, out);
184 static const struct wwan_port_ops wwan_hwsim_port_ops = {
185 .start = wwan_hwsim_port_start,
186 .stop = wwan_hwsim_port_stop,
187 .tx = wwan_hwsim_port_tx,
190 static struct wwan_hwsim_port *wwan_hwsim_port_new(struct wwan_hwsim_dev *dev)
192 struct wwan_hwsim_port *port;
196 port = kzalloc(sizeof(*port), GFP_KERNEL);
198 return ERR_PTR(-ENOMEM);
202 spin_lock(&dev->ports_lock);
203 port->id = dev->port_idx++;
204 spin_unlock(&dev->ports_lock);
206 port->wwan = wwan_create_port(&dev->dev, WWAN_PORT_AT,
207 &wwan_hwsim_port_ops,
209 if (IS_ERR(port->wwan)) {
210 err = PTR_ERR(port->wwan);
214 INIT_WORK(&port->del_work, wwan_hwsim_port_del_work);
216 snprintf(name, sizeof(name), "port%u", port->id);
217 port->debugfs_topdir = debugfs_create_dir(name, dev->debugfs_topdir);
218 debugfs_create_file("destroy", 0200, port->debugfs_topdir, port,
219 &wwan_hwsim_debugfs_portdestroy_fops);
229 static void wwan_hwsim_port_del(struct wwan_hwsim_port *port)
231 debugfs_remove(port->debugfs_topdir);
233 /* Make sure that there is no pending deletion work */
234 if (current_work() != &port->del_work)
235 cancel_work_sync(&port->del_work);
237 wwan_remove_port(port->wwan);
241 static void wwan_hwsim_port_del_work(struct work_struct *work)
243 struct wwan_hwsim_port *port =
244 container_of(work, typeof(*port), del_work);
245 struct wwan_hwsim_dev *dev = port->dev;
247 spin_lock(&dev->ports_lock);
248 if (list_empty(&port->list)) {
249 /* Someone else deleting port at the moment */
250 spin_unlock(&dev->ports_lock);
253 list_del_init(&port->list);
254 spin_unlock(&dev->ports_lock);
256 wwan_hwsim_port_del(port);
259 static void wwan_hwsim_dev_release(struct device *sysdev)
261 struct wwan_hwsim_dev *dev = container_of(sysdev, typeof(*dev), dev);
266 static struct wwan_hwsim_dev *wwan_hwsim_dev_new(void)
268 struct wwan_hwsim_dev *dev;
271 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
273 return ERR_PTR(-ENOMEM);
275 spin_lock(&wwan_hwsim_devs_lock);
276 dev->id = wwan_hwsim_dev_idx++;
277 spin_unlock(&wwan_hwsim_devs_lock);
279 dev->dev.release = wwan_hwsim_dev_release;
280 dev->dev.class = wwan_hwsim_class;
281 dev_set_name(&dev->dev, "hwsim%u", dev->id);
283 spin_lock_init(&dev->ports_lock);
284 INIT_LIST_HEAD(&dev->ports);
286 err = device_register(&dev->dev);
290 INIT_WORK(&dev->del_work, wwan_hwsim_dev_del_work);
292 err = wwan_register_ops(&dev->dev, &wwan_hwsim_wwan_rtnl_ops, dev, 1);
296 dev->debugfs_topdir = debugfs_create_dir(dev_name(&dev->dev),
297 wwan_hwsim_debugfs_topdir);
298 debugfs_create_file("destroy", 0200, dev->debugfs_topdir, dev,
299 &wwan_hwsim_debugfs_devdestroy_fops);
300 dev->debugfs_portcreate =
301 debugfs_create_file("portcreate", 0200,
302 dev->debugfs_topdir, dev,
303 &wwan_hwsim_debugfs_portcreate_fops);
308 device_unregister(&dev->dev);
309 /* Memory will be freed in the device release callback */
314 put_device(&dev->dev);
319 static void wwan_hwsim_dev_del(struct wwan_hwsim_dev *dev)
321 debugfs_remove(dev->debugfs_portcreate); /* Avoid new ports */
323 spin_lock(&dev->ports_lock);
324 while (!list_empty(&dev->ports)) {
325 struct wwan_hwsim_port *port;
327 port = list_first_entry(&dev->ports, struct wwan_hwsim_port,
329 list_del_init(&port->list);
330 spin_unlock(&dev->ports_lock);
331 wwan_hwsim_port_del(port);
332 spin_lock(&dev->ports_lock);
334 spin_unlock(&dev->ports_lock);
336 debugfs_remove(dev->debugfs_topdir);
338 /* This will remove all child netdev(s) */
339 wwan_unregister_ops(&dev->dev);
341 /* Make sure that there is no pending deletion work */
342 if (current_work() != &dev->del_work)
343 cancel_work_sync(&dev->del_work);
345 device_unregister(&dev->dev);
346 /* Memory will be freed in the device release callback */
349 static void wwan_hwsim_dev_del_work(struct work_struct *work)
351 struct wwan_hwsim_dev *dev = container_of(work, typeof(*dev), del_work);
353 spin_lock(&wwan_hwsim_devs_lock);
354 if (list_empty(&dev->list)) {
355 /* Someone else deleting device at the moment */
356 spin_unlock(&wwan_hwsim_devs_lock);
359 list_del_init(&dev->list);
360 spin_unlock(&wwan_hwsim_devs_lock);
362 wwan_hwsim_dev_del(dev);
365 static ssize_t wwan_hwsim_debugfs_portdestroy_write(struct file *file,
366 const char __user *usrbuf,
367 size_t count, loff_t *ppos)
369 struct wwan_hwsim_port *port = file->private_data;
371 /* We can not delete port here since it will cause a deadlock due to
372 * waiting this callback to finish in the debugfs_remove() call. So,
375 queue_work(wwan_wq, &port->del_work);
380 static const struct file_operations wwan_hwsim_debugfs_portdestroy_fops = {
381 .write = wwan_hwsim_debugfs_portdestroy_write,
383 .llseek = noop_llseek,
386 static ssize_t wwan_hwsim_debugfs_portcreate_write(struct file *file,
387 const char __user *usrbuf,
388 size_t count, loff_t *ppos)
390 struct wwan_hwsim_dev *dev = file->private_data;
391 struct wwan_hwsim_port *port;
393 port = wwan_hwsim_port_new(dev);
395 return PTR_ERR(port);
397 spin_lock(&dev->ports_lock);
398 list_add_tail(&port->list, &dev->ports);
399 spin_unlock(&dev->ports_lock);
404 static const struct file_operations wwan_hwsim_debugfs_portcreate_fops = {
405 .write = wwan_hwsim_debugfs_portcreate_write,
407 .llseek = noop_llseek,
410 static ssize_t wwan_hwsim_debugfs_devdestroy_write(struct file *file,
411 const char __user *usrbuf,
412 size_t count, loff_t *ppos)
414 struct wwan_hwsim_dev *dev = file->private_data;
416 /* We can not delete device here since it will cause a deadlock due to
417 * waiting this callback to finish in the debugfs_remove() call. So,
420 queue_work(wwan_wq, &dev->del_work);
425 static const struct file_operations wwan_hwsim_debugfs_devdestroy_fops = {
426 .write = wwan_hwsim_debugfs_devdestroy_write,
428 .llseek = noop_llseek,
431 static ssize_t wwan_hwsim_debugfs_devcreate_write(struct file *file,
432 const char __user *usrbuf,
433 size_t count, loff_t *ppos)
435 struct wwan_hwsim_dev *dev;
437 dev = wwan_hwsim_dev_new();
441 spin_lock(&wwan_hwsim_devs_lock);
442 list_add_tail(&dev->list, &wwan_hwsim_devs);
443 spin_unlock(&wwan_hwsim_devs_lock);
448 static const struct file_operations wwan_hwsim_debugfs_devcreate_fops = {
449 .write = wwan_hwsim_debugfs_devcreate_write,
451 .llseek = noop_llseek,
454 static int __init wwan_hwsim_init_devs(void)
456 struct wwan_hwsim_dev *dev;
459 for (i = 0; i < wwan_hwsim_devsnum; ++i) {
460 dev = wwan_hwsim_dev_new();
464 spin_lock(&wwan_hwsim_devs_lock);
465 list_add_tail(&dev->list, &wwan_hwsim_devs);
466 spin_unlock(&wwan_hwsim_devs_lock);
468 /* Create a couple of ports per each device to accelerate
469 * the simulator readiness time.
471 for (j = 0; j < 2; ++j) {
472 struct wwan_hwsim_port *port;
474 port = wwan_hwsim_port_new(dev);
476 return PTR_ERR(port);
478 spin_lock(&dev->ports_lock);
479 list_add_tail(&port->list, &dev->ports);
480 spin_unlock(&dev->ports_lock);
487 static void wwan_hwsim_free_devs(void)
489 struct wwan_hwsim_dev *dev;
491 spin_lock(&wwan_hwsim_devs_lock);
492 while (!list_empty(&wwan_hwsim_devs)) {
493 dev = list_first_entry(&wwan_hwsim_devs, struct wwan_hwsim_dev,
495 list_del_init(&dev->list);
496 spin_unlock(&wwan_hwsim_devs_lock);
497 wwan_hwsim_dev_del(dev);
498 spin_lock(&wwan_hwsim_devs_lock);
500 spin_unlock(&wwan_hwsim_devs_lock);
503 static int __init wwan_hwsim_init(void)
507 if (wwan_hwsim_devsnum < 0 || wwan_hwsim_devsnum > 128)
510 wwan_wq = alloc_workqueue("wwan_wq", 0, 0);
514 wwan_hwsim_class = class_create(THIS_MODULE, "wwan_hwsim");
515 if (IS_ERR(wwan_hwsim_class)) {
516 err = PTR_ERR(wwan_hwsim_class);
520 wwan_hwsim_debugfs_topdir = debugfs_create_dir("wwan_hwsim", NULL);
521 wwan_hwsim_debugfs_devcreate =
522 debugfs_create_file("devcreate", 0200,
523 wwan_hwsim_debugfs_topdir, NULL,
524 &wwan_hwsim_debugfs_devcreate_fops);
526 err = wwan_hwsim_init_devs();
533 debugfs_remove(wwan_hwsim_debugfs_devcreate); /* Avoid new devs */
534 wwan_hwsim_free_devs();
535 flush_workqueue(wwan_wq); /* Wait deletion works completion */
536 debugfs_remove(wwan_hwsim_debugfs_topdir);
537 class_destroy(wwan_hwsim_class);
539 destroy_workqueue(wwan_wq);
544 static void __exit wwan_hwsim_exit(void)
546 debugfs_remove(wwan_hwsim_debugfs_devcreate); /* Avoid new devs */
547 wwan_hwsim_free_devs();
548 flush_workqueue(wwan_wq); /* Wait deletion works completion */
549 debugfs_remove(wwan_hwsim_debugfs_topdir);
550 class_destroy(wwan_hwsim_class);
551 destroy_workqueue(wwan_wq);
554 module_init(wwan_hwsim_init);
555 module_exit(wwan_hwsim_exit);
557 MODULE_AUTHOR("Sergey Ryazanov");
558 MODULE_DESCRIPTION("Device simulator for WWAN framework");
559 MODULE_LICENSE("GPL");