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