X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=kernel%2Flinux%2Fkni%2Fkni_misc.c;h=2b464c438113f0379073373ecea13a2c7bb32551;hb=cbbbbd3365d299f55233b8f9a09ce0d9e43ec3ad;hp=fa69f8e6387af3324d06f22eab4773e1149f0eb5;hpb=e77fec694936ce067153c5a6596c6bc818baaa5c;p=dpdk.git diff --git a/kernel/linux/kni/kni_misc.c b/kernel/linux/kni/kni_misc.c index fa69f8e638..2b464c4381 100644 --- a/kernel/linux/kni/kni_misc.c +++ b/kernel/linux/kni/kni_misc.c @@ -16,11 +16,12 @@ #include #include -#include +#include #include "compat.h" #include "kni_dev.h" +MODULE_VERSION(KNI_VERSION); MODULE_LICENSE("Dual BSD/GPL"); MODULE_AUTHOR("Intel Corporation"); MODULE_DESCRIPTION("Kernel Module for managing kni devices"); @@ -29,9 +30,6 @@ MODULE_DESCRIPTION("Kernel Module for managing kni devices"); #define KNI_MAX_DEVICES 32 -extern const struct pci_device_id ixgbe_pci_tbl[]; -extern const struct pci_device_id igb_pci_tbl[]; - /* loopback mode */ static char *lo_mode; @@ -39,6 +37,10 @@ static char *lo_mode; static char *kthread_mode; static uint32_t multiple_kthread_on; +/* Default carrier state for created KNI network interfaces */ +static char *carrier; +uint32_t kni_dflt_carrier; + #define KNI_DEV_IN_USE_BIT_NUM 0 /* Bit number for device in use */ static int kni_net_id; @@ -178,15 +180,6 @@ kni_dev_remove(struct kni_dev *dev) if (!dev) return -ENODEV; -#ifdef RTE_KNI_KMOD_ETHTOOL - if (dev->pci_dev) { - if (pci_match_id(ixgbe_pci_tbl, dev->pci_dev)) - ixgbe_kni_remove(dev->pci_dev); - else if (pci_match_id(igb_pci_tbl, dev->pci_dev)) - igb_kni_remove(dev->pci_dev); - } -#endif - if (dev->net_dev) { unregister_netdev(dev->net_dev); free_netdev(dev->net_dev); @@ -302,11 +295,6 @@ kni_ioctl_create(struct net *net, uint32_t ioctl_num, struct rte_kni_device_info dev_info; struct net_device *net_dev = NULL; struct kni_dev *kni, *dev, *n; -#ifdef RTE_KNI_KMOD_ETHTOOL - struct pci_dev *found_pci = NULL; - struct net_device *lad_dev = NULL; - struct pci_dev *pci = NULL; -#endif pr_info("Creating kni...\n"); /* Check the buffer size, to avoid warning */ @@ -314,11 +302,8 @@ kni_ioctl_create(struct net *net, uint32_t ioctl_num, return -EINVAL; /* Copy kni info from user space */ - ret = copy_from_user(&dev_info, (void *)ioctl_param, sizeof(dev_info)); - if (ret) { - pr_err("copy_from_user in kni_ioctl_create"); - return -EIO; - } + if (copy_from_user(&dev_info, (void *)ioctl_param, sizeof(dev_info))) + return -EFAULT; /* Check if name is zero-ended */ if (strnlen(dev_info.name, sizeof(dev_info.name)) == sizeof(dev_info.name)) { @@ -359,20 +344,40 @@ kni_ioctl_create(struct net *net, uint32_t ioctl_num, kni = netdev_priv(net_dev); kni->net_dev = net_dev; - kni->group_id = dev_info.group_id; kni->core_id = dev_info.core_id; strncpy(kni->name, dev_info.name, RTE_KNI_NAMESIZE); /* Translate user space info into kernel space info */ - kni->tx_q = phys_to_virt(dev_info.tx_phys); - kni->rx_q = phys_to_virt(dev_info.rx_phys); - kni->alloc_q = phys_to_virt(dev_info.alloc_phys); - kni->free_q = phys_to_virt(dev_info.free_phys); + if (dev_info.iova_mode) { +#ifdef HAVE_IOVA_TO_KVA_MAPPING_SUPPORT + kni->tx_q = iova_to_kva(current, dev_info.tx_phys); + kni->rx_q = iova_to_kva(current, dev_info.rx_phys); + kni->alloc_q = iova_to_kva(current, dev_info.alloc_phys); + kni->free_q = iova_to_kva(current, dev_info.free_phys); + + kni->req_q = iova_to_kva(current, dev_info.req_phys); + kni->resp_q = iova_to_kva(current, dev_info.resp_phys); + kni->sync_va = dev_info.sync_va; + kni->sync_kva = iova_to_kva(current, dev_info.sync_phys); + kni->usr_tsk = current; + kni->iova_mode = 1; +#else + pr_err("KNI module does not support IOVA to VA translation\n"); + return -EINVAL; +#endif + } else { - kni->req_q = phys_to_virt(dev_info.req_phys); - kni->resp_q = phys_to_virt(dev_info.resp_phys); - kni->sync_va = dev_info.sync_va; - kni->sync_kva = phys_to_virt(dev_info.sync_phys); + kni->tx_q = phys_to_virt(dev_info.tx_phys); + kni->rx_q = phys_to_virt(dev_info.rx_phys); + kni->alloc_q = phys_to_virt(dev_info.alloc_phys); + kni->free_q = phys_to_virt(dev_info.free_phys); + + kni->req_q = phys_to_virt(dev_info.req_phys); + kni->resp_q = phys_to_virt(dev_info.resp_phys); + kni->sync_va = dev_info.sync_va; + kni->sync_kva = phys_to_virt(dev_info.sync_phys); + kni->iova_mode = 0; + } kni->mbuf_size = dev_info.mbuf_size; @@ -390,71 +395,27 @@ kni_ioctl_create(struct net *net, uint32_t ioctl_num, (unsigned long long) dev_info.resp_phys, kni->resp_q); pr_debug("mbuf_size: %u\n", kni->mbuf_size); - pr_debug("PCI: %02x:%02x.%02x %04x:%04x\n", - dev_info.bus, - dev_info.devid, - dev_info.function, - dev_info.vendor_id, - dev_info.device_id); -#ifdef RTE_KNI_KMOD_ETHTOOL - pci = pci_get_device(dev_info.vendor_id, dev_info.device_id, NULL); - - /* Support Ethtool */ - while (pci) { - pr_debug("pci_bus: %02x:%02x:%02x\n", - pci->bus->number, - PCI_SLOT(pci->devfn), - PCI_FUNC(pci->devfn)); - - if ((pci->bus->number == dev_info.bus) && - (PCI_SLOT(pci->devfn) == dev_info.devid) && - (PCI_FUNC(pci->devfn) == dev_info.function)) { - found_pci = pci; - - if (pci_match_id(ixgbe_pci_tbl, found_pci)) - ret = ixgbe_kni_probe(found_pci, &lad_dev); - else if (pci_match_id(igb_pci_tbl, found_pci)) - ret = igb_kni_probe(found_pci, &lad_dev); - else - ret = -1; - - pr_debug("PCI found: pci=0x%p, lad_dev=0x%p\n", - pci, lad_dev); - if (ret == 0) { - kni->lad_dev = lad_dev; - kni_set_ethtool_ops(kni->net_dev); - } else { - pr_err("Device not supported by ethtool"); - kni->lad_dev = NULL; - } - - kni->pci_dev = found_pci; - kni->device_id = dev_info.device_id; - break; - } - pci = pci_get_device(dev_info.vendor_id, - dev_info.device_id, pci); - } - if (pci) - pci_dev_put(pci); -#endif - - if (kni->lad_dev) - ether_addr_copy(net_dev->dev_addr, kni->lad_dev->dev_addr); - else { - /* if user has provided a valid mac address */ - if (is_valid_ether_addr((unsigned char *)(dev_info.mac_addr))) - memcpy(net_dev->dev_addr, dev_info.mac_addr, ETH_ALEN); - else - /* - * Generate random mac address. eth_random_addr() is the - * newer version of generating mac address in kernel. - */ - random_ether_addr(net_dev->dev_addr); - } + /* if user has provided a valid mac address */ + if (is_valid_ether_addr(dev_info.mac_addr)) + memcpy(net_dev->dev_addr, dev_info.mac_addr, ETH_ALEN); + else + /* + * Generate random mac address. eth_random_addr() is the + * newer version of generating mac address in kernel. + */ + random_ether_addr(net_dev->dev_addr); if (dev_info.mtu) net_dev->mtu = dev_info.mtu; +#ifdef HAVE_MAX_MTU_PARAM + net_dev->max_mtu = net_dev->mtu; + + if (dev_info.min_mtu) + net_dev->min_mtu = dev_info.min_mtu; + + if (dev_info.max_mtu) + net_dev->max_mtu = dev_info.max_mtu; +#endif ret = register_netdev(net_dev); if (ret) { @@ -466,6 +427,8 @@ kni_ioctl_create(struct net *net, uint32_t ioctl_num, return -ENODEV; } + netif_carrier_off(net_dev); + ret = kni_run_thread(knet, kni, dev_info.force_bind); if (ret != 0) return ret; @@ -489,15 +452,12 @@ kni_ioctl_release(struct net *net, uint32_t ioctl_num, if (_IOC_SIZE(ioctl_num) > sizeof(dev_info)) return -EINVAL; - ret = copy_from_user(&dev_info, (void *)ioctl_param, sizeof(dev_info)); - if (ret) { - pr_err("copy_from_user in kni_ioctl_release"); - return -EIO; - } + if (copy_from_user(&dev_info, (void *)ioctl_param, sizeof(dev_info))) + return -EFAULT; /* Release the network device according to its name */ if (strlen(dev_info.name) == 0) - return ret; + return -EINVAL; down_write(&knet->kni_list_lock); list_for_each_entry_safe(dev, n, &knet->kni_list_head, list) { @@ -590,6 +550,24 @@ kni_parse_kthread_mode(void) return 0; } +static int __init +kni_parse_carrier_state(void) +{ + if (!carrier) { + kni_dflt_carrier = 0; + return 0; + } + + if (strcmp(carrier, "off") == 0) + kni_dflt_carrier = 0; + else if (strcmp(carrier, "on") == 0) + kni_dflt_carrier = 1; + else + return -1; + + return 0; +} + static int __init kni_init(void) { @@ -605,6 +583,16 @@ kni_init(void) else pr_debug("Multiple kernel thread mode enabled\n"); + if (kni_parse_carrier_state() < 0) { + pr_err("Invalid parameter for carrier\n"); + return -EINVAL; + } + + if (kni_dflt_carrier == 0) + pr_debug("Default carrier state set to off.\n"); + else + pr_debug("Default carrier state set to on.\n"); + #ifdef HAVE_SIMPLIFIED_PERNET_OPERATIONS rc = register_pernet_subsys(&kni_net_ops); #else @@ -647,19 +635,27 @@ kni_exit(void) module_init(kni_init); module_exit(kni_exit); -module_param(lo_mode, charp, S_IRUGO | S_IWUSR); +module_param(lo_mode, charp, 0644); MODULE_PARM_DESC(lo_mode, "KNI loopback mode (default=lo_mode_none):\n" -" lo_mode_none Kernel loopback disabled\n" -" lo_mode_fifo Enable kernel loopback with fifo\n" -" lo_mode_fifo_skb Enable kernel loopback with fifo and skb buffer\n" -"\n" +"\t\tlo_mode_none Kernel loopback disabled\n" +"\t\tlo_mode_fifo Enable kernel loopback with fifo\n" +"\t\tlo_mode_fifo_skb Enable kernel loopback with fifo and skb buffer\n" +"\t\t" ); -module_param(kthread_mode, charp, S_IRUGO); +module_param(kthread_mode, charp, 0644); MODULE_PARM_DESC(kthread_mode, "Kernel thread mode (default=single):\n" -" single Single kernel thread mode enabled.\n" -" multiple Multiple kernel thread mode enabled.\n" -"\n" +"\t\tsingle Single kernel thread mode enabled.\n" +"\t\tmultiple Multiple kernel thread mode enabled.\n" +"\t\t" +); + +module_param(carrier, charp, 0644); +MODULE_PARM_DESC(carrier, +"Default carrier state for KNI interface (default=off):\n" +"\t\toff Interfaces will be created with carrier state set to off.\n" +"\t\ton Interfaces will be created with carrier state set to on.\n" +"\t\t" );