PCI: EPF: tvnet: disable the edma interrupt

1. Disable the corresponding PCIe EP controller
   EDMA interrupt.
2. Disable IP checksum to improve performance
   since the PCIe link is reliable.
3. DMA unmap matches the map size.
4. Adjust the SKB buffer link list handle.

Bug 4704944

Signed-off-by: Jason Mei <jianjunm@nvidia.com>
Change-Id: I05f76fa60e3533c2dd01e53ed17664d6898fcffd
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3158126
Reviewed-by: svcacv <svcacv@nvidia.com>
Reviewed-by: Nagarjuna Kristam <nkristam@nvidia.com>
GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com>
Reviewed-by: Bibek Basu <bbasu@nvidia.com>
This commit is contained in:
Jason Mei
2024-06-17 09:43:08 +08:00
committed by mobile promotions
parent f870a5f9fc
commit e2bb52def5
2 changed files with 39 additions and 6 deletions

View File

@@ -183,6 +183,11 @@ static void tvnet_host_alloc_empty_buffers(struct tvnet_priv *tvnet)
break; break;
} }
/* The PCIe link is stable and dependable,
* so it's not necessary to perform a software checksum.
*/
skb->ip_summed = CHECKSUM_UNNECESSARY;
ep2h_empty_ptr = kmalloc(sizeof(*ep2h_empty_ptr), GFP_ATOMIC); ep2h_empty_ptr = kmalloc(sizeof(*ep2h_empty_ptr), GFP_ATOMIC);
if (!ep2h_empty_ptr) { if (!ep2h_empty_ptr) {
dma_unmap_single(d, iova, len, DMA_FROM_DEVICE); dma_unmap_single(d, iova, len, DMA_FROM_DEVICE);
@@ -651,16 +656,18 @@ static int tvnet_host_process_ep2h_msg(struct tvnet_priv *tvnet)
list_for_each_entry(ep2h_empty_ptr, &tvnet->ep2h_empty_list, list_for_each_entry(ep2h_empty_ptr, &tvnet->ep2h_empty_list,
list) { list) {
if (ep2h_empty_ptr->iova == pcie_address) { if (ep2h_empty_ptr->iova == pcie_address) {
list_del(&ep2h_empty_ptr->list);
found = 1; found = 1;
break; break;
} }
} }
WARN_ON(!found);
list_del(&ep2h_empty_ptr->list);
spin_unlock_irqrestore(&tvnet->ep2h_empty_lock, flags); spin_unlock_irqrestore(&tvnet->ep2h_empty_lock, flags);
/* Advance H2EP full buffer after search in local list */ /* Advance H2EP full buffer after search in local list */
tvnet_ivc_advance_rd(&tvnet->ep2h_full); tvnet_ivc_advance_rd(&tvnet->ep2h_full);
if (WARN_ON(!found))
continue;
/* If EP2H network queue is stopped due to lack of EP2H_FULL /* If EP2H network queue is stopped due to lack of EP2H_FULL
* queue, raising ctrl irq will help. * queue, raising ctrl irq will help.
*/ */

View File

@@ -30,6 +30,8 @@
#endif #endif
#define BAR0_SIZE SZ_4M #define BAR0_SIZE SZ_4M
#define APPL_INTR_EN_L1_8_0 0x44
#define APPL_INTR_EN_L1_8_EDMA_INT_EN BIT(6)
enum bar0_amap_type { enum bar0_amap_type {
META_DATA, META_DATA,
@@ -146,6 +148,8 @@ struct pci_epf_tvnet {
/* IOVA alloc abstraction.*/ /* IOVA alloc abstraction.*/
struct iova_domain *iovad; struct iova_domain *iovad;
struct iova *iova; struct iova *iova;
struct resource *appl_res;
void __iomem *appl_base;
#endif #endif
}; };
@@ -304,6 +308,10 @@ static void tvnet_ep_alloc_empty_buffers(struct pci_epf_tvnet *tvnet)
break; break;
} }
/* The PCIe link is stable and dependable,
* so it's not necessary to perform a software checksum.
*/
skb->ip_summed = CHECKSUM_UNNECESSARY;
#else #else
iova = tvnet_ivoa_alloc(tvnet); iova = tvnet_ivoa_alloc(tvnet);
if (iova == DMA_ERROR_CODE) { if (iova == DMA_ERROR_CODE) {
@@ -849,18 +857,19 @@ static int tvnet_ep_process_h2ep_msg(struct pci_epf_tvnet *tvnet)
list_for_each_entry(h2ep_empty_ptr, &tvnet->h2ep_empty_list, list_for_each_entry(h2ep_empty_ptr, &tvnet->h2ep_empty_list,
list) { list) {
if (h2ep_empty_ptr->iova == pcie_address) { if (h2ep_empty_ptr->iova == pcie_address) {
list_del(&h2ep_empty_ptr->list);
found = 1; found = 1;
break; break;
} }
} }
WARN_ON(!found);
list_del(&h2ep_empty_ptr->list);
spin_unlock_irqrestore(&tvnet->h2ep_empty_lock, flags); spin_unlock_irqrestore(&tvnet->h2ep_empty_lock, flags);
/* Advance H2EP full buffer after search in local list */ /* Advance H2EP full buffer after search in local list */
tvnet_ivc_advance_rd(&tvnet->h2ep_full); tvnet_ivc_advance_rd(&tvnet->h2ep_full);
if (WARN_ON(!found))
continue;
#if ENABLE_DMA #if ENABLE_DMA
dma_unmap_single(cdev, pcie_address, ndev->mtu, dma_unmap_single(cdev, pcie_address, ndev->mtu + ETH_HLEN,
DMA_FROM_DEVICE); DMA_FROM_DEVICE);
skb = h2ep_empty_ptr->skb; skb = h2ep_empty_ptr->skb;
skb_put(skb, len); skb_put(skb, len);
@@ -1597,7 +1606,7 @@ static void tvnet_ep_pci_epf_linkup(struct pci_epf *epf)
#endif #endif
{ {
struct pci_epf_tvnet *tvnet = epf_get_drvdata(epf); struct pci_epf_tvnet *tvnet = epf_get_drvdata(epf);
u32 val;
#if ENABLE_DMA #if ENABLE_DMA
tvnet_ep_setup_dma(tvnet); tvnet_ep_setup_dma(tvnet);
#endif #endif
@@ -1611,6 +1620,11 @@ static void tvnet_ep_pci_epf_linkup(struct pci_epf *epf)
tvnet->pcie_link_status = true; tvnet->pcie_link_status = true;
#if (LINUX_VERSION_CODE > KERNEL_VERSION(5, 14, 0)) #if (LINUX_VERSION_CODE > KERNEL_VERSION(5, 14, 0))
val = readl(tvnet->appl_base + APPL_INTR_EN_L1_8_0);
if (val & APPL_INTR_EN_L1_8_EDMA_INT_EN)
writel(val & ~APPL_INTR_EN_L1_8_EDMA_INT_EN,
tvnet->appl_base + APPL_INTR_EN_L1_8_0);
return 0; return 0;
#endif #endif
} }
@@ -1714,6 +1728,18 @@ static int tvnet_ep_pci_epf_bind(struct pci_epf *epf)
goto fail; goto fail;
} }
tvnet->appl_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
"appl");
if (!tvnet->appl_res) {
dev_err(fdev, "Failed to find \"appl\" region\n");
goto fail;
}
tvnet->appl_base = devm_ioremap(fdev, tvnet->appl_res->start,
PAGE_SIZE);
if (IS_ERR(tvnet->appl_base))
goto fail;
#if (LINUX_VERSION_CODE > KERNEL_VERSION(5, 14, 0)) #if (LINUX_VERSION_CODE > KERNEL_VERSION(5, 14, 0))
tvnet->iovad = (struct iova_domain *)&domain->iova_cookie->iovad; tvnet->iovad = (struct iova_domain *)&domain->iova_cookie->iovad;