diff options
Diffstat (limited to 'kernel/4.13.0')
-rw-r--r-- | kernel/4.13.0/e1000e/e1000.h | 2 | ||||
-rw-r--r-- | kernel/4.13.0/e1000e/netdev.c | 23 | ||||
-rw-r--r-- | kernel/4.13.0/e1000e/vfio-net.c | 30 |
3 files changed, 39 insertions, 16 deletions
diff --git a/kernel/4.13.0/e1000e/e1000.h b/kernel/4.13.0/e1000e/e1000.h index 06ad27f..1955604 100644 --- a/kernel/4.13.0/e1000e/e1000.h +++ b/kernel/4.13.0/e1000e/e1000.h @@ -319,6 +319,7 @@ struct e1000_adapter { struct msix_entry *msix_entries; int int_mode; u32 eiac_mask; + u32 irq_mask; u32 eeprom_wol; u32 wol; @@ -507,6 +508,7 @@ void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter); void e1000e_get_hw_control(struct e1000_adapter *adapter); void e1000e_release_hw_control(struct e1000_adapter *adapter); void e1000e_write_itr(struct e1000_adapter *adapter, u32 itr); +void e1000e_trigger_lsc(struct e1000_adapter *adapter); extern unsigned int copybreak; diff --git a/kernel/4.13.0/e1000e/netdev.c b/kernel/4.13.0/e1000e/netdev.c index 5892d07..fd28d38 100644 --- a/kernel/4.13.0/e1000e/netdev.c +++ b/kernel/4.13.0/e1000e/netdev.c @@ -2246,11 +2246,11 @@ static void e1000_irq_enable(struct e1000_adapter *adapter) if (adapter->msix_entries) { ew32(EIAC_82574, adapter->eiac_mask & E1000_EIAC_MASK_82574); - ew32(IMS, adapter->eiac_mask | E1000_IMS_LSC); + ew32(IMS, ~adapter->irq_mask & (adapter->eiac_mask | E1000_IMS_LSC)); } else if (hw->mac.type >= e1000_pch_lpt) { - ew32(IMS, IMS_ENABLE_MASK | E1000_IMS_ECCER); + ew32(IMS, ~adapter->irq_mask & (IMS_ENABLE_MASK | E1000_IMS_ECCER)); } else { - ew32(IMS, IMS_ENABLE_MASK); + ew32(IMS, ~adapter->irq_mask & IMS_ENABLE_MASK); } e1e_flush(); } @@ -4202,7 +4202,7 @@ void e1000e_reset(struct e1000_adapter *adapter) * * Fire a link status change interrupt to start the watchdog. **/ -static void e1000e_trigger_lsc(struct e1000_adapter *adapter) +void e1000e_trigger_lsc(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; @@ -4219,13 +4219,12 @@ void e1000e_up(struct e1000_adapter *adapter) clear_bit(__E1000_DOWN, &adapter->state); - if (!test_bit(__E1000_VFIO_NET, &adapter->state)) { - if (adapter->msix_entries) - e1000_configure_msix(adapter); - e1000_irq_enable(adapter); + if (adapter->msix_entries) + e1000_configure_msix(adapter); + e1000_irq_enable(adapter); + if (!test_bit(__E1000_VFIO_NET, &adapter->state)) { netif_start_queue(adapter->netdev); - e1000e_trigger_lsc(adapter); } } @@ -5926,8 +5925,10 @@ static void e1000_tx_timeout(struct net_device *netdev) struct e1000_adapter *adapter = netdev_priv(netdev); /* Do the reset outside of interrupt context */ - adapter->tx_timeout_count++; - schedule_work(&adapter->reset_task); + if (!test_bit(__E1000_VFIO_NET, &adapter->state)) { + adapter->tx_timeout_count++; + schedule_work(&adapter->reset_task); + } } static void e1000_reset_task(struct work_struct *work) diff --git a/kernel/4.13.0/e1000e/vfio-net.c b/kernel/4.13.0/e1000e/vfio-net.c index 6a16f25..dd829af 100644 --- a/kernel/4.13.0/e1000e/vfio-net.c +++ b/kernel/4.13.0/e1000e/vfio-net.c @@ -87,6 +87,12 @@ static int e1000e_vfio_net_open(struct mdev_device *mdev) dev_hold(adapter->netdev); set_bit(__E1000_VFIO_NET, &adapter->state); + adapter->irq_mask = + E1000_IMS_RXT0 | + E1000_IMS_TXDW | + E1000_IMS_RXDMT0 | + E1000_IMS_RXSEQ; + if (netif_running(adapter->netdev)) e1000e_reinit_locked(adapter); else @@ -108,6 +114,8 @@ static void e1000e_vfio_net_release(struct mdev_device *mdev) struct e1000_adapter *adapter = netdev_priv(netdev); clear_bit(__E1000_VFIO_NET, &adapter->state); + adapter->irq_mask = 0; + if (netif_running(adapter->netdev)) e1000e_reinit_locked(adapter); else @@ -319,6 +327,7 @@ static long e1000e_vfio_net_ioctl(struct mdev_device *mdev, unsigned int cmd, /* return ret? */ return -ENOMEM; +#if 0 printk(KERN_INFO"VFIO_IOMMU_MAP_DMA: about to dma_map_single(%p, %p, %lld, DMA_FROM_DEVICE)\n", parent_dev, data, map.size); mapping = dma_map_single(parent_dev, data, map.size, @@ -329,11 +338,18 @@ static long e1000e_vfio_net_ioctl(struct mdev_device *mdev, unsigned int cmd, kfree(data); goto out; } +#else + data = dma_alloc_coherent(parent_dev, map.size, &mapping, GFP_KERNEL); + if (!data) { + if (net_ratelimit()) + printk(KERN_ERR"Failed to dma_alloc_coherent buffer for userland!\n"); + goto out; + } + +#endif map.iova = mapping; - ret = io_remap_pfn_range(vma, map.vaddr, - virt_to_phys(data) >> PAGE_SHIFT, - map.size, vma->vm_page_prot); - printk(KERN_INFO"VFIO_IOMMU_MAP_DMA: io_remap_pfn_range %llx -> physmem <- @%llx, %lld:%d\n", + ret = dma_mmap_coherent(parent_dev, vma, data, mapping, map.size); + printk(KERN_INFO"VFIO_IOMMU_MAP_DMA: dma_map_coherent %llx -> physmem <- @%llx, %lld:%d\n", map.vaddr, map.iova, map.size, ret); if (ret != 0) { dma_unmap_single(parent_dev, mapping, map.size, @@ -347,7 +363,7 @@ static long e1000e_vfio_net_ioctl(struct mdev_device *mdev, unsigned int cmd, netmdev->mappings_count); netmdev->mappings[netmdev->mappings_count].dev = parent_dev; netmdev->mappings[netmdev->mappings_count].vaddr = data; - netmdev->mappings[netmdev->mappings_count].iova = mapping; + netmdev->mappings[netmdev->mappings_count].iova = map.iova; netmdev->mappings[netmdev->mappings_count].size = map.size; netmdev->mappings_count++; @@ -370,6 +386,10 @@ out: return 0; + case 500: + e1000e_trigger_lsc(adapter); + return 0; + default: return -EOPNOTSUPP; } |