Imported Upstream version 16.07-rc1
[deb_dpdk.git] / lib / librte_eal / linuxapp / kni / kni_net.c
1 /*-
2  * GPL LICENSE SUMMARY
3  *
4  *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
5  *
6  *   This program is free software; you can redistribute it and/or modify
7  *   it under the terms of version 2 of the GNU General Public License as
8  *   published by the Free Software Foundation.
9  *
10  *   This program is distributed in the hope that it will be useful, but
11  *   WITHOUT ANY WARRANTY; without even the implied warranty of
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  *   General Public License for more details.
14  *
15  *   You should have received a copy of the GNU General Public License
16  *   along with this program; if not, write to the Free Software
17  *   Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18  *   The full GNU General Public License is included in this distribution
19  *   in the file called LICENSE.GPL.
20  *
21  *   Contact Information:
22  *   Intel Corporation
23  */
24
25 /*
26  * This code is inspired from the book "Linux Device Drivers" by
27  * Alessandro Rubini and Jonathan Corbet, published by O'Reilly & Associates
28  */
29
30 #include <linux/device.h>
31 #include <linux/module.h>
32 #include <linux/version.h>
33 #include <linux/netdevice.h>
34 #include <linux/etherdevice.h> /* eth_type_trans */
35 #include <linux/skbuff.h>
36 #include <linux/kthread.h>
37 #include <linux/delay.h>
38
39 #include <exec-env/rte_kni_common.h>
40 #include <kni_fifo.h>
41
42 #include "compat.h"
43 #include "kni_dev.h"
44
45 #define WD_TIMEOUT 5 /*jiffies */
46
47 #define MBUF_BURST_SZ 32
48
49 #define KNI_WAIT_RESPONSE_TIMEOUT 300 /* 3 seconds */
50
51 /* typedef for rx function */
52 typedef void (*kni_net_rx_t)(struct kni_dev *kni);
53
54 static int kni_net_tx(struct sk_buff *skb, struct net_device *dev);
55 static void kni_net_rx_normal(struct kni_dev *kni);
56 static void kni_net_rx_lo_fifo(struct kni_dev *kni);
57 static void kni_net_rx_lo_fifo_skb(struct kni_dev *kni);
58 static int kni_net_process_request(struct kni_dev *kni,
59                         struct rte_kni_request *req);
60
61 /* kni rx function pointer, with default to normal rx */
62 static kni_net_rx_t kni_net_rx_func = kni_net_rx_normal;
63
64 /*
65  * Open and close
66  */
67 static int
68 kni_net_open(struct net_device *dev)
69 {
70         int ret;
71         struct rte_kni_request req;
72         struct kni_dev *kni = netdev_priv(dev);
73
74         netif_start_queue(dev);
75
76         memset(&req, 0, sizeof(req));
77         req.req_id = RTE_KNI_REQ_CFG_NETWORK_IF;
78
79         /* Setting if_up to non-zero means up */
80         req.if_up = 1;
81         ret = kni_net_process_request(kni, &req);
82
83         return (ret == 0) ? req.result : ret;
84 }
85
86 static int
87 kni_net_release(struct net_device *dev)
88 {
89         int ret;
90         struct rte_kni_request req;
91         struct kni_dev *kni = netdev_priv(dev);
92
93         netif_stop_queue(dev); /* can't transmit any more */
94
95         memset(&req, 0, sizeof(req));
96         req.req_id = RTE_KNI_REQ_CFG_NETWORK_IF;
97
98         /* Setting if_up to 0 means down */
99         req.if_up = 0;
100         ret = kni_net_process_request(kni, &req);
101
102         return (ret == 0) ? req.result : ret;
103 }
104
105 /*
106  * Configuration changes (passed on by ifconfig)
107  */
108 static int
109 kni_net_config(struct net_device *dev, struct ifmap *map)
110 {
111         if (dev->flags & IFF_UP) /* can't act on a running interface */
112                 return -EBUSY;
113
114         /* ignore other fields */
115         return 0;
116 }
117
118 /*
119  * RX: normal working mode
120  */
121 static void
122 kni_net_rx_normal(struct kni_dev *kni)
123 {
124         unsigned ret;
125         uint32_t len;
126         unsigned i, num_rx, num_fq;
127         struct rte_kni_mbuf *kva;
128         struct rte_kni_mbuf *va[MBUF_BURST_SZ];
129         void * data_kva;
130
131         struct sk_buff *skb;
132         struct net_device *dev = kni->net_dev;
133
134         /* Get the number of free entries in free_q */
135         num_fq = kni_fifo_free_count(kni->free_q);
136         if (num_fq == 0) {
137                 /* No room on the free_q, bail out */
138                 return;
139         }
140
141         /* Calculate the number of entries to dequeue from rx_q */
142         num_rx = min(num_fq, (unsigned)MBUF_BURST_SZ);
143
144         /* Burst dequeue from rx_q */
145         num_rx = kni_fifo_get(kni->rx_q, (void **)va, num_rx);
146         if (num_rx == 0)
147                 return;
148
149         /* Transfer received packets to netif */
150         for (i = 0; i < num_rx; i++) {
151                 kva = (void *)va[i] - kni->mbuf_va + kni->mbuf_kva;
152                 len = kva->pkt_len;
153
154                 data_kva = kva->buf_addr + kva->data_off - kni->mbuf_va
155                                 + kni->mbuf_kva;
156
157                 skb = dev_alloc_skb(len + 2);
158                 if (!skb) {
159                         KNI_ERR("Out of mem, dropping pkts\n");
160                         /* Update statistics */
161                         kni->stats.rx_dropped++;
162                         continue;
163                 }
164
165                 /* Align IP on 16B boundary */
166                 skb_reserve(skb, 2);
167
168                 if (kva->nb_segs == 1) {
169                         memcpy(skb_put(skb, len), data_kva, len);
170                 } else {
171                         int nb_segs;
172                         int kva_nb_segs = kva->nb_segs;
173
174                         for (nb_segs = 0; nb_segs < kva_nb_segs; nb_segs++) {
175                                 memcpy(skb_put(skb, kva->data_len),
176                                         data_kva, kva->data_len);
177
178                                 if (!kva->next)
179                                         break;
180
181                                 kva = kva->next - kni->mbuf_va + kni->mbuf_kva;
182                                 data_kva = kva->buf_addr + kva->data_off
183                                         - kni->mbuf_va + kni->mbuf_kva;
184                         }
185                 }
186
187                 skb->dev = dev;
188                 skb->protocol = eth_type_trans(skb, dev);
189                 skb->ip_summed = CHECKSUM_UNNECESSARY;
190
191                 /* Call netif interface */
192                 netif_rx_ni(skb);
193
194                 /* Update statistics */
195                 kni->stats.rx_bytes += len;
196                 kni->stats.rx_packets++;
197         }
198
199         /* Burst enqueue mbufs into free_q */
200         ret = kni_fifo_put(kni->free_q, (void **)va, num_rx);
201         if (ret != num_rx)
202                 /* Failing should not happen */
203                 KNI_ERR("Fail to enqueue entries into free_q\n");
204 }
205
206 /*
207  * RX: loopback with enqueue/dequeue fifos.
208  */
209 static void
210 kni_net_rx_lo_fifo(struct kni_dev *kni)
211 {
212         unsigned ret;
213         uint32_t len;
214         unsigned i, num, num_rq, num_tq, num_aq, num_fq;
215         struct rte_kni_mbuf *kva;
216         struct rte_kni_mbuf *va[MBUF_BURST_SZ];
217         void * data_kva;
218
219         struct rte_kni_mbuf *alloc_kva;
220         struct rte_kni_mbuf *alloc_va[MBUF_BURST_SZ];
221         void *alloc_data_kva;
222
223         /* Get the number of entries in rx_q */
224         num_rq = kni_fifo_count(kni->rx_q);
225
226         /* Get the number of free entrie in tx_q */
227         num_tq = kni_fifo_free_count(kni->tx_q);
228
229         /* Get the number of entries in alloc_q */
230         num_aq = kni_fifo_count(kni->alloc_q);
231
232         /* Get the number of free entries in free_q */
233         num_fq = kni_fifo_free_count(kni->free_q);
234
235         /* Calculate the number of entries to be dequeued from rx_q */
236         num = min(num_rq, num_tq);
237         num = min(num, num_aq);
238         num = min(num, num_fq);
239         num = min(num, (unsigned)MBUF_BURST_SZ);
240
241         /* Return if no entry to dequeue from rx_q */
242         if (num == 0)
243                 return;
244
245         /* Burst dequeue from rx_q */
246         ret = kni_fifo_get(kni->rx_q, (void **)va, num);
247         if (ret == 0)
248                 return; /* Failing should not happen */
249
250         /* Dequeue entries from alloc_q */
251         ret = kni_fifo_get(kni->alloc_q, (void **)alloc_va, num);
252         if (ret) {
253                 num = ret;
254                 /* Copy mbufs */
255                 for (i = 0; i < num; i++) {
256                         kva = (void *)va[i] - kni->mbuf_va + kni->mbuf_kva;
257                         len = kva->pkt_len;
258                         data_kva = kva->buf_addr + kva->data_off -
259                                         kni->mbuf_va + kni->mbuf_kva;
260
261                         alloc_kva = (void *)alloc_va[i] - kni->mbuf_va +
262                                                         kni->mbuf_kva;
263                         alloc_data_kva = alloc_kva->buf_addr +
264                                         alloc_kva->data_off - kni->mbuf_va +
265                                                         kni->mbuf_kva;
266                         memcpy(alloc_data_kva, data_kva, len);
267                         alloc_kva->pkt_len = len;
268                         alloc_kva->data_len = len;
269
270                         kni->stats.tx_bytes += len;
271                         kni->stats.rx_bytes += len;
272                 }
273
274                 /* Burst enqueue mbufs into tx_q */
275                 ret = kni_fifo_put(kni->tx_q, (void **)alloc_va, num);
276                 if (ret != num)
277                         /* Failing should not happen */
278                         KNI_ERR("Fail to enqueue mbufs into tx_q\n");
279         }
280
281         /* Burst enqueue mbufs into free_q */
282         ret = kni_fifo_put(kni->free_q, (void **)va, num);
283         if (ret != num)
284                 /* Failing should not happen */
285                 KNI_ERR("Fail to enqueue mbufs into free_q\n");
286
287         /**
288          * Update statistic, and enqueue/dequeue failure is impossible,
289          * as all queues are checked at first.
290          */
291         kni->stats.tx_packets += num;
292         kni->stats.rx_packets += num;
293 }
294
295 /*
296  * RX: loopback with enqueue/dequeue fifos and sk buffer copies.
297  */
298 static void
299 kni_net_rx_lo_fifo_skb(struct kni_dev *kni)
300 {
301         unsigned ret;
302         uint32_t len;
303         unsigned i, num_rq, num_fq, num;
304         struct rte_kni_mbuf *kva;
305         struct rte_kni_mbuf *va[MBUF_BURST_SZ];
306         void * data_kva;
307
308         struct sk_buff *skb;
309         struct net_device *dev = kni->net_dev;
310
311         /* Get the number of entries in rx_q */
312         num_rq = kni_fifo_count(kni->rx_q);
313
314         /* Get the number of free entries in free_q */
315         num_fq = kni_fifo_free_count(kni->free_q);
316
317         /* Calculate the number of entries to dequeue from rx_q */
318         num = min(num_rq, num_fq);
319         num = min(num, (unsigned)MBUF_BURST_SZ);
320
321         /* Return if no entry to dequeue from rx_q */
322         if (num == 0)
323                 return;
324
325         /* Burst dequeue mbufs from rx_q */
326         ret = kni_fifo_get(kni->rx_q, (void **)va, num);
327         if (ret == 0)
328                 return;
329
330         /* Copy mbufs to sk buffer and then call tx interface */
331         for (i = 0; i < num; i++) {
332                 kva = (void *)va[i] - kni->mbuf_va + kni->mbuf_kva;
333                 len = kva->pkt_len;
334                 data_kva = kva->buf_addr + kva->data_off - kni->mbuf_va +
335                                 kni->mbuf_kva;
336
337                 skb = dev_alloc_skb(len + 2);
338                 if (skb == NULL)
339                         KNI_ERR("Out of mem, dropping pkts\n");
340                 else {
341                         /* Align IP on 16B boundary */
342                         skb_reserve(skb, 2);
343                         memcpy(skb_put(skb, len), data_kva, len);
344                         skb->dev = dev;
345                         skb->ip_summed = CHECKSUM_UNNECESSARY;
346                         dev_kfree_skb(skb);
347                 }
348
349                 /* Simulate real usage, allocate/copy skb twice */
350                 skb = dev_alloc_skb(len + 2);
351                 if (skb == NULL) {
352                         KNI_ERR("Out of mem, dropping pkts\n");
353                         kni->stats.rx_dropped++;
354                         continue;
355                 }
356
357                 /* Align IP on 16B boundary */
358                 skb_reserve(skb, 2);
359
360                 if (kva->nb_segs == 1) {
361                         memcpy(skb_put(skb, len), data_kva, len);
362                 } else {
363                         int nb_segs;
364                         int kva_nb_segs = kva->nb_segs;
365
366                         for (nb_segs = 0; nb_segs < kva_nb_segs; nb_segs++) {
367                                 memcpy(skb_put(skb, kva->data_len),
368                                         data_kva, kva->data_len);
369
370                                 if (!kva->next)
371                                         break;
372
373                                 kva = kva->next - kni->mbuf_va + kni->mbuf_kva;
374                                 data_kva = kva->buf_addr + kva->data_off
375                                         - kni->mbuf_va + kni->mbuf_kva;
376                         }
377                 }
378
379                 skb->dev = dev;
380                 skb->ip_summed = CHECKSUM_UNNECESSARY;
381
382                 kni->stats.rx_bytes += len;
383                 kni->stats.rx_packets++;
384
385                 /* call tx interface */
386                 kni_net_tx(skb, dev);
387         }
388
389         /* enqueue all the mbufs from rx_q into free_q */
390         ret = kni_fifo_put(kni->free_q, (void **)&va, num);
391         if (ret != num)
392                 /* Failing should not happen */
393                 KNI_ERR("Fail to enqueue mbufs into free_q\n");
394 }
395
396 /* rx interface */
397 void
398 kni_net_rx(struct kni_dev *kni)
399 {
400         /**
401          * It doesn't need to check if it is NULL pointer,
402          * as it has a default value
403          */
404         (*kni_net_rx_func)(kni);
405 }
406
407 /*
408  * Transmit a packet (called by the kernel)
409  */
410 #ifdef RTE_KNI_VHOST
411 static int
412 kni_net_tx(struct sk_buff *skb, struct net_device *dev)
413 {
414         struct kni_dev *kni = netdev_priv(dev);
415
416         dev_kfree_skb(skb);
417         kni->stats.tx_dropped++;
418
419         return NETDEV_TX_OK;
420 }
421 #else
422 static int
423 kni_net_tx(struct sk_buff *skb, struct net_device *dev)
424 {
425         int len = 0;
426         unsigned ret;
427         struct kni_dev *kni = netdev_priv(dev);
428         struct rte_kni_mbuf *pkt_kva = NULL;
429         struct rte_kni_mbuf *pkt_va = NULL;
430
431         /* save the timestamp */
432 #ifdef HAVE_TRANS_START_HELPER
433         netif_trans_update(dev);
434 #else
435         dev->trans_start = jiffies;
436 #endif
437
438         /* Check if the length of skb is less than mbuf size */
439         if (skb->len > kni->mbuf_size)
440                 goto drop;
441
442         /**
443          * Check if it has at least one free entry in tx_q and
444          * one entry in alloc_q.
445          */
446         if (kni_fifo_free_count(kni->tx_q) == 0 ||
447                         kni_fifo_count(kni->alloc_q) == 0) {
448                 /**
449                  * If no free entry in tx_q or no entry in alloc_q,
450                  * drops skb and goes out.
451                  */
452                 goto drop;
453         }
454
455         /* dequeue a mbuf from alloc_q */
456         ret = kni_fifo_get(kni->alloc_q, (void **)&pkt_va, 1);
457         if (likely(ret == 1)) {
458                 void *data_kva;
459
460                 pkt_kva = (void *)pkt_va - kni->mbuf_va + kni->mbuf_kva;
461                 data_kva = pkt_kva->buf_addr + pkt_kva->data_off - kni->mbuf_va
462                                 + kni->mbuf_kva;
463
464                 len = skb->len;
465                 memcpy(data_kva, skb->data, len);
466                 if (unlikely(len < ETH_ZLEN)) {
467                         memset(data_kva + len, 0, ETH_ZLEN - len);
468                         len = ETH_ZLEN;
469                 }
470                 pkt_kva->pkt_len = len;
471                 pkt_kva->data_len = len;
472
473                 /* enqueue mbuf into tx_q */
474                 ret = kni_fifo_put(kni->tx_q, (void **)&pkt_va, 1);
475                 if (unlikely(ret != 1)) {
476                         /* Failing should not happen */
477                         KNI_ERR("Fail to enqueue mbuf into tx_q\n");
478                         goto drop;
479                 }
480         } else {
481                 /* Failing should not happen */
482                 KNI_ERR("Fail to dequeue mbuf from alloc_q\n");
483                 goto drop;
484         }
485
486         /* Free skb and update statistics */
487         dev_kfree_skb(skb);
488         kni->stats.tx_bytes += len;
489         kni->stats.tx_packets++;
490
491         return NETDEV_TX_OK;
492
493 drop:
494         /* Free skb and update statistics */
495         dev_kfree_skb(skb);
496         kni->stats.tx_dropped++;
497
498         return NETDEV_TX_OK;
499 }
500 #endif
501
502 /*
503  * Deal with a transmit timeout.
504  */
505 static void
506 kni_net_tx_timeout (struct net_device *dev)
507 {
508         struct kni_dev *kni = netdev_priv(dev);
509
510         KNI_DBG("Transmit timeout at %ld, latency %ld\n", jiffies,
511                         jiffies - dev->trans_start);
512
513         kni->stats.tx_errors++;
514         netif_wake_queue(dev);
515         return;
516 }
517
518 /*
519  * Ioctl commands
520  */
521 static int
522 kni_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
523 {
524         KNI_DBG("kni_net_ioctl %d\n",
525                 ((struct kni_dev *)netdev_priv(dev))->group_id);
526
527         return 0;
528 }
529
530 static void
531 kni_net_set_rx_mode(struct net_device *dev)
532 {
533 }
534
535 static int
536 kni_net_change_mtu(struct net_device *dev, int new_mtu)
537 {
538         int ret;
539         struct rte_kni_request req;
540         struct kni_dev *kni = netdev_priv(dev);
541
542         KNI_DBG("kni_net_change_mtu new mtu %d to be set\n", new_mtu);
543
544         memset(&req, 0, sizeof(req));
545         req.req_id = RTE_KNI_REQ_CHANGE_MTU;
546         req.new_mtu = new_mtu;
547         ret = kni_net_process_request(kni, &req);
548         if (ret == 0 && req.result == 0)
549                 dev->mtu = new_mtu;
550
551         return (ret == 0) ? req.result : ret;
552 }
553
554 /*
555  * Checks if the user space application provided the resp message
556  */
557 void
558 kni_net_poll_resp(struct kni_dev *kni)
559 {
560         if (kni_fifo_count(kni->resp_q))
561                 wake_up_interruptible(&kni->wq);
562 }
563
564 /*
565  * It can be called to process the request.
566  */
567 static int
568 kni_net_process_request(struct kni_dev *kni, struct rte_kni_request *req)
569 {
570         int ret = -1;
571         void *resp_va;
572         unsigned num;
573         int ret_val;
574
575         if (!kni || !req) {
576                 KNI_ERR("No kni instance or request\n");
577                 return -EINVAL;
578         }
579
580         mutex_lock(&kni->sync_lock);
581
582         /* Construct data */
583         memcpy(kni->sync_kva, req, sizeof(struct rte_kni_request));
584         num = kni_fifo_put(kni->req_q, &kni->sync_va, 1);
585         if (num < 1) {
586                 KNI_ERR("Cannot send to req_q\n");
587                 ret = -EBUSY;
588                 goto fail;
589         }
590
591         ret_val = wait_event_interruptible_timeout(kni->wq,
592                         kni_fifo_count(kni->resp_q), 3 * HZ);
593         if (signal_pending(current) || ret_val <= 0) {
594                 ret = -ETIME;
595                 goto fail;
596         }
597         num = kni_fifo_get(kni->resp_q, (void **)&resp_va, 1);
598         if (num != 1 || resp_va != kni->sync_va) {
599                 /* This should never happen */
600                 KNI_ERR("No data in resp_q\n");
601                 ret = -ENODATA;
602                 goto fail;
603         }
604
605         memcpy(req, kni->sync_kva, sizeof(struct rte_kni_request));
606         ret = 0;
607
608 fail:
609         mutex_unlock(&kni->sync_lock);
610         return ret;
611 }
612
613 /*
614  * Return statistics to the caller
615  */
616 static struct net_device_stats *
617 kni_net_stats(struct net_device *dev)
618 {
619         struct kni_dev *kni = netdev_priv(dev);
620         return &kni->stats;
621 }
622
623 /*
624  *  Fill the eth header
625  */
626 static int
627 kni_net_header(struct sk_buff *skb, struct net_device *dev,
628                 unsigned short type, const void *daddr,
629                 const void *saddr, unsigned int len)
630 {
631         struct ethhdr *eth = (struct ethhdr *) skb_push(skb, ETH_HLEN);
632
633         memcpy(eth->h_source, saddr ? saddr : dev->dev_addr, dev->addr_len);
634         memcpy(eth->h_dest,   daddr ? daddr : dev->dev_addr, dev->addr_len);
635         eth->h_proto = htons(type);
636
637         return dev->hard_header_len;
638 }
639
640
641 /*
642  * Re-fill the eth header
643  */
644 #ifdef HAVE_REBUILD_HEADER
645 static int
646 kni_net_rebuild_header(struct sk_buff *skb)
647 {
648         struct net_device *dev = skb->dev;
649         struct ethhdr *eth = (struct ethhdr *) skb->data;
650
651         memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
652         memcpy(eth->h_dest, dev->dev_addr, dev->addr_len);
653
654         return 0;
655 }
656 #endif /* < 4.1.0  */
657
658 /**
659  * kni_net_set_mac - Change the Ethernet Address of the KNI NIC
660  * @netdev: network interface device structure
661  * @p: pointer to an address structure
662  *
663  * Returns 0 on success, negative on failure
664  **/
665 static int kni_net_set_mac(struct net_device *netdev, void *p)
666 {
667         struct sockaddr *addr = p;
668         if (!is_valid_ether_addr((unsigned char *)(addr->sa_data)))
669                 return -EADDRNOTAVAIL;
670         memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
671         return 0;
672 }
673
674 #ifdef HAVE_CHANGE_CARRIER_CB
675 static int kni_net_change_carrier(struct net_device *dev, bool new_carrier)
676 {
677         if (new_carrier)
678                 netif_carrier_on(dev);
679         else
680                 netif_carrier_off(dev);
681         return 0;
682 }
683 #endif
684
685 static const struct header_ops kni_net_header_ops = {
686         .create  = kni_net_header,
687 #ifdef HAVE_REBUILD_HEADER
688         .rebuild = kni_net_rebuild_header,
689 #endif /* < 4.1.0  */
690         .cache   = NULL,  /* disable caching */
691 };
692
693 static const struct net_device_ops kni_net_netdev_ops = {
694         .ndo_open = kni_net_open,
695         .ndo_stop = kni_net_release,
696         .ndo_set_config = kni_net_config,
697         .ndo_start_xmit = kni_net_tx,
698         .ndo_change_mtu = kni_net_change_mtu,
699         .ndo_do_ioctl = kni_net_ioctl,
700         .ndo_set_rx_mode = kni_net_set_rx_mode,
701         .ndo_get_stats = kni_net_stats,
702         .ndo_tx_timeout = kni_net_tx_timeout,
703         .ndo_set_mac_address = kni_net_set_mac,
704 #ifdef HAVE_CHANGE_CARRIER_CB
705         .ndo_change_carrier = kni_net_change_carrier,
706 #endif
707 };
708
709 void
710 kni_net_init(struct net_device *dev)
711 {
712         struct kni_dev *kni = netdev_priv(dev);
713
714         KNI_DBG("kni_net_init\n");
715
716         init_waitqueue_head(&kni->wq);
717         mutex_init(&kni->sync_lock);
718
719         ether_setup(dev); /* assign some of the fields */
720         dev->netdev_ops      = &kni_net_netdev_ops;
721         dev->header_ops      = &kni_net_header_ops;
722         dev->watchdog_timeo = WD_TIMEOUT;
723 }
724
725 void
726 kni_net_config_lo_mode(char *lo_str)
727 {
728         if (!lo_str) {
729                 KNI_PRINT("loopback disabled");
730                 return;
731         }
732
733         if (!strcmp(lo_str, "lo_mode_none"))
734                 KNI_PRINT("loopback disabled");
735         else if (!strcmp(lo_str, "lo_mode_fifo")) {
736                 KNI_PRINT("loopback mode=lo_mode_fifo enabled");
737                 kni_net_rx_func = kni_net_rx_lo_fifo;
738         } else if (!strcmp(lo_str, "lo_mode_fifo_skb")) {
739                 KNI_PRINT("loopback mode=lo_mode_fifo_skb enabled");
740                 kni_net_rx_func = kni_net_rx_lo_fifo_skb;
741         } else
742                 KNI_PRINT("Incognizant parameter, loopback disabled");
743 }