Lines Matching +full:port +full:- +full:id
1 // SPDX-License-Identifier: GPL-2.0-only
27 static DEFINE_IDA(minors); /* minors for WWAN port chardevs */
38 /* WWAN port flags */
42 * struct wwan_device - The structure that defines a WWAN device
44 * @id: WWAN device unique ID.
46 * @port_id: Current available port ID to pick.
52 unsigned int id; member
63 * struct wwan_port - The structure that defines a WWAN port
64 * @type: Port type
65 * @start_count: Port start counter
66 * @flags: Store port state and capabilities
67 * @ops: Pointer to WWAN port operations
68 * @ops_lock: Protect port ops
71 * @waitqueue: The waitqueue for port fops (read/write/poll)
72 * @data_lock: Port specific data access serialization
75 * @at_data: AT port specific data
86 struct mutex data_lock; /* Port specific data access serialization */
101 return sprintf(buf, "%d\n", wwan->id); in index_show()
115 ida_free(&wwan_dev_ids, wwandev->id); in wwan_dev_destroy()
127 return (dev->type == &wwan_dev_type && in wwan_dev_parent_match()
128 (dev->parent == parent || dev == parent)); in wwan_dev_parent_match()
137 return ERR_PTR(-ENODEV); in wwan_dev_get_by_parent()
144 return dev->type == &wwan_dev_type && in wwan_dev_name_match()
154 return ERR_PTR(-ENODEV); in wwan_dev_get_by_name()
168 return wwandev->debugfs_dir; in wwan_get_debugfs_dir()
176 if (dev->type != &wwan_dev_type) in wwan_dev_debugfs_match()
181 return wwandev->debugfs_dir == dir; in wwan_dev_debugfs_match()
190 return ERR_PTR(-ENODEV); in wwan_dev_get_by_debugfs()
203 put_device(&wwandev->dev); in wwan_put_debugfs_dir()
204 put_device(&wwandev->dev); in wwan_put_debugfs_dir()
217 int err, id; in wwan_create_dev() local
219 /* The 'find-alloc-register' operation must be protected against in wwan_create_dev()
230 id = ida_alloc(&wwan_dev_ids, GFP_KERNEL); in wwan_create_dev()
231 if (id < 0) { in wwan_create_dev()
232 wwandev = ERR_PTR(id); in wwan_create_dev()
238 wwandev = ERR_PTR(-ENOMEM); in wwan_create_dev()
239 ida_free(&wwan_dev_ids, id); in wwan_create_dev()
243 wwandev->dev.parent = parent; in wwan_create_dev()
244 wwandev->dev.class = &wwan_class; in wwan_create_dev()
245 wwandev->dev.type = &wwan_dev_type; in wwan_create_dev()
246 wwandev->id = id; in wwan_create_dev()
247 dev_set_name(&wwandev->dev, "wwan%d", wwandev->id); in wwan_create_dev()
249 err = device_register(&wwandev->dev); in wwan_create_dev()
251 put_device(&wwandev->dev); in wwan_create_dev()
257 wwandev->debugfs_dir = in wwan_create_dev()
258 debugfs_create_dir(kobject_name(&wwandev->dev.kobj), in wwan_create_dev()
270 return dev->class == &wwan_class; in is_wwan_child()
281 * child port, and subsequent port registrations only grab a reference in wwan_remove_dev()
283 * its last port, and reference simply dropped (put) otherwise. In the in wwan_remove_dev()
286 if (wwandev->ops) in wwan_remove_dev()
289 ret = device_for_each_child(&wwandev->dev, NULL, is_wwan_child); in wwan_remove_dev()
293 debugfs_remove_recursive(wwandev->debugfs_dir); in wwan_remove_dev()
295 device_unregister(&wwandev->dev); in wwan_remove_dev()
297 put_device(&wwandev->dev); in wwan_remove_dev()
303 /* ------- WWAN port management ------- */
306 const char * const name; /* Port type name */
307 const char * const devsuf; /* Port device name suffix */
350 struct wwan_port *port = to_wwan_port(dev); in type_show() local
352 return sprintf(buf, "%s\n", wwan_port_types[port->type].name); in type_show()
364 struct wwan_port *port = to_wwan_port(dev); in wwan_port_destroy() local
366 ida_free(&minors, MINOR(port->dev.devt)); in wwan_port_destroy()
367 mutex_destroy(&port->data_lock); in wwan_port_destroy()
368 mutex_destroy(&port->ops_lock); in wwan_port_destroy()
369 kfree(port); in wwan_port_destroy()
380 return (dev->type == &wwan_port_dev_type && in wwan_port_minor_match()
381 MINOR(dev->devt) == *(unsigned int *)minor); in wwan_port_minor_match()
390 return ERR_PTR(-ENODEV); in wwan_port_get_by_minor()
400 * To avoid names collision, the caller must prevent the new port device
403 static int __wwan_port_dev_assign_name(struct wwan_port *port, const char *fmt) in __wwan_port_dev_assign_name() argument
405 struct wwan_device *wwandev = to_wwan_dev(port->dev.parent); in __wwan_port_dev_assign_name()
411 int id; in __wwan_port_dev_assign_name() local
415 return -ENOMEM; in __wwan_port_dev_assign_name()
420 if (dev->parent != &wwandev->dev) in __wwan_port_dev_assign_name()
422 if (sscanf(dev_name(dev), fmt, &id) != 1) in __wwan_port_dev_assign_name()
424 if (id < 0 || id >= max_ports) in __wwan_port_dev_assign_name()
426 set_bit(id, idmap); in __wwan_port_dev_assign_name()
430 /* Allocate unique id */ in __wwan_port_dev_assign_name()
431 id = find_first_zero_bit(idmap, max_ports); in __wwan_port_dev_assign_name()
434 snprintf(buf, sizeof(buf), fmt, id); /* Name generation */ in __wwan_port_dev_assign_name()
436 dev = device_find_child_by_name(&wwandev->dev, buf); in __wwan_port_dev_assign_name()
439 return -ENFILE; in __wwan_port_dev_assign_name()
442 return dev_set_name(&port->dev, "%s", buf); in __wwan_port_dev_assign_name()
452 struct wwan_port *port; in wwan_create_port() local
457 return ERR_PTR(-EINVAL); in wwan_create_port()
459 /* A port is always a child of a WWAN device, retrieve (allocate or in wwan_create_port()
466 /* A port is exposed as character device, get a minor */ in wwan_create_port()
467 minor = ida_alloc_range(&minors, 0, WWAN_MAX_MINORS - 1, GFP_KERNEL); in wwan_create_port()
473 port = kzalloc(sizeof(*port), GFP_KERNEL); in wwan_create_port()
474 if (!port) { in wwan_create_port()
475 err = -ENOMEM; in wwan_create_port()
480 port->type = type; in wwan_create_port()
481 port->ops = ops; in wwan_create_port()
482 port->frag_len = caps ? caps->frag_len : SIZE_MAX; in wwan_create_port()
483 port->headroom_len = caps ? caps->headroom_len : 0; in wwan_create_port()
484 mutex_init(&port->ops_lock); in wwan_create_port()
485 skb_queue_head_init(&port->rxq); in wwan_create_port()
486 init_waitqueue_head(&port->waitqueue); in wwan_create_port()
487 mutex_init(&port->data_lock); in wwan_create_port()
489 port->dev.parent = &wwandev->dev; in wwan_create_port()
490 port->dev.class = &wwan_class; in wwan_create_port()
491 port->dev.type = &wwan_port_dev_type; in wwan_create_port()
492 port->dev.devt = MKDEV(wwan_major, minor); in wwan_create_port()
493 dev_set_drvdata(&port->dev, drvdata); in wwan_create_port()
495 /* allocate unique name based on wwan device id, port type and number */ in wwan_create_port()
496 snprintf(namefmt, sizeof(namefmt), "wwan%u%s%%d", wwandev->id, in wwan_create_port()
497 wwan_port_types[port->type].devsuf); in wwan_create_port()
502 __wwan_port_dev_assign_name(port, namefmt); in wwan_create_port()
503 err = device_register(&port->dev); in wwan_create_port()
510 dev_info(&wwandev->dev, "port %s attached\n", dev_name(&port->dev)); in wwan_create_port()
511 return port; in wwan_create_port()
514 put_device(&port->dev); in wwan_create_port()
522 void wwan_remove_port(struct wwan_port *port) in wwan_remove_port() argument
524 struct wwan_device *wwandev = to_wwan_dev(port->dev.parent); in wwan_remove_port()
526 mutex_lock(&port->ops_lock); in wwan_remove_port()
527 if (port->start_count) in wwan_remove_port()
528 port->ops->stop(port); in wwan_remove_port()
529 port->ops = NULL; /* Prevent any new port operations (e.g. from fops) */ in wwan_remove_port()
530 mutex_unlock(&port->ops_lock); in wwan_remove_port()
532 wake_up_interruptible(&port->waitqueue); in wwan_remove_port()
534 skb_queue_purge(&port->rxq); in wwan_remove_port()
535 dev_set_drvdata(&port->dev, NULL); in wwan_remove_port()
537 dev_info(&wwandev->dev, "port %s disconnected\n", dev_name(&port->dev)); in wwan_remove_port()
538 device_unregister(&port->dev); in wwan_remove_port()
545 void wwan_port_rx(struct wwan_port *port, struct sk_buff *skb) in wwan_port_rx() argument
547 skb_queue_tail(&port->rxq, skb); in wwan_port_rx()
548 wake_up_interruptible(&port->waitqueue); in wwan_port_rx()
552 void wwan_port_txon(struct wwan_port *port) in wwan_port_txon() argument
554 clear_bit(WWAN_PORT_TX_OFF, &port->flags); in wwan_port_txon()
555 wake_up_interruptible(&port->waitqueue); in wwan_port_txon()
559 void wwan_port_txoff(struct wwan_port *port) in wwan_port_txoff() argument
561 set_bit(WWAN_PORT_TX_OFF, &port->flags); in wwan_port_txoff()
565 void *wwan_port_get_drvdata(struct wwan_port *port) in wwan_port_get_drvdata() argument
567 return dev_get_drvdata(&port->dev); in wwan_port_get_drvdata()
571 static int wwan_port_op_start(struct wwan_port *port) in wwan_port_op_start() argument
575 mutex_lock(&port->ops_lock); in wwan_port_op_start()
576 if (!port->ops) { /* Port got unplugged */ in wwan_port_op_start()
577 ret = -ENODEV; in wwan_port_op_start()
581 /* If port is already started, don't start again */ in wwan_port_op_start()
582 if (!port->start_count) in wwan_port_op_start()
583 ret = port->ops->start(port); in wwan_port_op_start()
586 port->start_count++; in wwan_port_op_start()
589 mutex_unlock(&port->ops_lock); in wwan_port_op_start()
594 static void wwan_port_op_stop(struct wwan_port *port) in wwan_port_op_stop() argument
596 mutex_lock(&port->ops_lock); in wwan_port_op_stop()
597 port->start_count--; in wwan_port_op_stop()
598 if (!port->start_count) { in wwan_port_op_stop()
599 if (port->ops) in wwan_port_op_stop()
600 port->ops->stop(port); in wwan_port_op_stop()
601 skb_queue_purge(&port->rxq); in wwan_port_op_stop()
603 mutex_unlock(&port->ops_lock); in wwan_port_op_stop()
606 static int wwan_port_op_tx(struct wwan_port *port, struct sk_buff *skb, in wwan_port_op_tx() argument
611 mutex_lock(&port->ops_lock); in wwan_port_op_tx()
612 if (!port->ops) { /* Port got unplugged */ in wwan_port_op_tx()
613 ret = -ENODEV; in wwan_port_op_tx()
617 if (nonblock || !port->ops->tx_blocking) in wwan_port_op_tx()
618 ret = port->ops->tx(port, skb); in wwan_port_op_tx()
620 ret = port->ops->tx_blocking(port, skb); in wwan_port_op_tx()
623 mutex_unlock(&port->ops_lock); in wwan_port_op_tx()
628 static bool is_read_blocked(struct wwan_port *port) in is_read_blocked() argument
630 return skb_queue_empty(&port->rxq) && port->ops; in is_read_blocked()
633 static bool is_write_blocked(struct wwan_port *port) in is_write_blocked() argument
635 return test_bit(WWAN_PORT_TX_OFF, &port->flags) && port->ops; in is_write_blocked()
638 static int wwan_wait_rx(struct wwan_port *port, bool nonblock) in wwan_wait_rx() argument
640 if (!is_read_blocked(port)) in wwan_wait_rx()
644 return -EAGAIN; in wwan_wait_rx()
646 if (wait_event_interruptible(port->waitqueue, !is_read_blocked(port))) in wwan_wait_rx()
647 return -ERESTARTSYS; in wwan_wait_rx()
652 static int wwan_wait_tx(struct wwan_port *port, bool nonblock) in wwan_wait_tx() argument
654 if (!is_write_blocked(port)) in wwan_wait_tx()
658 return -EAGAIN; in wwan_wait_tx()
660 if (wait_event_interruptible(port->waitqueue, !is_write_blocked(port))) in wwan_wait_tx()
661 return -ERESTARTSYS; in wwan_wait_tx()
668 struct wwan_port *port; in wwan_port_fops_open() local
671 port = wwan_port_get_by_minor(iminor(inode)); in wwan_port_fops_open()
672 if (IS_ERR(port)) in wwan_port_fops_open()
673 return PTR_ERR(port); in wwan_port_fops_open()
675 file->private_data = port; in wwan_port_fops_open()
678 err = wwan_port_op_start(port); in wwan_port_fops_open()
680 put_device(&port->dev); in wwan_port_fops_open()
687 struct wwan_port *port = filp->private_data; in wwan_port_fops_release() local
689 wwan_port_op_stop(port); in wwan_port_fops_release()
690 put_device(&port->dev); in wwan_port_fops_release()
698 struct wwan_port *port = filp->private_data; in wwan_port_fops_read() local
703 ret = wwan_wait_rx(port, !!(filp->f_flags & O_NONBLOCK)); in wwan_port_fops_read()
707 skb = skb_dequeue(&port->rxq); in wwan_port_fops_read()
709 return -EIO; in wwan_port_fops_read()
711 copied = min_t(size_t, count, skb->len); in wwan_port_fops_read()
712 if (copy_to_user(buf, skb->data, copied)) { in wwan_port_fops_read()
714 return -EFAULT; in wwan_port_fops_read()
719 if (skb->len) in wwan_port_fops_read()
720 skb_queue_head(&port->rxq, skb); in wwan_port_fops_read()
731 struct wwan_port *port = filp->private_data; in wwan_port_fops_write() local
735 ret = wwan_wait_tx(port, !!(filp->f_flags & O_NONBLOCK)); in wwan_port_fops_write()
740 frag_len = min(remain, port->frag_len); in wwan_port_fops_write()
741 skb = alloc_skb(frag_len + port->headroom_len, GFP_KERNEL); in wwan_port_fops_write()
743 ret = -ENOMEM; in wwan_port_fops_write()
746 skb_reserve(skb, port->headroom_len); in wwan_port_fops_write()
751 skb_shinfo(head)->frag_list = skb; in wwan_port_fops_write()
754 tail->next = skb; in wwan_port_fops_write()
758 if (copy_from_user(skb_put(skb, frag_len), buf + count - remain, frag_len)) { in wwan_port_fops_write()
759 ret = -EFAULT; in wwan_port_fops_write()
764 head->data_len += skb->len; in wwan_port_fops_write()
765 head->len += skb->len; in wwan_port_fops_write()
766 head->truesize += skb->truesize; in wwan_port_fops_write()
768 } while (remain -= frag_len); in wwan_port_fops_write()
770 ret = wwan_port_op_tx(port, head, !!(filp->f_flags & O_NONBLOCK)); in wwan_port_fops_write()
781 struct wwan_port *port = filp->private_data; in wwan_port_fops_poll() local
784 poll_wait(filp, &port->waitqueue, wait); in wwan_port_fops_poll()
786 mutex_lock(&port->ops_lock); in wwan_port_fops_poll()
787 if (port->ops && port->ops->tx_poll) in wwan_port_fops_poll()
788 mask |= port->ops->tx_poll(port, filp, wait); in wwan_port_fops_poll()
789 else if (!is_write_blocked(port)) in wwan_port_fops_poll()
791 if (!is_read_blocked(port)) in wwan_port_fops_poll()
793 if (!port->ops) in wwan_port_fops_poll()
795 mutex_unlock(&port->ops_lock); in wwan_port_fops_poll()
801 static long wwan_port_fops_at_ioctl(struct wwan_port *port, unsigned int cmd, in wwan_port_fops_at_ioctl() argument
806 mutex_lock(&port->data_lock); in wwan_port_fops_at_ioctl()
813 if (copy_to_user((void __user *)arg, &port->at_data.termios, in wwan_port_fops_at_ioctl()
815 ret = -EFAULT; in wwan_port_fops_at_ioctl()
821 if (copy_from_user(&port->at_data.termios, (void __user *)arg, in wwan_port_fops_at_ioctl()
823 ret = -EFAULT; in wwan_port_fops_at_ioctl()
828 if (copy_to_user((void __user *)arg, &port->at_data.termios, in wwan_port_fops_at_ioctl()
830 ret = -EFAULT; in wwan_port_fops_at_ioctl()
836 if (copy_from_user(&port->at_data.termios, (void __user *)arg, in wwan_port_fops_at_ioctl()
838 ret = -EFAULT; in wwan_port_fops_at_ioctl()
843 ret = put_user(port->at_data.mdmbits, (int __user *)arg); in wwan_port_fops_at_ioctl()
852 ret = -EFAULT; in wwan_port_fops_at_ioctl()
856 port->at_data.mdmbits &= ~mdmbits; in wwan_port_fops_at_ioctl()
858 port->at_data.mdmbits |= mdmbits; in wwan_port_fops_at_ioctl()
860 port->at_data.mdmbits = mdmbits; in wwan_port_fops_at_ioctl()
865 ret = -ENOIOCTLCMD; in wwan_port_fops_at_ioctl()
868 mutex_unlock(&port->data_lock); in wwan_port_fops_at_ioctl()
876 struct wwan_port *port = filp->private_data; in wwan_port_fops_ioctl() local
879 if (port->type == WWAN_PORT_AT) { /* AT port specific IOCTLs */ in wwan_port_fops_ioctl()
880 res = wwan_port_fops_at_ioctl(port, cmd, arg); in wwan_port_fops_ioctl()
881 if (res != -ENOIOCTLCMD) in wwan_port_fops_ioctl()
891 spin_lock_irqsave(&port->rxq.lock, flags); in wwan_port_fops_ioctl()
892 skb_queue_walk(&port->rxq, skb) in wwan_port_fops_ioctl()
893 amount += skb->len; in wwan_port_fops_ioctl()
894 spin_unlock_irqrestore(&port->rxq.lock, flags); in wwan_port_fops_ioctl()
900 return -ENOIOCTLCMD; in wwan_port_fops_ioctl()
922 return -EINVAL; in wwan_rtnl_validate()
925 return -EINVAL; in wwan_rtnl_validate()
928 return -EINVAL; in wwan_rtnl_validate()
950 if (!wwandev->ops) { in wwan_rtnl_alloc()
951 dev = ERR_PTR(-EOPNOTSUPP); in wwan_rtnl_alloc()
955 priv_size = sizeof(struct wwan_netdev_priv) + wwandev->ops->priv_size; in wwan_rtnl_alloc()
957 wwandev->ops->setup, num_tx_queues, num_rx_queues); in wwan_rtnl_alloc()
960 SET_NETDEV_DEV(dev, &wwandev->dev); in wwan_rtnl_alloc()
966 put_device(&wwandev->dev); in wwan_rtnl_alloc()
974 struct wwan_device *wwandev = wwan_dev_get_by_parent(dev->dev.parent); in wwan_rtnl_newlink()
976 struct nlattr **data = params->data; in wwan_rtnl_newlink()
986 if (WARN_ON(!wwandev->ops)) { in wwan_rtnl_newlink()
987 ret = -EOPNOTSUPP; in wwan_rtnl_newlink()
991 priv->link_id = link_id; in wwan_rtnl_newlink()
992 if (wwandev->ops->newlink) in wwan_rtnl_newlink()
993 ret = wwandev->ops->newlink(wwandev->ops_ctxt, dev, in wwan_rtnl_newlink()
1000 put_device(&wwandev->dev); in wwan_rtnl_newlink()
1006 struct wwan_device *wwandev = wwan_dev_get_by_parent(dev->dev.parent); in wwan_rtnl_dellink()
1012 if (WARN_ON(!wwandev->ops)) in wwan_rtnl_dellink()
1015 if (wwandev->ops->dellink) in wwan_rtnl_dellink()
1016 wwandev->ops->dellink(wwandev->ops_ctxt, dev, head); in wwan_rtnl_dellink()
1022 put_device(&wwandev->dev); in wwan_rtnl_dellink()
1037 if (nla_put_u32(skb, IFLA_WWAN_LINK_ID, priv->link_id)) in wwan_rtnl_fill_info()
1043 return -EMSGSIZE; in wwan_rtnl_fill_info()
1087 if (nla_put_string(msg, IFLA_PARENT_DEV_NAME, dev_name(&wwandev->dev))) in wwan_create_default_link()
1131 * wwan_register_ops - register WWAN device ops
1136 * @def_link_id: id of the default link that will be automatically created by
1147 if (WARN_ON(!parent || !ops || !ops->setup)) in wwan_register_ops()
1148 return -EINVAL; in wwan_register_ops()
1154 if (WARN_ON(wwandev->ops)) { in wwan_register_ops()
1156 return -EBUSY; in wwan_register_ops()
1159 wwandev->ops = ops; in wwan_register_ops()
1160 wwandev->ops_ctxt = ctxt; in wwan_register_ops()
1180 if (dev->type == &wwan_type) in wwan_child_dellink()
1187 * wwan_unregister_ops - remove WWAN device ops
1198 if (WARN_ON(!wwandev->ops)) { in wwan_unregister_ops()
1199 put_device(&wwandev->dev); in wwan_unregister_ops()
1207 put_device(&wwandev->dev); in wwan_unregister_ops()
1212 device_for_each_child(&wwandev->dev, &kill_list, in wwan_unregister_ops()
1216 wwandev->ops = NULL; /* Finally remove ops */ in wwan_unregister_ops()
1220 wwandev->ops_ctxt = NULL; in wwan_unregister_ops()