layerscape: clean up kernel patches
[openwrt/staging/lynxis.git] / target / linux / layerscape / patches-4.9 / 202-core-linux-support-layerscape.patch
1 From c37953457a7ebeb0d97ae8574b3d41274fcd9119 Mon Sep 17 00:00:00 2001
2 From: Yangbo Lu <yangbo.lu@nxp.com>
3 Date: Wed, 1 Nov 2017 16:22:33 +0800
4 Subject: [PATCH] core-linux: support layerscape
5
6 This is a integrated patch for layerscape core-linux support.
7
8 Signed-off-by: Madalin Bucur <madalin.bucur@freescale.com>
9 Signed-off-by: Zhao Qiang <qiang.zhao@nxp.com>
10 Signed-off-by: Camelia Groza <camelia.groza@nxp.com>
11 Signed-off-by: Madalin Bucur <madalin.bucur@nxp.com>
12 Signed-off-by: Zhang Ying-22455 <ying.zhang22455@nxp.com>
13 Signed-off-by: Ramneek Mehresh <ramneek.mehresh@freescale.com>
14 Signed-off-by: Jarod Wilson <jarod@redhat.com>
15 Signed-off-by: Nikhil Badola <nikhil.badola@freescale.com>
16 Signed-off-by: stephen hemminger <stephen@networkplumber.org>
17 Signed-off-by: Arnd Bergmann <arnd@arndb.de>
18 Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
19 ---
20 drivers/base/devres.c | 66 ++++++++++++++++++++++++++++
21 drivers/base/soc.c | 66 ++++++++++++++++++++++++++++
22 include/linux/device.h | 19 ++++++++
23 include/linux/fsl/svr.h | 97 +++++++++++++++++++++++++++++++++++++++++
24 include/linux/fsl_devices.h | 3 ++
25 include/linux/netdev_features.h | 2 +
26 include/linux/netdevice.h | 4 ++
27 include/linux/skbuff.h | 2 +
28 include/linux/sys_soc.h | 3 ++
29 include/uapi/linux/if_ether.h | 1 +
30 net/core/dev.c | 13 +++++-
31 net/core/skbuff.c | 29 +++++++++++-
32 net/sched/sch_generic.c | 7 +++
33 13 files changed, 309 insertions(+), 3 deletions(-)
34 create mode 100644 include/linux/fsl/svr.h
35
36 diff --git a/drivers/base/devres.c b/drivers/base/devres.c
37 index 8fc654f0..71d57702 100644
38 --- a/drivers/base/devres.c
39 +++ b/drivers/base/devres.c
40 @@ -10,6 +10,7 @@
41 #include <linux/device.h>
42 #include <linux/module.h>
43 #include <linux/slab.h>
44 +#include <linux/percpu.h>
45
46 #include "base.h"
47
48 @@ -985,3 +986,68 @@ void devm_free_pages(struct device *dev, unsigned long addr)
49 &devres));
50 }
51 EXPORT_SYMBOL_GPL(devm_free_pages);
52 +
53 +static void devm_percpu_release(struct device *dev, void *pdata)
54 +{
55 + void __percpu *p;
56 +
57 + p = *(void __percpu **)pdata;
58 + free_percpu(p);
59 +}
60 +
61 +static int devm_percpu_match(struct device *dev, void *data, void *p)
62 +{
63 + struct devres *devr = container_of(data, struct devres, data);
64 +
65 + return *(void **)devr->data == p;
66 +}
67 +
68 +/**
69 + * __devm_alloc_percpu - Resource-managed alloc_percpu
70 + * @dev: Device to allocate per-cpu memory for
71 + * @size: Size of per-cpu memory to allocate
72 + * @align: Alignment of per-cpu memory to allocate
73 + *
74 + * Managed alloc_percpu. Per-cpu memory allocated with this function is
75 + * automatically freed on driver detach.
76 + *
77 + * RETURNS:
78 + * Pointer to allocated memory on success, NULL on failure.
79 + */
80 +void __percpu *__devm_alloc_percpu(struct device *dev, size_t size,
81 + size_t align)
82 +{
83 + void *p;
84 + void __percpu *pcpu;
85 +
86 + pcpu = __alloc_percpu(size, align);
87 + if (!pcpu)
88 + return NULL;
89 +
90 + p = devres_alloc(devm_percpu_release, sizeof(void *), GFP_KERNEL);
91 + if (!p) {
92 + free_percpu(pcpu);
93 + return NULL;
94 + }
95 +
96 + *(void __percpu **)p = pcpu;
97 +
98 + devres_add(dev, p);
99 +
100 + return pcpu;
101 +}
102 +EXPORT_SYMBOL_GPL(__devm_alloc_percpu);
103 +
104 +/**
105 + * devm_free_percpu - Resource-managed free_percpu
106 + * @dev: Device this memory belongs to
107 + * @pdata: Per-cpu memory to free
108 + *
109 + * Free memory allocated with devm_alloc_percpu().
110 + */
111 +void devm_free_percpu(struct device *dev, void __percpu *pdata)
112 +{
113 + WARN_ON(devres_destroy(dev, devm_percpu_release, devm_percpu_match,
114 + (void *)pdata));
115 +}
116 +EXPORT_SYMBOL_GPL(devm_free_percpu);
117 diff --git a/drivers/base/soc.c b/drivers/base/soc.c
118 index b63f23e6..0c5cf872 100644
119 --- a/drivers/base/soc.c
120 +++ b/drivers/base/soc.c
121 @@ -13,6 +13,7 @@
122 #include <linux/spinlock.h>
123 #include <linux/sys_soc.h>
124 #include <linux/err.h>
125 +#include <linux/glob.h>
126
127 static DEFINE_IDA(soc_ida);
128
129 @@ -159,3 +160,68 @@ static int __init soc_bus_register(void)
130 return bus_register(&soc_bus_type);
131 }
132 core_initcall(soc_bus_register);
133 +
134 +static int soc_device_match_one(struct device *dev, void *arg)
135 +{
136 + struct soc_device *soc_dev = container_of(dev, struct soc_device, dev);
137 + const struct soc_device_attribute *match = arg;
138 +
139 + if (match->machine &&
140 + !glob_match(match->machine, soc_dev->attr->machine))
141 + return 0;
142 +
143 + if (match->family &&
144 + !glob_match(match->family, soc_dev->attr->family))
145 + return 0;
146 +
147 + if (match->revision &&
148 + !glob_match(match->revision, soc_dev->attr->revision))
149 + return 0;
150 +
151 + if (match->soc_id &&
152 + !glob_match(match->soc_id, soc_dev->attr->soc_id))
153 + return 0;
154 +
155 + return 1;
156 +}
157 +
158 +/*
159 + * soc_device_match - identify the SoC in the machine
160 + * @matches: zero-terminated array of possible matches
161 + *
162 + * returns the first matching entry of the argument array, or NULL
163 + * if none of them match.
164 + *
165 + * This function is meant as a helper in place of of_match_node()
166 + * in cases where either no device tree is available or the information
167 + * in a device node is insufficient to identify a particular variant
168 + * by its compatible strings or other properties. For new devices,
169 + * the DT binding should always provide unique compatible strings
170 + * that allow the use of of_match_node() instead.
171 + *
172 + * The calling function can use the .data entry of the
173 + * soc_device_attribute to pass a structure or function pointer for
174 + * each entry.
175 + */
176 +const struct soc_device_attribute *soc_device_match(
177 + const struct soc_device_attribute *matches)
178 +{
179 + int ret = 0;
180 +
181 + if (!matches)
182 + return NULL;
183 +
184 + while (!ret) {
185 + if (!(matches->machine || matches->family ||
186 + matches->revision || matches->soc_id))
187 + break;
188 + ret = bus_for_each_dev(&soc_bus_type, NULL, (void *)matches,
189 + soc_device_match_one);
190 + if (!ret)
191 + matches++;
192 + else
193 + return matches;
194 + }
195 + return NULL;
196 +}
197 +EXPORT_SYMBOL_GPL(soc_device_match);
198 diff --git a/include/linux/device.h b/include/linux/device.h
199 index 8d732965..6d206930 100644
200 --- a/include/linux/device.h
201 +++ b/include/linux/device.h
202 @@ -688,6 +688,25 @@ void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res);
203 int devm_add_action(struct device *dev, void (*action)(void *), void *data);
204 void devm_remove_action(struct device *dev, void (*action)(void *), void *data);
205
206 +/**
207 + * devm_alloc_percpu - Resource-managed alloc_percpu
208 + * @dev: Device to allocate per-cpu memory for
209 + * @type: Type to allocate per-cpu memory for
210 + *
211 + * Managed alloc_percpu. Per-cpu memory allocated with this function is
212 + * automatically freed on driver detach.
213 + *
214 + * RETURNS:
215 + * Pointer to allocated memory on success, NULL on failure.
216 + */
217 +#define devm_alloc_percpu(dev, type) \
218 + ((typeof(type) __percpu *)__devm_alloc_percpu((dev), sizeof(type), \
219 + __alignof__(type)))
220 +
221 +void __percpu *__devm_alloc_percpu(struct device *dev, size_t size,
222 + size_t align);
223 +void devm_free_percpu(struct device *dev, void __percpu *pdata);
224 +
225 static inline int devm_add_action_or_reset(struct device *dev,
226 void (*action)(void *), void *data)
227 {
228 diff --git a/include/linux/fsl/svr.h b/include/linux/fsl/svr.h
229 new file mode 100644
230 index 00000000..e95c8f43
231 --- /dev/null
232 +++ b/include/linux/fsl/svr.h
233 @@ -0,0 +1,97 @@
234 +/*
235 + * MPC85xx cpu type detection
236 + *
237 + * Copyright 2011-2012 Freescale Semiconductor, Inc.
238 + *
239 + * This is free software; you can redistribute it and/or modify
240 + * it under the terms of the GNU General Public License as published by
241 + * the Free Software Foundation; either version 2 of the License, or
242 + * (at your option) any later version.
243 + */
244 +
245 +#ifndef FSL_SVR_H
246 +#define FSL_SVR_H
247 +
248 +#define SVR_REV(svr) ((svr) & 0xFF) /* SOC design resision */
249 +#define SVR_MAJ(svr) (((svr) >> 4) & 0xF) /* Major revision field*/
250 +#define SVR_MIN(svr) (((svr) >> 0) & 0xF) /* Minor revision field*/
251 +
252 +/* Some parts define SVR[0:23] as the SOC version */
253 +#define SVR_SOC_VER(svr) (((svr) >> 8) & 0xFFF7FF) /* SOC Version fields */
254 +
255 +#define SVR_8533 0x803400
256 +#define SVR_8535 0x803701
257 +#define SVR_8536 0x803700
258 +#define SVR_8540 0x803000
259 +#define SVR_8541 0x807200
260 +#define SVR_8543 0x803200
261 +#define SVR_8544 0x803401
262 +#define SVR_8545 0x803102
263 +#define SVR_8547 0x803101
264 +#define SVR_8548 0x803100
265 +#define SVR_8555 0x807100
266 +#define SVR_8560 0x807000
267 +#define SVR_8567 0x807501
268 +#define SVR_8568 0x807500
269 +#define SVR_8569 0x808000
270 +#define SVR_8572 0x80E000
271 +#define SVR_P1010 0x80F100
272 +#define SVR_P1011 0x80E500
273 +#define SVR_P1012 0x80E501
274 +#define SVR_P1013 0x80E700
275 +#define SVR_P1014 0x80F101
276 +#define SVR_P1017 0x80F700
277 +#define SVR_P1020 0x80E400
278 +#define SVR_P1021 0x80E401
279 +#define SVR_P1022 0x80E600
280 +#define SVR_P1023 0x80F600
281 +#define SVR_P1024 0x80E402
282 +#define SVR_P1025 0x80E403
283 +#define SVR_P2010 0x80E300
284 +#define SVR_P2020 0x80E200
285 +#define SVR_P2040 0x821000
286 +#define SVR_P2041 0x821001
287 +#define SVR_P3041 0x821103
288 +#define SVR_P4040 0x820100
289 +#define SVR_P4080 0x820000
290 +#define SVR_P5010 0x822100
291 +#define SVR_P5020 0x822000
292 +#define SVR_P5021 0X820500
293 +#define SVR_P5040 0x820400
294 +#define SVR_T4240 0x824000
295 +#define SVR_T4120 0x824001
296 +#define SVR_T4160 0x824100
297 +#define SVR_T4080 0x824102
298 +#define SVR_C291 0x850000
299 +#define SVR_C292 0x850020
300 +#define SVR_C293 0x850030
301 +#define SVR_B4860 0X868000
302 +#define SVR_G4860 0x868001
303 +#define SVR_G4060 0x868003
304 +#define SVR_B4440 0x868100
305 +#define SVR_G4440 0x868101
306 +#define SVR_B4420 0x868102
307 +#define SVR_B4220 0x868103
308 +#define SVR_T1040 0x852000
309 +#define SVR_T1041 0x852001
310 +#define SVR_T1042 0x852002
311 +#define SVR_T1020 0x852100
312 +#define SVR_T1021 0x852101
313 +#define SVR_T1022 0x852102
314 +#define SVR_T1023 0x854100
315 +#define SVR_T1024 0x854000
316 +#define SVR_T2080 0x853000
317 +#define SVR_T2081 0x853100
318 +
319 +#define SVR_8610 0x80A000
320 +#define SVR_8641 0x809000
321 +#define SVR_8641D 0x809001
322 +
323 +#define SVR_9130 0x860001
324 +#define SVR_9131 0x860000
325 +#define SVR_9132 0x861000
326 +#define SVR_9232 0x861400
327 +
328 +#define SVR_Unknown 0xFFFFFF
329 +
330 +#endif
331 diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h
332 index f2912914..22308465 100644
333 --- a/include/linux/fsl_devices.h
334 +++ b/include/linux/fsl_devices.h
335 @@ -99,7 +99,10 @@ struct fsl_usb2_platform_data {
336 unsigned suspended:1;
337 unsigned already_suspended:1;
338 unsigned has_fsl_erratum_a007792:1;
339 + unsigned has_fsl_erratum_14:1;
340 unsigned has_fsl_erratum_a005275:1;
341 + unsigned has_fsl_erratum_a006918:1;
342 + unsigned has_fsl_erratum_a005697:1;
343 unsigned check_phy_clk_valid:1;
344
345 /* register save area for suspend/resume */
346 diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h
347 index 9c6c8ef2..90b4107e 100644
348 --- a/include/linux/netdev_features.h
349 +++ b/include/linux/netdev_features.h
350 @@ -74,6 +74,7 @@ enum {
351 NETIF_F_BUSY_POLL_BIT, /* Busy poll */
352
353 NETIF_F_HW_TC_BIT, /* Offload TC infrastructure */
354 + NETIF_F_HW_ACCEL_MQ_BIT, /* Hardware-accelerated multiqueue */
355
356 /*
357 * Add your fresh new feature above and remember to update
358 @@ -136,6 +137,7 @@ enum {
359 #define NETIF_F_HW_L2FW_DOFFLOAD __NETIF_F(HW_L2FW_DOFFLOAD)
360 #define NETIF_F_BUSY_POLL __NETIF_F(BUSY_POLL)
361 #define NETIF_F_HW_TC __NETIF_F(HW_TC)
362 +#define NETIF_F_HW_ACCEL_MQ __NETIF_F(HW_ACCEL_MQ)
363
364 #define for_each_netdev_feature(mask_addr, bit) \
365 for_each_set_bit(bit, (unsigned long *)mask_addr, NETDEV_FEATURE_COUNT)
366 diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
367 index c3a1537c..9740875b 100644
368 --- a/include/linux/netdevice.h
369 +++ b/include/linux/netdevice.h
370 @@ -1509,6 +1509,8 @@ enum netdev_priv_flags {
371 * @if_port: Selectable AUI, TP, ...
372 * @dma: DMA channel
373 * @mtu: Interface MTU value
374 + * @min_mtu: Interface Minimum MTU value
375 + * @max_mtu: Interface Maximum MTU value
376 * @type: Interface hardware type
377 * @hard_header_len: Maximum hardware header length.
378 * @min_header_len: Minimum hardware header length
379 @@ -1735,6 +1737,8 @@ struct net_device {
380 unsigned char dma;
381
382 unsigned int mtu;
383 + unsigned int min_mtu;
384 + unsigned int max_mtu;
385 unsigned short type;
386 unsigned short hard_header_len;
387 unsigned short min_header_len;
388 diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
389 index 9a0c945e..06f33c98 100644
390 --- a/include/linux/skbuff.h
391 +++ b/include/linux/skbuff.h
392 @@ -903,6 +903,7 @@ void kfree_skb(struct sk_buff *skb);
393 void kfree_skb_list(struct sk_buff *segs);
394 void skb_tx_error(struct sk_buff *skb);
395 void consume_skb(struct sk_buff *skb);
396 +void skb_recycle(struct sk_buff *skb);
397 void __kfree_skb(struct sk_buff *skb);
398 extern struct kmem_cache *skbuff_head_cache;
399
400 @@ -3057,6 +3058,7 @@ static inline void skb_free_datagram_locked(struct sock *sk,
401 }
402 int skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags);
403 int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len);
404 +void copy_skb_header(struct sk_buff *new, const struct sk_buff *old);
405 int skb_store_bits(struct sk_buff *skb, int offset, const void *from, int len);
406 __wsum skb_copy_and_csum_bits(const struct sk_buff *skb, int offset, u8 *to,
407 int len, __wsum csum);
408 diff --git a/include/linux/sys_soc.h b/include/linux/sys_soc.h
409 index 2739ccb6..9f5eb06f 100644
410 --- a/include/linux/sys_soc.h
411 +++ b/include/linux/sys_soc.h
412 @@ -13,6 +13,7 @@ struct soc_device_attribute {
413 const char *family;
414 const char *revision;
415 const char *soc_id;
416 + const void *data;
417 };
418
419 /**
420 @@ -34,4 +35,6 @@ void soc_device_unregister(struct soc_device *soc_dev);
421 */
422 struct device *soc_device_to_device(struct soc_device *soc);
423
424 +const struct soc_device_attribute *soc_device_match(
425 + const struct soc_device_attribute *matches);
426 #endif /* __SOC_BUS_H */
427 diff --git a/include/uapi/linux/if_ether.h b/include/uapi/linux/if_ether.h
428 index 51f38442..5c01afbf 100644
429 --- a/include/uapi/linux/if_ether.h
430 +++ b/include/uapi/linux/if_ether.h
431 @@ -35,6 +35,7 @@
432 #define ETH_DATA_LEN 1500 /* Max. octets in payload */
433 #define ETH_FRAME_LEN 1514 /* Max. octets in frame sans FCS */
434 #define ETH_FCS_LEN 4 /* Octets in the FCS */
435 +#define ETH_MIN_MTU 68 /* Min IPv4 MTU per RFC791 */
436
437 /*
438 * These are the defined Ethernet Protocol ID's.
439 diff --git a/net/core/dev.c b/net/core/dev.c
440 index 512086f2..6e3bb7bc 100644
441 --- a/net/core/dev.c
442 +++ b/net/core/dev.c
443 @@ -6603,9 +6603,18 @@ int dev_set_mtu(struct net_device *dev, int new_mtu)
444 if (new_mtu == dev->mtu)
445 return 0;
446
447 - /* MTU must be positive. */
448 - if (new_mtu < 0)
449 + /* MTU must be positive, and in range */
450 + if (new_mtu < 0 || new_mtu < dev->min_mtu) {
451 + net_err_ratelimited("%s: Invalid MTU %d requested, hw min %d\n",
452 + dev->name, new_mtu, dev->min_mtu);
453 return -EINVAL;
454 + }
455 +
456 + if (dev->max_mtu > 0 && new_mtu > dev->max_mtu) {
457 + net_err_ratelimited("%s: Invalid MTU %d requested, hw max %d\n",
458 + dev->name, new_mtu, dev->min_mtu);
459 + return -EINVAL;
460 + }
461
462 if (!netif_device_present(dev))
463 return -ENODEV;
464 diff --git a/net/core/skbuff.c b/net/core/skbuff.c
465 index 7e7b7ce0..0f9c014a 100644
466 --- a/net/core/skbuff.c
467 +++ b/net/core/skbuff.c
468 @@ -842,6 +842,32 @@ void napi_consume_skb(struct sk_buff *skb, int budget)
469 }
470 EXPORT_SYMBOL(napi_consume_skb);
471
472 +/**
473 + * skb_recycle - clean up an skb for reuse
474 + * @skb: buffer
475 + *
476 + * Recycles the skb to be reused as a receive buffer. This
477 + * function does any necessary reference count dropping, and
478 + * cleans up the skbuff as if it just came from __alloc_skb().
479 + */
480 +void skb_recycle(struct sk_buff *skb)
481 +{
482 + struct skb_shared_info *shinfo;
483 + u8 head_frag = skb->head_frag;
484 +
485 + skb_release_head_state(skb);
486 +
487 + shinfo = skb_shinfo(skb);
488 + memset(shinfo, 0, offsetof(struct skb_shared_info, dataref));
489 + atomic_set(&shinfo->dataref, 1);
490 +
491 + memset(skb, 0, offsetof(struct sk_buff, tail));
492 + skb->data = skb->head + NET_SKB_PAD;
493 + skb->head_frag = head_frag;
494 + skb_reset_tail_pointer(skb);
495 +}
496 +EXPORT_SYMBOL(skb_recycle);
497 +
498 /* Make sure a field is enclosed inside headers_start/headers_end section */
499 #define CHECK_SKB_FIELD(field) \
500 BUILD_BUG_ON(offsetof(struct sk_buff, field) < \
501 @@ -1073,7 +1099,7 @@ static void skb_headers_offset_update(struct sk_buff *skb, int off)
502 skb->inner_mac_header += off;
503 }
504
505 -static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
506 +void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
507 {
508 __copy_skb_header(new, old);
509
510 @@ -1081,6 +1107,7 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
511 skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs;
512 skb_shinfo(new)->gso_type = skb_shinfo(old)->gso_type;
513 }
514 +EXPORT_SYMBOL(copy_skb_header);
515
516 static inline int skb_alloc_rx_flag(const struct sk_buff *skb)
517 {
518 diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
519 index 8018dd3a..ea760b83 100644
520 --- a/net/sched/sch_generic.c
521 +++ b/net/sched/sch_generic.c
522 @@ -309,6 +309,13 @@ static void dev_watchdog(unsigned long arg)
523 txq->trans_timeout++;
524 break;
525 }
526 +
527 + /* Devices with HW_ACCEL_MQ have multiple txqs
528 + * but update only the first one's transmission
529 + * timestamp so avoid checking the rest.
530 + */
531 + if (dev->features & NETIF_F_HW_ACCEL_MQ)
532 + break;
533 }
534
535 if (some_queue_timedout) {
536 --
537 2.14.1
538