mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-29 10:08:59 +00:00
155 lines
5.8 KiB
Diff
155 lines
5.8 KiB
Diff
|
From fcf41cba6f3ac0f33a5e9e0c7d79dbbbff586271 Mon Sep 17 00:00:00 2001
|
||
|
From: Camelia Groza <camelia.groza@nxp.com>
|
||
|
Date: Tue, 15 May 2018 11:48:42 +0300
|
||
|
Subject: [PATCH] sdk_dpaa: enable Jumbo frame support on LS1043A
|
||
|
|
||
|
Due to the A010022 errata restrictions, Jumbo frames on LS1043A require two
|
||
|
conditions to be met:
|
||
|
- on TX, the data is stored in a contiguous buffer of up to 9600 bytes
|
||
|
- the data is aligned to 256 bytes
|
||
|
|
||
|
The conditions are met by realigning all outgoing frames to 256 bytes.
|
||
|
Also, compound pages of varying orders are allocated to accommodate the
|
||
|
outgoing contiguous buffers.
|
||
|
|
||
|
Signed-off-by: Camelia Groza <camelia.groza@nxp.com>
|
||
|
---
|
||
|
drivers/net/ethernet/freescale/sdk_dpaa/Kconfig | 1 -
|
||
|
drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c | 9 ++---
|
||
|
drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h | 5 +--
|
||
|
.../net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 40 ++++++++--------------
|
||
|
4 files changed, 20 insertions(+), 35 deletions(-)
|
||
|
|
||
|
--- a/drivers/net/ethernet/freescale/sdk_dpaa/Kconfig
|
||
|
+++ b/drivers/net/ethernet/freescale/sdk_dpaa/Kconfig
|
||
|
@@ -80,7 +80,6 @@ config FSL_DPAA_ETH_JUMBO_FRAME
|
||
|
significantly the driver's memory footprint and may even deplete
|
||
|
the system memory. Also, the skb truesize is altered and messages
|
||
|
from the stack that warn against this are bypassed.
|
||
|
- This option is not available on LS1043.
|
||
|
|
||
|
config FSL_DPAA_TS
|
||
|
bool "Linux compliant timestamping"
|
||
|
--- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c
|
||
|
+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c
|
||
|
@@ -779,12 +779,10 @@ static int dpa_private_netdev_init(struc
|
||
|
net_dev->features |= NETIF_F_HW_ACCEL_MQ;
|
||
|
|
||
|
#ifndef CONFIG_PPC
|
||
|
- /* Due to the A010022 FMan errata, we can not use contig frames larger
|
||
|
- * than 4K, nor S/G frames. We need to prevent the user from setting a
|
||
|
- * large MTU. We also stop advertising S/G and GSO support.
|
||
|
+ /* Due to the A010022 FMan errata, we can not use S/G frames. We need
|
||
|
+ * to stop advertising S/G and GSO support.
|
||
|
*/
|
||
|
if (unlikely(dpaa_errata_a010022)) {
|
||
|
- net_dev->max_mtu = DPA_BP_RAW_SIZE;
|
||
|
net_dev->hw_features &= ~NETIF_F_SG;
|
||
|
net_dev->features &= ~NETIF_F_GSO;
|
||
|
}
|
||
|
@@ -985,9 +983,6 @@ dpaa_eth_priv_probe(struct platform_devi
|
||
|
/* We only want to use jumbo frame optimization if we actually have
|
||
|
* L2 MAX FRM set for jumbo frames as well.
|
||
|
*/
|
||
|
-#ifndef CONFIG_PPC
|
||
|
- if (likely(!dpaa_errata_a010022))
|
||
|
-#endif
|
||
|
if(fm_get_max_frm() < 9600)
|
||
|
dev_warn(dev,
|
||
|
"Invalid configuration: if jumbo frames support is on, FSL_FM_MAX_FRAME_SIZE should be set to 9600\n");
|
||
|
--- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h
|
||
|
+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h
|
||
|
@@ -672,8 +672,8 @@ static inline void _dpa_bp_free_pf(void
|
||
|
/* LS1043A SoC has a HW issue regarding FMan DMA transactions; The issue
|
||
|
* manifests itself at high traffic rates when frames cross 4K memory
|
||
|
* boundaries or when they are not aligned to 16 bytes; For the moment, we
|
||
|
- * use a SW workaround to avoid frames larger than 4K or that exceed 4K
|
||
|
- * alignments and to realign the frames to 16 bytes.
|
||
|
+ * use a SW workaround that realigns frames to 256 bytes. Scatter/Gather
|
||
|
+ * frames aren't supported on egress.
|
||
|
*/
|
||
|
|
||
|
#ifndef CONFIG_PPC
|
||
|
@@ -682,6 +682,7 @@ extern bool dpaa_errata_a010022; /* SoC
|
||
|
#define HAS_DMA_ISSUE(start, size) \
|
||
|
(((uintptr_t)(start) + (size)) > \
|
||
|
(((uintptr_t)(start) + 0x1000) & ~0xFFF))
|
||
|
+#define DPAA_A010022_HEADROOM 256
|
||
|
#endif /* !CONFIG_PPC */
|
||
|
|
||
|
#endif /* __DPA_H */
|
||
|
--- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c
|
||
|
+++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c
|
||
|
@@ -407,12 +407,6 @@ static struct sk_buff *__hot contig_fd_t
|
||
|
* warn us that the frame length is larger than the truesize. We
|
||
|
* bypass the warning.
|
||
|
*/
|
||
|
-#ifndef CONFIG_PPC
|
||
|
- /* We do not support Jumbo frames on LS1043 and thus we edit
|
||
|
- * the skb truesize only when the 4k errata is not present.
|
||
|
- */
|
||
|
- if (likely(!dpaa_errata_a010022))
|
||
|
-#endif
|
||
|
skb->truesize = SKB_TRUESIZE(dpa_fd_length(fd));
|
||
|
#endif
|
||
|
|
||
|
@@ -809,35 +803,31 @@ static struct sk_buff *a010022_realign_s
|
||
|
{
|
||
|
int trans_offset = skb_transport_offset(skb);
|
||
|
int net_offset = skb_network_offset(skb);
|
||
|
+ int nsize, headroom, npage_order;
|
||
|
struct sk_buff *nskb = NULL;
|
||
|
- int nsize, headroom;
|
||
|
struct page *npage;
|
||
|
void *npage_addr;
|
||
|
|
||
|
- /* Guarantee the minimum required headroom */
|
||
|
- if (skb_headroom(skb) >= priv->tx_headroom)
|
||
|
- headroom = skb_headroom(skb);
|
||
|
- else
|
||
|
- headroom = priv->tx_headroom;
|
||
|
+ /* The headroom needs to accommodate our private data (64 bytes) but
|
||
|
+ * we reserve 256 bytes instead to guarantee 256 data alignment.
|
||
|
+ */
|
||
|
+ headroom = DPAA_A010022_HEADROOM;
|
||
|
+
|
||
|
+ /* For the new skb we only need the old one's data (both non-paged and
|
||
|
+ * paged). We can skip the old tailroom.
|
||
|
+ */
|
||
|
+ nsize = headroom + skb->len +
|
||
|
+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
|
||
|
|
||
|
- npage = alloc_page(GFP_ATOMIC);
|
||
|
+ /* Reserve enough memory to accommodate Jumbo frames */
|
||
|
+ npage_order = (nsize - 1) / PAGE_SIZE;
|
||
|
+ npage = alloc_pages(GFP_ATOMIC | __GFP_COMP, npage_order);
|
||
|
if (unlikely(!npage)) {
|
||
|
WARN_ONCE(1, "Memory allocation failure\n");
|
||
|
return NULL;
|
||
|
}
|
||
|
npage_addr = page_address(npage);
|
||
|
|
||
|
- /* For the new skb we only need the old one's data (both non-paged and
|
||
|
- * paged) and a headroom large enough to fit our private info. We can
|
||
|
- * skip the old tailroom.
|
||
|
- *
|
||
|
- * Make sure the new linearized buffer will not exceed a page's size.
|
||
|
- */
|
||
|
- nsize = headroom + skb->len +
|
||
|
- SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
|
||
|
- if (unlikely(nsize > 4096))
|
||
|
- goto err;
|
||
|
-
|
||
|
nskb = build_skb(npage_addr, nsize);
|
||
|
if (unlikely(!nskb))
|
||
|
goto err;
|
||
|
@@ -846,7 +836,7 @@ static struct sk_buff *a010022_realign_s
|
||
|
* alignment.
|
||
|
* Code borrowed and adapted from skb_copy().
|
||
|
*/
|
||
|
- skb_reserve(nskb, priv->tx_headroom);
|
||
|
+ skb_reserve(nskb, headroom);
|
||
|
skb_put(nskb, skb->len);
|
||
|
if (skb_copy_bits(skb, 0, nskb->data, skb->len)) {
|
||
|
WARN_ONCE(1, "skb parsing failure\n");
|