Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) ST-Ericsson AB 2010
0004  * Author:  Sjur Brendeland
0005  */
0006 
0007 #include <linux/hardirq.h>
0008 #include <linux/init.h>
0009 #include <linux/module.h>
0010 #include <linux/device.h>
0011 #include <linux/types.h>
0012 #include <linux/skbuff.h>
0013 #include <linux/netdevice.h>
0014 #include <linux/rtnetlink.h>
0015 #include <linux/tty.h>
0016 #include <linux/file.h>
0017 #include <linux/if_arp.h>
0018 #include <net/caif/caif_device.h>
0019 #include <net/caif/cfcnfg.h>
0020 #include <linux/err.h>
0021 #include <linux/debugfs.h>
0022 
0023 MODULE_LICENSE("GPL");
0024 MODULE_AUTHOR("Sjur Brendeland");
0025 MODULE_DESCRIPTION("CAIF serial device TTY line discipline");
0026 MODULE_LICENSE("GPL");
0027 MODULE_ALIAS_LDISC(N_CAIF);
0028 
0029 #define SEND_QUEUE_LOW 10
0030 #define SEND_QUEUE_HIGH 100
0031 #define CAIF_SENDING            1 /* Bit 1 = 0x02*/
0032 #define CAIF_FLOW_OFF_SENT  4 /* Bit 4 = 0x10 */
0033 #define MAX_WRITE_CHUNK      4096
0034 #define ON 1
0035 #define OFF 0
0036 #define CAIF_MAX_MTU 4096
0037 
0038 static DEFINE_SPINLOCK(ser_lock);
0039 static LIST_HEAD(ser_list);
0040 static LIST_HEAD(ser_release_list);
0041 
0042 static bool ser_loop;
0043 module_param(ser_loop, bool, 0444);
0044 MODULE_PARM_DESC(ser_loop, "Run in simulated loopback mode.");
0045 
0046 static bool ser_use_stx = true;
0047 module_param(ser_use_stx, bool, 0444);
0048 MODULE_PARM_DESC(ser_use_stx, "STX enabled or not.");
0049 
0050 static bool ser_use_fcs = true;
0051 
0052 module_param(ser_use_fcs, bool, 0444);
0053 MODULE_PARM_DESC(ser_use_fcs, "FCS enabled or not.");
0054 
0055 static int ser_write_chunk = MAX_WRITE_CHUNK;
0056 module_param(ser_write_chunk, int, 0444);
0057 
0058 MODULE_PARM_DESC(ser_write_chunk, "Maximum size of data written to UART.");
0059 
0060 static struct dentry *debugfsdir;
0061 
0062 static int caif_net_open(struct net_device *dev);
0063 static int caif_net_close(struct net_device *dev);
0064 
0065 struct ser_device {
0066     struct caif_dev_common common;
0067     struct list_head node;
0068     struct net_device *dev;
0069     struct sk_buff_head head;
0070     struct tty_struct *tty;
0071     bool tx_started;
0072     unsigned long state;
0073 #ifdef CONFIG_DEBUG_FS
0074     struct dentry *debugfs_tty_dir;
0075     struct debugfs_blob_wrapper tx_blob;
0076     struct debugfs_blob_wrapper rx_blob;
0077     u8 rx_data[128];
0078     u8 tx_data[128];
0079     u8 tty_status;
0080 
0081 #endif
0082 };
0083 
0084 static void caifdev_setup(struct net_device *dev);
0085 static void ldisc_tx_wakeup(struct tty_struct *tty);
0086 #ifdef CONFIG_DEBUG_FS
0087 static inline void update_tty_status(struct ser_device *ser)
0088 {
0089     ser->tty_status =
0090         ser->tty->flow.stopped << 5 |
0091         ser->tty->flow.tco_stopped << 3 |
0092         ser->tty->ctrl.packet << 2;
0093 }
0094 static inline void debugfs_init(struct ser_device *ser, struct tty_struct *tty)
0095 {
0096     ser->debugfs_tty_dir = debugfs_create_dir(tty->name, debugfsdir);
0097 
0098     debugfs_create_blob("last_tx_msg", 0400, ser->debugfs_tty_dir,
0099                 &ser->tx_blob);
0100 
0101     debugfs_create_blob("last_rx_msg", 0400, ser->debugfs_tty_dir,
0102                 &ser->rx_blob);
0103 
0104     debugfs_create_xul("ser_state", 0400, ser->debugfs_tty_dir,
0105                &ser->state);
0106 
0107     debugfs_create_x8("tty_status", 0400, ser->debugfs_tty_dir,
0108               &ser->tty_status);
0109 
0110     ser->tx_blob.data = ser->tx_data;
0111     ser->tx_blob.size = 0;
0112     ser->rx_blob.data = ser->rx_data;
0113     ser->rx_blob.size = 0;
0114 }
0115 
0116 static inline void debugfs_deinit(struct ser_device *ser)
0117 {
0118     debugfs_remove_recursive(ser->debugfs_tty_dir);
0119 }
0120 
0121 static inline void debugfs_rx(struct ser_device *ser, const u8 *data, int size)
0122 {
0123     if (size > sizeof(ser->rx_data))
0124         size = sizeof(ser->rx_data);
0125     memcpy(ser->rx_data, data, size);
0126     ser->rx_blob.data = ser->rx_data;
0127     ser->rx_blob.size = size;
0128 }
0129 
0130 static inline void debugfs_tx(struct ser_device *ser, const u8 *data, int size)
0131 {
0132     if (size > sizeof(ser->tx_data))
0133         size = sizeof(ser->tx_data);
0134     memcpy(ser->tx_data, data, size);
0135     ser->tx_blob.data = ser->tx_data;
0136     ser->tx_blob.size = size;
0137 }
0138 #else
0139 static inline void debugfs_init(struct ser_device *ser, struct tty_struct *tty)
0140 {
0141 }
0142 
0143 static inline void debugfs_deinit(struct ser_device *ser)
0144 {
0145 }
0146 
0147 static inline void update_tty_status(struct ser_device *ser)
0148 {
0149 }
0150 
0151 static inline void debugfs_rx(struct ser_device *ser, const u8 *data, int size)
0152 {
0153 }
0154 
0155 static inline void debugfs_tx(struct ser_device *ser, const u8 *data, int size)
0156 {
0157 }
0158 
0159 #endif
0160 
0161 static void ldisc_receive(struct tty_struct *tty, const u8 *data,
0162             const char *flags, int count)
0163 {
0164     struct sk_buff *skb = NULL;
0165     struct ser_device *ser;
0166     int ret;
0167 
0168     ser = tty->disc_data;
0169 
0170     /*
0171      * NOTE: flags may contain information about break or overrun.
0172      * This is not yet handled.
0173      */
0174 
0175 
0176     /*
0177      * Workaround for garbage at start of transmission,
0178      * only enable if STX handling is not enabled.
0179      */
0180     if (!ser->common.use_stx && !ser->tx_started) {
0181         dev_info(&ser->dev->dev,
0182             "Bytes received before initial transmission -"
0183             "bytes discarded.\n");
0184         return;
0185     }
0186 
0187     BUG_ON(ser->dev == NULL);
0188 
0189     /* Get a suitable caif packet and copy in data. */
0190     skb = netdev_alloc_skb(ser->dev, count+1);
0191     if (skb == NULL)
0192         return;
0193     skb_put_data(skb, data, count);
0194 
0195     skb->protocol = htons(ETH_P_CAIF);
0196     skb_reset_mac_header(skb);
0197     debugfs_rx(ser, data, count);
0198     /* Push received packet up the stack. */
0199     ret = netif_rx(skb);
0200     if (!ret) {
0201         ser->dev->stats.rx_packets++;
0202         ser->dev->stats.rx_bytes += count;
0203     } else
0204         ++ser->dev->stats.rx_dropped;
0205     update_tty_status(ser);
0206 }
0207 
0208 static int handle_tx(struct ser_device *ser)
0209 {
0210     struct tty_struct *tty;
0211     struct sk_buff *skb;
0212     int tty_wr, len, room;
0213 
0214     tty = ser->tty;
0215     ser->tx_started = true;
0216 
0217     /* Enter critical section */
0218     if (test_and_set_bit(CAIF_SENDING, &ser->state))
0219         return 0;
0220 
0221     /* skb_peek is safe because handle_tx is called after skb_queue_tail */
0222     while ((skb = skb_peek(&ser->head)) != NULL) {
0223 
0224         /* Make sure you don't write too much */
0225         len = skb->len;
0226         room = tty_write_room(tty);
0227         if (!room)
0228             break;
0229         if (room > ser_write_chunk)
0230             room = ser_write_chunk;
0231         if (len > room)
0232             len = room;
0233 
0234         /* Write to tty or loopback */
0235         if (!ser_loop) {
0236             tty_wr = tty->ops->write(tty, skb->data, len);
0237             update_tty_status(ser);
0238         } else {
0239             tty_wr = len;
0240             ldisc_receive(tty, skb->data, NULL, len);
0241         }
0242         ser->dev->stats.tx_packets++;
0243         ser->dev->stats.tx_bytes += tty_wr;
0244 
0245         /* Error on TTY ?! */
0246         if (tty_wr < 0)
0247             goto error;
0248         /* Reduce buffer written, and discard if empty */
0249         skb_pull(skb, tty_wr);
0250         if (skb->len == 0) {
0251             struct sk_buff *tmp = skb_dequeue(&ser->head);
0252             WARN_ON(tmp != skb);
0253             dev_consume_skb_any(skb);
0254         }
0255     }
0256     /* Send flow off if queue is empty */
0257     if (ser->head.qlen <= SEND_QUEUE_LOW &&
0258         test_and_clear_bit(CAIF_FLOW_OFF_SENT, &ser->state) &&
0259         ser->common.flowctrl != NULL)
0260                 ser->common.flowctrl(ser->dev, ON);
0261     clear_bit(CAIF_SENDING, &ser->state);
0262     return 0;
0263 error:
0264     clear_bit(CAIF_SENDING, &ser->state);
0265     return tty_wr;
0266 }
0267 
0268 static netdev_tx_t caif_xmit(struct sk_buff *skb, struct net_device *dev)
0269 {
0270     struct ser_device *ser;
0271 
0272     ser = netdev_priv(dev);
0273 
0274     /* Send flow off once, on high water mark */
0275     if (ser->head.qlen > SEND_QUEUE_HIGH &&
0276         !test_and_set_bit(CAIF_FLOW_OFF_SENT, &ser->state) &&
0277         ser->common.flowctrl != NULL)
0278 
0279         ser->common.flowctrl(ser->dev, OFF);
0280 
0281     skb_queue_tail(&ser->head, skb);
0282     return handle_tx(ser);
0283 }
0284 
0285 
0286 static void ldisc_tx_wakeup(struct tty_struct *tty)
0287 {
0288     struct ser_device *ser;
0289 
0290     ser = tty->disc_data;
0291     BUG_ON(ser == NULL);
0292     WARN_ON(ser->tty != tty);
0293     handle_tx(ser);
0294 }
0295 
0296 
0297 static void ser_release(struct work_struct *work)
0298 {
0299     struct list_head list;
0300     struct ser_device *ser, *tmp;
0301 
0302     spin_lock(&ser_lock);
0303     list_replace_init(&ser_release_list, &list);
0304     spin_unlock(&ser_lock);
0305 
0306     if (!list_empty(&list)) {
0307         rtnl_lock();
0308         list_for_each_entry_safe(ser, tmp, &list, node) {
0309             dev_close(ser->dev);
0310             unregister_netdevice(ser->dev);
0311             debugfs_deinit(ser);
0312         }
0313         rtnl_unlock();
0314     }
0315 }
0316 
0317 static DECLARE_WORK(ser_release_work, ser_release);
0318 
0319 static int ldisc_open(struct tty_struct *tty)
0320 {
0321     struct ser_device *ser;
0322     struct net_device *dev;
0323     char name[64];
0324     int result;
0325 
0326     /* No write no play */
0327     if (tty->ops->write == NULL)
0328         return -EOPNOTSUPP;
0329     if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_TTY_CONFIG))
0330         return -EPERM;
0331 
0332     /* release devices to avoid name collision */
0333     ser_release(NULL);
0334 
0335     result = snprintf(name, sizeof(name), "cf%s", tty->name);
0336     if (result >= IFNAMSIZ)
0337         return -EINVAL;
0338     dev = alloc_netdev(sizeof(*ser), name, NET_NAME_UNKNOWN,
0339                caifdev_setup);
0340     if (!dev)
0341         return -ENOMEM;
0342 
0343     ser = netdev_priv(dev);
0344     ser->tty = tty_kref_get(tty);
0345     ser->dev = dev;
0346     debugfs_init(ser, tty);
0347     tty->receive_room = N_TTY_BUF_SIZE;
0348     tty->disc_data = ser;
0349     set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
0350     rtnl_lock();
0351     result = register_netdevice(dev);
0352     if (result) {
0353         tty_kref_put(tty);
0354         rtnl_unlock();
0355         free_netdev(dev);
0356         return -ENODEV;
0357     }
0358 
0359     spin_lock(&ser_lock);
0360     list_add(&ser->node, &ser_list);
0361     spin_unlock(&ser_lock);
0362     rtnl_unlock();
0363     netif_stop_queue(dev);
0364     update_tty_status(ser);
0365     return 0;
0366 }
0367 
0368 static void ldisc_close(struct tty_struct *tty)
0369 {
0370     struct ser_device *ser = tty->disc_data;
0371 
0372     tty_kref_put(ser->tty);
0373 
0374     spin_lock(&ser_lock);
0375     list_move(&ser->node, &ser_release_list);
0376     spin_unlock(&ser_lock);
0377     schedule_work(&ser_release_work);
0378 }
0379 
0380 /* The line discipline structure. */
0381 static struct tty_ldisc_ops caif_ldisc = {
0382     .owner =    THIS_MODULE,
0383     .num =      N_CAIF,
0384     .name =     "n_caif",
0385     .open =     ldisc_open,
0386     .close =    ldisc_close,
0387     .receive_buf =  ldisc_receive,
0388     .write_wakeup = ldisc_tx_wakeup
0389 };
0390 
0391 static const struct net_device_ops netdev_ops = {
0392     .ndo_open = caif_net_open,
0393     .ndo_stop = caif_net_close,
0394     .ndo_start_xmit = caif_xmit
0395 };
0396 
0397 static void caifdev_setup(struct net_device *dev)
0398 {
0399     struct ser_device *serdev = netdev_priv(dev);
0400 
0401     dev->features = 0;
0402     dev->netdev_ops = &netdev_ops;
0403     dev->type = ARPHRD_CAIF;
0404     dev->flags = IFF_POINTOPOINT | IFF_NOARP;
0405     dev->mtu = CAIF_MAX_MTU;
0406     dev->priv_flags |= IFF_NO_QUEUE;
0407     dev->needs_free_netdev = true;
0408     skb_queue_head_init(&serdev->head);
0409     serdev->common.link_select = CAIF_LINK_LOW_LATENCY;
0410     serdev->common.use_frag = true;
0411     serdev->common.use_stx = ser_use_stx;
0412     serdev->common.use_fcs = ser_use_fcs;
0413     serdev->dev = dev;
0414 }
0415 
0416 
0417 static int caif_net_open(struct net_device *dev)
0418 {
0419     netif_wake_queue(dev);
0420     return 0;
0421 }
0422 
0423 static int caif_net_close(struct net_device *dev)
0424 {
0425     netif_stop_queue(dev);
0426     return 0;
0427 }
0428 
0429 static int __init caif_ser_init(void)
0430 {
0431     int ret;
0432 
0433     ret = tty_register_ldisc(&caif_ldisc);
0434     if (ret < 0)
0435         pr_err("cannot register CAIF ldisc=%d err=%d\n", N_CAIF, ret);
0436 
0437     debugfsdir = debugfs_create_dir("caif_serial", NULL);
0438     return ret;
0439 }
0440 
0441 static void __exit caif_ser_exit(void)
0442 {
0443     spin_lock(&ser_lock);
0444     list_splice(&ser_list, &ser_release_list);
0445     spin_unlock(&ser_lock);
0446     ser_release(NULL);
0447     cancel_work_sync(&ser_release_work);
0448     tty_unregister_ldisc(&caif_ldisc);
0449     debugfs_remove_recursive(debugfsdir);
0450 }
0451 
0452 module_init(caif_ser_init);
0453 module_exit(caif_ser_exit);