acd0e8275ff79324e2c37bafa6aeb68c2e0b3cf9
[dpdk.git] / lib / librte_eal / linuxapp / kni / kni_misc.c
1 /*-
2  * GPL LICENSE SUMMARY
3  * 
4  *   Copyright(c) 2010-2012 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 #include <linux/module.h>
27 #include <linux/miscdevice.h>
28 #include <linux/netdevice.h>
29 #include <linux/pci.h>
30 #include <linux/kthread.h>
31
32 #include <exec-env/rte_kni_common.h>
33 #include "kni_dev.h"
34 #include <rte_config.h>
35
36 MODULE_LICENSE("Dual BSD/GPL");
37 MODULE_AUTHOR("Intel Corporation");
38 MODULE_DESCRIPTION("Kernel Module for managing kni devices");
39
40 #define KNI_RX_LOOP_NUM 1000
41
42 #define KNI_MAX_DEVICES 32
43
44 extern void kni_net_rx(struct kni_dev *kni);
45 extern void kni_net_init(struct net_device *dev);
46 extern void kni_net_config_lo_mode(char *lo_str);
47 extern void kni_net_poll_resp(struct kni_dev *kni);
48 extern void kni_set_ethtool_ops(struct net_device *netdev);
49
50 extern int ixgbe_kni_probe(struct pci_dev *pdev, struct net_device **lad_dev);
51 extern void ixgbe_kni_remove(struct pci_dev *pdev);
52 extern int igb_kni_probe(struct pci_dev *pdev, struct net_device **lad_dev);
53 extern void igb_kni_remove(struct pci_dev *pdev);
54
55 static int kni_open(struct inode *inode, struct file *file);
56 static int kni_release(struct inode *inode, struct file *file);
57 static int kni_ioctl(struct inode *inode, unsigned int ioctl_num,
58                                         unsigned long ioctl_param);
59 static int kni_compat_ioctl(struct inode *inode, unsigned int ioctl_num,
60                                                 unsigned long ioctl_param);
61
62 /* kni kernel thread for rx */
63 static int kni_thread(void *unused);
64
65 static struct file_operations kni_fops = {
66         .owner = THIS_MODULE,
67         .open = kni_open,
68         .release = kni_release,
69         .unlocked_ioctl = (void *)kni_ioctl,
70         .compat_ioctl = (void *)kni_compat_ioctl,
71 };
72
73 static struct miscdevice kni_misc = {
74         .minor = MISC_DYNAMIC_MINOR,
75         .name = KNI_DEVICE,
76         .fops = &kni_fops,
77 };
78
79 /* loopback mode */
80 static char *lo_mode = NULL;
81
82 static struct kni_dev *kni_devs[KNI_MAX_DEVICES];
83 static volatile int num_devs;  /* number of kni devices */
84
85 #define KNI_DEV_IN_USE_BIT_NUM 0 /* Bit number for device in use */
86
87 static volatile unsigned long device_in_use; /* device in use flag */
88 static struct task_struct *kni_kthread;
89
90 static int __init
91 kni_init(void)
92 {
93         KNI_PRINT("######## DPDK kni module loading ########\n");
94
95         if (misc_register(&kni_misc) != 0) {
96                 KNI_ERR("Misc registration failed\n");
97                 return 1;
98         }
99
100         /* Clear the bit of device in use */
101         clear_bit(KNI_DEV_IN_USE_BIT_NUM, &device_in_use);
102
103         /* Configure the lo mode according to the input parameter */
104         kni_net_config_lo_mode(lo_mode);
105
106         KNI_PRINT("######## DPDK kni module loaded  ########\n");
107
108         return 0;
109 }
110
111 static void __exit
112 kni_exit(void)
113 {
114         misc_deregister(&kni_misc);
115         KNI_PRINT("####### DPDK kni module unloaded  #######\n");
116 }
117
118 static int
119 kni_open(struct inode *inode, struct file *file)
120 {
121         /* kni device can be opened by one user only, test and set bit */
122         if (test_and_set_bit(KNI_DEV_IN_USE_BIT_NUM, &device_in_use))
123                 return -EBUSY;
124
125         memset(kni_devs, 0, sizeof(kni_devs));
126         num_devs = 0;
127
128         /* Create kernel thread for RX */
129         kni_kthread = kthread_run(kni_thread, NULL, "kni_thread");
130         if (IS_ERR(kni_kthread)) {
131                 KNI_ERR("Unable to create kernel threaed\n");
132                 return PTR_ERR(kni_kthread);
133         }
134
135         KNI_PRINT("/dev/kni opened\n");
136
137         return 0;
138 }
139
140 static int
141 kni_release(struct inode *inode, struct file *file)
142 {
143         int i;
144
145         KNI_PRINT("Stopping KNI thread...");
146
147         /* Stop kernel thread */
148         kthread_stop(kni_kthread);
149         kni_kthread = NULL;
150
151         for (i = 0; i < KNI_MAX_DEVICES; i++) {
152                 if (kni_devs[i] != NULL) {
153                         /* Call the remove part to restore pci dev */
154                         switch (kni_devs[i]->device_id) {
155                         #define RTE_PCI_DEV_ID_DECL_IGB(vend, dev) case (dev):
156                         #include <rte_pci_dev_ids.h>
157                                 igb_kni_remove(kni_devs[i]->pci_dev);
158                                 break;
159                         #define RTE_PCI_DEV_ID_DECL_IXGBE(vend, dev) case (dev):
160                         #include <rte_pci_dev_ids.h>
161                                 ixgbe_kni_remove(kni_devs[i]->pci_dev);
162                                 break;
163                         default:
164                                 break;
165                         }
166
167                         unregister_netdev(kni_devs[i]->net_dev);
168                         free_netdev(kni_devs[i]->net_dev);
169                         kni_devs[i] = NULL;
170                 }
171         }
172         num_devs = 0;
173
174         /* Clear the bit of device in use */
175         clear_bit(KNI_DEV_IN_USE_BIT_NUM, &device_in_use);
176
177         KNI_PRINT("/dev/kni closed\n");
178
179         return 0;
180 }
181
182 static int
183 kni_thread(void *unused)
184 {
185         int i, j;
186
187         KNI_PRINT("Kernel thread for KNI started\n");
188         while (!kthread_should_stop()) {
189                 int n_devs = num_devs;
190                 for (j = 0; j < KNI_RX_LOOP_NUM; j++) {
191                         for (i = 0; i < n_devs; i++) {
192                                 /* This shouldn't be needed */
193                                 if (kni_devs[i]) {
194                                         kni_net_rx(kni_devs[i]);
195                                         kni_net_poll_resp(kni_devs[i]);
196                                 }
197                                 else
198                                         KNI_ERR("kni_thread -no kni found!!!");
199                         }
200                 }
201                 /* reschedule out for a while */
202                 schedule_timeout_interruptible(usecs_to_jiffies( \
203                                 KNI_KTHREAD_RESCHEDULE_INTERVAL));
204         }
205         KNI_PRINT("Kernel thread for KNI stopped\n");
206
207         return 0;
208 }
209
210 static int
211 kni_ioctl_create(unsigned int ioctl_num, unsigned long ioctl_param)
212 {
213         int ret;
214         struct rte_kni_device_info dev_info;
215         struct pci_dev *pci = NULL;
216         struct pci_dev *found_pci = NULL;
217         struct net_device *net_dev = NULL;
218         struct net_device *lad_dev = NULL;
219         struct kni_dev *kni;
220
221         if (num_devs == KNI_MAX_DEVICES)
222                 return -EBUSY;
223
224         /* Check the buffer size, to avoid warning */
225         if (_IOC_SIZE(ioctl_num) > sizeof(dev_info))
226                 return -EINVAL;
227
228         /* Copy kni info from user space */
229         ret = copy_from_user(&dev_info, (void *)ioctl_param,
230                                         _IOC_SIZE(ioctl_num));
231         if (ret) {
232                 KNI_ERR("copy_from_user");
233                 return -EIO;
234         }
235
236         net_dev = alloc_netdev(sizeof(struct kni_dev), dev_info.name,
237                                                         kni_net_init);
238         if (net_dev == NULL) {
239                 KNI_ERR("error allocating device \"%s\"\n", dev_info.name);
240                 return -EBUSY;
241         }
242
243         kni = netdev_priv(net_dev);
244
245         kni->net_dev = net_dev;
246         kni->idx = num_devs;
247
248         /* Translate user space info into kernel space info */
249         kni->tx_q = phys_to_virt(dev_info.tx_phys);
250         kni->rx_q = phys_to_virt(dev_info.rx_phys);
251         kni->alloc_q = phys_to_virt(dev_info.alloc_phys);
252         kni->free_q = phys_to_virt(dev_info.free_phys);
253
254         kni->req_q = phys_to_virt(dev_info.req_phys);
255         kni->resp_q = phys_to_virt(dev_info.resp_phys);
256
257         kni->sync_va = dev_info.sync_va;
258         kni->sync_kva = phys_to_virt(dev_info.sync_phys);
259
260         kni->mbuf_kva = phys_to_virt(dev_info.mbuf_phys);
261         kni->mbuf_va = dev_info.mbuf_va;
262
263         kni->mbuf_size = dev_info.mbuf_size;
264
265         KNI_PRINT("tx_phys:          0x%016llx, tx_q addr:          0x%p\n",
266                                                 dev_info.tx_phys, kni->tx_q);
267         KNI_PRINT("rx_phys:          0x%016llx, rx_q addr:          0x%p\n",
268                                                 dev_info.rx_phys, kni->rx_q);
269         KNI_PRINT("alloc_phys:       0x%016llx, alloc_q addr:       0x%p\n",
270                                         dev_info.alloc_phys, kni->alloc_q);
271         KNI_PRINT("free_phys:        0x%016llx, free_q addr:        0x%p\n",
272                                         dev_info.free_phys, kni->free_q);
273         KNI_PRINT("req_phys:         0x%016llx, req_q addr:         0x%p\n",
274                                         dev_info.req_phys, kni->req_q);
275         KNI_PRINT("resp_phys:        0x%016llx, resp_q addr:        0x%p\n",
276                                         dev_info.resp_phys, kni->resp_q);
277         KNI_PRINT("mbuf_phys:        0x%016llx, mbuf_kva:           0x%p\n",
278                                         dev_info.mbuf_phys, kni->mbuf_kva);
279         KNI_PRINT("mbuf_va:          0x%p\n", dev_info.mbuf_va);
280         KNI_PRINT("mbuf_size:        %u\n", kni->mbuf_size);
281
282         KNI_DBG("PCI: %02x:%02x.%02x %04x:%04x\n", dev_info.bus, dev_info.devid,
283                         dev_info.function, dev_info.vendor_id, dev_info.device_id);
284
285         pci = pci_get_device(dev_info.vendor_id, dev_info.device_id, NULL);
286
287         /* Support Ethtool */
288         while (pci) {
289                 KNI_PRINT("pci_bus: %02x:%02x:%02x \n", pci->bus->number,
290                                 PCI_SLOT(pci->devfn), PCI_FUNC(pci->devfn));
291
292                 if ((pci->bus->number == dev_info.bus) &&
293                         (PCI_SLOT(pci->devfn) == dev_info.devid) &&
294                         (PCI_FUNC(pci->devfn) == dev_info.function)) {
295                         found_pci = pci;
296
297                         switch (dev_info.device_id) {
298                         #define RTE_PCI_DEV_ID_DECL_IGB(vend, dev) case (dev):
299                         #include <rte_pci_dev_ids.h>
300                                 ret = igb_kni_probe(found_pci, &lad_dev);
301                                 break;
302                         #define RTE_PCI_DEV_ID_DECL_IXGBE(vend, dev) case (dev):
303                         #include <rte_pci_dev_ids.h>
304                                 ret = ixgbe_kni_probe(found_pci, &lad_dev);
305                                 break;
306                         default:
307                                 ret = -1;
308                                 break;
309                         }
310
311                         KNI_DBG("PCI found: pci=0x%p, lad_dev=0x%p\n", pci, lad_dev);
312                         if (ret == 0) {
313                                 kni->lad_dev = lad_dev;
314                                 kni_set_ethtool_ops(kni->net_dev);
315                         }
316                         else {
317                                 KNI_ERR("Device not supported by ethtool");
318                                 kni->lad_dev = NULL;
319                         }
320
321                         kni->pci_dev = found_pci;
322                         kni->device_id = dev_info.device_id;
323                         break;
324                 }
325                 pci = pci_get_device(dev_info.vendor_id, dev_info.device_id,
326                                                                         pci);
327         }
328
329         if (pci)
330                 pci_dev_put(pci);
331
332         ret = register_netdev(net_dev);
333         if (ret) {
334                 KNI_ERR("error %i registering device \"%s\"\n", ret,
335                                                         dev_info.name);
336                 free_netdev(net_dev);
337                 return -ENODEV;
338         }
339
340         kni_devs[num_devs++] = kni;
341
342         return 0;
343 }
344
345 static int
346 kni_ioctl(struct inode *inode,
347         unsigned int ioctl_num,
348         unsigned long ioctl_param)
349 {
350         int ret = -EINVAL;
351
352         KNI_DBG("IOCTL num=0x%0x param=0x%0lx \n", ioctl_num, ioctl_param);
353
354         /*
355          * Switch according to the ioctl called
356          */
357         switch (_IOC_NR(ioctl_num)) {
358         case _IOC_NR(RTE_KNI_IOCTL_TEST):
359                 /* For test only, not used */
360                 break;
361         case _IOC_NR(RTE_KNI_IOCTL_CREATE):
362                 ret = kni_ioctl_create(ioctl_num, ioctl_param);
363                 break;
364         default:
365                 KNI_DBG("IOCTL default \n");
366                 break;
367         }
368
369         return ret;
370 }
371
372 static int
373 kni_compat_ioctl(struct inode *inode,
374                 unsigned int ioctl_num,
375                 unsigned long ioctl_param)
376 {
377         /* 32 bits app on 64 bits OS to be supported later */
378         KNI_PRINT("Not implemented.\n");
379
380         return -EINVAL;
381 }
382
383 module_init(kni_init);
384 module_exit(kni_exit);
385
386 module_param(lo_mode, charp, S_IRUGO | S_IWUSR);
387 MODULE_PARM_DESC(lo_mode,
388 "KNI loopback mode (default=lo_mode_none):\n"
389 "    lo_mode_none        Kernel loopback disabled\n"
390 "    lo_mode_fifo        Enable kernel loopback with fifo\n"
391 "    lo_mode_fifo_skb    Enable kernel loopback with fifo and skb buffer\n"
392 "\n"
393 );
394