37da91aeb48f1aa5cf561361b70af9a001311434
[openwrt/openwrt.git] /
1 From fcf41cba6f3ac0f33a5e9e0c7d79dbbbff586271 Mon Sep 17 00:00:00 2001
2 From: Camelia Groza <camelia.groza@nxp.com>
3 Date: Tue, 15 May 2018 11:48:42 +0300
4 Subject: [PATCH] sdk_dpaa: enable Jumbo frame support on LS1043A
5
6 Due to the A010022 errata restrictions, Jumbo frames on LS1043A require two
7 conditions to be met:
8 - on TX, the data is stored in a contiguous buffer of up to 9600 bytes
9 - the data is aligned to 256 bytes
10
11 The conditions are met by realigning all outgoing frames to 256 bytes.
12 Also, compound pages of varying orders are allocated to accommodate the
13 outgoing contiguous buffers.
14
15 Signed-off-by: Camelia Groza <camelia.groza@nxp.com>
16 ---
17 drivers/net/ethernet/freescale/sdk_dpaa/Kconfig | 1 -
18 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c | 9 ++---
19 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h | 5 +--
20 .../net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 40 ++++++++--------------
21 4 files changed, 20 insertions(+), 35 deletions(-)
22
23 --- a/drivers/net/ethernet/freescale/sdk_dpaa/Kconfig
24 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/Kconfig
25 @@ -80,7 +80,6 @@ config FSL_DPAA_ETH_JUMBO_FRAME
26 significantly the driver's memory footprint and may even deplete
27 the system memory. Also, the skb truesize is altered and messages
28 from the stack that warn against this are bypassed.
29 - This option is not available on LS1043.
30
31 config FSL_DPAA_TS
32 bool "Linux compliant timestamping"
33 --- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c
34 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c
35 @@ -779,12 +779,10 @@ static int dpa_private_netdev_init(struc
36 net_dev->features |= NETIF_F_HW_ACCEL_MQ;
37
38 #ifndef CONFIG_PPC
39 - /* Due to the A010022 FMan errata, we can not use contig frames larger
40 - * than 4K, nor S/G frames. We need to prevent the user from setting a
41 - * large MTU. We also stop advertising S/G and GSO support.
42 + /* Due to the A010022 FMan errata, we can not use S/G frames. We need
43 + * to stop advertising S/G and GSO support.
44 */
45 if (unlikely(dpaa_errata_a010022)) {
46 - net_dev->max_mtu = DPA_BP_RAW_SIZE;
47 net_dev->hw_features &= ~NETIF_F_SG;
48 net_dev->features &= ~NETIF_F_GSO;
49 }
50 @@ -985,9 +983,6 @@ dpaa_eth_priv_probe(struct platform_devi
51 /* We only want to use jumbo frame optimization if we actually have
52 * L2 MAX FRM set for jumbo frames as well.
53 */
54 -#ifndef CONFIG_PPC
55 - if (likely(!dpaa_errata_a010022))
56 -#endif
57 if(fm_get_max_frm() < 9600)
58 dev_warn(dev,
59 "Invalid configuration: if jumbo frames support is on, FSL_FM_MAX_FRAME_SIZE should be set to 9600\n");
60 --- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h
61 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h
62 @@ -672,8 +672,8 @@ static inline void _dpa_bp_free_pf(void
63 /* LS1043A SoC has a HW issue regarding FMan DMA transactions; The issue
64 * manifests itself at high traffic rates when frames cross 4K memory
65 * boundaries or when they are not aligned to 16 bytes; For the moment, we
66 - * use a SW workaround to avoid frames larger than 4K or that exceed 4K
67 - * alignments and to realign the frames to 16 bytes.
68 + * use a SW workaround that realigns frames to 256 bytes. Scatter/Gather
69 + * frames aren't supported on egress.
70 */
71
72 #ifndef CONFIG_PPC
73 @@ -682,6 +682,7 @@ extern bool dpaa_errata_a010022; /* SoC
74 #define HAS_DMA_ISSUE(start, size) \
75 (((uintptr_t)(start) + (size)) > \
76 (((uintptr_t)(start) + 0x1000) & ~0xFFF))
77 +#define DPAA_A010022_HEADROOM 256
78 #endif /* !CONFIG_PPC */
79
80 #endif /* __DPA_H */
81 --- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c
82 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c
83 @@ -407,12 +407,6 @@ static struct sk_buff *__hot contig_fd_t
84 * warn us that the frame length is larger than the truesize. We
85 * bypass the warning.
86 */
87 -#ifndef CONFIG_PPC
88 - /* We do not support Jumbo frames on LS1043 and thus we edit
89 - * the skb truesize only when the 4k errata is not present.
90 - */
91 - if (likely(!dpaa_errata_a010022))
92 -#endif
93 skb->truesize = SKB_TRUESIZE(dpa_fd_length(fd));
94 #endif
95
96 @@ -809,35 +803,31 @@ static struct sk_buff *a010022_realign_s
97 {
98 int trans_offset = skb_transport_offset(skb);
99 int net_offset = skb_network_offset(skb);
100 + int nsize, headroom, npage_order;
101 struct sk_buff *nskb = NULL;
102 - int nsize, headroom;
103 struct page *npage;
104 void *npage_addr;
105
106 - /* Guarantee the minimum required headroom */
107 - if (skb_headroom(skb) >= priv->tx_headroom)
108 - headroom = skb_headroom(skb);
109 - else
110 - headroom = priv->tx_headroom;
111 + /* The headroom needs to accommodate our private data (64 bytes) but
112 + * we reserve 256 bytes instead to guarantee 256 data alignment.
113 + */
114 + headroom = DPAA_A010022_HEADROOM;
115 +
116 + /* For the new skb we only need the old one's data (both non-paged and
117 + * paged). We can skip the old tailroom.
118 + */
119 + nsize = headroom + skb->len +
120 + SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
121
122 - npage = alloc_page(GFP_ATOMIC);
123 + /* Reserve enough memory to accommodate Jumbo frames */
124 + npage_order = (nsize - 1) / PAGE_SIZE;
125 + npage = alloc_pages(GFP_ATOMIC | __GFP_COMP, npage_order);
126 if (unlikely(!npage)) {
127 WARN_ONCE(1, "Memory allocation failure\n");
128 return NULL;
129 }
130 npage_addr = page_address(npage);
131
132 - /* For the new skb we only need the old one's data (both non-paged and
133 - * paged) and a headroom large enough to fit our private info. We can
134 - * skip the old tailroom.
135 - *
136 - * Make sure the new linearized buffer will not exceed a page's size.
137 - */
138 - nsize = headroom + skb->len +
139 - SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
140 - if (unlikely(nsize > 4096))
141 - goto err;
142 -
143 nskb = build_skb(npage_addr, nsize);
144 if (unlikely(!nskb))
145 goto err;
146 @@ -846,7 +836,7 @@ static struct sk_buff *a010022_realign_s
147 * alignment.
148 * Code borrowed and adapted from skb_copy().
149 */
150 - skb_reserve(nskb, priv->tx_headroom);
151 + skb_reserve(nskb, headroom);
152 skb_put(nskb, skb->len);
153 if (skb_copy_bits(skb, 0, nskb->data, skb->len)) {
154 WARN_ONCE(1, "skb parsing failure\n");