1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 *
4 * arch/xtensa/platforms/iss/network.c
5 *
6 * Platform specific initialization.
7 *
8 * Authors: Chris Zankel <chris@zankel.net>
9 * Based on work form the UML team.
10 *
11 * Copyright 2005 Tensilica Inc.
12 */
13
14 #define pr_fmt(fmt) "%s: " fmt, __func__
15
16 #include <linux/hex.h>
17 #include <linux/list.h>
18 #include <linux/irq.h>
19 #include <linux/spinlock.h>
20 #include <linux/slab.h>
21 #include <linux/timer.h>
22 #include <linux/if_ether.h>
23 #include <linux/inetdevice.h>
24 #include <linux/init.h>
25 #include <linux/if_tun.h>
26 #include <linux/etherdevice.h>
27 #include <linux/interrupt.h>
28 #include <linux/ioctl.h>
29 #include <linux/memblock.h>
30 #include <linux/ethtool.h>
31 #include <linux/rtnetlink.h>
32 #include <linux/platform_device.h>
33
34 #include <platform/simcall.h>
35
36 #define DRIVER_NAME "iss-netdev"
37 #define ETH_MAX_PACKET 1500
38 #define ETH_HEADER_OTHER 14
39 #define ISS_NET_TIMER_VALUE (HZ / 10)
40
41 /* ------------------------------------------------------------------------- */
42
43 /* We currently only support the TUNTAP transport protocol. */
44
45 #define TRANSPORT_TUNTAP_NAME "tuntap"
46 #define TRANSPORT_TUNTAP_MTU ETH_MAX_PACKET
47
48 struct tuntap_info {
49 char dev_name[IFNAMSIZ];
50 int fd;
51 };
52
53 /* ------------------------------------------------------------------------- */
54
55
56 struct iss_net_private;
57
58 struct iss_net_ops {
59 int (*open)(struct iss_net_private *lp);
60 void (*close)(struct iss_net_private *lp);
61 int (*read)(struct iss_net_private *lp, struct sk_buff **skb);
62 int (*write)(struct iss_net_private *lp, struct sk_buff **skb);
63 unsigned short (*protocol)(struct sk_buff *skb);
64 int (*poll)(struct iss_net_private *lp);
65 };
66
67 /* This structure contains out private information for the driver. */
68
69 struct iss_net_private {
70 spinlock_t lock;
71 struct net_device *dev;
72 struct platform_device pdev;
73 struct timer_list tl;
74 struct rtnl_link_stats64 stats;
75
76 struct timer_list timer;
77 unsigned int timer_val;
78
79 int index;
80 int mtu;
81
82 struct {
83 union {
84 struct tuntap_info tuntap;
85 } info;
86
87 const struct iss_net_ops *net_ops;
88 } tp;
89
90 };
91
92 /* ================================ HELPERS ================================ */
93
94
split_if_spec(char * str,...)95 static char *split_if_spec(char *str, ...)
96 {
97 char **arg, *end;
98 va_list ap;
99
100 va_start(ap, str);
101 while ((arg = va_arg(ap, char**)) != NULL) {
102 if (*str == '\0') {
103 va_end(ap);
104 return NULL;
105 }
106 end = strchr(str, ',');
107 if (end != str)
108 *arg = str;
109 if (end == NULL) {
110 va_end(ap);
111 return NULL;
112 }
113 *end++ = '\0';
114 str = end;
115 }
116 va_end(ap);
117 return str;
118 }
119
120 /* Set Ethernet address of the specified device. */
121
setup_etheraddr(struct net_device * dev,char * str)122 static void setup_etheraddr(struct net_device *dev, char *str)
123 {
124 u8 addr[ETH_ALEN];
125
126 if (str == NULL)
127 goto random;
128
129 if (!mac_pton(str, addr)) {
130 pr_err("%s: failed to parse '%s' as an ethernet address\n",
131 dev->name, str);
132 goto random;
133 }
134 if (is_multicast_ether_addr(addr)) {
135 pr_err("%s: attempt to assign a multicast ethernet address\n",
136 dev->name);
137 goto random;
138 }
139 if (!is_valid_ether_addr(addr)) {
140 pr_err("%s: attempt to assign an invalid ethernet address\n",
141 dev->name);
142 goto random;
143 }
144 if (!is_local_ether_addr(addr))
145 pr_warn("%s: assigning a globally valid ethernet address\n",
146 dev->name);
147 eth_hw_addr_set(dev, addr);
148 return;
149
150 random:
151 pr_info("%s: choosing a random ethernet address\n",
152 dev->name);
153 eth_hw_addr_random(dev);
154 }
155
156 /* ======================= TUNTAP TRANSPORT INTERFACE ====================== */
157
tuntap_open(struct iss_net_private * lp)158 static int tuntap_open(struct iss_net_private *lp)
159 {
160 struct ifreq ifr;
161 char *dev_name = lp->tp.info.tuntap.dev_name;
162 int err = -EINVAL;
163 int fd;
164
165 fd = simc_open("/dev/net/tun", 02, 0); /* O_RDWR */
166 if (fd < 0) {
167 pr_err("%s: failed to open /dev/net/tun, returned %d (errno = %d)\n",
168 lp->dev->name, fd, errno);
169 return fd;
170 }
171
172 memset(&ifr, 0, sizeof(ifr));
173 ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
174 strscpy(ifr.ifr_name, dev_name, sizeof(ifr.ifr_name));
175
176 err = simc_ioctl(fd, TUNSETIFF, &ifr);
177 if (err < 0) {
178 pr_err("%s: failed to set interface %s, returned %d (errno = %d)\n",
179 lp->dev->name, dev_name, err, errno);
180 simc_close(fd);
181 return err;
182 }
183
184 lp->tp.info.tuntap.fd = fd;
185 return err;
186 }
187
tuntap_close(struct iss_net_private * lp)188 static void tuntap_close(struct iss_net_private *lp)
189 {
190 simc_close(lp->tp.info.tuntap.fd);
191 lp->tp.info.tuntap.fd = -1;
192 }
193
tuntap_read(struct iss_net_private * lp,struct sk_buff ** skb)194 static int tuntap_read(struct iss_net_private *lp, struct sk_buff **skb)
195 {
196 return simc_read(lp->tp.info.tuntap.fd,
197 (*skb)->data, (*skb)->dev->mtu + ETH_HEADER_OTHER);
198 }
199
tuntap_write(struct iss_net_private * lp,struct sk_buff ** skb)200 static int tuntap_write(struct iss_net_private *lp, struct sk_buff **skb)
201 {
202 return simc_write(lp->tp.info.tuntap.fd, (*skb)->data, (*skb)->len);
203 }
204
tuntap_protocol(struct sk_buff * skb)205 static unsigned short tuntap_protocol(struct sk_buff *skb)
206 {
207 return eth_type_trans(skb, skb->dev);
208 }
209
tuntap_poll(struct iss_net_private * lp)210 static int tuntap_poll(struct iss_net_private *lp)
211 {
212 return simc_poll(lp->tp.info.tuntap.fd);
213 }
214
215 static const struct iss_net_ops tuntap_ops = {
216 .open = tuntap_open,
217 .close = tuntap_close,
218 .read = tuntap_read,
219 .write = tuntap_write,
220 .protocol = tuntap_protocol,
221 .poll = tuntap_poll,
222 };
223
224 /*
225 * ethX=tuntap,[mac address],device name
226 */
227
tuntap_probe(struct iss_net_private * lp,int index,char * init)228 static int tuntap_probe(struct iss_net_private *lp, int index, char *init)
229 {
230 struct net_device *dev = lp->dev;
231 char *dev_name = NULL, *mac_str = NULL, *rem = NULL;
232
233 /* Transport should be 'tuntap': ethX=tuntap,mac,dev_name */
234
235 if (strncmp(init, TRANSPORT_TUNTAP_NAME,
236 sizeof(TRANSPORT_TUNTAP_NAME) - 1))
237 return 0;
238
239 init += sizeof(TRANSPORT_TUNTAP_NAME) - 1;
240 if (*init == ',') {
241 rem = split_if_spec(init + 1, &mac_str, &dev_name, NULL);
242 if (rem != NULL) {
243 pr_err("%s: extra garbage on specification : '%s'\n",
244 dev->name, rem);
245 return 0;
246 }
247 } else if (*init != '\0') {
248 pr_err("%s: invalid argument: %s. Skipping device!\n",
249 dev->name, init);
250 return 0;
251 }
252
253 if (!dev_name) {
254 pr_err("%s: missing tuntap device name\n", dev->name);
255 return 0;
256 }
257
258 strscpy(lp->tp.info.tuntap.dev_name, dev_name,
259 sizeof(lp->tp.info.tuntap.dev_name));
260
261 setup_etheraddr(dev, mac_str);
262
263 lp->mtu = TRANSPORT_TUNTAP_MTU;
264
265 lp->tp.info.tuntap.fd = -1;
266 lp->tp.net_ops = &tuntap_ops;
267
268 return 1;
269 }
270
271 /* ================================ ISS NET ================================ */
272
iss_net_rx(struct net_device * dev)273 static int iss_net_rx(struct net_device *dev)
274 {
275 struct iss_net_private *lp = netdev_priv(dev);
276 int pkt_len;
277 struct sk_buff *skb;
278
279 /* Check if there is any new data. */
280
281 if (lp->tp.net_ops->poll(lp) == 0)
282 return 0;
283
284 /* Try to allocate memory, if it fails, try again next round. */
285
286 skb = dev_alloc_skb(dev->mtu + 2 + ETH_HEADER_OTHER);
287 if (skb == NULL) {
288 spin_lock_bh(&lp->lock);
289 lp->stats.rx_dropped++;
290 spin_unlock_bh(&lp->lock);
291 return 0;
292 }
293
294 skb_reserve(skb, 2);
295
296 /* Setup skb */
297
298 skb->dev = dev;
299 skb_reset_mac_header(skb);
300 pkt_len = lp->tp.net_ops->read(lp, &skb);
301 skb_put(skb, pkt_len);
302
303 if (pkt_len > 0) {
304 skb_trim(skb, pkt_len);
305 skb->protocol = lp->tp.net_ops->protocol(skb);
306
307 spin_lock_bh(&lp->lock);
308 lp->stats.rx_bytes += skb->len;
309 lp->stats.rx_packets++;
310 spin_unlock_bh(&lp->lock);
311 netif_rx(skb);
312 return pkt_len;
313 }
314 kfree_skb(skb);
315 return pkt_len;
316 }
317
iss_net_poll(struct iss_net_private * lp)318 static int iss_net_poll(struct iss_net_private *lp)
319 {
320 int err, ret = 0;
321
322 if (!netif_running(lp->dev))
323 return 0;
324
325 while ((err = iss_net_rx(lp->dev)) > 0)
326 ret++;
327
328 if (err < 0) {
329 pr_err("Device '%s' read returned %d, shutting it down\n",
330 lp->dev->name, err);
331 dev_close(lp->dev);
332 } else {
333 /* FIXME reactivate_fd(lp->fd, ISS_ETH_IRQ); */
334 }
335
336 return ret;
337 }
338
339
iss_net_timer(struct timer_list * t)340 static void iss_net_timer(struct timer_list *t)
341 {
342 struct iss_net_private *lp = timer_container_of(lp, t, timer);
343
344 iss_net_poll(lp);
345 mod_timer(&lp->timer, jiffies + lp->timer_val);
346 }
347
348
iss_net_open(struct net_device * dev)349 static int iss_net_open(struct net_device *dev)
350 {
351 struct iss_net_private *lp = netdev_priv(dev);
352 int err;
353
354 err = lp->tp.net_ops->open(lp);
355 if (err < 0)
356 return err;
357
358 netif_start_queue(dev);
359
360 /* clear buffer - it can happen that the host side of the interface
361 * is full when we get here. In this case, new data is never queued,
362 * SIGIOs never arrive, and the net never works.
363 */
364 while ((err = iss_net_rx(dev)) > 0)
365 ;
366
367 timer_setup(&lp->timer, iss_net_timer, 0);
368 lp->timer_val = ISS_NET_TIMER_VALUE;
369 mod_timer(&lp->timer, jiffies + lp->timer_val);
370
371 return err;
372 }
373
iss_net_close(struct net_device * dev)374 static int iss_net_close(struct net_device *dev)
375 {
376 struct iss_net_private *lp = netdev_priv(dev);
377
378 netif_stop_queue(dev);
379 timer_delete_sync(&lp->timer);
380 lp->tp.net_ops->close(lp);
381
382 return 0;
383 }
384
iss_net_start_xmit(struct sk_buff * skb,struct net_device * dev)385 static int iss_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
386 {
387 struct iss_net_private *lp = netdev_priv(dev);
388 int len;
389
390 netif_stop_queue(dev);
391
392 len = lp->tp.net_ops->write(lp, &skb);
393
394 if (len == skb->len) {
395 spin_lock_bh(&lp->lock);
396 lp->stats.tx_packets++;
397 lp->stats.tx_bytes += skb->len;
398 spin_unlock_bh(&lp->lock);
399 netif_trans_update(dev);
400 netif_start_queue(dev);
401
402 /* this is normally done in the interrupt when tx finishes */
403 netif_wake_queue(dev);
404
405 } else if (len == 0) {
406 netif_start_queue(dev);
407 spin_lock_bh(&lp->lock);
408 lp->stats.tx_dropped++;
409 spin_unlock_bh(&lp->lock);
410
411 } else {
412 netif_start_queue(dev);
413 pr_err("%s: %s failed(%d)\n", dev->name, __func__, len);
414 }
415
416
417 dev_kfree_skb(skb);
418 return NETDEV_TX_OK;
419 }
420
421
iss_net_get_stats64(struct net_device * dev,struct rtnl_link_stats64 * stats)422 static void iss_net_get_stats64(struct net_device *dev,
423 struct rtnl_link_stats64 *stats)
424 {
425 struct iss_net_private *lp = netdev_priv(dev);
426
427 spin_lock_bh(&lp->lock);
428 *stats = lp->stats;
429 spin_unlock_bh(&lp->lock);
430 }
431
iss_net_set_multicast_list(struct net_device * dev)432 static void iss_net_set_multicast_list(struct net_device *dev)
433 {
434 }
435
iss_net_tx_timeout(struct net_device * dev,unsigned int txqueue)436 static void iss_net_tx_timeout(struct net_device *dev, unsigned int txqueue)
437 {
438 }
439
iss_net_change_mtu(struct net_device * dev,int new_mtu)440 static int iss_net_change_mtu(struct net_device *dev, int new_mtu)
441 {
442 return -EINVAL;
443 }
444
iss_net_user_timer_expire(struct timer_list * unused)445 static void iss_net_user_timer_expire(struct timer_list *unused)
446 {
447 }
448
449
450 static struct platform_driver iss_net_driver = {
451 .driver = {
452 .name = DRIVER_NAME,
453 },
454 };
455
456 static int driver_registered;
457
458 static const struct net_device_ops iss_netdev_ops = {
459 .ndo_open = iss_net_open,
460 .ndo_stop = iss_net_close,
461 .ndo_get_stats64 = iss_net_get_stats64,
462 .ndo_start_xmit = iss_net_start_xmit,
463 .ndo_validate_addr = eth_validate_addr,
464 .ndo_change_mtu = iss_net_change_mtu,
465 .ndo_set_mac_address = eth_mac_addr,
466 .ndo_tx_timeout = iss_net_tx_timeout,
467 .ndo_set_rx_mode = iss_net_set_multicast_list,
468 };
469
iss_net_pdev_release(struct device * dev)470 static void iss_net_pdev_release(struct device *dev)
471 {
472 struct platform_device *pdev = to_platform_device(dev);
473 struct iss_net_private *lp =
474 container_of(pdev, struct iss_net_private, pdev);
475
476 free_netdev(lp->dev);
477 }
478
iss_net_configure(int index,char * init)479 static void iss_net_configure(int index, char *init)
480 {
481 struct net_device *dev;
482 struct iss_net_private *lp;
483
484 dev = alloc_etherdev(sizeof(*lp));
485 if (dev == NULL) {
486 pr_err("eth_configure: failed to allocate device\n");
487 return;
488 }
489
490 /* Initialize private element. */
491
492 lp = netdev_priv(dev);
493 *lp = (struct iss_net_private) {
494 .dev = dev,
495 .index = index,
496 };
497
498 spin_lock_init(&lp->lock);
499 /*
500 * If this name ends up conflicting with an existing registered
501 * netdevice, that is OK, register_netdev{,ice}() will notice this
502 * and fail.
503 */
504 snprintf(dev->name, sizeof(dev->name), "eth%d", index);
505
506 /*
507 * Try all transport protocols.
508 * Note: more protocols can be added by adding '&& !X_init(lp, eth)'.
509 */
510
511 if (!tuntap_probe(lp, index, init)) {
512 pr_err("%s: invalid arguments. Skipping device!\n",
513 dev->name);
514 goto err_free_netdev;
515 }
516
517 pr_info("Netdevice %d (%pM)\n", index, dev->dev_addr);
518
519 /* sysfs register */
520
521 if (!driver_registered) {
522 if (platform_driver_register(&iss_net_driver))
523 goto err_free_netdev;
524 driver_registered = 1;
525 }
526
527 lp->pdev.id = index;
528 lp->pdev.name = DRIVER_NAME;
529 lp->pdev.dev.release = iss_net_pdev_release;
530 if (platform_device_register(&lp->pdev))
531 goto err_free_netdev;
532 SET_NETDEV_DEV(dev, &lp->pdev.dev);
533
534 dev->netdev_ops = &iss_netdev_ops;
535 dev->mtu = lp->mtu;
536 dev->watchdog_timeo = (HZ >> 1);
537 dev->irq = -1;
538
539 rtnl_lock();
540 if (register_netdevice(dev)) {
541 rtnl_unlock();
542 pr_err("%s: error registering net device!\n", dev->name);
543 platform_device_unregister(&lp->pdev);
544 /* dev is freed by the iss_net_pdev_release callback */
545 return;
546 }
547 rtnl_unlock();
548
549 timer_setup(&lp->tl, iss_net_user_timer_expire, 0);
550
551 return;
552
553 err_free_netdev:
554 free_netdev(dev);
555 }
556
557 /* ------------------------------------------------------------------------- */
558
559 /* Filled in during early boot */
560
561 struct list_head eth_cmd_line = LIST_HEAD_INIT(eth_cmd_line);
562
563 struct iss_net_init {
564 struct list_head list;
565 char *init; /* init string */
566 int index;
567 };
568
569 /*
570 * Parse the command line and look for 'ethX=...' fields, and register all
571 * those fields. They will be later initialized in iss_net_init.
572 */
573
iss_net_setup(char * str)574 static int __init iss_net_setup(char *str)
575 {
576 struct iss_net_init *device = NULL;
577 struct iss_net_init *new;
578 struct list_head *ele;
579 char *end;
580 int rc;
581 unsigned n;
582
583 end = strchr(str, '=');
584 if (!end) {
585 pr_err("Expected '=' after device number\n");
586 return 1;
587 }
588 *end = 0;
589 rc = kstrtouint(str, 0, &n);
590 *end = '=';
591 if (rc < 0) {
592 pr_err("Failed to parse '%s'\n", str);
593 return 1;
594 }
595 str = end;
596
597 list_for_each(ele, ð_cmd_line) {
598 device = list_entry(ele, struct iss_net_init, list);
599 if (device->index == n)
600 break;
601 }
602
603 if (device && device->index == n) {
604 pr_err("Device %u already configured\n", n);
605 return 1;
606 }
607
608 new = memblock_alloc(sizeof(*new), SMP_CACHE_BYTES);
609 if (new == NULL) {
610 pr_err("Alloc_bootmem failed\n");
611 return 1;
612 }
613
614 INIT_LIST_HEAD(&new->list);
615 new->index = n;
616 new->init = str + 1;
617
618 list_add_tail(&new->list, ð_cmd_line);
619 return 1;
620 }
621
622 __setup("eth", iss_net_setup);
623
624 /*
625 * Initialize all ISS Ethernet devices previously registered in iss_net_setup.
626 */
627
iss_net_init(void)628 static int iss_net_init(void)
629 {
630 struct list_head *ele, *next;
631
632 /* Walk through all Ethernet devices specified in the command line. */
633
634 list_for_each_safe(ele, next, ð_cmd_line) {
635 struct iss_net_init *eth;
636 eth = list_entry(ele, struct iss_net_init, list);
637 iss_net_configure(eth->index, eth->init);
638 }
639
640 return 1;
641 }
642 device_initcall(iss_net_init);
643