0001
0002
0003
0004
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
0032 #define CAIF_FLOW_OFF_SENT 4
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
0172
0173
0174
0175
0176
0177
0178
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
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
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
0218 if (test_and_set_bit(CAIF_SENDING, &ser->state))
0219 return 0;
0220
0221
0222 while ((skb = skb_peek(&ser->head)) != NULL) {
0223
0224
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
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
0246 if (tty_wr < 0)
0247 goto error;
0248
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
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
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
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
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
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);