diff options
author | Yangbo Lu <yangbo.lu@nxp.com> | 2020-04-10 10:47:05 +0800 |
---|---|---|
committer | Petr Štetiar <ynezz@true.cz> | 2020-05-07 12:53:06 +0200 |
commit | cddd4591404fb4c53dc0b3c0b15b942cdbed4356 (patch) | |
tree | 392c1179de46b0f804e3789edca19069b64e6b44 /target/linux/layerscape/patches-5.4/701-net-0093-dpaa_eth-fix-iova-handling-for-contiguous-frames.patch | |
parent | d1d2c0b5579ea4f69a42246c9318539d61ba1999 (diff) | |
download | upstream-cddd4591404fb4c53dc0b3c0b15b942cdbed4356.tar.gz upstream-cddd4591404fb4c53dc0b3c0b15b942cdbed4356.tar.bz2 upstream-cddd4591404fb4c53dc0b3c0b15b942cdbed4356.zip |
layerscape: add patches-5.4
Add patches for linux-5.4. The patches are from NXP LSDK-20.04 release
which was tagged LSDK-20.04-V5.4.
https://source.codeaurora.org/external/qoriq/qoriq-components/linux/
For boards LS1021A-IOT, and Traverse-LS1043 which are not involved in
LSDK, port the dts patches from 4.14.
The patches are sorted into the following categories:
301-arch-xxxx
302-dts-xxxx
303-core-xxxx
701-net-xxxx
801-audio-xxxx
802-can-xxxx
803-clock-xxxx
804-crypto-xxxx
805-display-xxxx
806-dma-xxxx
807-gpio-xxxx
808-i2c-xxxx
809-jailhouse-xxxx
810-keys-xxxx
811-kvm-xxxx
812-pcie-xxxx
813-pm-xxxx
814-qe-xxxx
815-sata-xxxx
816-sdhc-xxxx
817-spi-xxxx
818-thermal-xxxx
819-uart-xxxx
820-usb-xxxx
821-vfio-xxxx
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
Diffstat (limited to 'target/linux/layerscape/patches-5.4/701-net-0093-dpaa_eth-fix-iova-handling-for-contiguous-frames.patch')
-rw-r--r-- | target/linux/layerscape/patches-5.4/701-net-0093-dpaa_eth-fix-iova-handling-for-contiguous-frames.patch | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/target/linux/layerscape/patches-5.4/701-net-0093-dpaa_eth-fix-iova-handling-for-contiguous-frames.patch b/target/linux/layerscape/patches-5.4/701-net-0093-dpaa_eth-fix-iova-handling-for-contiguous-frames.patch new file mode 100644 index 0000000000..430bed1378 --- /dev/null +++ b/target/linux/layerscape/patches-5.4/701-net-0093-dpaa_eth-fix-iova-handling-for-contiguous-frames.patch @@ -0,0 +1,129 @@ +From 39e4cf29431dec8aaad599d9734f7a0468a9c20b Mon Sep 17 00:00:00 2001 +From: Laurentiu Tudor <laurentiu.tudor@nxp.com> +Date: Wed, 4 Apr 2018 12:31:05 +0300 +Subject: [PATCH] dpaa_eth: fix iova handling for contiguous frames + +The driver relies on the no longer valid assumption that dma addresses +(iovas) are identical to physical addressees and uses phys_to_virt() to +make iova -> vaddr conversions. Fix this by adding a function that does +proper iova -> phys conversions using the iommu api and update the code +to use it. +Also, a dma_unmap_single() call had to be moved further down the code +because iova -> vaddr conversions were required before the unmap. +For now only the contiguous frame case is handled and the SG case is +split in a following patch. +While at it, clean-up a redundant dpaa_bpid2pool() and pass the bp +as parameter. + +Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com> +Acked-by: Madalin Bucur <madalin.bucur@nxp.com> +--- + drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 44 ++++++++++++++------------ + 1 file changed, 24 insertions(+), 20 deletions(-) + +--- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c ++++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +@@ -50,6 +50,7 @@ + #include <linux/highmem.h> + #include <linux/percpu.h> + #include <linux/dma-mapping.h> ++#include <linux/iommu.h> + #include <linux/sort.h> + #include <linux/phy_fixed.h> + #include <soc/fsl/bman.h> +@@ -1615,6 +1616,17 @@ static int dpaa_eth_refill_bpools(struct + return 0; + } + ++static phys_addr_t dpaa_iova_to_phys(struct device *dev, dma_addr_t addr) ++{ ++ struct iommu_domain *domain; ++ ++ domain = iommu_get_domain_for_dev(dev); ++ if (domain) ++ return iommu_iova_to_phys(domain, addr); ++ else ++ return addr; ++} ++ + /* Cleanup function for outgoing frame descriptors that were built on Tx path, + * either contiguous frames or scatter/gather ones. + * Skb freeing is not handled here. +@@ -1639,7 +1651,7 @@ static struct sk_buff *dpaa_cleanup_tx_f + int nr_frags, i; + u64 ns; + +- skbh = (struct sk_buff **)phys_to_virt(addr); ++ skbh = (struct sk_buff **)phys_to_virt(dpaa_iova_to_phys(dev, addr)); + skb = *skbh; + + if (unlikely(qm_fd_get_format(fd) == qm_fd_sg)) { +@@ -1718,25 +1730,21 @@ static u8 rx_csum_offload(const struct d + * accommodate the shared info area of the skb. + */ + static struct sk_buff *contig_fd_to_skb(const struct dpaa_priv *priv, +- const struct qm_fd *fd) ++ const struct qm_fd *fd, ++ struct dpaa_bp *dpaa_bp, ++ void *vaddr) + { + ssize_t fd_off = qm_fd_get_offset(fd); +- dma_addr_t addr = qm_fd_addr(fd); +- struct dpaa_bp *dpaa_bp; + struct sk_buff *skb; +- void *vaddr; + +- vaddr = phys_to_virt(addr); + WARN_ON(!IS_ALIGNED((unsigned long)vaddr, SMP_CACHE_BYTES)); + +- dpaa_bp = dpaa_bpid2pool(fd->bpid); +- if (!dpaa_bp) +- goto free_buffer; +- + skb = build_skb(vaddr, dpaa_bp->size + + SKB_DATA_ALIGN(sizeof(struct skb_shared_info))); +- if (WARN_ONCE(!skb, "Build skb failure on Rx\n")) +- goto free_buffer; ++ if (WARN_ONCE(!skb, "Build skb failure on Rx\n")) { ++ skb_free_frag(vaddr); ++ return NULL; ++ } + WARN_ON(fd_off != priv->rx_headroom); + skb_reserve(skb, fd_off); + skb_put(skb, qm_fd_get_length(fd)); +@@ -1744,10 +1752,6 @@ static struct sk_buff *contig_fd_to_skb( + skb->ip_summed = rx_csum_offload(priv, fd); + + return skb; +- +-free_buffer: +- skb_free_frag(vaddr); +- return NULL; + } + + /* Build an skb with the data of the first S/G entry in the linear portion and +@@ -2476,12 +2480,12 @@ static enum qman_cb_dqrr_result rx_defau + if (!dpaa_bp) + return qman_cb_dqrr_consume; + +- dma_unmap_single(dpaa_bp->dev, addr, dpaa_bp->size, DMA_FROM_DEVICE); +- + /* prefetch the first 64 bytes of the frame or the SGT start */ +- vaddr = phys_to_virt(addr); ++ vaddr = phys_to_virt(dpaa_iova_to_phys(dpaa_bp->dev, addr)); + prefetch(vaddr + qm_fd_get_offset(fd)); + ++ dma_unmap_single(dpaa_bp->dev, addr, dpaa_bp->size, DMA_FROM_DEVICE); ++ + /* The only FD types that we may receive are contig and S/G */ + WARN_ON((fd_format != qm_fd_contig) && (fd_format != qm_fd_sg)); + +@@ -2492,7 +2496,7 @@ static enum qman_cb_dqrr_result rx_defau + (*count_ptr)--; + + if (likely(fd_format == qm_fd_contig)) +- skb = contig_fd_to_skb(priv, fd); ++ skb = contig_fd_to_skb(priv, fd, dpaa_bp, vaddr); + else + skb = sg_fd_to_skb(priv, fd); + if (!skb) |