xref: /openbmc/linux/drivers/net/rionet.c (revision b96fc2f3)
1 /*
2  * rionet - Ethernet driver over RapidIO messaging services
3  *
4  * Copyright 2005 MontaVista Software, Inc.
5  * Matt Porter <mporter@kernel.crashing.org>
6  *
7  * This program is free software; you can redistribute  it and/or modify it
8  * under  the terms of  the GNU General  Public License as published by the
9  * Free Software Foundation;  either version 2 of the  License, or (at your
10  * option) any later version.
11  */
12 
13 #include <linux/module.h>
14 #include <linux/kernel.h>
15 #include <linux/dma-mapping.h>
16 #include <linux/delay.h>
17 #include <linux/rio.h>
18 #include <linux/rio_drv.h>
19 #include <linux/slab.h>
20 #include <linux/rio_ids.h>
21 
22 #include <linux/netdevice.h>
23 #include <linux/etherdevice.h>
24 #include <linux/skbuff.h>
25 #include <linux/crc32.h>
26 #include <linux/ethtool.h>
27 
28 #define DRV_NAME        "rionet"
29 #define DRV_VERSION     "0.3"
30 #define DRV_AUTHOR      "Matt Porter <mporter@kernel.crashing.org>"
31 #define DRV_DESC        "Ethernet over RapidIO"
32 
33 MODULE_AUTHOR(DRV_AUTHOR);
34 MODULE_DESCRIPTION(DRV_DESC);
35 MODULE_LICENSE("GPL");
36 
37 #define RIONET_DEFAULT_MSGLEVEL \
38 			(NETIF_MSG_DRV          | \
39 			 NETIF_MSG_LINK         | \
40 			 NETIF_MSG_RX_ERR       | \
41 			 NETIF_MSG_TX_ERR)
42 
43 #define RIONET_DOORBELL_JOIN	0x1000
44 #define RIONET_DOORBELL_LEAVE	0x1001
45 
46 #define RIONET_MAILBOX		0
47 
48 #define RIONET_TX_RING_SIZE	CONFIG_RIONET_TX_SIZE
49 #define RIONET_RX_RING_SIZE	CONFIG_RIONET_RX_SIZE
50 #define RIONET_MAX_NETS		8
51 
52 struct rionet_private {
53 	struct rio_mport *mport;
54 	struct sk_buff *rx_skb[RIONET_RX_RING_SIZE];
55 	struct sk_buff *tx_skb[RIONET_TX_RING_SIZE];
56 	int rx_slot;
57 	int tx_slot;
58 	int tx_cnt;
59 	int ack_slot;
60 	spinlock_t lock;
61 	spinlock_t tx_lock;
62 	u32 msg_enable;
63 };
64 
65 struct rionet_peer {
66 	struct list_head node;
67 	struct rio_dev *rdev;
68 	struct resource *res;
69 };
70 
71 struct rionet_net {
72 	struct net_device *ndev;
73 	struct list_head peers;
74 	struct rio_dev **active;
75 	int nact;	/* number of active peers */
76 };
77 
78 static struct rionet_net nets[RIONET_MAX_NETS];
79 
80 #define is_rionet_capable(src_ops, dst_ops)			\
81 			((src_ops & RIO_SRC_OPS_DATA_MSG) &&	\
82 			 (dst_ops & RIO_DST_OPS_DATA_MSG) &&	\
83 			 (src_ops & RIO_SRC_OPS_DOORBELL) &&	\
84 			 (dst_ops & RIO_DST_OPS_DOORBELL))
85 #define dev_rionet_capable(dev) \
86 	is_rionet_capable(dev->src_ops, dev->dst_ops)
87 
88 #define RIONET_MAC_MATCH(x)	(!memcmp((x), "\00\01\00\01", 4))
89 #define RIONET_GET_DESTID(x)	((*((u8 *)x + 4) << 8) | *((u8 *)x + 5))
90 
91 static int rionet_rx_clean(struct net_device *ndev)
92 {
93 	int i;
94 	int error = 0;
95 	struct rionet_private *rnet = netdev_priv(ndev);
96 	void *data;
97 
98 	i = rnet->rx_slot;
99 
100 	do {
101 		if (!rnet->rx_skb[i])
102 			continue;
103 
104 		if (!(data = rio_get_inb_message(rnet->mport, RIONET_MAILBOX)))
105 			break;
106 
107 		rnet->rx_skb[i]->data = data;
108 		skb_put(rnet->rx_skb[i], RIO_MAX_MSG_SIZE);
109 		rnet->rx_skb[i]->protocol =
110 		    eth_type_trans(rnet->rx_skb[i], ndev);
111 		error = netif_rx(rnet->rx_skb[i]);
112 
113 		if (error == NET_RX_DROP) {
114 			ndev->stats.rx_dropped++;
115 		} else {
116 			ndev->stats.rx_packets++;
117 			ndev->stats.rx_bytes += RIO_MAX_MSG_SIZE;
118 		}
119 
120 	} while ((i = (i + 1) % RIONET_RX_RING_SIZE) != rnet->rx_slot);
121 
122 	return i;
123 }
124 
125 static void rionet_rx_fill(struct net_device *ndev, int end)
126 {
127 	int i;
128 	struct rionet_private *rnet = netdev_priv(ndev);
129 
130 	i = rnet->rx_slot;
131 	do {
132 		rnet->rx_skb[i] = dev_alloc_skb(RIO_MAX_MSG_SIZE);
133 
134 		if (!rnet->rx_skb[i])
135 			break;
136 
137 		rio_add_inb_buffer(rnet->mport, RIONET_MAILBOX,
138 				   rnet->rx_skb[i]->data);
139 	} while ((i = (i + 1) % RIONET_RX_RING_SIZE) != end);
140 
141 	rnet->rx_slot = i;
142 }
143 
144 static int rionet_queue_tx_msg(struct sk_buff *skb, struct net_device *ndev,
145 			       struct rio_dev *rdev)
146 {
147 	struct rionet_private *rnet = netdev_priv(ndev);
148 
149 	rio_add_outb_message(rnet->mport, rdev, 0, skb->data, skb->len);
150 	rnet->tx_skb[rnet->tx_slot] = skb;
151 
152 	ndev->stats.tx_packets++;
153 	ndev->stats.tx_bytes += skb->len;
154 
155 	if (++rnet->tx_cnt == RIONET_TX_RING_SIZE)
156 		netif_stop_queue(ndev);
157 
158 	++rnet->tx_slot;
159 	rnet->tx_slot &= (RIONET_TX_RING_SIZE - 1);
160 
161 	if (netif_msg_tx_queued(rnet))
162 		printk(KERN_INFO "%s: queued skb len %8.8x\n", DRV_NAME,
163 		       skb->len);
164 
165 	return 0;
166 }
167 
168 static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
169 {
170 	int i;
171 	struct rionet_private *rnet = netdev_priv(ndev);
172 	struct ethhdr *eth = (struct ethhdr *)skb->data;
173 	u16 destid;
174 	unsigned long flags;
175 	int add_num = 1;
176 
177 	local_irq_save(flags);
178 	if (!spin_trylock(&rnet->tx_lock)) {
179 		local_irq_restore(flags);
180 		return NETDEV_TX_LOCKED;
181 	}
182 
183 	if (is_multicast_ether_addr(eth->h_dest))
184 		add_num = nets[rnet->mport->id].nact;
185 
186 	if ((rnet->tx_cnt + add_num) > RIONET_TX_RING_SIZE) {
187 		netif_stop_queue(ndev);
188 		spin_unlock_irqrestore(&rnet->tx_lock, flags);
189 		printk(KERN_ERR "%s: BUG! Tx Ring full when queue awake!\n",
190 		       ndev->name);
191 		return NETDEV_TX_BUSY;
192 	}
193 
194 	if (is_multicast_ether_addr(eth->h_dest)) {
195 		int count = 0;
196 
197 		for (i = 0; i < RIO_MAX_ROUTE_ENTRIES(rnet->mport->sys_size);
198 				i++)
199 			if (nets[rnet->mport->id].active[i]) {
200 				rionet_queue_tx_msg(skb, ndev,
201 					nets[rnet->mport->id].active[i]);
202 				if (count)
203 					atomic_inc(&skb->users);
204 				count++;
205 			}
206 	} else if (RIONET_MAC_MATCH(eth->h_dest)) {
207 		destid = RIONET_GET_DESTID(eth->h_dest);
208 		if (nets[rnet->mport->id].active[destid])
209 			rionet_queue_tx_msg(skb, ndev,
210 					nets[rnet->mport->id].active[destid]);
211 		else {
212 			/*
213 			 * If the target device was removed from the list of
214 			 * active peers but we still have TX packets targeting
215 			 * it just report sending a packet to the target
216 			 * (without actual packet transfer).
217 			 */
218 			dev_kfree_skb_any(skb);
219 			ndev->stats.tx_packets++;
220 			ndev->stats.tx_bytes += skb->len;
221 		}
222 	}
223 
224 	spin_unlock_irqrestore(&rnet->tx_lock, flags);
225 
226 	return NETDEV_TX_OK;
227 }
228 
229 static void rionet_dbell_event(struct rio_mport *mport, void *dev_id, u16 sid, u16 tid,
230 			       u16 info)
231 {
232 	struct net_device *ndev = dev_id;
233 	struct rionet_private *rnet = netdev_priv(ndev);
234 	struct rionet_peer *peer;
235 
236 	if (netif_msg_intr(rnet))
237 		printk(KERN_INFO "%s: doorbell sid %4.4x tid %4.4x info %4.4x",
238 		       DRV_NAME, sid, tid, info);
239 	if (info == RIONET_DOORBELL_JOIN) {
240 		if (!nets[rnet->mport->id].active[sid]) {
241 			list_for_each_entry(peer,
242 					   &nets[rnet->mport->id].peers, node) {
243 				if (peer->rdev->destid == sid) {
244 					nets[rnet->mport->id].active[sid] =
245 								peer->rdev;
246 					nets[rnet->mport->id].nact++;
247 				}
248 			}
249 			rio_mport_send_doorbell(mport, sid,
250 						RIONET_DOORBELL_JOIN);
251 		}
252 	} else if (info == RIONET_DOORBELL_LEAVE) {
253 		nets[rnet->mport->id].active[sid] = NULL;
254 		nets[rnet->mport->id].nact--;
255 	} else {
256 		if (netif_msg_intr(rnet))
257 			printk(KERN_WARNING "%s: unhandled doorbell\n",
258 			       DRV_NAME);
259 	}
260 }
261 
262 static void rionet_inb_msg_event(struct rio_mport *mport, void *dev_id, int mbox, int slot)
263 {
264 	int n;
265 	struct net_device *ndev = dev_id;
266 	struct rionet_private *rnet = netdev_priv(ndev);
267 
268 	if (netif_msg_intr(rnet))
269 		printk(KERN_INFO "%s: inbound message event, mbox %d slot %d\n",
270 		       DRV_NAME, mbox, slot);
271 
272 	spin_lock(&rnet->lock);
273 	if ((n = rionet_rx_clean(ndev)) != rnet->rx_slot)
274 		rionet_rx_fill(ndev, n);
275 	spin_unlock(&rnet->lock);
276 }
277 
278 static void rionet_outb_msg_event(struct rio_mport *mport, void *dev_id, int mbox, int slot)
279 {
280 	struct net_device *ndev = dev_id;
281 	struct rionet_private *rnet = netdev_priv(ndev);
282 
283 	spin_lock(&rnet->lock);
284 
285 	if (netif_msg_intr(rnet))
286 		printk(KERN_INFO
287 		       "%s: outbound message event, mbox %d slot %d\n",
288 		       DRV_NAME, mbox, slot);
289 
290 	while (rnet->tx_cnt && (rnet->ack_slot != slot)) {
291 		/* dma unmap single */
292 		dev_kfree_skb_irq(rnet->tx_skb[rnet->ack_slot]);
293 		rnet->tx_skb[rnet->ack_slot] = NULL;
294 		++rnet->ack_slot;
295 		rnet->ack_slot &= (RIONET_TX_RING_SIZE - 1);
296 		rnet->tx_cnt--;
297 	}
298 
299 	if (rnet->tx_cnt < RIONET_TX_RING_SIZE)
300 		netif_wake_queue(ndev);
301 
302 	spin_unlock(&rnet->lock);
303 }
304 
305 static int rionet_open(struct net_device *ndev)
306 {
307 	int i, rc = 0;
308 	struct rionet_peer *peer, *tmp;
309 	struct rionet_private *rnet = netdev_priv(ndev);
310 
311 	if (netif_msg_ifup(rnet))
312 		printk(KERN_INFO "%s: open\n", DRV_NAME);
313 
314 	if ((rc = rio_request_inb_dbell(rnet->mport,
315 					(void *)ndev,
316 					RIONET_DOORBELL_JOIN,
317 					RIONET_DOORBELL_LEAVE,
318 					rionet_dbell_event)) < 0)
319 		goto out;
320 
321 	if ((rc = rio_request_inb_mbox(rnet->mport,
322 				       (void *)ndev,
323 				       RIONET_MAILBOX,
324 				       RIONET_RX_RING_SIZE,
325 				       rionet_inb_msg_event)) < 0)
326 		goto out;
327 
328 	if ((rc = rio_request_outb_mbox(rnet->mport,
329 					(void *)ndev,
330 					RIONET_MAILBOX,
331 					RIONET_TX_RING_SIZE,
332 					rionet_outb_msg_event)) < 0)
333 		goto out;
334 
335 	/* Initialize inbound message ring */
336 	for (i = 0; i < RIONET_RX_RING_SIZE; i++)
337 		rnet->rx_skb[i] = NULL;
338 	rnet->rx_slot = 0;
339 	rionet_rx_fill(ndev, 0);
340 
341 	rnet->tx_slot = 0;
342 	rnet->tx_cnt = 0;
343 	rnet->ack_slot = 0;
344 
345 	netif_carrier_on(ndev);
346 	netif_start_queue(ndev);
347 
348 	list_for_each_entry_safe(peer, tmp,
349 				 &nets[rnet->mport->id].peers, node) {
350 		if (!(peer->res = rio_request_outb_dbell(peer->rdev,
351 							 RIONET_DOORBELL_JOIN,
352 							 RIONET_DOORBELL_LEAVE)))
353 		{
354 			printk(KERN_ERR "%s: error requesting doorbells\n",
355 			       DRV_NAME);
356 			continue;
357 		}
358 
359 		/* Send a join message */
360 		rio_send_doorbell(peer->rdev, RIONET_DOORBELL_JOIN);
361 	}
362 
363       out:
364 	return rc;
365 }
366 
367 static int rionet_close(struct net_device *ndev)
368 {
369 	struct rionet_private *rnet = netdev_priv(ndev);
370 	struct rionet_peer *peer, *tmp;
371 	int i;
372 
373 	if (netif_msg_ifup(rnet))
374 		printk(KERN_INFO "%s: close %s\n", DRV_NAME, ndev->name);
375 
376 	netif_stop_queue(ndev);
377 	netif_carrier_off(ndev);
378 
379 	for (i = 0; i < RIONET_RX_RING_SIZE; i++)
380 		kfree_skb(rnet->rx_skb[i]);
381 
382 	list_for_each_entry_safe(peer, tmp,
383 				 &nets[rnet->mport->id].peers, node) {
384 		if (nets[rnet->mport->id].active[peer->rdev->destid]) {
385 			rio_send_doorbell(peer->rdev, RIONET_DOORBELL_LEAVE);
386 			nets[rnet->mport->id].active[peer->rdev->destid] = NULL;
387 		}
388 		rio_release_outb_dbell(peer->rdev, peer->res);
389 	}
390 
391 	rio_release_inb_dbell(rnet->mport, RIONET_DOORBELL_JOIN,
392 			      RIONET_DOORBELL_LEAVE);
393 	rio_release_inb_mbox(rnet->mport, RIONET_MAILBOX);
394 	rio_release_outb_mbox(rnet->mport, RIONET_MAILBOX);
395 
396 	return 0;
397 }
398 
399 static void rionet_remove_dev(struct device *dev, struct subsys_interface *sif)
400 {
401 	struct rio_dev *rdev = to_rio_dev(dev);
402 	unsigned char netid = rdev->net->hport->id;
403 	struct rionet_peer *peer, *tmp;
404 
405 	if (dev_rionet_capable(rdev)) {
406 		list_for_each_entry_safe(peer, tmp, &nets[netid].peers, node) {
407 			if (peer->rdev == rdev) {
408 				if (nets[netid].active[rdev->destid]) {
409 					nets[netid].active[rdev->destid] = NULL;
410 					nets[netid].nact--;
411 				}
412 
413 				list_del(&peer->node);
414 				kfree(peer);
415 				break;
416 			}
417 		}
418 	}
419 }
420 
421 static void rionet_get_drvinfo(struct net_device *ndev,
422 			       struct ethtool_drvinfo *info)
423 {
424 	struct rionet_private *rnet = netdev_priv(ndev);
425 
426 	strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
427 	strlcpy(info->version, DRV_VERSION, sizeof(info->version));
428 	strlcpy(info->fw_version, "n/a", sizeof(info->fw_version));
429 	strlcpy(info->bus_info, rnet->mport->name, sizeof(info->bus_info));
430 }
431 
432 static u32 rionet_get_msglevel(struct net_device *ndev)
433 {
434 	struct rionet_private *rnet = netdev_priv(ndev);
435 
436 	return rnet->msg_enable;
437 }
438 
439 static void rionet_set_msglevel(struct net_device *ndev, u32 value)
440 {
441 	struct rionet_private *rnet = netdev_priv(ndev);
442 
443 	rnet->msg_enable = value;
444 }
445 
446 static const struct ethtool_ops rionet_ethtool_ops = {
447 	.get_drvinfo = rionet_get_drvinfo,
448 	.get_msglevel = rionet_get_msglevel,
449 	.set_msglevel = rionet_set_msglevel,
450 	.get_link = ethtool_op_get_link,
451 };
452 
453 static const struct net_device_ops rionet_netdev_ops = {
454 	.ndo_open		= rionet_open,
455 	.ndo_stop		= rionet_close,
456 	.ndo_start_xmit		= rionet_start_xmit,
457 	.ndo_change_mtu		= eth_change_mtu,
458 	.ndo_validate_addr	= eth_validate_addr,
459 	.ndo_set_mac_address	= eth_mac_addr,
460 };
461 
462 static int rionet_setup_netdev(struct rio_mport *mport, struct net_device *ndev)
463 {
464 	int rc = 0;
465 	struct rionet_private *rnet;
466 	u16 device_id;
467 	const size_t rionet_active_bytes = sizeof(void *) *
468 				RIO_MAX_ROUTE_ENTRIES(mport->sys_size);
469 
470 	nets[mport->id].active = (struct rio_dev **)__get_free_pages(GFP_KERNEL,
471 						get_order(rionet_active_bytes));
472 	if (!nets[mport->id].active) {
473 		rc = -ENOMEM;
474 		goto out;
475 	}
476 	memset((void *)nets[mport->id].active, 0, rionet_active_bytes);
477 
478 	/* Set up private area */
479 	rnet = netdev_priv(ndev);
480 	rnet->mport = mport;
481 
482 	/* Set the default MAC address */
483 	device_id = rio_local_get_device_id(mport);
484 	ndev->dev_addr[0] = 0x00;
485 	ndev->dev_addr[1] = 0x01;
486 	ndev->dev_addr[2] = 0x00;
487 	ndev->dev_addr[3] = 0x01;
488 	ndev->dev_addr[4] = device_id >> 8;
489 	ndev->dev_addr[5] = device_id & 0xff;
490 
491 	ndev->netdev_ops = &rionet_netdev_ops;
492 	ndev->mtu = RIO_MAX_MSG_SIZE - 14;
493 	ndev->features = NETIF_F_LLTX;
494 	SET_NETDEV_DEV(ndev, &mport->dev);
495 	ndev->ethtool_ops = &rionet_ethtool_ops;
496 
497 	spin_lock_init(&rnet->lock);
498 	spin_lock_init(&rnet->tx_lock);
499 
500 	rnet->msg_enable = RIONET_DEFAULT_MSGLEVEL;
501 
502 	rc = register_netdev(ndev);
503 	if (rc != 0)
504 		goto out;
505 
506 	printk(KERN_INFO "%s: %s %s Version %s, MAC %pM, %s\n",
507 	       ndev->name,
508 	       DRV_NAME,
509 	       DRV_DESC,
510 	       DRV_VERSION,
511 	       ndev->dev_addr,
512 	       mport->name);
513 
514       out:
515 	return rc;
516 }
517 
518 static unsigned long net_table[RIONET_MAX_NETS/sizeof(unsigned long) + 1];
519 
520 static int rionet_add_dev(struct device *dev, struct subsys_interface *sif)
521 {
522 	int rc = -ENODEV;
523 	u32 lsrc_ops, ldst_ops;
524 	struct rionet_peer *peer;
525 	struct net_device *ndev = NULL;
526 	struct rio_dev *rdev = to_rio_dev(dev);
527 	unsigned char netid = rdev->net->hport->id;
528 	int oldnet;
529 
530 	if (netid >= RIONET_MAX_NETS)
531 		return rc;
532 
533 	oldnet = test_and_set_bit(netid, net_table);
534 
535 	/*
536 	 * If first time through this net, make sure local device is rionet
537 	 * capable and setup netdev (this step will be skipped in later probes
538 	 * on the same net).
539 	 */
540 	if (!oldnet) {
541 		rio_local_read_config_32(rdev->net->hport, RIO_SRC_OPS_CAR,
542 					 &lsrc_ops);
543 		rio_local_read_config_32(rdev->net->hport, RIO_DST_OPS_CAR,
544 					 &ldst_ops);
545 		if (!is_rionet_capable(lsrc_ops, ldst_ops)) {
546 			printk(KERN_ERR
547 			       "%s: local device %s is not network capable\n",
548 			       DRV_NAME, rdev->net->hport->name);
549 			goto out;
550 		}
551 
552 		/* Allocate our net_device structure */
553 		ndev = alloc_etherdev(sizeof(struct rionet_private));
554 		if (ndev == NULL) {
555 			rc = -ENOMEM;
556 			goto out;
557 		}
558 		nets[netid].ndev = ndev;
559 		rc = rionet_setup_netdev(rdev->net->hport, ndev);
560 		if (rc) {
561 			printk(KERN_ERR "%s: failed to setup netdev (rc=%d)\n",
562 			       DRV_NAME, rc);
563 			goto out;
564 		}
565 
566 		INIT_LIST_HEAD(&nets[netid].peers);
567 		nets[netid].nact = 0;
568 	} else if (nets[netid].ndev == NULL)
569 		goto out;
570 
571 	/*
572 	 * If the remote device has mailbox/doorbell capabilities,
573 	 * add it to the peer list.
574 	 */
575 	if (dev_rionet_capable(rdev)) {
576 		if (!(peer = kmalloc(sizeof(struct rionet_peer), GFP_KERNEL))) {
577 			rc = -ENOMEM;
578 			goto out;
579 		}
580 		peer->rdev = rdev;
581 		list_add_tail(&peer->node, &nets[netid].peers);
582 	}
583 
584 	return 0;
585 out:
586 	return rc;
587 }
588 
589 #ifdef MODULE
590 static struct rio_device_id rionet_id_table[] = {
591 	{RIO_DEVICE(RIO_ANY_ID, RIO_ANY_ID)},
592 	{ 0, }	/* terminate list */
593 };
594 
595 MODULE_DEVICE_TABLE(rapidio, rionet_id_table);
596 #endif
597 
598 static struct subsys_interface rionet_interface = {
599 	.name		= "rionet",
600 	.subsys		= &rio_bus_type,
601 	.add_dev	= rionet_add_dev,
602 	.remove_dev	= rionet_remove_dev,
603 };
604 
605 static int __init rionet_init(void)
606 {
607 	return subsys_interface_register(&rionet_interface);
608 }
609 
610 static void __exit rionet_exit(void)
611 {
612 	struct rionet_private *rnet;
613 	struct net_device *ndev;
614 	struct rionet_peer *peer, *tmp;
615 	int i;
616 
617 	for (i = 0; i < RIONET_MAX_NETS; i++) {
618 		if (nets[i].ndev != NULL) {
619 			ndev = nets[i].ndev;
620 			rnet = netdev_priv(ndev);
621 			unregister_netdev(ndev);
622 
623 			list_for_each_entry_safe(peer,
624 						 tmp, &nets[i].peers, node) {
625 				list_del(&peer->node);
626 				kfree(peer);
627 			}
628 
629 			free_pages((unsigned long)nets[i].active,
630 				 get_order(sizeof(void *) *
631 				 RIO_MAX_ROUTE_ENTRIES(rnet->mport->sys_size)));
632 			nets[i].active = NULL;
633 
634 			free_netdev(ndev);
635 		}
636 	}
637 
638 	subsys_interface_unregister(&rionet_interface);
639 }
640 
641 late_initcall(rionet_init);
642 module_exit(rionet_exit);
643