xref: /linux/arch/xtensa/platforms/iss/network.c (revision 24c776355f4097316a763005434ffff716aa21a8)
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 
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 
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 
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 
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 
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 
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 
205 static unsigned short tuntap_protocol(struct sk_buff *skb)
206 {
207 	return eth_type_trans(skb, skb->dev);
208 }
209 
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 
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 
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 
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 
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 
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 
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 
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 
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 
432 static void iss_net_set_multicast_list(struct net_device *dev)
433 {
434 }
435 
436 static void iss_net_tx_timeout(struct net_device *dev, unsigned int txqueue)
437 {
438 }
439 
440 static int iss_net_change_mtu(struct net_device *dev, int new_mtu)
441 {
442 	return -EINVAL;
443 }
444 
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 
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 
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 
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, &eth_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, &eth_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 
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, &eth_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