aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/layerscape/patches-5.4/701-net-0358-sdk_dpaa-ls1043a-errata-update-and-optimize-the-rest.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/layerscape/patches-5.4/701-net-0358-sdk_dpaa-ls1043a-errata-update-and-optimize-the-rest.patch')
-rw-r--r--target/linux/layerscape/patches-5.4/701-net-0358-sdk_dpaa-ls1043a-errata-update-and-optimize-the-rest.patch252
1 files changed, 0 insertions, 252 deletions
diff --git a/target/linux/layerscape/patches-5.4/701-net-0358-sdk_dpaa-ls1043a-errata-update-and-optimize-the-rest.patch b/target/linux/layerscape/patches-5.4/701-net-0358-sdk_dpaa-ls1043a-errata-update-and-optimize-the-rest.patch
deleted file mode 100644
index 684d04b256..0000000000
--- a/target/linux/layerscape/patches-5.4/701-net-0358-sdk_dpaa-ls1043a-errata-update-and-optimize-the-rest.patch
+++ /dev/null
@@ -1,252 +0,0 @@
-From e89db675171a7a12f19b6ec0089a9cc62807cdf1 Mon Sep 17 00:00:00 2001
-From: Camelia Groza <camelia.groza@nxp.com>
-Date: Tue, 29 Oct 2019 16:34:08 +0200
-Subject: [PATCH] sdk_dpaa: ls1043a errata: update and optimize the
- restrictions
-
-An skb is in no danger of triggering the errata under the following
-conditions:
-- the paged data doesn't cross a 4K page boundary OR the linear data
-is aligned to 256 bytes when crossing a 4K page boundary
-- the linear and the paged data are 16 byte aligned
-- the paged data is a multiple of 16 bytes in size
-
-Optimize the detection for each skb that might trigger the errata. Parse
-the skb twice, at most, and realign it only once.
-
-Signed-off-by: Camelia Groza <camelia.groza@nxp.com>
----
- drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h | 2 +-
- .../net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 147 +++++++++++++++------
- 2 files changed, 111 insertions(+), 38 deletions(-)
-
---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h
-+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h
-@@ -662,7 +662,7 @@ static inline void _dpa_bp_free_pf(void
- #ifndef CONFIG_PPC
- extern bool dpaa_errata_a010022; /* SoC affected by A010022 errata */
- #define NONREC_MARK 0x01
--#define HAS_DMA_ISSUE(start, size) \
-+#define CROSS_4K(start, size) \
- (((uintptr_t)(start) + (size)) > \
- (((uintptr_t)(start) + 0x1000) & ~0xFFF))
- /* The headroom needs to accommodate our private data (64 bytes) but
---- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c
-+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c
-@@ -771,32 +771,73 @@ int __hot skb_to_contig_fd(struct dpa_pr
- EXPORT_SYMBOL(skb_to_contig_fd);
-
- #ifndef CONFIG_PPC
--/* Verify the conditions that trigger the A010022 errata: data unaligned to
-- * 16 bytes, 4K memory address crossings and S/G fragments.
-+/* Verify the conditions that trigger the A010022 errata:
-+ * - 4K memory address boundary crossings when the data/SG fragments aren't
-+ * aligned to 256 bytes
-+ * - data and SG fragments that aren't aligned to 16 bytes
-+ * - SG fragments that aren't mod 16 bytes in size (except for the last
-+ * fragment)
- */
- static bool a010022_check_skb(struct sk_buff *skb, struct dpa_priv_s *priv)
- {
-- /* Check if the headroom is aligned */
-- if (((uintptr_t)skb->data - priv->tx_headroom) %
-- priv->buf_layout[TX].data_align != 0)
-- return true;
-+ skb_frag_t *frag;
-+ int i, nr_frags;
-
-- /* Check for paged data in the skb. We do not support S/G fragments */
-- if (skb_is_nonlinear(skb))
-+ nr_frags = skb_shinfo(skb)->nr_frags;
-+
-+ /* Check if the linear data is 16 byte aligned */
-+ if ((uintptr_t)skb->data % 16)
- return true;
-
-- /* Check if the headroom crosses a boundary */
-- if (HAS_DMA_ISSUE(skb->head, skb_headroom(skb)))
-+ /* Check if the needed headroom crosses a 4K address boundary without
-+ * being 256 byte aligned
-+ */
-+ if (CROSS_4K(skb->data - priv->tx_headroom, priv->tx_headroom) &&
-+ (((uintptr_t)skb->data - priv->tx_headroom) % 256))
- return true;
-
-- /* Check if the non-paged data crosses a boundary */
-- if (HAS_DMA_ISSUE(skb->data, skb_headlen(skb)))
-+ /* Check if the linear data crosses a 4K address boundary without
-+ * being 256 byte aligned
-+ */
-+ if (CROSS_4K(skb->data, skb_headlen(skb)) &&
-+ ((uintptr_t)skb->data % 256))
- return true;
-
-- /* Check if the entire linear skb crosses a boundary */
-- if (HAS_DMA_ISSUE(skb->head, skb_end_offset(skb)))
-+ /* When using Scatter/Gather, the linear data becomes the first
-+ * fragment in the list and must follow the same restrictions as the
-+ * other fragments.
-+ *
-+ * Check if the linear data is mod 16 bytes in size.
-+ */
-+ if (nr_frags && (skb_headlen(skb) % 16))
- return true;
-
-+ /* Check the SG fragments. They must follow the same rules as the
-+ * linear data with and additional restriction: they must be multiple
-+ * of 16 bytes in size to account for the hardware carryover effect.
-+ */
-+ for (i = 0; i < nr_frags; i++) {
-+ frag = &skb_shinfo(skb)->frags[i];
-+
-+ /* Check if the fragment is a multiple of 16 bytes in size.
-+ * The last fragment is exempt from this restriction.
-+ */
-+ if ((i != (nr_frags - 1)) && (skb_frag_size(frag) % 16))
-+ return true;
-+
-+ /* Check if the fragment is 16 byte aligned */
-+ if (skb_frag_off(frag) % 16)
-+ return true;
-+
-+ /* Check if the fragment crosses a 4K address boundary. Since
-+ * the alignment of previous fragments can influence the
-+ * current fragment, checking for the 256 byte alignment
-+ * isn't relevant.
-+ */
-+ if (CROSS_4K(skb_frag_off(frag), skb_frag_size(frag)))
-+ return true;
-+ }
-+
- return false;
- }
-
-@@ -1062,10 +1103,24 @@ int __hot dpa_tx_extended(struct sk_buff
- struct dpa_percpu_priv_s *percpu_priv;
- struct rtnl_link_stats64 *percpu_stats;
- int err = 0;
-- bool nonlinear;
-+ bool nonlinear, skb_changed, skb_need_wa;
- int *countptr, offset = 0;
- struct sk_buff *nskb;
-
-+ /* Flags to help optimize the A010022 errata restriction checks.
-+ *
-+ * First flag marks if the skb changed between the first A010022 check
-+ * and the moment it's converted to an FD.
-+ *
-+ * The second flag marks if the skb needs to be realigned in order to
-+ * avoid the errata.
-+ *
-+ * The flags should have minimal impact on platforms not impacted by
-+ * the errata.
-+ */
-+ skb_changed = false;
-+ skb_need_wa = false;
-+
- priv = netdev_priv(net_dev);
- /* Non-migratable context, safe to use raw_cpu_ptr */
- percpu_priv = raw_cpu_ptr(priv->percpu_priv);
-@@ -1075,13 +1130,8 @@ int __hot dpa_tx_extended(struct sk_buff
- clear_fd(&fd);
-
- #ifndef CONFIG_PPC
-- if (unlikely(dpaa_errata_a010022) && a010022_check_skb(skb, priv)) {
-- nskb = a010022_realign_skb(skb, priv);
-- if (!nskb)
-- goto skb_to_fd_failed;
-- dev_kfree_skb(skb);
-- skb = nskb;
-- }
-+ if (unlikely(dpaa_errata_a010022) && a010022_check_skb(skb, priv))
-+ skb_need_wa = true;
- #endif
-
- nonlinear = skb_is_nonlinear(skb);
-@@ -1102,8 +1152,8 @@ int __hot dpa_tx_extended(struct sk_buff
- * Btw, we're using the first sgt entry to store the linear part of
- * the skb, so we're one extra frag short.
- */
-- if (nonlinear &&
-- likely(skb_shinfo(skb)->nr_frags < DPA_SGT_MAX_ENTRIES)) {
-+ if (nonlinear && !skb_need_wa &&
-+ likely(skb_shinfo(skb)->nr_frags < DPA_SGT_MAX_ENTRIES)) {
- /* Just create a S/G fd based on the skb */
- err = skb_to_sg_fd(priv, skb, &fd);
- percpu_priv->tx_frag_skbuffs++;
-@@ -1128,39 +1178,62 @@ int __hot dpa_tx_extended(struct sk_buff
-
- dev_kfree_skb(skb);
- skb = skb_new;
-+ skb_changed = true;
- }
-
- /* We're going to store the skb backpointer at the beginning
- * of the data buffer, so we need a privately owned skb
-+ *
-+ * Under the A010022 errata, we are going to have a privately
-+ * owned skb after realigning the current one, so no point in
-+ * copying it here in that case.
- */
-
- /* Code borrowed from skb_unshare(). */
-- if (skb_cloned(skb)) {
-+ if (skb_cloned(skb) && !skb_need_wa) {
- nskb = skb_copy(skb, GFP_ATOMIC);
- kfree_skb(skb);
- skb = nskb;
--#ifndef CONFIG_PPC
-- if (unlikely(dpaa_errata_a010022) &&
-- a010022_check_skb(skb, priv)) {
-- nskb = a010022_realign_skb(skb, priv);
-- if (!nskb)
-- goto skb_to_fd_failed;
-- dev_kfree_skb(skb);
-- skb = nskb;
-- }
--#endif
-+ skb_changed = true;
-+
- /* skb_copy() has now linearized the skbuff. */
-- } else if (unlikely(nonlinear)) {
-+ } else if (unlikely(nonlinear) && !skb_need_wa) {
- /* We are here because the egress skb contains
- * more fragments than we support. In this case,
- * we have no choice but to linearize it ourselves.
- */
-- err = __skb_linearize(skb);
-+#ifndef CONFIG_PPC
-+ /* No point in linearizing the skb now if we are going
-+ * to realign and linearize it again further down due
-+ * to the A010022 errata
-+ */
-+ if (unlikely(dpaa_errata_a010022))
-+ skb_need_wa = true;
-+ else
-+#endif
-+ err = __skb_linearize(skb);
- }
- if (unlikely(!skb || err < 0))
- /* Common out-of-memory error path */
- goto enomem;
-
-+#ifndef CONFIG_PPC
-+ /* Verify the skb a second time if it has been updated since
-+ * the previous check
-+ */
-+ if (unlikely(dpaa_errata_a010022) && skb_changed &&
-+ a010022_check_skb(skb, priv))
-+ skb_need_wa = true;
-+
-+ if (unlikely(dpaa_errata_a010022) && skb_need_wa) {
-+ nskb = a010022_realign_skb(skb, priv);
-+ if (!nskb)
-+ goto skb_to_fd_failed;
-+ dev_kfree_skb(skb);
-+ skb = nskb;
-+ }
-+#endif
-+
- err = skb_to_contig_fd(priv, skb, &fd, countptr, &offset);
- }
- if (unlikely(err < 0))