Browse code

nxp:ls1012a: Add support to enable network

- Add pfe driver to NXP LS1012A FRWY board.
- Add grub-efi based boot on NXP ls1012a FRWY Board.

Change-Id: I3877e25afc9b67cabe6f7a22f075a31ecad50e80
Signed-off-by: srinidhira0 <srinidhir@vmware.com>
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/6498
Tested-by: gerrit-photon <photon-checkins@vmware.com>
Reviewed-by: Alexey Makhalov <amakhalov@vmware.com>

srinidhira0 authored on 2019/01/13 17:39:52
Showing 29 changed files
... ...
@@ -1496,7 +1496,7 @@ CONFIG_NET_MPLS_GSO=m
1496 1496
 # CONFIG_MPLS_ROUTING is not set
1497 1497
 CONFIG_NET_NSH=m
1498 1498
 # CONFIG_HSR is not set
1499
-# CONFIG_NET_SWITCHDEV is not set
1499
+CONFIG_NET_SWITCHDEV=y
1500 1500
 CONFIG_NET_L3_MASTER_DEV=y
1501 1501
 # CONFIG_QRTR is not set
1502 1502
 # CONFIG_NET_NCSI is not set
... ...
@@ -2210,10 +2210,11 @@ CONFIG_BE2NET_HWMON=y
2210 2210
 CONFIG_NET_VENDOR_EZCHIP=y
2211 2211
 # CONFIG_EZCHIP_NPS_MANAGEMENT_ENET is not set
2212 2212
 CONFIG_NET_VENDOR_FREESCALE=y
2213
-# CONFIG_FSL_FMAN is not set
2213
+CONFIG_FSL_FMAN=m
2214 2214
 # CONFIG_FSL_PQ_MDIO is not set
2215
-# CONFIG_FSL_XGMAC_MDIO is not set
2215
+CONFIG_FSL_XGMAC_MDIO=m
2216 2216
 # CONFIG_GIANFAR is not set
2217
+CONFIG_FSL_DPAA_ETH=m
2217 2218
 CONFIG_NET_VENDOR_HISILICON=y
2218 2219
 # CONFIG_HIX5HD2_GMAC is not set
2219 2220
 # CONFIG_HISI_FEMAC is not set
... ...
@@ -2270,6 +2271,7 @@ CONFIG_NET_VENDOR_MICROCHIP=y
2270 2270
 # CONFIG_ENCX24J600 is not set
2271 2271
 CONFIG_LAN743X=m
2272 2272
 CONFIG_NET_VENDOR_MICROSEMI=y
2273
+# CONFIG_MSCC_OCELOT_SWITCH is not set
2273 2274
 CONFIG_NET_VENDOR_MYRI=y
2274 2275
 CONFIG_MYRI10GE=m
2275 2276
 # CONFIG_FEALNX is not set
... ...
@@ -2303,6 +2305,7 @@ CONFIG_8139TOO_8129=y
2303 2303
 CONFIG_R8169=m
2304 2304
 CONFIG_NET_VENDOR_RENESAS=y
2305 2305
 CONFIG_NET_VENDOR_ROCKER=y
2306
+# CONFIG_ROCKER is not set
2306 2307
 CONFIG_NET_VENDOR_SAMSUNG=y
2307 2308
 # CONFIG_SXGBE_ETH is not set
2308 2309
 # CONFIG_NET_VENDOR_SEEQ is not set
... ...
@@ -2902,6 +2905,7 @@ CONFIG_PPS=y
2902 2902
 #
2903 2903
 CONFIG_PTP_1588_CLOCK=y
2904 2904
 CONFIG_PTP_1588_CLOCK_DTE=y
2905
+CONFIG_PTP_1588_CLOCK_QORIQ=m
2905 2906
 # CONFIG_DP83640_PHY is not set
2906 2907
 CONFIG_PINCTRL=y
2907 2908
 CONFIG_PINMUX=y
... ...
@@ -4942,6 +4946,8 @@ CONFIG_VIDEO_BCM2835=m
4942 4942
 # CONFIG_STAGING_GASKET_FRAMEWORK is not set
4943 4943
 # CONFIG_XIL_AXIS_FIFO is not set
4944 4944
 # CONFIG_EROFS_FS is not set
4945
+CONFIG_FSL_PPFE=m
4946
+CONFIG_FSL_PPFE_UTIL_DISABLED=y
4945 4947
 # CONFIG_GOLDFISH is not set
4946 4948
 # CONFIG_CHROME_PLATFORMS is not set
4947 4949
 CONFIG_CLKDEV_LOOKUP=y
... ...
@@ -4964,7 +4970,7 @@ CONFIG_CLK_VEXPRESS_OSC=y
4964 4964
 # CONFIG_COMMON_CLK_CDCE706 is not set
4965 4965
 # CONFIG_COMMON_CLK_CDCE925 is not set
4966 4966
 # CONFIG_COMMON_CLK_CS2000_CP is not set
4967
-# CONFIG_CLK_QORIQ is not set
4967
+CONFIG_CLK_QORIQ=y
4968 4968
 CONFIG_COMMON_CLK_XGENE=y
4969 4969
 # CONFIG_COMMON_CLK_PWM is not set
4970 4970
 # CONFIG_COMMON_CLK_VC5 is not set
... ...
@@ -5098,7 +5104,11 @@ CONFIG_RASPBERRYPI_POWER=y
5098 5098
 #
5099 5099
 # NXP/Freescale QorIQ SoC drivers
5100 5100
 #
5101
-# CONFIG_FSL_DPAA is not set
5101
+CONFIG_FSL_DPAA=y
5102
+# CONFIG_FSL_DPAA_CHECKING is not set
5103
+# CONFIG_FSL_BMAN_TEST is not set
5104
+# CONFIG_FSL_QMAN_TEST is not set
5105
+CONFIG_FSL_GUTS=y
5102 5106
 
5103 5107
 #
5104 5108
 # i.MX SoC drivers
... ...
@@ -2,7 +2,7 @@
2 2
 Summary:        Kernel
3 3
 Name:           linux
4 4
 Version:        4.19.6
5
-Release:        6%{?kat_build:.%kat_build}%{?dist}
5
+Release:        7%{?kat_build:.%kat_build}%{?dist}
6 6
 License:    	GPLv2
7 7
 URL:        	http://www.kernel.org/
8 8
 Group:        	System Environment/Kernel
... ...
@@ -43,7 +43,32 @@ Patch29:        4.17-0001-apparmor-patch-to-provide-compatibility-with-v2.x-ne.p
43 43
 Patch30:        4.17-0002-apparmor-af_unix-mediation.patch
44 44
 Patch31:        4.17-0003-apparmor-fix-use-after-free-in-sk_peer_label.patch
45 45
 Patch32:        4.18-0001-hwrng-rdrand-Add-RNG-driver-based-on-x86-rdrand-inst.patch
46
-
46
+%ifarch aarch64
47
+# NXP LS1012a FRWY patches
48
+Patch51:        0001-staging-fsl_ppfe-eth-header-files-for-pfe-driver.patch
49
+Patch52:        0002-staging-fsl_ppfe-eth-introduce-pfe-driver.patch
50
+Patch53:        0003-staging-fsl_ppfe-eth-fix-RGMII-tx-delay-issue.patch
51
+Patch54:        0004-staging-fsl_ppfe-eth-remove-unused-functions.patch
52
+Patch55:        0005-staging-fsl_ppfe-eth-fix-read-write-ack-idx-issue.patch
53
+Patch56:        0006-staging-fsl_ppfe-eth-Make-phy_ethtool_ksettings_get-.patch
54
+Patch57:        0007-staging-fsl_ppfe-eth-add-function-to-update-tmu-cred.patch
55
+Patch58:        0008-staging-fsl_ppfe-eth-Avoid-packet-drop-at-TMU-queues.patch
56
+Patch59:        0009-staging-fsl_ppfe-eth-Enable-PFE-in-clause-45-mode.patch
57
+Patch60:        0010-staging-fsl_ppfe-eth-Disable-autonegotiation-for-2.5.patch
58
+Patch61:        0011-staging-fsl_ppfe-eth-add-missing-included-header-fil.patch
59
+Patch62:        0012-staging-fsl_ppfe-eth-clean-up-iounmap-pfe-ddr_basead.patch
60
+Patch63:        0013-staging-fsl_ppfe-eth-calculate-PFE_PKT_SIZE-with-SKB.patch
61
+Patch64:        0014-staging-fsl_ppfe-eth-support-for-userspace-networkin.patch
62
+Patch65:        0015-staging-fsl_ppfe-eth-unregister-netdev-after-pfe_phy.patch
63
+Patch66:        0016-staging-fsl_ppfe-eth-HW-parse-results-for-DPDK.patch
64
+Patch67:        0017-staging-fsl_ppfe-eth-reorganize-pfe_netdev_ops.patch
65
+Patch68:        0018-staging-fsl_ppfe-eth-use-mask-for-rx-max-frame-len.patch
66
+Patch69:        0019-staging-fsl_ppfe-eth-define-pfe-ndo_change_mtu-funct.patch
67
+Patch70:        0020-staging-fsl_ppfe-eth-remove-jumbo-frame-enable-from-.patch
68
+Patch71:        0021-staging-fsl_ppfe-eth-disable-CRC-removal.patch
69
+Patch72:        0022-staging-fsl_ppfe-eth-handle-ls1012a-errata_a010897.patch
70
+Patch73:        0023-staging-fsl_ppfe-eth-Modify-Kconfig-to-enable-pfe-dr.patch
71
+%endif
47 72
 
48 73
 %if 0%{?kat_build:1}
49 74
 Patch1000:	%{kat_build}.patch
... ...
@@ -155,6 +180,32 @@ Kernel Device Tree Blob files for NXP ls1012a FRWY board
155 155
 %patch31 -p1
156 156
 %patch32 -p1
157 157
 
158
+%ifarch aarch64
159
+# NXP FSL_PPFE Driver patches
160
+%patch51 -p1
161
+%patch52 -p1
162
+%patch53 -p1
163
+%patch54 -p1
164
+%patch55 -p1
165
+%patch56 -p1
166
+%patch57 -p1
167
+%patch58 -p1
168
+%patch59 -p1
169
+%patch60 -p1
170
+%patch61 -p1
171
+%patch62 -p1
172
+%patch63 -p1
173
+%patch64 -p1
174
+%patch65 -p1
175
+%patch66 -p1
176
+%patch67 -p1
177
+%patch68 -p1
178
+%patch69 -p1
179
+%patch70 -p1
180
+%patch71 -p1
181
+%patch72 -p1
182
+%patch73 -p1
183
+%endif
158 184
 %if 0%{?kat_build:1}
159 185
 %patch1000 -p1
160 186
 %endif
... ...
@@ -249,7 +300,7 @@ install -vm 644 arch/arm64/boot/Image %{buildroot}/boot/vmlinuz-%{uname_r}
249 249
 # Install DTB files
250 250
 install -vdm 755 %{buildroot}/boot/dtb
251 251
 install -vm 640 arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dtb %{buildroot}/boot/dtb/
252
-install -vm 640 arch/arm64/boot/dts/freescale/fsl-ls1012a-frdm.dtb %{buildroot}/boot/dtb/
252
+install -vm 640 arch/arm64/boot/dts/freescale/fsl-ls1012a-frwy.dtb %{buildroot}/boot/dtb/
253 253
 %endif
254 254
 
255 255
 # Restrict the permission on System.map-X file
... ...
@@ -381,11 +432,13 @@ ln -sf %{name}-%{uname_r}.cfg /boot/photon.cfg
381 381
 
382 382
 %files dtb-ls1012afrwy
383 383
 %defattr(-,root,root)
384
-/boot/dtb/fsl-ls1012a-frdm.dtb
384
+/boot/dtb/fsl-ls1012a-frwy.dtb
385 385
 
386 386
 %endif
387 387
 
388 388
 %changelog
389
+*   Fri Jan 11 2019 Srinidhi Rao <srinidhir@vmware.com> 4.19.6-7
390
+-   Add Network support for NXP LS1012A board.
389 391
 *   Wed Jan 09 2019 Ankit Jain <ankitja@vmware.com> 4.19.6-6
390 392
 -   Enable following for x86_64 and aarch64:
391 393
 -    Enable Kernel Address Space Layout Randomization.
392 394
new file mode 100644
... ...
@@ -0,0 +1,2692 @@
0
+From 77d2c2e907a9921aaed61cb33230a866500d5512 Mon Sep 17 00:00:00 2001
1
+From: Calvin Johnson <calvin.johnson@nxp.com>
2
+Date: Sat, 16 Sep 2017 14:21:37 +0530
3
+Subject: [PATCH 01/22] staging: fsl_ppfe/eth: header files for pfe driver
4
+
5
+This patch has all pfe header files.
6
+
7
+Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
8
+Signed-off-by: Anjaneyulu Jagarlmudi <anji.jagarlmudi@nxp.com>
9
+
10
+[ Srinidhi Rao : Ported this patch to photon linux from
11
+  qoriq-components linux 'linux-4.14-nxp'
12
+  (https://source.codeaurora.org/external/qoriq/qoriq-components/linux)
13
+]
14
+
15
+Signed-off-by: srinidhira0 <srinidhir@vmware.com>
16
+---
17
+ drivers/staging/fsl_ppfe/include/pfe/cbus.h        |  78 +++++
18
+ drivers/staging/fsl_ppfe/include/pfe/cbus/bmu.h    |  55 +++
19
+ .../staging/fsl_ppfe/include/pfe/cbus/class_csr.h  | 289 ++++++++++++++++
20
+ .../staging/fsl_ppfe/include/pfe/cbus/emac_mtip.h  | 242 ++++++++++++++
21
+ drivers/staging/fsl_ppfe/include/pfe/cbus/gpi.h    |  86 +++++
22
+ drivers/staging/fsl_ppfe/include/pfe/cbus/hif.h    | 100 ++++++
23
+ .../staging/fsl_ppfe/include/pfe/cbus/hif_nocpy.h  |  50 +++
24
+ .../staging/fsl_ppfe/include/pfe/cbus/tmu_csr.h    | 168 ++++++++++
25
+ .../staging/fsl_ppfe/include/pfe/cbus/util_csr.h   |  61 ++++
26
+ drivers/staging/fsl_ppfe/include/pfe/pfe.h         | 372 +++++++++++++++++++++
27
+ drivers/staging/fsl_ppfe/pfe_ctrl.h                | 112 +++++++
28
+ drivers/staging/fsl_ppfe/pfe_debugfs.h             |  25 ++
29
+ drivers/staging/fsl_ppfe/pfe_eth.h                 | 184 ++++++++++
30
+ drivers/staging/fsl_ppfe/pfe_firmware.h            |  32 ++
31
+ drivers/staging/fsl_ppfe/pfe_hif.h                 | 211 ++++++++++++
32
+ drivers/staging/fsl_ppfe/pfe_hif_lib.h             | 239 +++++++++++++
33
+ drivers/staging/fsl_ppfe/pfe_hw.h                  |  27 ++
34
+ drivers/staging/fsl_ppfe/pfe_mod.h                 | 112 +++++++
35
+ drivers/staging/fsl_ppfe/pfe_perfmon.h             |  38 +++
36
+ drivers/staging/fsl_ppfe/pfe_sysfs.h               |  29 ++
37
+ 20 files changed, 2510 insertions(+)
38
+ create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus.h
39
+ create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/bmu.h
40
+ create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/class_csr.h
41
+ create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/emac_mtip.h
42
+ create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/gpi.h
43
+ create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/hif.h
44
+ create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/hif_nocpy.h
45
+ create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/tmu_csr.h
46
+ create mode 100644 drivers/staging/fsl_ppfe/include/pfe/cbus/util_csr.h
47
+ create mode 100644 drivers/staging/fsl_ppfe/include/pfe/pfe.h
48
+ create mode 100644 drivers/staging/fsl_ppfe/pfe_ctrl.h
49
+ create mode 100644 drivers/staging/fsl_ppfe/pfe_debugfs.h
50
+ create mode 100644 drivers/staging/fsl_ppfe/pfe_eth.h
51
+ create mode 100644 drivers/staging/fsl_ppfe/pfe_firmware.h
52
+ create mode 100644 drivers/staging/fsl_ppfe/pfe_hif.h
53
+ create mode 100644 drivers/staging/fsl_ppfe/pfe_hif_lib.h
54
+ create mode 100644 drivers/staging/fsl_ppfe/pfe_hw.h
55
+ create mode 100644 drivers/staging/fsl_ppfe/pfe_mod.h
56
+ create mode 100644 drivers/staging/fsl_ppfe/pfe_perfmon.h
57
+ create mode 100644 drivers/staging/fsl_ppfe/pfe_sysfs.h
58
+
59
+diff --git a/drivers/staging/fsl_ppfe/include/pfe/cbus.h b/drivers/staging/fsl_ppfe/include/pfe/cbus.h
60
+new file mode 100644
61
+index 000000000000..04503d28c982
62
+--- /dev/null
63
+@@ -0,0 +1,78 @@
64
++/*
65
++ * Copyright 2015-2016 Freescale Semiconductor, Inc.
66
++ * Copyright 2017 NXP
67
++ *
68
++ * This program is free software; you can redistribute it and/or modify
69
++ * it under the terms of the GNU General Public License as published by
70
++ * the Free Software Foundation; either version 2 of the License, or
71
++ * (at your option) any later version.
72
++ *
73
++ * This program is distributed in the hope that it will be useful,
74
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
75
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
76
++ * GNU General Public License for more details.
77
++ *
78
++ * You should have received a copy of the GNU General Public License
79
++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
80
++ */
81
++
82
++#ifndef _CBUS_H_
83
++#define _CBUS_H_
84
++
85
++#define EMAC1_BASE_ADDR	(CBUS_BASE_ADDR + 0x200000)
86
++#define EGPI1_BASE_ADDR	(CBUS_BASE_ADDR + 0x210000)
87
++#define EMAC2_BASE_ADDR	(CBUS_BASE_ADDR + 0x220000)
88
++#define EGPI2_BASE_ADDR	(CBUS_BASE_ADDR + 0x230000)
89
++#define BMU1_BASE_ADDR	(CBUS_BASE_ADDR + 0x240000)
90
++#define BMU2_BASE_ADDR	(CBUS_BASE_ADDR + 0x250000)
91
++#define ARB_BASE_ADDR	(CBUS_BASE_ADDR + 0x260000)
92
++#define DDR_CONFIG_BASE_ADDR	(CBUS_BASE_ADDR + 0x270000)
93
++#define HIF_BASE_ADDR	(CBUS_BASE_ADDR + 0x280000)
94
++#define HGPI_BASE_ADDR	(CBUS_BASE_ADDR + 0x290000)
95
++#define LMEM_BASE_ADDR	(CBUS_BASE_ADDR + 0x300000)
96
++#define LMEM_SIZE	0x10000
97
++#define LMEM_END	(LMEM_BASE_ADDR + LMEM_SIZE)
98
++#define TMU_CSR_BASE_ADDR	(CBUS_BASE_ADDR + 0x310000)
99
++#define CLASS_CSR_BASE_ADDR	(CBUS_BASE_ADDR + 0x320000)
100
++#define HIF_NOCPY_BASE_ADDR	(CBUS_BASE_ADDR + 0x350000)
101
++#define UTIL_CSR_BASE_ADDR	(CBUS_BASE_ADDR + 0x360000)
102
++#define CBUS_GPT_BASE_ADDR	(CBUS_BASE_ADDR + 0x370000)
103
++
104
++/*
105
++ * defgroup XXX_MEM_ACCESS_ADDR PE memory access through CSR
106
++ * XXX_MEM_ACCESS_ADDR register bit definitions.
107
++ */
108
++#define PE_MEM_ACCESS_WRITE	BIT(31)	/* Internal Memory Write. */
109
++#define PE_MEM_ACCESS_IMEM	BIT(15)
110
++#define PE_MEM_ACCESS_DMEM	BIT(16)
111
++
112
++/* Byte Enables of the Internal memory access. These are interpred in BE */
113
++#define PE_MEM_ACCESS_BYTE_ENABLE(offset, size)	\
114
++	({ typeof(size) size_ = (size);		\
115
++	(((BIT(size_) - 1) << (4 - (offset) - (size_))) & 0xf) << 24; })
116
++
117
++#include "cbus/emac_mtip.h"
118
++#include "cbus/gpi.h"
119
++#include "cbus/bmu.h"
120
++#include "cbus/hif.h"
121
++#include "cbus/tmu_csr.h"
122
++#include "cbus/class_csr.h"
123
++#include "cbus/hif_nocpy.h"
124
++#include "cbus/util_csr.h"
125
++
126
++/* PFE cores states */
127
++#define CORE_DISABLE	0x00000000
128
++#define CORE_ENABLE	0x00000001
129
++#define CORE_SW_RESET	0x00000002
130
++
131
++/* LMEM defines */
132
++#define LMEM_HDR_SIZE	0x0010
133
++#define LMEM_BUF_SIZE_LN2	0x7
134
++#define LMEM_BUF_SIZE	BIT(LMEM_BUF_SIZE_LN2)
135
++
136
++/* DDR defines */
137
++#define DDR_HDR_SIZE	0x0100
138
++#define DDR_BUF_SIZE_LN2	0xb
139
++#define DDR_BUF_SIZE	BIT(DDR_BUF_SIZE_LN2)
140
++
141
++#endif /* _CBUS_H_ */
142
+diff --git a/drivers/staging/fsl_ppfe/include/pfe/cbus/bmu.h b/drivers/staging/fsl_ppfe/include/pfe/cbus/bmu.h
143
+new file mode 100644
144
+index 000000000000..87738ca3cfbb
145
+--- /dev/null
146
+@@ -0,0 +1,55 @@
147
++/*
148
++ * Copyright 2015-2016 Freescale Semiconductor, Inc.
149
++ * Copyright 2017 NXP
150
++ *
151
++ * This program is free software; you can redistribute it and/or modify
152
++ * it under the terms of the GNU General Public License as published by
153
++ * the Free Software Foundation; either version 2 of the License, or
154
++ * (at your option) any later version.
155
++ *
156
++ * This program is distributed in the hope that it will be useful,
157
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
158
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
159
++ * GNU General Public License for more details.
160
++ *
161
++ * You should have received a copy of the GNU General Public License
162
++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
163
++ */
164
++
165
++#ifndef _BMU_H_
166
++#define _BMU_H_
167
++
168
++#define BMU_VERSION	0x000
169
++#define BMU_CTRL	0x004
170
++#define BMU_UCAST_CONFIG	0x008
171
++#define BMU_UCAST_BASE_ADDR	0x00c
172
++#define BMU_BUF_SIZE	0x010
173
++#define BMU_BUF_CNT	0x014
174
++#define BMU_THRES	0x018
175
++#define BMU_INT_SRC	0x020
176
++#define BMU_INT_ENABLE	0x024
177
++#define BMU_ALLOC_CTRL	0x030
178
++#define BMU_FREE_CTRL	0x034
179
++#define BMU_FREE_ERR_ADDR	0x038
180
++#define BMU_CURR_BUF_CNT	0x03c
181
++#define BMU_MCAST_CNT	0x040
182
++#define BMU_MCAST_ALLOC_CTRL	0x044
183
++#define BMU_REM_BUF_CNT	0x048
184
++#define BMU_LOW_WATERMARK	0x050
185
++#define BMU_HIGH_WATERMARK	0x054
186
++#define BMU_INT_MEM_ACCESS	0x100
187
++
188
++struct BMU_CFG {
189
++	unsigned long baseaddr;
190
++	u32 count;
191
++	u32 size;
192
++	u32 low_watermark;
193
++	u32 high_watermark;
194
++};
195
++
196
++#define BMU1_BUF_SIZE	LMEM_BUF_SIZE_LN2
197
++#define BMU2_BUF_SIZE	DDR_BUF_SIZE_LN2
198
++
199
++#define BMU2_MCAST_ALLOC_CTRL	(BMU2_BASE_ADDR + BMU_MCAST_ALLOC_CTRL)
200
++
201
++#endif /* _BMU_H_ */
202
+diff --git a/drivers/staging/fsl_ppfe/include/pfe/cbus/class_csr.h b/drivers/staging/fsl_ppfe/include/pfe/cbus/class_csr.h
203
+new file mode 100644
204
+index 000000000000..e4dadff58768
205
+--- /dev/null
206
+@@ -0,0 +1,289 @@
207
++/*
208
++ * Copyright 2015-2016 Freescale Semiconductor, Inc.
209
++ * Copyright 2017 NXP
210
++ *
211
++ * This program is free software; you can redistribute it and/or modify
212
++ * it under the terms of the GNU General Public License as published by
213
++ * the Free Software Foundation; either version 2 of the License, or
214
++ * (at your option) any later version.
215
++ *
216
++ * This program is distributed in the hope that it will be useful,
217
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
218
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
219
++ * GNU General Public License for more details.
220
++ *
221
++ * You should have received a copy of the GNU General Public License
222
++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
223
++ */
224
++
225
++#ifndef _CLASS_CSR_H_
226
++#define _CLASS_CSR_H_
227
++
228
++/* @file class_csr.h.
229
++ * class_csr - block containing all the classifier control and status register.
230
++ * Mapped on CBUS and accessible from all PE's and ARM.
231
++ */
232
++#define CLASS_VERSION	(CLASS_CSR_BASE_ADDR + 0x000)
233
++#define CLASS_TX_CTRL	(CLASS_CSR_BASE_ADDR + 0x004)
234
++#define CLASS_INQ_PKTPTR	(CLASS_CSR_BASE_ADDR + 0x010)
235
++
236
++/* (ddr_hdr_size[24:16], lmem_hdr_size[5:0]) */
237
++#define CLASS_HDR_SIZE	(CLASS_CSR_BASE_ADDR + 0x014)
238
++
239
++/* LMEM header size for the Classifier block.\ Data in the LMEM
240
++ * is written from this offset.
241
++ */
242
++#define CLASS_HDR_SIZE_LMEM(off)	((off) & 0x3f)
243
++
244
++/* DDR header size for the Classifier block.\ Data in the DDR
245
++ * is written from this offset.
246
++ */
247
++#define CLASS_HDR_SIZE_DDR(off)	(((off) & 0x1ff) << 16)
248
++
249
++#define CLASS_PE0_QB_DM_ADDR0	(CLASS_CSR_BASE_ADDR + 0x020)
250
++
251
++/* DMEM address of first [15:0] and second [31:16] buffers on QB side. */
252
++#define CLASS_PE0_QB_DM_ADDR1	(CLASS_CSR_BASE_ADDR + 0x024)
253
++
254
++/* DMEM address of third [15:0] and fourth [31:16] buffers on QB side. */
255
++#define CLASS_PE0_RO_DM_ADDR0	(CLASS_CSR_BASE_ADDR + 0x060)
256
++
257
++/* DMEM address of first [15:0] and second [31:16] buffers on RO side. */
258
++#define CLASS_PE0_RO_DM_ADDR1	(CLASS_CSR_BASE_ADDR + 0x064)
259
++
260
++/* DMEM address of third [15:0] and fourth [31:16] buffers on RO side. */
261
++
262
++/* @name Class PE memory access. Allows external PE's and HOST to
263
++ * read/write PMEM/DMEM memory ranges for each classifier PE.
264
++ */
265
++/* {sr_pe_mem_cmd[31], csr_pe_mem_wren[27:24], csr_pe_mem_addr[23:0]},
266
++ * See \ref XXX_MEM_ACCESS_ADDR for details.
267
++ */
268
++#define CLASS_MEM_ACCESS_ADDR	(CLASS_CSR_BASE_ADDR + 0x100)
269
++
270
++/* Internal Memory Access Write Data [31:0] */
271
++#define CLASS_MEM_ACCESS_WDATA	(CLASS_CSR_BASE_ADDR + 0x104)
272
++
273
++/* Internal Memory Access Read Data [31:0] */
274
++#define CLASS_MEM_ACCESS_RDATA	(CLASS_CSR_BASE_ADDR + 0x108)
275
++#define CLASS_TM_INQ_ADDR	(CLASS_CSR_BASE_ADDR + 0x114)
276
++#define CLASS_PE_STATUS	(CLASS_CSR_BASE_ADDR + 0x118)
277
++
278
++#define CLASS_PHY1_RX_PKTS	(CLASS_CSR_BASE_ADDR + 0x11c)
279
++#define CLASS_PHY1_TX_PKTS	(CLASS_CSR_BASE_ADDR + 0x120)
280
++#define CLASS_PHY1_LP_FAIL_PKTS	(CLASS_CSR_BASE_ADDR + 0x124)
281
++#define CLASS_PHY1_INTF_FAIL_PKTS	(CLASS_CSR_BASE_ADDR + 0x128)
282
++#define CLASS_PHY1_INTF_MATCH_PKTS	(CLASS_CSR_BASE_ADDR + 0x12c)
283
++#define CLASS_PHY1_L3_FAIL_PKTS	(CLASS_CSR_BASE_ADDR + 0x130)
284
++#define CLASS_PHY1_V4_PKTS	(CLASS_CSR_BASE_ADDR + 0x134)
285
++#define CLASS_PHY1_V6_PKTS	(CLASS_CSR_BASE_ADDR + 0x138)
286
++#define CLASS_PHY1_CHKSUM_ERR_PKTS	(CLASS_CSR_BASE_ADDR + 0x13c)
287
++#define CLASS_PHY1_TTL_ERR_PKTS	(CLASS_CSR_BASE_ADDR + 0x140)
288
++#define CLASS_PHY2_RX_PKTS	(CLASS_CSR_BASE_ADDR + 0x144)
289
++#define CLASS_PHY2_TX_PKTS	(CLASS_CSR_BASE_ADDR + 0x148)
290
++#define CLASS_PHY2_LP_FAIL_PKTS	(CLASS_CSR_BASE_ADDR + 0x14c)
291
++#define CLASS_PHY2_INTF_FAIL_PKTS	(CLASS_CSR_BASE_ADDR + 0x150)
292
++#define CLASS_PHY2_INTF_MATCH_PKTS	(CLASS_CSR_BASE_ADDR + 0x154)
293
++#define CLASS_PHY2_L3_FAIL_PKTS	(CLASS_CSR_BASE_ADDR + 0x158)
294
++#define CLASS_PHY2_V4_PKTS	(CLASS_CSR_BASE_ADDR + 0x15c)
295
++#define CLASS_PHY2_V6_PKTS	(CLASS_CSR_BASE_ADDR + 0x160)
296
++#define CLASS_PHY2_CHKSUM_ERR_PKTS	(CLASS_CSR_BASE_ADDR + 0x164)
297
++#define CLASS_PHY2_TTL_ERR_PKTS	(CLASS_CSR_BASE_ADDR + 0x168)
298
++#define CLASS_PHY3_RX_PKTS	(CLASS_CSR_BASE_ADDR + 0x16c)
299
++#define CLASS_PHY3_TX_PKTS	(CLASS_CSR_BASE_ADDR + 0x170)
300
++#define CLASS_PHY3_LP_FAIL_PKTS	(CLASS_CSR_BASE_ADDR + 0x174)
301
++#define CLASS_PHY3_INTF_FAIL_PKTS	(CLASS_CSR_BASE_ADDR + 0x178)
302
++#define CLASS_PHY3_INTF_MATCH_PKTS	(CLASS_CSR_BASE_ADDR + 0x17c)
303
++#define CLASS_PHY3_L3_FAIL_PKTS	(CLASS_CSR_BASE_ADDR + 0x180)
304
++#define CLASS_PHY3_V4_PKTS	(CLASS_CSR_BASE_ADDR + 0x184)
305
++#define CLASS_PHY3_V6_PKTS	(CLASS_CSR_BASE_ADDR + 0x188)
306
++#define CLASS_PHY3_CHKSUM_ERR_PKTS	(CLASS_CSR_BASE_ADDR + 0x18c)
307
++#define CLASS_PHY3_TTL_ERR_PKTS	(CLASS_CSR_BASE_ADDR + 0x190)
308
++#define CLASS_PHY1_ICMP_PKTS	(CLASS_CSR_BASE_ADDR + 0x194)
309
++#define CLASS_PHY1_IGMP_PKTS	(CLASS_CSR_BASE_ADDR + 0x198)
310
++#define CLASS_PHY1_TCP_PKTS	(CLASS_CSR_BASE_ADDR + 0x19c)
311
++#define CLASS_PHY1_UDP_PKTS	(CLASS_CSR_BASE_ADDR + 0x1a0)
312
++#define CLASS_PHY2_ICMP_PKTS	(CLASS_CSR_BASE_ADDR + 0x1a4)
313
++#define CLASS_PHY2_IGMP_PKTS	(CLASS_CSR_BASE_ADDR + 0x1a8)
314
++#define CLASS_PHY2_TCP_PKTS	(CLASS_CSR_BASE_ADDR + 0x1ac)
315
++#define CLASS_PHY2_UDP_PKTS	(CLASS_CSR_BASE_ADDR + 0x1b0)
316
++#define CLASS_PHY3_ICMP_PKTS	(CLASS_CSR_BASE_ADDR + 0x1b4)
317
++#define CLASS_PHY3_IGMP_PKTS	(CLASS_CSR_BASE_ADDR + 0x1b8)
318
++#define CLASS_PHY3_TCP_PKTS	(CLASS_CSR_BASE_ADDR + 0x1bc)
319
++#define CLASS_PHY3_UDP_PKTS	(CLASS_CSR_BASE_ADDR + 0x1c0)
320
++#define CLASS_PHY4_ICMP_PKTS	(CLASS_CSR_BASE_ADDR + 0x1c4)
321
++#define CLASS_PHY4_IGMP_PKTS	(CLASS_CSR_BASE_ADDR + 0x1c8)
322
++#define CLASS_PHY4_TCP_PKTS	(CLASS_CSR_BASE_ADDR + 0x1cc)
323
++#define CLASS_PHY4_UDP_PKTS	(CLASS_CSR_BASE_ADDR + 0x1d0)
324
++#define CLASS_PHY4_RX_PKTS	(CLASS_CSR_BASE_ADDR + 0x1d4)
325
++#define CLASS_PHY4_TX_PKTS	(CLASS_CSR_BASE_ADDR + 0x1d8)
326
++#define CLASS_PHY4_LP_FAIL_PKTS	(CLASS_CSR_BASE_ADDR + 0x1dc)
327
++#define CLASS_PHY4_INTF_FAIL_PKTS	(CLASS_CSR_BASE_ADDR + 0x1e0)
328
++#define CLASS_PHY4_INTF_MATCH_PKTS	(CLASS_CSR_BASE_ADDR + 0x1e4)
329
++#define CLASS_PHY4_L3_FAIL_PKTS	(CLASS_CSR_BASE_ADDR + 0x1e8)
330
++#define CLASS_PHY4_V4_PKTS	(CLASS_CSR_BASE_ADDR + 0x1ec)
331
++#define CLASS_PHY4_V6_PKTS	(CLASS_CSR_BASE_ADDR + 0x1f0)
332
++#define CLASS_PHY4_CHKSUM_ERR_PKTS	(CLASS_CSR_BASE_ADDR + 0x1f4)
333
++#define CLASS_PHY4_TTL_ERR_PKTS	(CLASS_CSR_BASE_ADDR + 0x1f8)
334
++
335
++#define CLASS_PE_SYS_CLK_RATIO	(CLASS_CSR_BASE_ADDR + 0x200)
336
++#define CLASS_AFULL_THRES	(CLASS_CSR_BASE_ADDR + 0x204)
337
++#define CLASS_GAP_BETWEEN_READS	(CLASS_CSR_BASE_ADDR + 0x208)
338
++#define CLASS_MAX_BUF_CNT	(CLASS_CSR_BASE_ADDR + 0x20c)
339
++#define CLASS_TSQ_FIFO_THRES	(CLASS_CSR_BASE_ADDR + 0x210)
340
++#define CLASS_TSQ_MAX_CNT	(CLASS_CSR_BASE_ADDR + 0x214)
341
++#define CLASS_IRAM_DATA_0	(CLASS_CSR_BASE_ADDR + 0x218)
342
++#define CLASS_IRAM_DATA_1	(CLASS_CSR_BASE_ADDR + 0x21c)
343
++#define CLASS_IRAM_DATA_2	(CLASS_CSR_BASE_ADDR + 0x220)
344
++#define CLASS_IRAM_DATA_3	(CLASS_CSR_BASE_ADDR + 0x224)
345
++
346
++#define CLASS_BUS_ACCESS_ADDR	(CLASS_CSR_BASE_ADDR + 0x228)
347
++
348
++#define CLASS_BUS_ACCESS_WDATA	(CLASS_CSR_BASE_ADDR + 0x22c)
349
++#define CLASS_BUS_ACCESS_RDATA	(CLASS_CSR_BASE_ADDR + 0x230)
350
++
351
++/* (route_entry_size[9:0], route_hash_size[23:16]
352
++ * (this is actually ln2(size)))
353
++ */
354
++#define CLASS_ROUTE_HASH_ENTRY_SIZE	(CLASS_CSR_BASE_ADDR + 0x234)
355
++
356
++#define CLASS_ROUTE_ENTRY_SIZE(size)	 ((size) & 0x1ff)
357
++#define CLASS_ROUTE_HASH_SIZE(hash_bits) (((hash_bits) & 0xff) << 16)
358
++
359
++#define CLASS_ROUTE_TABLE_BASE	(CLASS_CSR_BASE_ADDR + 0x238)
360
++
361
++#define CLASS_ROUTE_MULTI	(CLASS_CSR_BASE_ADDR + 0x23c)
362
++#define CLASS_SMEM_OFFSET	(CLASS_CSR_BASE_ADDR + 0x240)
363
++#define CLASS_LMEM_BUF_SIZE	(CLASS_CSR_BASE_ADDR + 0x244)
364
++#define CLASS_VLAN_ID	(CLASS_CSR_BASE_ADDR + 0x248)
365
++#define CLASS_BMU1_BUF_FREE	(CLASS_CSR_BASE_ADDR + 0x24c)
366
++#define CLASS_USE_TMU_INQ	(CLASS_CSR_BASE_ADDR + 0x250)
367
++#define CLASS_VLAN_ID1	(CLASS_CSR_BASE_ADDR + 0x254)
368
++
369
++#define CLASS_BUS_ACCESS_BASE	(CLASS_CSR_BASE_ADDR + 0x258)
370
++#define CLASS_BUS_ACCESS_BASE_MASK	(0xFF000000)
371
++/* bit 31:24 of PE peripheral address are stored in CLASS_BUS_ACCESS_BASE */
372
++
373
++#define CLASS_HIF_PARSE	(CLASS_CSR_BASE_ADDR + 0x25c)
374
++
375
++#define CLASS_HOST_PE0_GP	(CLASS_CSR_BASE_ADDR + 0x260)
376
++#define CLASS_PE0_GP	(CLASS_CSR_BASE_ADDR + 0x264)
377
++#define CLASS_HOST_PE1_GP	(CLASS_CSR_BASE_ADDR + 0x268)
378
++#define CLASS_PE1_GP	(CLASS_CSR_BASE_ADDR + 0x26c)
379
++#define CLASS_HOST_PE2_GP	(CLASS_CSR_BASE_ADDR + 0x270)
380
++#define CLASS_PE2_GP	(CLASS_CSR_BASE_ADDR + 0x274)
381
++#define CLASS_HOST_PE3_GP	(CLASS_CSR_BASE_ADDR + 0x278)
382
++#define CLASS_PE3_GP	(CLASS_CSR_BASE_ADDR + 0x27c)
383
++#define CLASS_HOST_PE4_GP	(CLASS_CSR_BASE_ADDR + 0x280)
384
++#define CLASS_PE4_GP	(CLASS_CSR_BASE_ADDR + 0x284)
385
++#define CLASS_HOST_PE5_GP	(CLASS_CSR_BASE_ADDR + 0x288)
386
++#define CLASS_PE5_GP	(CLASS_CSR_BASE_ADDR + 0x28c)
387
++
388
++#define CLASS_PE_INT_SRC	(CLASS_CSR_BASE_ADDR + 0x290)
389
++#define CLASS_PE_INT_ENABLE	(CLASS_CSR_BASE_ADDR + 0x294)
390
++
391
++#define CLASS_TPID0_TPID1	(CLASS_CSR_BASE_ADDR + 0x298)
392
++#define CLASS_TPID2	(CLASS_CSR_BASE_ADDR + 0x29c)
393
++
394
++#define CLASS_L4_CHKSUM_ADDR	(CLASS_CSR_BASE_ADDR + 0x2a0)
395
++
396
++#define CLASS_PE0_DEBUG	(CLASS_CSR_BASE_ADDR + 0x2a4)
397
++#define CLASS_PE1_DEBUG	(CLASS_CSR_BASE_ADDR + 0x2a8)
398
++#define CLASS_PE2_DEBUG	(CLASS_CSR_BASE_ADDR + 0x2ac)
399
++#define CLASS_PE3_DEBUG	(CLASS_CSR_BASE_ADDR + 0x2b0)
400
++#define CLASS_PE4_DEBUG	(CLASS_CSR_BASE_ADDR + 0x2b4)
401
++#define CLASS_PE5_DEBUG	(CLASS_CSR_BASE_ADDR + 0x2b8)
402
++
403
++#define CLASS_STATE	(CLASS_CSR_BASE_ADDR + 0x2bc)
404
++
405
++/* CLASS defines */
406
++#define CLASS_PBUF_SIZE	0x100	/* Fixed by hardware */
407
++#define CLASS_PBUF_HEADER_OFFSET	0x80	/* Can be configured */
408
++
409
++/* Can be configured */
410
++#define CLASS_PBUF0_BASE_ADDR	0x000
411
++/* Can be configured */
412
++#define CLASS_PBUF1_BASE_ADDR	(CLASS_PBUF0_BASE_ADDR + CLASS_PBUF_SIZE)
413
++/* Can be configured */
414
++#define CLASS_PBUF2_BASE_ADDR	(CLASS_PBUF1_BASE_ADDR + CLASS_PBUF_SIZE)
415
++/* Can be configured */
416
++#define CLASS_PBUF3_BASE_ADDR	(CLASS_PBUF2_BASE_ADDR + CLASS_PBUF_SIZE)
417
++
418
++#define CLASS_PBUF0_HEADER_BASE_ADDR	(CLASS_PBUF0_BASE_ADDR + \
419
++						CLASS_PBUF_HEADER_OFFSET)
420
++#define CLASS_PBUF1_HEADER_BASE_ADDR	(CLASS_PBUF1_BASE_ADDR + \
421
++						CLASS_PBUF_HEADER_OFFSET)
422
++#define CLASS_PBUF2_HEADER_BASE_ADDR	(CLASS_PBUF2_BASE_ADDR + \
423
++						CLASS_PBUF_HEADER_OFFSET)
424
++#define CLASS_PBUF3_HEADER_BASE_ADDR	(CLASS_PBUF3_BASE_ADDR + \
425
++						CLASS_PBUF_HEADER_OFFSET)
426
++
427
++#define CLASS_PE0_RO_DM_ADDR0_VAL	((CLASS_PBUF1_BASE_ADDR << 16) | \
428
++						CLASS_PBUF0_BASE_ADDR)
429
++#define CLASS_PE0_RO_DM_ADDR1_VAL	((CLASS_PBUF3_BASE_ADDR << 16) | \
430
++						CLASS_PBUF2_BASE_ADDR)
431
++
432
++#define CLASS_PE0_QB_DM_ADDR0_VAL	((CLASS_PBUF1_HEADER_BASE_ADDR << 16) |\
433
++						CLASS_PBUF0_HEADER_BASE_ADDR)
434
++#define CLASS_PE0_QB_DM_ADDR1_VAL	((CLASS_PBUF3_HEADER_BASE_ADDR << 16) |\
435
++						CLASS_PBUF2_HEADER_BASE_ADDR)
436
++
437
++#define CLASS_ROUTE_SIZE	128
438
++#define CLASS_MAX_ROUTE_SIZE	256
439
++#define CLASS_ROUTE_HASH_BITS	20
440
++#define CLASS_ROUTE_HASH_MASK	(BIT(CLASS_ROUTE_HASH_BITS) - 1)
441
++
442
++/* Can be configured */
443
++#define	CLASS_ROUTE0_BASE_ADDR	0x400
444
++/* Can be configured */
445
++#define CLASS_ROUTE1_BASE_ADDR	(CLASS_ROUTE0_BASE_ADDR + CLASS_ROUTE_SIZE)
446
++/* Can be configured */
447
++#define CLASS_ROUTE2_BASE_ADDR	(CLASS_ROUTE1_BASE_ADDR + CLASS_ROUTE_SIZE)
448
++/* Can be configured */
449
++#define CLASS_ROUTE3_BASE_ADDR	(CLASS_ROUTE2_BASE_ADDR + CLASS_ROUTE_SIZE)
450
++
451
++#define CLASS_SA_SIZE	128
452
++#define CLASS_IPSEC_SA0_BASE_ADDR	0x600
453
++/* not used */
454
++#define CLASS_IPSEC_SA1_BASE_ADDR  (CLASS_IPSEC_SA0_BASE_ADDR + CLASS_SA_SIZE)
455
++/* not used */
456
++#define CLASS_IPSEC_SA2_BASE_ADDR  (CLASS_IPSEC_SA1_BASE_ADDR + CLASS_SA_SIZE)
457
++/* not used */
458
++#define CLASS_IPSEC_SA3_BASE_ADDR  (CLASS_IPSEC_SA2_BASE_ADDR + CLASS_SA_SIZE)
459
++
460
++/* generic purpose free dmem buffer, last portion of 2K dmem pbuf */
461
++#define CLASS_GP_DMEM_BUF_SIZE	(2048 - (CLASS_PBUF_SIZE * 4) - \
462
++				(CLASS_ROUTE_SIZE * 4) - (CLASS_SA_SIZE))
463
++#define CLASS_GP_DMEM_BUF	((void *)(CLASS_IPSEC_SA0_BASE_ADDR + \
464
++					CLASS_SA_SIZE))
465
++
466
++#define TWO_LEVEL_ROUTE		BIT(0)
467
++#define PHYNO_IN_HASH		BIT(1)
468
++#define HW_ROUTE_FETCH		BIT(3)
469
++#define HW_BRIDGE_FETCH		BIT(5)
470
++#define IP_ALIGNED		BIT(6)
471
++#define ARC_HIT_CHECK_EN	BIT(7)
472
++#define CLASS_TOE		BIT(11)
473
++#define HASH_NORMAL		(0 << 12)
474
++#define HASH_CRC_PORT		BIT(12)
475
++#define HASH_CRC_IP		(2 << 12)
476
++#define HASH_CRC_PORT_IP	(3 << 12)
477
++#define QB2BUS_LE		BIT(15)
478
++
479
++#define TCP_CHKSUM_DROP		BIT(0)
480
++#define UDP_CHKSUM_DROP		BIT(1)
481
++#define IPV4_CHKSUM_DROP	BIT(9)
482
++
483
++/*CLASS_HIF_PARSE bits*/
484
++#define HIF_PKT_CLASS_EN	BIT(0)
485
++#define HIF_PKT_OFFSET(ofst)	(((ofst) & 0xF) << 1)
486
++
487
++struct class_cfg {
488
++	u32 toe_mode;
489
++	unsigned long route_table_baseaddr;
490
++	u32 route_table_hash_bits;
491
++	u32 pe_sys_clk_ratio;
492
++	u32 resume;
493
++};
494
++
495
++#endif /* _CLASS_CSR_H_ */
496
+diff --git a/drivers/staging/fsl_ppfe/include/pfe/cbus/emac_mtip.h b/drivers/staging/fsl_ppfe/include/pfe/cbus/emac_mtip.h
497
+new file mode 100644
498
+index 000000000000..9c5d7919455d
499
+--- /dev/null
500
+@@ -0,0 +1,242 @@
501
++/*
502
++ * Copyright 2015-2016 Freescale Semiconductor, Inc.
503
++ * Copyright 2017 NXP
504
++ *
505
++ * This program is free software; you can redistribute it and/or modify
506
++ * it under the terms of the GNU General Public License as published by
507
++ * the Free Software Foundation; either version 2 of the License, or
508
++ * (at your option) any later version.
509
++ *
510
++ * This program is distributed in the hope that it will be useful,
511
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
512
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
513
++ * GNU General Public License for more details.
514
++ *
515
++ * You should have received a copy of the GNU General Public License
516
++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
517
++ */
518
++
519
++#ifndef _EMAC_H_
520
++#define _EMAC_H_
521
++
522
++#include <linux/ethtool.h>
523
++
524
++#define EMAC_IEVENT_REG		0x004
525
++#define EMAC_IMASK_REG		0x008
526
++#define EMAC_R_DES_ACTIVE_REG	0x010
527
++#define EMAC_X_DES_ACTIVE_REG	0x014
528
++#define EMAC_ECNTRL_REG		0x024
529
++#define EMAC_MII_DATA_REG	0x040
530
++#define EMAC_MII_CTRL_REG	0x044
531
++#define EMAC_MIB_CTRL_STS_REG	0x064
532
++#define EMAC_RCNTRL_REG		0x084
533
++#define EMAC_TCNTRL_REG		0x0C4
534
++#define EMAC_PHY_ADDR_LOW	0x0E4
535
++#define EMAC_PHY_ADDR_HIGH	0x0E8
536
++#define EMAC_GAUR		0x120
537
++#define EMAC_GALR		0x124
538
++#define EMAC_TFWR_STR_FWD	0x144
539
++#define EMAC_RX_SECTION_FULL	0x190
540
++#define EMAC_RX_SECTION_EMPTY	0x194
541
++#define EMAC_TX_SECTION_EMPTY	0x1A0
542
++#define EMAC_TRUNC_FL		0x1B0
543
++
544
++#define RMON_T_DROP	0x200 /* Count of frames not cntd correctly */
545
++#define RMON_T_PACKETS	0x204 /* RMON TX packet count */
546
++#define RMON_T_BC_PKT	0x208 /* RMON TX broadcast pkts */
547
++#define RMON_T_MC_PKT	0x20c /* RMON TX multicast pkts */
548
++#define RMON_T_CRC_ALIGN	0x210 /* RMON TX pkts with CRC align err */
549
++#define RMON_T_UNDERSIZE	0x214 /* RMON TX pkts < 64 bytes, good CRC */
550
++#define RMON_T_OVERSIZE	0x218 /* RMON TX pkts > MAX_FL bytes good CRC */
551
++#define RMON_T_FRAG	0x21c /* RMON TX pkts < 64 bytes, bad CRC */
552
++#define RMON_T_JAB	0x220 /* RMON TX pkts > MAX_FL bytes, bad CRC */
553
++#define RMON_T_COL	0x224 /* RMON TX collision count */
554
++#define RMON_T_P64	0x228 /* RMON TX 64 byte pkts */
555
++#define RMON_T_P65TO127	0x22c /* RMON TX 65 to 127 byte pkts */
556
++#define RMON_T_P128TO255	0x230 /* RMON TX 128 to 255 byte pkts */
557
++#define RMON_T_P256TO511	0x234 /* RMON TX 256 to 511 byte pkts */
558
++#define RMON_T_P512TO1023	0x238 /* RMON TX 512 to 1023 byte pkts */
559
++#define RMON_T_P1024TO2047	0x23c /* RMON TX 1024 to 2047 byte pkts */
560
++#define RMON_T_P_GTE2048	0x240 /* RMON TX pkts > 2048 bytes */
561
++#define RMON_T_OCTETS	0x244 /* RMON TX octets */
562
++#define IEEE_T_DROP	0x248 /* Count of frames not counted crtly */
563
++#define IEEE_T_FRAME_OK	0x24c /* Frames tx'd OK */
564
++#define IEEE_T_1COL	0x250 /* Frames tx'd with single collision */
565
++#define IEEE_T_MCOL	0x254 /* Frames tx'd with multiple collision */
566
++#define IEEE_T_DEF	0x258 /* Frames tx'd after deferral delay */
567
++#define IEEE_T_LCOL	0x25c /* Frames tx'd with late collision */
568
++#define IEEE_T_EXCOL	0x260 /* Frames tx'd with excesv collisions */
569
++#define IEEE_T_MACERR	0x264 /* Frames tx'd with TX FIFO underrun */
570
++#define IEEE_T_CSERR	0x268 /* Frames tx'd with carrier sense err */
571
++#define IEEE_T_SQE	0x26c /* Frames tx'd with SQE err */
572
++#define IEEE_T_FDXFC	0x270 /* Flow control pause frames tx'd */
573
++#define IEEE_T_OCTETS_OK	0x274 /* Octet count for frames tx'd w/o err */
574
++#define RMON_R_PACKETS	0x284 /* RMON RX packet count */
575
++#define RMON_R_BC_PKT	0x288 /* RMON RX broadcast pkts */
576
++#define RMON_R_MC_PKT	0x28c /* RMON RX multicast pkts */
577
++#define RMON_R_CRC_ALIGN	0x290 /* RMON RX pkts with CRC alignment err */
578
++#define RMON_R_UNDERSIZE	0x294 /* RMON RX pkts < 64 bytes, good CRC */
579
++#define RMON_R_OVERSIZE	0x298 /* RMON RX pkts > MAX_FL bytes good CRC */
580
++#define RMON_R_FRAG	0x29c /* RMON RX pkts < 64 bytes, bad CRC */
581
++#define RMON_R_JAB	0x2a0 /* RMON RX pkts > MAX_FL bytes, bad CRC */
582
++#define RMON_R_RESVD_O	0x2a4 /* Reserved */
583
++#define RMON_R_P64	0x2a8 /* RMON RX 64 byte pkts */
584
++#define RMON_R_P65TO127	0x2ac /* RMON RX 65 to 127 byte pkts */
585
++#define RMON_R_P128TO255	0x2b0 /* RMON RX 128 to 255 byte pkts */
586
++#define RMON_R_P256TO511	0x2b4 /* RMON RX 256 to 511 byte pkts */
587
++#define RMON_R_P512TO1023	0x2b8 /* RMON RX 512 to 1023 byte pkts */
588
++#define RMON_R_P1024TO2047	0x2bc /* RMON RX 1024 to 2047 byte pkts */
589
++#define RMON_R_P_GTE2048	0x2c0 /* RMON RX pkts > 2048 bytes */
590
++#define RMON_R_OCTETS	0x2c4 /* RMON RX octets */
591
++#define IEEE_R_DROP	0x2c8 /* Count frames not counted correctly */
592
++#define IEEE_R_FRAME_OK	0x2cc /* Frames rx'd OK */
593
++#define IEEE_R_CRC	0x2d0 /* Frames rx'd with CRC err */
594
++#define IEEE_R_ALIGN	0x2d4 /* Frames rx'd with alignment err */
595
++#define IEEE_R_MACERR	0x2d8 /* Receive FIFO overflow count */
596
++#define IEEE_R_FDXFC	0x2dc /* Flow control pause frames rx'd */
597
++#define IEEE_R_OCTETS_OK	0x2e0 /* Octet cnt for frames rx'd w/o err */
598
++
599
++#define EMAC_SMAC_0_0	0x500 /*Supplemental MAC Address 0 (RW).*/
600
++#define EMAC_SMAC_0_1	0x504 /*Supplemental MAC Address 0 (RW).*/
601
++
602
++/* GEMAC definitions and settings */
603
++
604
++#define EMAC_PORT_0	0
605
++#define EMAC_PORT_1	1
606
++
607
++/* GEMAC Bit definitions */
608
++#define EMAC_IEVENT_HBERR		 0x80000000
609
++#define EMAC_IEVENT_BABR		 0x40000000
610
++#define EMAC_IEVENT_BABT		 0x20000000
611
++#define EMAC_IEVENT_GRA			 0x10000000
612
++#define EMAC_IEVENT_TXF			 0x08000000
613
++#define EMAC_IEVENT_TXB			 0x04000000
614
++#define EMAC_IEVENT_RXF			 0x02000000
615
++#define EMAC_IEVENT_RXB			 0x01000000
616
++#define EMAC_IEVENT_MII			 0x00800000
617
++#define EMAC_IEVENT_EBERR		 0x00400000
618
++#define EMAC_IEVENT_LC			 0x00200000
619
++#define EMAC_IEVENT_RL			 0x00100000
620
++#define EMAC_IEVENT_UN			 0x00080000
621
++
622
++#define EMAC_IMASK_HBERR                 0x80000000
623
++#define EMAC_IMASK_BABR                  0x40000000
624
++#define EMAC_IMASKT_BABT                 0x20000000
625
++#define EMAC_IMASK_GRA                   0x10000000
626
++#define EMAC_IMASKT_TXF                  0x08000000
627
++#define EMAC_IMASK_TXB                   0x04000000
628
++#define EMAC_IMASKT_RXF                  0x02000000
629
++#define EMAC_IMASK_RXB                   0x01000000
630
++#define EMAC_IMASK_MII                   0x00800000
631
++#define EMAC_IMASK_EBERR                 0x00400000
632
++#define EMAC_IMASK_LC                    0x00200000
633
++#define EMAC_IMASKT_RL                   0x00100000
634
++#define EMAC_IMASK_UN                    0x00080000
635
++
636
++#define EMAC_RCNTRL_MAX_FL_SHIFT         16
637
++#define EMAC_RCNTRL_LOOP                 0x00000001
638
++#define EMAC_RCNTRL_DRT                  0x00000002
639
++#define EMAC_RCNTRL_MII_MODE             0x00000004
640
++#define EMAC_RCNTRL_PROM                 0x00000008
641
++#define EMAC_RCNTRL_BC_REJ               0x00000010
642
++#define EMAC_RCNTRL_FCE                  0x00000020
643
++#define EMAC_RCNTRL_RGMII                0x00000040
644
++#define EMAC_RCNTRL_SGMII                0x00000080
645
++#define EMAC_RCNTRL_RMII                 0x00000100
646
++#define EMAC_RCNTRL_RMII_10T             0x00000200
647
++#define EMAC_RCNTRL_CRC_FWD		 0x00004000
648
++
649
++#define EMAC_TCNTRL_GTS                  0x00000001
650
++#define EMAC_TCNTRL_HBC                  0x00000002
651
++#define EMAC_TCNTRL_FDEN                 0x00000004
652
++#define EMAC_TCNTRL_TFC_PAUSE            0x00000008
653
++#define EMAC_TCNTRL_RFC_PAUSE            0x00000010
654
++
655
++#define EMAC_ECNTRL_RESET                0x00000001      /* reset the EMAC */
656
++#define EMAC_ECNTRL_ETHER_EN             0x00000002      /* enable the EMAC */
657
++#define EMAC_ECNTRL_MAGIC_ENA		 0x00000004
658
++#define EMAC_ECNTRL_SLEEP		 0x00000008
659
++#define EMAC_ECNTRL_SPEED                0x00000020
660
++#define EMAC_ECNTRL_DBSWAP               0x00000100
661
++
662
++#define EMAC_X_WMRK_STRFWD               0x00000100
663
++
664
++#define EMAC_X_DES_ACTIVE_TDAR           0x01000000
665
++#define EMAC_R_DES_ACTIVE_RDAR           0x01000000
666
++
667
++#define EMAC_RX_SECTION_EMPTY_V		0x00010006
668
++/*
669
++ * The possible operating speeds of the MAC, currently supporting 10, 100 and
670
++ * 1000Mb modes.
671
++ */
672
++enum mac_speed {SPEED_10M, SPEED_100M, SPEED_1000M, SPEED_1000M_PCS};
673
++
674
++/* MII-related definitios */
675
++#define EMAC_MII_DATA_ST         0x40000000      /* Start of frame delimiter */
676
++#define EMAC_MII_DATA_OP_RD      0x20000000      /* Perform a read operation */
677
++#define EMAC_MII_DATA_OP_CL45_RD 0x30000000      /* Perform a read operation */
678
++#define EMAC_MII_DATA_OP_WR      0x10000000      /* Perform a write operation */
679
++#define EMAC_MII_DATA_OP_CL45_WR 0x10000000      /* Perform a write operation */
680
++#define EMAC_MII_DATA_PA_MSK     0x0f800000      /* PHY Address field mask */
681
++#define EMAC_MII_DATA_RA_MSK     0x007c0000      /* PHY Register field mask */
682
++#define EMAC_MII_DATA_TA         0x00020000      /* Turnaround */
683
++#define EMAC_MII_DATA_DATAMSK    0x0000ffff      /* PHY data field */
684
++
685
++#define EMAC_MII_DATA_RA_SHIFT   18      /* MII Register address bits */
686
++#define EMAC_MII_DATA_RA_MASK	 0x1F      /* MII Register address mask */
687
++#define EMAC_MII_DATA_PA_SHIFT   23      /* MII PHY address bits */
688
++#define EMAC_MII_DATA_PA_MASK    0x1F      /* MII PHY address mask */
689
++
690
++#define EMAC_MII_DATA_RA(v) (((v) & EMAC_MII_DATA_RA_MASK) << \
691
++				EMAC_MII_DATA_RA_SHIFT)
692
++#define EMAC_MII_DATA_PA(v) (((v) & EMAC_MII_DATA_RA_MASK) << \
693
++				EMAC_MII_DATA_PA_SHIFT)
694
++#define EMAC_MII_DATA(v)    ((v) & 0xffff)
695
++
696
++#define EMAC_MII_SPEED_SHIFT	1
697
++#define EMAC_HOLDTIME_SHIFT	8
698
++#define EMAC_HOLDTIME_MASK	0x7
699
++#define EMAC_HOLDTIME(v)	(((v) & EMAC_HOLDTIME_MASK) << \
700
++					EMAC_HOLDTIME_SHIFT)
701
++
702
++/*
703
++ * The Address organisation for the MAC device.  All addresses are split into
704
++ * two 32-bit register fields.  The first one (bottom) is the lower 32-bits of
705
++ * the address and the other field are the high order bits - this may be 16-bits
706
++ * in the case of MAC addresses, or 32-bits for the hash address.
707
++ * In terms of memory storage, the first item (bottom) is assumed to be at a
708
++ * lower address location than 'top'. i.e. top should be at address location of
709
++ * 'bottom' + 4 bytes.
710
++ */
711
++struct pfe_mac_addr {
712
++	u32 bottom;     /* Lower 32-bits of address. */
713
++	u32 top;        /* Upper 32-bits of address. */
714
++};
715
++
716
++/*
717
++ * The following is the organisation of the address filters section of the MAC
718
++ * registers.  The Cadence MAC contains four possible specific address match
719
++ * addresses, if an incoming frame corresponds to any one of these four
720
++ * addresses then the frame will be copied to memory.
721
++ * It is not necessary for all four of the address match registers to be
722
++ * programmed, this is application dependent.
723
++ */
724
++struct spec_addr {
725
++	struct pfe_mac_addr one;        /* Specific address register 1. */
726
++	struct pfe_mac_addr two;        /* Specific address register 2. */
727
++	struct pfe_mac_addr three;      /* Specific address register 3. */
728
++	struct pfe_mac_addr four;       /* Specific address register 4. */
729
++};
730
++
731
++struct gemac_cfg {
732
++	u32 mode;
733
++	u32 speed;
734
++	u32 duplex;
735
++};
736
++
737
++/* EMAC Hash size */
738
++#define EMAC_HASH_REG_BITS       64
739
++
740
++#define EMAC_SPEC_ADDR_MAX	4
741
++
742
++#endif /* _EMAC_H_ */
743
+diff --git a/drivers/staging/fsl_ppfe/include/pfe/cbus/gpi.h b/drivers/staging/fsl_ppfe/include/pfe/cbus/gpi.h
744
+new file mode 100644
745
+index 000000000000..7b295830f50b
746
+--- /dev/null
747
+@@ -0,0 +1,86 @@
748
++/*
749
++ * Copyright 2015-2016 Freescale Semiconductor, Inc.
750
++ * Copyright 2017 NXP
751
++ *
752
++ * This program is free software; you can redistribute it and/or modify
753
++ * it under the terms of the GNU General Public License as published by
754
++ * the Free Software Foundation; either version 2 of the License, or
755
++ * (at your option) any later version.
756
++ *
757
++ * This program is distributed in the hope that it will be useful,
758
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
759
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
760
++ * GNU General Public License for more details.
761
++ *
762
++ * You should have received a copy of the GNU General Public License
763
++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
764
++ */
765
++
766
++#ifndef _GPI_H_
767
++#define _GPI_H_
768
++
769
++#define GPI_VERSION	0x00
770
++#define GPI_CTRL	0x04
771
++#define GPI_RX_CONFIG	0x08
772
++#define GPI_HDR_SIZE	0x0c
773
++#define GPI_BUF_SIZE	0x10
774
++#define GPI_LMEM_ALLOC_ADDR	0x14
775
++#define GPI_LMEM_FREE_ADDR	0x18
776
++#define GPI_DDR_ALLOC_ADDR	0x1c
777
++#define GPI_DDR_FREE_ADDR	0x20
778
++#define GPI_CLASS_ADDR	0x24
779
++#define GPI_DRX_FIFO	0x28
780
++#define GPI_TRX_FIFO	0x2c
781
++#define GPI_INQ_PKTPTR	0x30
782
++#define GPI_DDR_DATA_OFFSET	0x34
783
++#define GPI_LMEM_DATA_OFFSET	0x38
784
++#define GPI_TMLF_TX	0x4c
785
++#define GPI_DTX_ASEQ	0x50
786
++#define GPI_FIFO_STATUS	0x54
787
++#define GPI_FIFO_DEBUG	0x58
788
++#define GPI_TX_PAUSE_TIME	0x5c
789
++#define GPI_LMEM_SEC_BUF_DATA_OFFSET	0x60
790
++#define GPI_DDR_SEC_BUF_DATA_OFFSET	0x64
791
++#define GPI_TOE_CHKSUM_EN	0x68
792
++#define GPI_OVERRUN_DROPCNT	0x6c
793
++#define GPI_CSR_MTIP_PAUSE_REG		0x74
794
++#define GPI_CSR_MTIP_PAUSE_QUANTUM	0x78
795
++#define GPI_CSR_RX_CNT			0x7c
796
++#define GPI_CSR_TX_CNT			0x80
797
++#define GPI_CSR_DEBUG1			0x84
798
++#define GPI_CSR_DEBUG2			0x88
799
++
800
++struct gpi_cfg {
801
++	u32 lmem_rtry_cnt;
802
++	u32 tmlf_txthres;
803
++	u32 aseq_len;
804
++	u32 mtip_pause_reg;
805
++};
806
++
807
++/* GPI commons defines */
808
++#define GPI_LMEM_BUF_EN	0x1
809
++#define GPI_DDR_BUF_EN	0x1
810
++
811
++/* EGPI 1 defines */
812
++#define EGPI1_LMEM_RTRY_CNT	0x40
813
++#define EGPI1_TMLF_TXTHRES	0xBC
814
++#define EGPI1_ASEQ_LEN	0x50
815
++
816
++/* EGPI 2 defines */
817
++#define EGPI2_LMEM_RTRY_CNT	0x40
818
++#define EGPI2_TMLF_TXTHRES	0xBC
819
++#define EGPI2_ASEQ_LEN	0x40
820
++
821
++/* EGPI 3 defines */
822
++#define EGPI3_LMEM_RTRY_CNT	0x40
823
++#define EGPI3_TMLF_TXTHRES	0xBC
824
++#define EGPI3_ASEQ_LEN	0x40
825
++
826
++/* HGPI defines */
827
++#define HGPI_LMEM_RTRY_CNT	0x40
828
++#define HGPI_TMLF_TXTHRES	0xBC
829
++#define HGPI_ASEQ_LEN	0x40
830
++
831
++#define EGPI_PAUSE_TIME		0x000007D0
832
++#define EGPI_PAUSE_ENABLE	0x40000000
833
++#endif /* _GPI_H_ */
834
+diff --git a/drivers/staging/fsl_ppfe/include/pfe/cbus/hif.h b/drivers/staging/fsl_ppfe/include/pfe/cbus/hif.h
835
+new file mode 100644
836
+index 000000000000..71cf81a7910c
837
+--- /dev/null
838
+@@ -0,0 +1,100 @@
839
++/*
840
++ * Copyright 2015-2016 Freescale Semiconductor, Inc.
841
++ * Copyright 2017 NXP
842
++ *
843
++ * This program is free software; you can redistribute it and/or modify
844
++ * it under the terms of the GNU General Public License as published by
845
++ * the Free Software Foundation; either version 2 of the License, or
846
++ * (at your option) any later version.
847
++ *
848
++ * This program is distributed in the hope that it will be useful,
849
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
850
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
851
++ * GNU General Public License for more details.
852
++ *
853
++ * You should have received a copy of the GNU General Public License
854
++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
855
++ */
856
++
857
++#ifndef _HIF_H_
858
++#define _HIF_H_
859
++
860
++/* @file hif.h.
861
++ * hif - PFE hif block control and status register.
862
++ * Mapped on CBUS and accessible from all PE's and ARM.
863
++ */
864
++#define HIF_VERSION	(HIF_BASE_ADDR + 0x00)
865
++#define HIF_TX_CTRL	(HIF_BASE_ADDR + 0x04)
866
++#define HIF_TX_CURR_BD_ADDR	(HIF_BASE_ADDR + 0x08)
867
++#define HIF_TX_ALLOC	(HIF_BASE_ADDR + 0x0c)
868
++#define HIF_TX_BDP_ADDR	(HIF_BASE_ADDR + 0x10)
869
++#define HIF_TX_STATUS	(HIF_BASE_ADDR + 0x14)
870
++#define HIF_RX_CTRL	(HIF_BASE_ADDR + 0x20)
871
++#define HIF_RX_BDP_ADDR	(HIF_BASE_ADDR + 0x24)
872
++#define HIF_RX_STATUS	(HIF_BASE_ADDR + 0x30)
873
++#define HIF_INT_SRC	(HIF_BASE_ADDR + 0x34)
874
++#define HIF_INT_ENABLE	(HIF_BASE_ADDR + 0x38)
875
++#define HIF_POLL_CTRL	(HIF_BASE_ADDR + 0x3c)
876
++#define HIF_RX_CURR_BD_ADDR	(HIF_BASE_ADDR + 0x40)
877
++#define HIF_RX_ALLOC	(HIF_BASE_ADDR + 0x44)
878
++#define HIF_TX_DMA_STATUS	(HIF_BASE_ADDR + 0x48)
879
++#define HIF_RX_DMA_STATUS	(HIF_BASE_ADDR + 0x4c)
880
++#define HIF_INT_COAL	(HIF_BASE_ADDR + 0x50)
881
++
882
++/* HIF_INT_SRC/ HIF_INT_ENABLE control bits */
883
++#define HIF_INT		BIT(0)
884
++#define HIF_RXBD_INT	BIT(1)
885
++#define HIF_RXPKT_INT	BIT(2)
886
++#define HIF_TXBD_INT	BIT(3)
887
++#define HIF_TXPKT_INT	BIT(4)
888
++
889
++/* HIF_TX_CTRL bits */
890
++#define HIF_CTRL_DMA_EN			BIT(0)
891
++#define HIF_CTRL_BDP_POLL_CTRL_EN	BIT(1)
892
++#define HIF_CTRL_BDP_CH_START_WSTB	BIT(2)
893
++
894
++/* HIF_RX_STATUS bits */
895
++#define BDP_CSR_RX_DMA_ACTV     BIT(16)
896
++
897
++/* HIF_INT_ENABLE bits */
898
++#define HIF_INT_EN		BIT(0)
899
++#define HIF_RXBD_INT_EN		BIT(1)
900
++#define HIF_RXPKT_INT_EN	BIT(2)
901
++#define HIF_TXBD_INT_EN		BIT(3)
902
++#define HIF_TXPKT_INT_EN	BIT(4)
903
++
904
++/* HIF_POLL_CTRL bits*/
905
++#define HIF_RX_POLL_CTRL_CYCLE	0x0400
906
++#define HIF_TX_POLL_CTRL_CYCLE	0x0400
907
++
908
++/* HIF_INT_COAL bits*/
909
++#define HIF_INT_COAL_ENABLE	BIT(31)
910
++
911
++/* Buffer descriptor control bits */
912
++#define BD_CTRL_BUFLEN_MASK	0x3fff
913
++#define BD_BUF_LEN(x)	((x) & BD_CTRL_BUFLEN_MASK)
914
++#define BD_CTRL_CBD_INT_EN	BIT(16)
915
++#define BD_CTRL_PKT_INT_EN	BIT(17)
916
++#define BD_CTRL_LIFM		BIT(18)
917
++#define BD_CTRL_LAST_BD		BIT(19)
918
++#define BD_CTRL_DIR		BIT(20)
919
++#define BD_CTRL_LMEM_CPY	BIT(21) /* Valid only for HIF_NOCPY */
920
++#define BD_CTRL_PKT_XFER	BIT(24)
921
++#define BD_CTRL_DESC_EN		BIT(31)
922
++#define BD_CTRL_PARSE_DISABLE	BIT(25)
923
++#define BD_CTRL_BRFETCH_DISABLE	BIT(26)
924
++#define BD_CTRL_RTFETCH_DISABLE	BIT(27)
925
++
926
++/* Buffer descriptor status bits*/
927
++#define BD_STATUS_CONN_ID(x)	((x) & 0xffff)
928
++#define BD_STATUS_DIR_PROC_ID	BIT(16)
929
++#define BD_STATUS_CONN_ID_EN	BIT(17)
930
++#define BD_STATUS_PE2PROC_ID(x)	(((x) & 7) << 18)
931
++#define BD_STATUS_LE_DATA	BIT(21)
932
++#define BD_STATUS_CHKSUM_EN	BIT(22)
933
++
934
++/* HIF Buffer descriptor status bits */
935
++#define DIR_PROC_ID	BIT(16)
936
++#define PROC_ID(id)	((id) << 18)
937
++
938
++#endif /* _HIF_H_ */
939
+diff --git a/drivers/staging/fsl_ppfe/include/pfe/cbus/hif_nocpy.h b/drivers/staging/fsl_ppfe/include/pfe/cbus/hif_nocpy.h
940
+new file mode 100644
941
+index 000000000000..3d4d43ce9fe2
942
+--- /dev/null
943
+@@ -0,0 +1,50 @@
944
++/*
945
++ * Copyright 2015-2016 Freescale Semiconductor, Inc.
946
++ * Copyright 2017 NXP
947
++ *
948
++ * This program is free software; you can redistribute it and/or modify
949
++ * it under the terms of the GNU General Public License as published by
950
++ * the Free Software Foundation; either version 2 of the License, or
951
++ * (at your option) any later version.
952
++ *
953
++ * This program is distributed in the hope that it will be useful,
954
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
955
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
956
++ * GNU General Public License for more details.
957
++ *
958
++ * You should have received a copy of the GNU General Public License
959
++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
960
++ */
961
++
962
++#ifndef _HIF_NOCPY_H_
963
++#define _HIF_NOCPY_H_
964
++
965
++#define HIF_NOCPY_VERSION	(HIF_NOCPY_BASE_ADDR + 0x00)
966
++#define HIF_NOCPY_TX_CTRL	(HIF_NOCPY_BASE_ADDR + 0x04)
967
++#define HIF_NOCPY_TX_CURR_BD_ADDR	(HIF_NOCPY_BASE_ADDR + 0x08)
968
++#define HIF_NOCPY_TX_ALLOC	(HIF_NOCPY_BASE_ADDR + 0x0c)
969
++#define HIF_NOCPY_TX_BDP_ADDR	(HIF_NOCPY_BASE_ADDR + 0x10)
970
++#define HIF_NOCPY_TX_STATUS	(HIF_NOCPY_BASE_ADDR + 0x14)
971
++#define HIF_NOCPY_RX_CTRL	(HIF_NOCPY_BASE_ADDR + 0x20)
972
++#define HIF_NOCPY_RX_BDP_ADDR	(HIF_NOCPY_BASE_ADDR + 0x24)
973
++#define HIF_NOCPY_RX_STATUS	(HIF_NOCPY_BASE_ADDR + 0x30)
974
++#define HIF_NOCPY_INT_SRC	(HIF_NOCPY_BASE_ADDR + 0x34)
975
++#define HIF_NOCPY_INT_ENABLE	(HIF_NOCPY_BASE_ADDR + 0x38)
976
++#define HIF_NOCPY_POLL_CTRL	(HIF_NOCPY_BASE_ADDR + 0x3c)
977
++#define HIF_NOCPY_RX_CURR_BD_ADDR	(HIF_NOCPY_BASE_ADDR + 0x40)
978
++#define HIF_NOCPY_RX_ALLOC	(HIF_NOCPY_BASE_ADDR + 0x44)
979
++#define HIF_NOCPY_TX_DMA_STATUS	(HIF_NOCPY_BASE_ADDR + 0x48)
980
++#define HIF_NOCPY_RX_DMA_STATUS	(HIF_NOCPY_BASE_ADDR + 0x4c)
981
++#define HIF_NOCPY_RX_INQ0_PKTPTR	(HIF_NOCPY_BASE_ADDR + 0x50)
982
++#define HIF_NOCPY_RX_INQ1_PKTPTR	(HIF_NOCPY_BASE_ADDR + 0x54)
983
++#define HIF_NOCPY_TX_PORT_NO	(HIF_NOCPY_BASE_ADDR + 0x60)
984
++#define HIF_NOCPY_LMEM_ALLOC_ADDR	(HIF_NOCPY_BASE_ADDR + 0x64)
985
++#define HIF_NOCPY_CLASS_ADDR	(HIF_NOCPY_BASE_ADDR + 0x68)
986
++#define HIF_NOCPY_TMU_PORT0_ADDR	(HIF_NOCPY_BASE_ADDR + 0x70)
987
++#define HIF_NOCPY_TMU_PORT1_ADDR	(HIF_NOCPY_BASE_ADDR + 0x74)
988
++#define HIF_NOCPY_TMU_PORT2_ADDR	(HIF_NOCPY_BASE_ADDR + 0x7c)
989
++#define HIF_NOCPY_TMU_PORT3_ADDR	(HIF_NOCPY_BASE_ADDR + 0x80)
990
++#define HIF_NOCPY_TMU_PORT4_ADDR	(HIF_NOCPY_BASE_ADDR + 0x84)
991
++#define HIF_NOCPY_INT_COAL	(HIF_NOCPY_BASE_ADDR + 0x90)
992
++
993
++#endif /* _HIF_NOCPY_H_ */
994
+diff --git a/drivers/staging/fsl_ppfe/include/pfe/cbus/tmu_csr.h b/drivers/staging/fsl_ppfe/include/pfe/cbus/tmu_csr.h
995
+new file mode 100644
996
+index 000000000000..05f3d681d1a4
997
+--- /dev/null
998
+@@ -0,0 +1,168 @@
999
++/*
1000
++ * Copyright 2015-2016 Freescale Semiconductor, Inc.
1001
++ * Copyright 2017 NXP
1002
++ *
1003
++ * This program is free software; you can redistribute it and/or modify
1004
++ * it under the terms of the GNU General Public License as published by
1005
++ * the Free Software Foundation; either version 2 of the License, or
1006
++ * (at your option) any later version.
1007
++ *
1008
++ * This program is distributed in the hope that it will be useful,
1009
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1010
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1011
++ * GNU General Public License for more details.
1012
++ *
1013
++ * You should have received a copy of the GNU General Public License
1014
++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
1015
++ */
1016
++
1017
++#ifndef _TMU_CSR_H_
1018
++#define _TMU_CSR_H_
1019
++
1020
++#define TMU_VERSION	(TMU_CSR_BASE_ADDR + 0x000)
1021
++#define TMU_INQ_WATERMARK	(TMU_CSR_BASE_ADDR + 0x004)
1022
++#define TMU_PHY_INQ_PKTPTR	(TMU_CSR_BASE_ADDR + 0x008)
1023
++#define TMU_PHY_INQ_PKTINFO	(TMU_CSR_BASE_ADDR + 0x00c)
1024
++#define TMU_PHY_INQ_FIFO_CNT	(TMU_CSR_BASE_ADDR + 0x010)
1025
++#define TMU_SYS_GENERIC_CONTROL	(TMU_CSR_BASE_ADDR + 0x014)
1026
++#define TMU_SYS_GENERIC_STATUS	(TMU_CSR_BASE_ADDR + 0x018)
1027
++#define TMU_SYS_GEN_CON0	(TMU_CSR_BASE_ADDR + 0x01c)
1028
++#define TMU_SYS_GEN_CON1	(TMU_CSR_BASE_ADDR + 0x020)
1029
++#define TMU_SYS_GEN_CON2	(TMU_CSR_BASE_ADDR + 0x024)
1030
++#define TMU_SYS_GEN_CON3	(TMU_CSR_BASE_ADDR + 0x028)
1031
++#define TMU_SYS_GEN_CON4	(TMU_CSR_BASE_ADDR + 0x02c)
1032
++#define TMU_TEQ_DISABLE_DROPCHK	(TMU_CSR_BASE_ADDR + 0x030)
1033
++#define TMU_TEQ_CTRL	(TMU_CSR_BASE_ADDR + 0x034)
1034
++#define TMU_TEQ_QCFG	(TMU_CSR_BASE_ADDR + 0x038)
1035
++#define TMU_TEQ_DROP_STAT	(TMU_CSR_BASE_ADDR + 0x03c)
1036
++#define TMU_TEQ_QAVG	(TMU_CSR_BASE_ADDR + 0x040)
1037
++#define TMU_TEQ_WREG_PROB	(TMU_CSR_BASE_ADDR + 0x044)
1038
++#define TMU_TEQ_TRANS_STAT	(TMU_CSR_BASE_ADDR + 0x048)
1039
++#define TMU_TEQ_HW_PROB_CFG0	(TMU_CSR_BASE_ADDR + 0x04c)
1040
++#define TMU_TEQ_HW_PROB_CFG1	(TMU_CSR_BASE_ADDR + 0x050)
1041
++#define TMU_TEQ_HW_PROB_CFG2	(TMU_CSR_BASE_ADDR + 0x054)
1042
++#define TMU_TEQ_HW_PROB_CFG3	(TMU_CSR_BASE_ADDR + 0x058)
1043
++#define TMU_TEQ_HW_PROB_CFG4	(TMU_CSR_BASE_ADDR + 0x05c)
1044
++#define TMU_TEQ_HW_PROB_CFG5	(TMU_CSR_BASE_ADDR + 0x060)
1045
++#define TMU_TEQ_HW_PROB_CFG6	(TMU_CSR_BASE_ADDR + 0x064)
1046
++#define TMU_TEQ_HW_PROB_CFG7	(TMU_CSR_BASE_ADDR + 0x068)
1047
++#define TMU_TEQ_HW_PROB_CFG8	(TMU_CSR_BASE_ADDR + 0x06c)
1048
++#define TMU_TEQ_HW_PROB_CFG9	(TMU_CSR_BASE_ADDR + 0x070)
1049
++#define TMU_TEQ_HW_PROB_CFG10	(TMU_CSR_BASE_ADDR + 0x074)
1050
++#define TMU_TEQ_HW_PROB_CFG11	(TMU_CSR_BASE_ADDR + 0x078)
1051
++#define TMU_TEQ_HW_PROB_CFG12	(TMU_CSR_BASE_ADDR + 0x07c)
1052
++#define TMU_TEQ_HW_PROB_CFG13	(TMU_CSR_BASE_ADDR + 0x080)
1053
++#define TMU_TEQ_HW_PROB_CFG14	(TMU_CSR_BASE_ADDR + 0x084)
1054
++#define TMU_TEQ_HW_PROB_CFG15	(TMU_CSR_BASE_ADDR + 0x088)
1055
++#define TMU_TEQ_HW_PROB_CFG16	(TMU_CSR_BASE_ADDR + 0x08c)
1056
++#define TMU_TEQ_HW_PROB_CFG17	(TMU_CSR_BASE_ADDR + 0x090)
1057
++#define TMU_TEQ_HW_PROB_CFG18	(TMU_CSR_BASE_ADDR + 0x094)
1058
++#define TMU_TEQ_HW_PROB_CFG19	(TMU_CSR_BASE_ADDR + 0x098)
1059
++#define TMU_TEQ_HW_PROB_CFG20	(TMU_CSR_BASE_ADDR + 0x09c)
1060
++#define TMU_TEQ_HW_PROB_CFG21	(TMU_CSR_BASE_ADDR + 0x0a0)
1061
++#define TMU_TEQ_HW_PROB_CFG22	(TMU_CSR_BASE_ADDR + 0x0a4)
1062
++#define TMU_TEQ_HW_PROB_CFG23	(TMU_CSR_BASE_ADDR + 0x0a8)
1063
++#define TMU_TEQ_HW_PROB_CFG24	(TMU_CSR_BASE_ADDR + 0x0ac)
1064
++#define TMU_TEQ_HW_PROB_CFG25	(TMU_CSR_BASE_ADDR + 0x0b0)
1065
++#define TMU_TDQ_IIFG_CFG	(TMU_CSR_BASE_ADDR + 0x0b4)
1066
++/* [9:0] Scheduler Enable for each of the scheduler in the TDQ.
1067
++ * This is a global Enable for all schedulers in PHY0
1068
++ */
1069
++#define TMU_TDQ0_SCH_CTRL	(TMU_CSR_BASE_ADDR + 0x0b8)
1070
++
1071
++#define TMU_LLM_CTRL	(TMU_CSR_BASE_ADDR + 0x0bc)
1072
++#define TMU_LLM_BASE_ADDR	(TMU_CSR_BASE_ADDR + 0x0c0)
1073
++#define TMU_LLM_QUE_LEN	(TMU_CSR_BASE_ADDR + 0x0c4)
1074
++#define TMU_LLM_QUE_HEADPTR	(TMU_CSR_BASE_ADDR + 0x0c8)
1075
++#define TMU_LLM_QUE_TAILPTR	(TMU_CSR_BASE_ADDR + 0x0cc)
1076
++#define TMU_LLM_QUE_DROPCNT	(TMU_CSR_BASE_ADDR + 0x0d0)
1077
++#define TMU_INT_EN	(TMU_CSR_BASE_ADDR + 0x0d4)
1078
++#define TMU_INT_SRC	(TMU_CSR_BASE_ADDR + 0x0d8)
1079
++#define TMU_INQ_STAT	(TMU_CSR_BASE_ADDR + 0x0dc)
1080
++#define TMU_CTRL	(TMU_CSR_BASE_ADDR + 0x0e0)
1081
++
1082
++/* [31] Mem Access Command. 0 = Internal Memory Read, 1 = Internal memory
1083
++ * Write [27:24] Byte Enables of the Internal memory access [23:0] Address of
1084
++ * the internal memory. This address is used to access both the PM and DM of
1085
++ * all the PE's
1086
++ */
1087
++#define TMU_MEM_ACCESS_ADDR	(TMU_CSR_BASE_ADDR + 0x0e4)
1088
++
1089
++/* Internal Memory Access Write Data */
1090
++#define TMU_MEM_ACCESS_WDATA	(TMU_CSR_BASE_ADDR + 0x0e8)
1091
++/* Internal Memory Access Read Data. The commands are blocked
1092
++ * at the mem_access only
1093
++ */
1094
++#define TMU_MEM_ACCESS_RDATA	(TMU_CSR_BASE_ADDR + 0x0ec)
1095
++
1096
++/* [31:0] PHY0 in queue address (must be initialized with one of the
1097
++ * xxx_INQ_PKTPTR cbus addresses)
1098
++ */
1099
++#define TMU_PHY0_INQ_ADDR	(TMU_CSR_BASE_ADDR + 0x0f0)
1100
++/* [31:0] PHY1 in queue address (must be initialized with one of the
1101
++ * xxx_INQ_PKTPTR cbus addresses)
1102
++ */
1103
++#define TMU_PHY1_INQ_ADDR	(TMU_CSR_BASE_ADDR + 0x0f4)
1104
++/* [31:0] PHY2 in queue address (must be initialized with one of the
1105
++ * xxx_INQ_PKTPTR cbus addresses)
1106
++ */
1107
++#define TMU_PHY2_INQ_ADDR	(TMU_CSR_BASE_ADDR + 0x0f8)
1108
++/* [31:0] PHY3 in queue address (must be initialized with one of the
1109
++ * xxx_INQ_PKTPTR cbus addresses)
1110
++ */
1111
++#define TMU_PHY3_INQ_ADDR	(TMU_CSR_BASE_ADDR + 0x0fc)
1112
++#define TMU_BMU_INQ_ADDR	(TMU_CSR_BASE_ADDR + 0x100)
1113
++#define TMU_TX_CTRL	(TMU_CSR_BASE_ADDR + 0x104)
1114
++
1115
++#define TMU_BUS_ACCESS_WDATA	(TMU_CSR_BASE_ADDR + 0x108)
1116
++#define TMU_BUS_ACCESS	(TMU_CSR_BASE_ADDR + 0x10c)
1117
++#define TMU_BUS_ACCESS_RDATA	(TMU_CSR_BASE_ADDR + 0x110)
1118
++
1119
++#define TMU_PE_SYS_CLK_RATIO	(TMU_CSR_BASE_ADDR + 0x114)
1120
++#define TMU_PE_STATUS	(TMU_CSR_BASE_ADDR + 0x118)
1121
++#define TMU_TEQ_MAX_THRESHOLD	(TMU_CSR_BASE_ADDR + 0x11c)
1122
++/* [31:0] PHY4 in queue address (must be initialized with one of the
1123
++ * xxx_INQ_PKTPTR cbus addresses)
1124
++ */
1125
++#define TMU_PHY4_INQ_ADDR	(TMU_CSR_BASE_ADDR + 0x134)
1126
++/* [9:0] Scheduler Enable for each of the scheduler in the TDQ.
1127
++ * This is a global Enable for all schedulers in PHY1
1128
++ */
1129
++#define TMU_TDQ1_SCH_CTRL	(TMU_CSR_BASE_ADDR + 0x138)
1130
++/* [9:0] Scheduler Enable for each of the scheduler in the TDQ.
1131
++ * This is a global Enable for all schedulers in PHY2
1132
++ */
1133
++#define TMU_TDQ2_SCH_CTRL	(TMU_CSR_BASE_ADDR + 0x13c)
1134
++/* [9:0] Scheduler Enable for each of the scheduler in the TDQ.
1135
++ * This is a global Enable for all schedulers in PHY3
1136
++ */
1137
++#define TMU_TDQ3_SCH_CTRL	(TMU_CSR_BASE_ADDR + 0x140)
1138
++#define TMU_BMU_BUF_SIZE	(TMU_CSR_BASE_ADDR + 0x144)
1139
++/* [31:0] PHY5 in queue address (must be initialized with one of the
1140
++ * xxx_INQ_PKTPTR cbus addresses)
1141
++ */
1142
++#define TMU_PHY5_INQ_ADDR	(TMU_CSR_BASE_ADDR + 0x148)
1143
++
1144
++#define SW_RESET		BIT(0)	/* Global software reset */
1145
++#define INQ_RESET		BIT(2)
1146
++#define TEQ_RESET		BIT(3)
1147
++#define TDQ_RESET		BIT(4)
1148
++#define PE_RESET		BIT(5)
1149
++#define MEM_INIT		BIT(6)
1150
++#define MEM_INIT_DONE		BIT(7)
1151
++#define LLM_INIT		BIT(8)
1152
++#define LLM_INIT_DONE		BIT(9)
1153
++#define ECC_MEM_INIT_DONE	BIT(10)
1154
++
1155
++struct tmu_cfg {
1156
++	u32 pe_sys_clk_ratio;
1157
++	unsigned long llm_base_addr;
1158
++	u32 llm_queue_len;
1159
++};
1160
++
1161
++/* Not HW related for pfe_ctrl / pfe common defines */
1162
++#define DEFAULT_MAX_QDEPTH	80
1163
++#define DEFAULT_Q0_QDEPTH	511 /*We keep one large queue for host tx qos */
1164
++#define DEFAULT_TMU3_QDEPTH	127
1165
++
1166
++#endif /* _TMU_CSR_H_ */
1167
+diff --git a/drivers/staging/fsl_ppfe/include/pfe/cbus/util_csr.h b/drivers/staging/fsl_ppfe/include/pfe/cbus/util_csr.h
1168
+new file mode 100644
1169
+index 000000000000..ae623cdafe7b
1170
+--- /dev/null
1171
+@@ -0,0 +1,61 @@
1172
++/*
1173
++ * Copyright 2015-2016 Freescale Semiconductor, Inc.
1174
++ * Copyright 2017 NXP
1175
++ *
1176
++ * This program is free software; you can redistribute it and/or modify
1177
++ * it under the terms of the GNU General Public License as published by
1178
++ * the Free Software Foundation; either version 2 of the License, or
1179
++ * (at your option) any later version.
1180
++ *
1181
++ * This program is distributed in the hope that it will be useful,
1182
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1183
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1184
++ * GNU General Public License for more details.
1185
++ *
1186
++ * You should have received a copy of the GNU General Public License
1187
++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
1188
++ */
1189
++
1190
++#ifndef _UTIL_CSR_H_
1191
++#define _UTIL_CSR_H_
1192
++
1193
++#define UTIL_VERSION	(UTIL_CSR_BASE_ADDR + 0x000)
1194
++#define UTIL_TX_CTRL	(UTIL_CSR_BASE_ADDR + 0x004)
1195
++#define UTIL_INQ_PKTPTR	(UTIL_CSR_BASE_ADDR + 0x010)
1196
++
1197
++#define UTIL_HDR_SIZE	(UTIL_CSR_BASE_ADDR + 0x014)
1198
++
1199
++#define UTIL_PE0_QB_DM_ADDR0	(UTIL_CSR_BASE_ADDR + 0x020)
1200
++#define UTIL_PE0_QB_DM_ADDR1	(UTIL_CSR_BASE_ADDR + 0x024)
1201
++#define UTIL_PE0_RO_DM_ADDR0	(UTIL_CSR_BASE_ADDR + 0x060)
1202
++#define UTIL_PE0_RO_DM_ADDR1	(UTIL_CSR_BASE_ADDR + 0x064)
1203
++
1204
++#define UTIL_MEM_ACCESS_ADDR	(UTIL_CSR_BASE_ADDR + 0x100)
1205
++#define UTIL_MEM_ACCESS_WDATA	(UTIL_CSR_BASE_ADDR + 0x104)
1206
++#define UTIL_MEM_ACCESS_RDATA	(UTIL_CSR_BASE_ADDR + 0x108)
1207
++
1208
++#define UTIL_TM_INQ_ADDR	(UTIL_CSR_BASE_ADDR + 0x114)
1209
++#define UTIL_PE_STATUS	(UTIL_CSR_BASE_ADDR + 0x118)
1210
++
1211
++#define UTIL_PE_SYS_CLK_RATIO	(UTIL_CSR_BASE_ADDR + 0x200)
1212
++#define UTIL_AFULL_THRES	(UTIL_CSR_BASE_ADDR + 0x204)
1213
++#define UTIL_GAP_BETWEEN_READS	(UTIL_CSR_BASE_ADDR + 0x208)
1214
++#define UTIL_MAX_BUF_CNT	(UTIL_CSR_BASE_ADDR + 0x20c)
1215
++#define UTIL_TSQ_FIFO_THRES	(UTIL_CSR_BASE_ADDR + 0x210)
1216
++#define UTIL_TSQ_MAX_CNT	(UTIL_CSR_BASE_ADDR + 0x214)
1217
++#define UTIL_IRAM_DATA_0	(UTIL_CSR_BASE_ADDR + 0x218)
1218
++#define UTIL_IRAM_DATA_1	(UTIL_CSR_BASE_ADDR + 0x21c)
1219
++#define UTIL_IRAM_DATA_2	(UTIL_CSR_BASE_ADDR + 0x220)
1220
++#define UTIL_IRAM_DATA_3	(UTIL_CSR_BASE_ADDR + 0x224)
1221
++
1222
++#define UTIL_BUS_ACCESS_ADDR	(UTIL_CSR_BASE_ADDR + 0x228)
1223
++#define UTIL_BUS_ACCESS_WDATA	(UTIL_CSR_BASE_ADDR + 0x22c)
1224
++#define UTIL_BUS_ACCESS_RDATA	(UTIL_CSR_BASE_ADDR + 0x230)
1225
++
1226
++#define UTIL_INQ_AFULL_THRES	(UTIL_CSR_BASE_ADDR + 0x234)
1227
++
1228
++struct util_cfg {
1229
++	u32 pe_sys_clk_ratio;
1230
++};
1231
++
1232
++#endif /* _UTIL_CSR_H_ */
1233
+diff --git a/drivers/staging/fsl_ppfe/include/pfe/pfe.h b/drivers/staging/fsl_ppfe/include/pfe/pfe.h
1234
+new file mode 100644
1235
+index 000000000000..d93ae4c60251
1236
+--- /dev/null
1237
+@@ -0,0 +1,372 @@
1238
++/*
1239
++ * Copyright 2015-2016 Freescale Semiconductor, Inc.
1240
++ * Copyright 2017 NXP
1241
++ *
1242
++ * This program is free software; you can redistribute it and/or modify
1243
++ * it under the terms of the GNU General Public License as published by
1244
++ * the Free Software Foundation; either version 2 of the License, or
1245
++ * (at your option) any later version.
1246
++ *
1247
++ * This program is distributed in the hope that it will be useful,
1248
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1249
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1250
++ * GNU General Public License for more details.
1251
++ *
1252
++ * You should have received a copy of the GNU General Public License
1253
++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
1254
++ */
1255
++
1256
++#ifndef _PFE_H_
1257
++#define _PFE_H_
1258
++
1259
++#include "cbus.h"
1260
++
1261
++#define CLASS_DMEM_BASE_ADDR(i)	(0x00000000 | ((i) << 20))
1262
++/*
1263
++ * Only valid for mem access register interface
1264
++ */
1265
++#define CLASS_IMEM_BASE_ADDR(i)	(0x00000000 | ((i) << 20))
1266
++#define CLASS_DMEM_SIZE	0x00002000
1267
++#define CLASS_IMEM_SIZE	0x00008000
1268
++
1269
++#define TMU_DMEM_BASE_ADDR(i)	(0x00000000 + ((i) << 20))
1270
++/*
1271
++ * Only valid for mem access register interface
1272
++ */
1273
++#define TMU_IMEM_BASE_ADDR(i)	(0x00000000 + ((i) << 20))
1274
++#define TMU_DMEM_SIZE	0x00000800
1275
++#define TMU_IMEM_SIZE	0x00002000
1276
++
1277
++#define UTIL_DMEM_BASE_ADDR	0x00000000
1278
++#define UTIL_DMEM_SIZE	0x00002000
1279
++
1280
++#define PE_LMEM_BASE_ADDR	0xc3010000
1281
++#define PE_LMEM_SIZE	0x8000
1282
++#define PE_LMEM_END	(PE_LMEM_BASE_ADDR + PE_LMEM_SIZE)
1283
++
1284
++#define DMEM_BASE_ADDR	0x00000000
1285
++#define DMEM_SIZE	0x2000	/* TMU has less... */
1286
++#define DMEM_END	(DMEM_BASE_ADDR + DMEM_SIZE)
1287
++
1288
++#define PMEM_BASE_ADDR	0x00010000
1289
++#define PMEM_SIZE	0x8000	/* TMU has less... */
1290
++#define PMEM_END	(PMEM_BASE_ADDR + PMEM_SIZE)
1291
++
1292
++/* These check memory ranges from PE point of view/memory map */
1293
++#define IS_DMEM(addr, len)				\
1294
++	({ typeof(addr) addr_ = (addr);			\
1295
++	((unsigned long)(addr_) >= DMEM_BASE_ADDR) &&	\
1296
++	(((unsigned long)(addr_) + (len)) <= DMEM_END); })
1297
++
1298
++#define IS_PMEM(addr, len)				\
1299
++	({ typeof(addr) addr_ = (addr);			\
1300
++	((unsigned long)(addr_) >= PMEM_BASE_ADDR) &&	\
1301
++	(((unsigned long)(addr_) + (len)) <= PMEM_END); })
1302
++
1303
++#define IS_PE_LMEM(addr, len)				\
1304
++	({ typeof(addr) addr_ = (addr);			\
1305
++	((unsigned long)(addr_) >=			\
1306
++	PE_LMEM_BASE_ADDR) &&				\
1307
++	(((unsigned long)(addr_) +			\
1308
++	(len)) <= PE_LMEM_END); })
1309
++
1310
++#define IS_PFE_LMEM(addr, len)				\
1311
++	({ typeof(addr) addr_ = (addr);			\
1312
++	((unsigned long)(addr_) >=			\
1313
++	CBUS_VIRT_TO_PFE(LMEM_BASE_ADDR)) &&		\
1314
++	(((unsigned long)(addr_) + (len)) <=		\
1315
++	CBUS_VIRT_TO_PFE(LMEM_END)); })
1316
++
1317
++#define __IS_PHYS_DDR(addr, len)			\
1318
++	({ typeof(addr) addr_ = (addr);			\
1319
++	((unsigned long)(addr_) >=			\
1320
++	DDR_PHYS_BASE_ADDR) &&				\
1321
++	(((unsigned long)(addr_) + (len)) <=		\
1322
++	DDR_PHYS_END); })
1323
++
1324
++#define IS_PHYS_DDR(addr, len)	__IS_PHYS_DDR(DDR_PFE_TO_PHYS(addr), len)
1325
++
1326
++/*
1327
++ * If using a run-time virtual address for the cbus base address use this code
1328
++ */
1329
++extern void *cbus_base_addr;
1330
++extern void *ddr_base_addr;
1331
++extern unsigned long ddr_phys_base_addr;
1332
++extern unsigned int ddr_size;
1333
++
1334
++#define CBUS_BASE_ADDR	cbus_base_addr
1335
++#define DDR_PHYS_BASE_ADDR	ddr_phys_base_addr
1336
++#define DDR_BASE_ADDR	ddr_base_addr
1337
++#define DDR_SIZE	ddr_size
1338
++
1339
++#define DDR_PHYS_END	(DDR_PHYS_BASE_ADDR + DDR_SIZE)
1340
++
1341
++#define LS1012A_PFE_RESET_WA	/*
1342
++				 * PFE doesn't have global reset and re-init
1343
++				 * should takecare few things to make PFE
1344
++				 * functional after reset
1345
++				 */
1346
++#define PFE_CBUS_PHYS_BASE_ADDR	0xc0000000	/* CBUS physical base address
1347
++						 * as seen by PE's.
1348
++						 */
1349
++/* CBUS physical base address as seen by PE's. */
1350
++#define PFE_CBUS_PHYS_BASE_ADDR_FROM_PFE	0xc0000000
1351
++
1352
++#define DDR_PHYS_TO_PFE(p)	(((unsigned long int)(p)) & 0x7FFFFFFF)
1353
++#define DDR_PFE_TO_PHYS(p)	(((unsigned long int)(p)) | 0x80000000)
1354
++#define CBUS_PHYS_TO_PFE(p)	(((p) - PFE_CBUS_PHYS_BASE_ADDR) + \
1355
++				PFE_CBUS_PHYS_BASE_ADDR_FROM_PFE)
1356
++/* Translates to PFE address map */
1357
++
1358
++#define DDR_PHYS_TO_VIRT(p)	(((p) - DDR_PHYS_BASE_ADDR) + DDR_BASE_ADDR)
1359
++#define DDR_VIRT_TO_PHYS(v)	(((v) - DDR_BASE_ADDR) + DDR_PHYS_BASE_ADDR)
1360
++#define DDR_VIRT_TO_PFE(p)	(DDR_PHYS_TO_PFE(DDR_VIRT_TO_PHYS(p)))
1361
++
1362
++#define CBUS_VIRT_TO_PFE(v)	(((v) - CBUS_BASE_ADDR) + \
1363
++				PFE_CBUS_PHYS_BASE_ADDR)
1364
++#define CBUS_PFE_TO_VIRT(p)	(((unsigned long int)(p) - \
1365
++				PFE_CBUS_PHYS_BASE_ADDR) + CBUS_BASE_ADDR)
1366
++
1367
++/* The below part of the code is used in QOS control driver from host */
1368
++#define TMU_APB_BASE_ADDR       0xc1000000      /* TMU base address seen by
1369
++						 * pe's
1370
++						 */
1371
++
1372
++enum {
1373
++	CLASS0_ID = 0,
1374
++	CLASS1_ID,
1375
++	CLASS2_ID,
1376
++	CLASS3_ID,
1377
++	CLASS4_ID,
1378
++	CLASS5_ID,
1379
++	TMU0_ID,
1380
++	TMU1_ID,
1381
++	TMU2_ID,
1382
++	TMU3_ID,
1383
++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
1384
++	UTIL_ID,
1385
++#endif
1386
++	MAX_PE
1387
++};
1388
++
1389
++#define CLASS_MASK	(BIT(CLASS0_ID) | BIT(CLASS1_ID) |\
1390
++			BIT(CLASS2_ID) | BIT(CLASS3_ID) |\
1391
++			BIT(CLASS4_ID) | BIT(CLASS5_ID))
1392
++#define CLASS_MAX_ID	CLASS5_ID
1393
++
1394
++#define TMU_MASK	(BIT(TMU0_ID) | BIT(TMU1_ID) |\
1395
++			BIT(TMU3_ID))
1396
++
1397
++#define TMU_MAX_ID	TMU3_ID
1398
++
1399
++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
1400
++#define UTIL_MASK	BIT(UTIL_ID)
1401
++#endif
1402
++
1403
++struct pe_status {
1404
++	u32	cpu_state;
1405
++	u32	activity_counter;
1406
++	u32	rx;
1407
++	union {
1408
++	u32	tx;
1409
++	u32	tmu_qstatus;
1410
++	};
1411
++	u32	drop;
1412
++#if defined(CFG_PE_DEBUG)
1413
++	u32	debug_indicator;
1414
++	u32	debug[16];
1415
++#endif
1416
++} __aligned(16);
1417
++
1418
++struct pe_sync_mailbox {
1419
++	u32 stop;
1420
++	u32 stopped;
1421
++};
1422
++
1423
++/* Drop counter definitions */
1424
++
1425
++#define	CLASS_NUM_DROP_COUNTERS	13
1426
++#define	UTIL_NUM_DROP_COUNTERS	8
1427
++
1428
++/* PE information.
1429
++ * Structure containing PE's specific information. It is used to create
1430
++ * generic C functions common to all PE's.
1431
++ * Before using the library functions this structure needs to be initialized
1432
++ * with the different registers virtual addresses
1433
++ * (according to the ARM MMU mmaping). The default initialization supports a
1434
++ * virtual == physical mapping.
1435
++ */
1436
++struct pe_info {
1437
++	u32 dmem_base_addr;	/* PE's dmem base address */
1438
++	u32 pmem_base_addr;	/* PE's pmem base address */
1439
++	u32 pmem_size;	/* PE's pmem size */
1440
++
1441
++	void *mem_access_wdata;	/* PE's _MEM_ACCESS_WDATA register
1442
++				 * address
1443
++				 */
1444
++	void *mem_access_addr;	/* PE's _MEM_ACCESS_ADDR register
1445
++				 * address
1446
++				 */
1447
++	void *mem_access_rdata;	/* PE's _MEM_ACCESS_RDATA register
1448
++				 * address
1449
++				 */
1450
++};
1451
++
1452
++void pe_lmem_read(u32 *dst, u32 len, u32 offset);
1453
++void pe_lmem_write(u32 *src, u32 len, u32 offset);
1454
++
1455
++void pe_dmem_memcpy_to32(int id, u32 dst, const void *src, unsigned int len);
1456
++void pe_pmem_memcpy_to32(int id, u32 dst, const void *src, unsigned int len);
1457
++
1458
++u32 pe_pmem_read(int id, u32 addr, u8 size);
1459
++
1460
++void pe_dmem_write(int id, u32 val, u32 addr, u8 size);
1461
++u32 pe_dmem_read(int id, u32 addr, u8 size);
1462
++void class_pe_lmem_memcpy_to32(u32 dst, const void *src, unsigned int len);
1463
++void class_pe_lmem_memset(u32 dst, int val, unsigned int len);
1464
++void class_bus_write(u32 val, u32 addr, u8 size);
1465
++u32 class_bus_read(u32 addr, u8 size);
1466
++
1467
++#define class_bus_readl(addr)	class_bus_read(addr, 4)
1468
++#define class_bus_readw(addr)	class_bus_read(addr, 2)
1469
++#define class_bus_readb(addr)	class_bus_read(addr, 1)
1470
++
1471
++#define class_bus_writel(val, addr)	class_bus_write(val, addr, 4)
1472
++#define class_bus_writew(val, addr)	class_bus_write(val, addr, 2)
1473
++#define class_bus_writeb(val, addr)	class_bus_write(val, addr, 1)
1474
++
1475
++#define pe_dmem_readl(id, addr)	pe_dmem_read(id, addr, 4)
1476
++#define pe_dmem_readw(id, addr)	pe_dmem_read(id, addr, 2)
1477
++#define pe_dmem_readb(id, addr)	pe_dmem_read(id, addr, 1)
1478
++
1479
++#define pe_dmem_writel(id, val, addr)	pe_dmem_write(id, val, addr, 4)
1480
++#define pe_dmem_writew(id, val, addr)	pe_dmem_write(id, val, addr, 2)
1481
++#define pe_dmem_writeb(id, val, addr)	pe_dmem_write(id, val, addr, 1)
1482
++
1483
++/*int pe_load_elf_section(int id, const void *data, elf32_shdr *shdr); */
1484
++int pe_load_elf_section(int id, const void *data, struct elf32_shdr *shdr,
1485
++			struct device *dev);
1486
++
1487
++void pfe_lib_init(void *cbus_base, void *ddr_base, unsigned long ddr_phys_base,
1488
++		  unsigned int ddr_size);
1489
++void bmu_init(void *base, struct BMU_CFG *cfg);
1490
++void bmu_reset(void *base);
1491
++void bmu_enable(void *base);
1492
++void bmu_disable(void *base);
1493
++void bmu_set_config(void *base, struct BMU_CFG *cfg);
1494
++
1495
++/*
1496
++ * An enumerated type for loopback values.  This can be one of three values, no
1497
++ * loopback -normal operation, local loopback with internal loopback module of
1498
++ * MAC or PHY loopback which is through the external PHY.
1499
++ */
1500
++#ifndef __MAC_LOOP_ENUM__
1501
++#define __MAC_LOOP_ENUM__
1502
++enum mac_loop {LB_NONE, LB_EXT, LB_LOCAL};
1503
++#endif
1504
++
1505
++void gemac_init(void *base, void *config);
1506
++void gemac_disable_rx_checksum_offload(void *base);
1507
++void gemac_enable_rx_checksum_offload(void *base);
1508
++void gemac_set_mdc_div(void *base, int mdc_div);
1509
++void gemac_set_speed(void *base, enum mac_speed gem_speed);
1510
++void gemac_set_duplex(void *base, int duplex);
1511
++void gemac_set_mode(void *base, int mode);
1512
++void gemac_enable(void *base);
1513
++void gemac_tx_disable(void *base);
1514
++void gemac_tx_enable(void *base);
1515
++void gemac_disable(void *base);
1516
++void gemac_reset(void *base);
1517
++void gemac_set_address(void *base, struct spec_addr *addr);
1518
++struct spec_addr gemac_get_address(void *base);
1519
++void gemac_set_loop(void *base, enum mac_loop gem_loop);
1520
++void gemac_set_laddr1(void *base, struct pfe_mac_addr *address);
1521
++void gemac_set_laddr2(void *base, struct pfe_mac_addr *address);
1522
++void gemac_set_laddr3(void *base, struct pfe_mac_addr *address);
1523
++void gemac_set_laddr4(void *base, struct pfe_mac_addr *address);
1524
++void gemac_set_laddrN(void *base, struct pfe_mac_addr *address,
1525
++		      unsigned int entry_index);
1526
++void gemac_clear_laddr1(void *base);
1527
++void gemac_clear_laddr2(void *base);
1528
++void gemac_clear_laddr3(void *base);
1529
++void gemac_clear_laddr4(void *base);
1530
++void gemac_clear_laddrN(void *base, unsigned int entry_index);
1531
++struct pfe_mac_addr gemac_get_hash(void *base);
1532
++void gemac_set_hash(void *base, struct pfe_mac_addr *hash);
1533
++struct pfe_mac_addr gem_get_laddr1(void *base);
1534
++struct pfe_mac_addr gem_get_laddr2(void *base);
1535
++struct pfe_mac_addr gem_get_laddr3(void *base);
1536
++struct pfe_mac_addr gem_get_laddr4(void *base);
1537
++struct pfe_mac_addr gem_get_laddrN(void *base, unsigned int entry_index);
1538
++void gemac_set_config(void *base, struct gemac_cfg *cfg);
1539
++void gemac_allow_broadcast(void *base);
1540
++void gemac_no_broadcast(void *base);
1541
++void gemac_enable_1536_rx(void *base);
1542
++void gemac_disable_1536_rx(void *base);
1543
++void gemac_enable_rx_jmb(void *base);
1544
++void gemac_disable_rx_jmb(void *base);
1545
++void gemac_enable_stacked_vlan(void *base);
1546
++void gemac_disable_stacked_vlan(void *base);
1547
++void gemac_enable_pause_rx(void *base);
1548
++void gemac_disable_pause_rx(void *base);
1549
++void gemac_enable_copy_all(void *base);
1550
++void gemac_disable_copy_all(void *base);
1551
++void gemac_set_bus_width(void *base, int width);
1552
++void gemac_set_wol(void *base, u32 wol_conf);
1553
++
1554
++void gpi_init(void *base, struct gpi_cfg *cfg);
1555
++void gpi_reset(void *base);
1556
++void gpi_enable(void *base);
1557
++void gpi_disable(void *base);
1558
++void gpi_set_config(void *base, struct gpi_cfg *cfg);
1559
++
1560
++void class_init(struct class_cfg *cfg);
1561
++void class_reset(void);
1562
++void class_enable(void);
1563
++void class_disable(void);
1564
++void class_set_config(struct class_cfg *cfg);
1565
++
1566
++void tmu_reset(void);
1567
++void tmu_init(struct tmu_cfg *cfg);
1568
++void tmu_enable(u32 pe_mask);
1569
++void tmu_disable(u32 pe_mask);
1570
++u32  tmu_qstatus(u32 if_id);
1571
++u32  tmu_pkts_processed(u32 if_id);
1572
++
1573
++void util_init(struct util_cfg *cfg);
1574
++void util_reset(void);
1575
++void util_enable(void);
1576
++void util_disable(void);
1577
++
1578
++void hif_init(void);
1579
++void hif_tx_enable(void);
1580
++void hif_tx_disable(void);
1581
++void hif_rx_enable(void);
1582
++void hif_rx_disable(void);
1583
++
1584
++/* Get Chip Revision level
1585
++ *
1586
++ */
1587
++static inline unsigned int CHIP_REVISION(void)
1588
++{
1589
++	/*For LS1012A return always 1 */
1590
++	return 1;
1591
++}
1592
++
1593
++/* Start HIF rx DMA
1594
++ *
1595
++ */
1596
++static inline void hif_rx_dma_start(void)
1597
++{
1598
++	writel(HIF_CTRL_DMA_EN | HIF_CTRL_BDP_CH_START_WSTB, HIF_RX_CTRL);
1599
++}
1600
++
1601
++/* Start HIF tx DMA
1602
++ *
1603
++ */
1604
++static inline void hif_tx_dma_start(void)
1605
++{
1606
++	writel(HIF_CTRL_DMA_EN | HIF_CTRL_BDP_CH_START_WSTB, HIF_TX_CTRL);
1607
++}
1608
++
1609
++#endif /* _PFE_H_ */
1610
+diff --git a/drivers/staging/fsl_ppfe/pfe_ctrl.h b/drivers/staging/fsl_ppfe/pfe_ctrl.h
1611
+new file mode 100644
1612
+index 000000000000..22115c76896c
1613
+--- /dev/null
1614
+@@ -0,0 +1,112 @@
1615
++/*
1616
++ * Copyright 2015-2016 Freescale Semiconductor, Inc.
1617
++ * Copyright 2017 NXP
1618
++ *
1619
++ * This program is free software; you can redistribute it and/or modify
1620
++ * it under the terms of the GNU General Public License as published by
1621
++ * the Free Software Foundation; either version 2 of the License, or
1622
++ * (at your option) any later version.
1623
++ *
1624
++ * This program is distributed in the hope that it will be useful,
1625
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1626
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1627
++ * GNU General Public License for more details.
1628
++ *
1629
++ * You should have received a copy of the GNU General Public License
1630
++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
1631
++ */
1632
++
1633
++#ifndef _PFE_CTRL_H_
1634
++#define _PFE_CTRL_H_
1635
++
1636
++#include <linux/dmapool.h>
1637
++
1638
++#include "pfe_mod.h"
1639
++#include "pfe/pfe.h"
1640
++
1641
++#define DMA_BUF_SIZE_128	0x80	/* enough for 1 conntracks */
1642
++#define DMA_BUF_SIZE_256	0x100
1643
++/* enough for 2 conntracks, 1 bridge entry or 1 multicast entry */
1644
++#define DMA_BUF_SIZE_512	0x200
1645
++/* 512bytes dma allocated buffers used by rtp relay feature */
1646
++#define DMA_BUF_MIN_ALIGNMENT	8
1647
++#define DMA_BUF_BOUNDARY	(4 * 1024)
1648
++/* bursts can not cross 4k boundary */
1649
++
1650
++#define CMD_TX_ENABLE	0x0501
1651
++#define CMD_TX_DISABLE	0x0502
1652
++
1653
++#define CMD_RX_LRO		0x0011
1654
++#define CMD_PKTCAP_ENABLE       0x0d01
1655
++#define CMD_QM_EXPT_RATE	0x020c
1656
++
1657
++#define CLASS_DM_SH_STATIC		(0x800)
1658
++#define CLASS_DM_CPU_TICKS		(CLASS_DM_SH_STATIC)
1659
++#define CLASS_DM_SYNC_MBOX		(0x808)
1660
++#define CLASS_DM_MSG_MBOX		(0x810)
1661
++#define CLASS_DM_DROP_CNTR		(0x820)
1662
++#define CLASS_DM_RESUME			(0x854)
1663
++#define CLASS_DM_PESTATUS		(0x860)
1664
++
1665
++#define TMU_DM_SH_STATIC		(0x80)
1666
++#define TMU_DM_CPU_TICKS		(TMU_DM_SH_STATIC)
1667
++#define TMU_DM_SYNC_MBOX		(0x88)
1668
++#define TMU_DM_MSG_MBOX			(0x90)
1669
++#define TMU_DM_RESUME			(0xA0)
1670
++#define TMU_DM_PESTATUS			(0xB0)
1671
++#define TMU_DM_CONTEXT			(0x300)
1672
++#define TMU_DM_TX_TRANS			(0x480)
1673
++
1674
++#define UTIL_DM_SH_STATIC		(0x0)
1675
++#define UTIL_DM_CPU_TICKS		(UTIL_DM_SH_STATIC)
1676
++#define UTIL_DM_SYNC_MBOX		(0x8)
1677
++#define UTIL_DM_MSG_MBOX		(0x10)
1678
++#define UTIL_DM_DROP_CNTR		(0x20)
1679
++#define UTIL_DM_RESUME			(0x40)
1680
++#define UTIL_DM_PESTATUS		(0x50)
1681
++
1682
++struct pfe_ctrl {
1683
++	struct mutex mutex; /* to serialize pfe control access */
1684
++	spinlock_t lock;
1685
++
1686
++	void *dma_pool;
1687
++	void *dma_pool_512;
1688
++	void *dma_pool_128;
1689
++
1690
++	struct device *dev;
1691
++
1692
++	void *hash_array_baseaddr;		/*
1693
++						 * Virtual base address of
1694
++						 * the conntrack hash array
1695
++						 */
1696
++	unsigned long hash_array_phys_baseaddr; /*
1697
++						 * Physical base address of
1698
++						 * the conntrack hash array
1699
++						 */
1700
++
1701
++	int (*event_cb)(u16, u16, u16*);
1702
++
1703
++	unsigned long sync_mailbox_baseaddr[MAX_PE]; /*
1704
++						      * Sync mailbox PFE
1705
++						      * internal address,
1706
++						      * initialized
1707
++						      * when parsing elf images
1708
++						      */
1709
++	unsigned long msg_mailbox_baseaddr[MAX_PE]; /*
1710
++						     * Msg mailbox PFE internal
1711
++						     * address, initialized
1712
++						     * when parsing elf images
1713
++						     */
1714
++	unsigned int sys_clk;			/* AXI clock value, in KHz */
1715
++};
1716
++
1717
++int pfe_ctrl_init(struct pfe *pfe);
1718
++void pfe_ctrl_exit(struct pfe *pfe);
1719
++int pe_sync_stop(struct pfe_ctrl *ctrl, int pe_mask);
1720
++void pe_start(struct pfe_ctrl *ctrl, int pe_mask);
1721
++int pe_reset_all(struct pfe_ctrl *ctrl);
1722
++void pfe_ctrl_suspend(struct pfe_ctrl *ctrl);
1723
++void pfe_ctrl_resume(struct pfe_ctrl *ctrl);
1724
++int relax(unsigned long end);
1725
++
1726
++#endif /* _PFE_CTRL_H_ */
1727
+diff --git a/drivers/staging/fsl_ppfe/pfe_debugfs.h b/drivers/staging/fsl_ppfe/pfe_debugfs.h
1728
+new file mode 100644
1729
+index 000000000000..301d9fc22004
1730
+--- /dev/null
1731
+@@ -0,0 +1,25 @@
1732
++/*
1733
++ * Copyright 2015-2016 Freescale Semiconductor, Inc.
1734
++ * Copyright 2017 NXP
1735
++ *
1736
++ * This program is free software; you can redistribute it and/or modify
1737
++ * it under the terms of the GNU General Public License as published by
1738
++ * the Free Software Foundation; either version 2 of the License, or
1739
++ * (at your option) any later version.
1740
++ *
1741
++ * This program is distributed in the hope that it will be useful,
1742
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1743
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1744
++ * GNU General Public License for more details.
1745
++ *
1746
++ * You should have received a copy of the GNU General Public License
1747
++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
1748
++ */
1749
++
1750
++#ifndef _PFE_DEBUGFS_H_
1751
++#define _PFE_DEBUGFS_H_
1752
++
1753
++int pfe_debugfs_init(struct pfe *pfe);
1754
++void pfe_debugfs_exit(struct pfe *pfe);
1755
++
1756
++#endif /* _PFE_DEBUGFS_H_ */
1757
+diff --git a/drivers/staging/fsl_ppfe/pfe_eth.h b/drivers/staging/fsl_ppfe/pfe_eth.h
1758
+new file mode 100644
1759
+index 000000000000..721bef3ef53b
1760
+--- /dev/null
1761
+@@ -0,0 +1,184 @@
1762
++/*
1763
++ * Copyright 2015-2016 Freescale Semiconductor, Inc.
1764
++ * Copyright 2017 NXP
1765
++ *
1766
++ * This program is free software; you can redistribute it and/or modify
1767
++ * it under the terms of the GNU General Public License as published by
1768
++ * the Free Software Foundation; either version 2 of the License, or
1769
++ * (at your option) any later version.
1770
++ *
1771
++ * This program is distributed in the hope that it will be useful,
1772
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1773
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1774
++ * GNU General Public License for more details.
1775
++ *
1776
++ * You should have received a copy of the GNU General Public License
1777
++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
1778
++ */
1779
++
1780
++#ifndef _PFE_ETH_H_
1781
++#define _PFE_ETH_H_
1782
++#include <linux/kernel.h>
1783
++#include <linux/netdevice.h>
1784
++#include <linux/etherdevice.h>
1785
++#include <linux/ethtool.h>
1786
++#include <linux/mii.h>
1787
++#include <linux/phy.h>
1788
++#include <linux/clk.h>
1789
++#include <linux/interrupt.h>
1790
++#include <linux/time.h>
1791
++
1792
++#define PFE_ETH_NAPI_STATS
1793
++#define PFE_ETH_TX_STATS
1794
++
1795
++#define PFE_ETH_FRAGS_MAX (65536 / HIF_RX_PKT_MIN_SIZE)
1796
++#define LRO_LEN_COUNT_MAX	32
1797
++#define LRO_NB_COUNT_MAX	32
1798
++
1799
++#define PFE_PAUSE_FLAG_ENABLE		1
1800
++#define PFE_PAUSE_FLAG_AUTONEG		2
1801
++
1802
++/* GEMAC configured by SW */
1803
++/* GEMAC configured by phy lines (not for MII/GMII) */
1804
++
1805
++#define GEMAC_SW_FULL_DUPLEX    BIT(9)
1806
++#define GEMAC_SW_SPEED_10M      (0 << 12)
1807
++#define GEMAC_SW_SPEED_100M     BIT(12)
1808
++#define GEMAC_SW_SPEED_1G       (2 << 12)
1809
++
1810
++#define GEMAC_NO_PHY            BIT(0)
1811
++
1812
++struct ls1012a_eth_platform_data {
1813
++	/* device specific information */
1814
++	u32 device_flags;
1815
++	char name[16];
1816
++
1817
++	/* board specific information */
1818
++	u32 mii_config;
1819
++	u32 phy_flags;
1820
++	u32 gem_id;
1821
++	u32 bus_id;
1822
++	u32 phy_id;
1823
++	u32 mdio_muxval;
1824
++	u8 mac_addr[ETH_ALEN];
1825
++};
1826
++
1827
++struct ls1012a_mdio_platform_data {
1828
++	int enabled;
1829
++	int irq[32];
1830
++	u32 phy_mask;
1831
++	int mdc_div;
1832
++};
1833
++
1834
++struct ls1012a_pfe_platform_data {
1835
++	struct ls1012a_eth_platform_data ls1012a_eth_pdata[3];
1836
++	struct ls1012a_mdio_platform_data ls1012a_mdio_pdata[3];
1837
++};
1838
++
1839
++#define NUM_GEMAC_SUPPORT	2
1840
++#define DRV_NAME		"pfe-eth"
1841
++#define DRV_VERSION		"1.0"
1842
++
1843
++#define LS1012A_TX_FAST_RECOVERY_TIMEOUT_MS	3
1844
++#define TX_POLL_TIMEOUT_MS	1000
1845
++
1846
++#define EMAC_TXQ_CNT	16
1847
++#define EMAC_TXQ_DEPTH	(HIF_TX_DESC_NT)
1848
++
1849
++#define JUMBO_FRAME_SIZE	10258
1850
++/*
1851
++ * Client Tx queue threshold, for txQ flush condition.
1852
++ * It must be smaller than the queue size (in case we ever change it in the
1853
++ * future).
1854
++ */
1855
++#define HIF_CL_TX_FLUSH_MARK	32
1856
++
1857
++/*
1858
++ * Max number of TX resources (HIF descriptors or skbs) that will be released
1859
++ * in a single go during batch recycling.
1860
++ * Should be lower than the flush mark so the SW can provide the HW with a
1861
++ * continuous stream of packets instead of bursts.
1862
++ */
1863
++#define TX_FREE_MAX_COUNT 16
1864
++#define EMAC_RXQ_CNT	3
1865
++#define EMAC_RXQ_DEPTH	HIF_RX_DESC_NT
1866
++/* make sure clients can receive a full burst of packets */
1867
++#define EMAC_RMON_TXBYTES_POS	0x00
1868
++#define EMAC_RMON_RXBYTES_POS	0x14
1869
++
1870
++#define EMAC_QUEUENUM_MASK      (emac_txq_cnt - 1)
1871
++#define EMAC_MDIO_TIMEOUT	1000
1872
++#define MAX_UC_SPEC_ADDR_REG 31
1873
++
1874
++struct pfe_eth_fast_timer {
1875
++	int queuenum;
1876
++	struct hrtimer timer;
1877
++	void *base;
1878
++};
1879
++
1880
++struct  pfe_eth_priv_s {
1881
++	struct pfe		*pfe;
1882
++	struct hif_client_s	client;
1883
++	struct napi_struct	lro_napi;
1884
++	struct napi_struct	low_napi;
1885
++	struct napi_struct	high_napi;
1886
++	int			low_tmu_q;
1887
++	int			high_tmu_q;
1888
++	struct net_device_stats stats;
1889
++	struct net_device	*ndev;
1890
++	int			id;
1891
++	int			promisc;
1892
++	unsigned int		msg_enable;
1893
++	unsigned int		usr_features;
1894
++
1895
++	spinlock_t		lock; /* protect member variables */
1896
++	unsigned int		event_status;
1897
++	int			irq;
1898
++	void			*EMAC_baseaddr;
1899
++	/* This points to the EMAC base from where we access PHY */
1900
++	void			*PHY_baseaddr;
1901
++	void			*GPI_baseaddr;
1902
++	/* PHY stuff */
1903
++	struct phy_device	*phydev;
1904
++	int			oldspeed;
1905
++	int			oldduplex;
1906
++	int			oldlink;
1907
++	/* mdio info */
1908
++	int			mdc_div;
1909
++	struct mii_bus		*mii_bus;
1910
++	struct clk		*gemtx_clk;
1911
++	int			wol;
1912
++	int			pause_flag;
1913
++
1914
++	int			default_priority;
1915
++	struct pfe_eth_fast_timer fast_tx_timeout[EMAC_TXQ_CNT];
1916
++
1917
++	struct ls1012a_eth_platform_data *einfo;
1918
++	struct sk_buff *skb_inflight[EMAC_RXQ_CNT + 6];
1919
++
1920
++#ifdef PFE_ETH_TX_STATS
1921
++	unsigned int stop_queue_total[EMAC_TXQ_CNT];
1922
++	unsigned int stop_queue_hif[EMAC_TXQ_CNT];
1923
++	unsigned int stop_queue_hif_client[EMAC_TXQ_CNT];
1924
++	unsigned int stop_queue_credit[EMAC_TXQ_CNT];
1925
++	unsigned int clean_fail[EMAC_TXQ_CNT];
1926
++	unsigned int was_stopped[EMAC_TXQ_CNT];
1927
++#endif
1928
++
1929
++#ifdef PFE_ETH_NAPI_STATS
1930
++	unsigned int napi_counters[NAPI_MAX_COUNT];
1931
++#endif
1932
++	unsigned int frags_inflight[EMAC_RXQ_CNT + 6];
1933
++};
1934
++
1935
++struct pfe_eth {
1936
++	struct pfe_eth_priv_s *eth_priv[3];
1937
++};
1938
++
1939
++int pfe_eth_init(struct pfe *pfe);
1940
++void pfe_eth_exit(struct pfe *pfe);
1941
++int pfe_eth_suspend(struct net_device *dev);
1942
++int pfe_eth_resume(struct net_device *dev);
1943
++int pfe_eth_mdio_reset(struct mii_bus *bus);
1944
++
1945
++#endif /* _PFE_ETH_H_ */
1946
+diff --git a/drivers/staging/fsl_ppfe/pfe_firmware.h b/drivers/staging/fsl_ppfe/pfe_firmware.h
1947
+new file mode 100644
1948
+index 000000000000..5ade848b9d2d
1949
+--- /dev/null
1950
+@@ -0,0 +1,32 @@
1951
++/*
1952
++ * Copyright 2015-2016 Freescale Semiconductor, Inc.
1953
++ * Copyright 2017 NXP
1954
++ *
1955
++ * This program is free software; you can redistribute it and/or modify
1956
++ * it under the terms of the GNU General Public License as published by
1957
++ * the Free Software Foundation; either version 2 of the License, or
1958
++ * (at your option) any later version.
1959
++ *
1960
++ * This program is distributed in the hope that it will be useful,
1961
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1962
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1963
++ * GNU General Public License for more details.
1964
++ *
1965
++ * You should have received a copy of the GNU General Public License
1966
++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
1967
++ */
1968
++
1969
++#ifndef _PFE_FIRMWARE_H_
1970
++#define _PFE_FIRMWARE_H_
1971
++
1972
++#define CLASS_FIRMWARE_FILENAME		"ppfe_class_ls1012a.elf"
1973
++#define TMU_FIRMWARE_FILENAME		"ppfe_tmu_ls1012a.elf"
1974
++
1975
++#define PFE_FW_CHECK_PASS		0
1976
++#define PFE_FW_CHECK_FAIL		1
1977
++#define NUM_PFE_FW				3
1978
++
1979
++int pfe_firmware_init(struct pfe *pfe);
1980
++void pfe_firmware_exit(struct pfe *pfe);
1981
++
1982
++#endif /* _PFE_FIRMWARE_H_ */
1983
+diff --git a/drivers/staging/fsl_ppfe/pfe_hif.h b/drivers/staging/fsl_ppfe/pfe_hif.h
1984
+new file mode 100644
1985
+index 000000000000..6e36f0c1f4ff
1986
+--- /dev/null
1987
+@@ -0,0 +1,211 @@
1988
++/*
1989
++ * Copyright 2015-2016 Freescale Semiconductor, Inc.
1990
++ * Copyright 2017 NXP
1991
++ *
1992
++ * This program is free software; you can redistribute it and/or modify
1993
++ * it under the terms of the GNU General Public License as published by
1994
++ * the Free Software Foundation; either version 2 of the License, or
1995
++ * (at your option) any later version.
1996
++ *
1997
++ * This program is distributed in the hope that it will be useful,
1998
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1999
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2000
++ * GNU General Public License for more details.
2001
++ *
2002
++ * You should have received a copy of the GNU General Public License
2003
++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
2004
++ */
2005
++
2006
++#ifndef _PFE_HIF_H_
2007
++#define _PFE_HIF_H_
2008
++
2009
++#include <linux/netdevice.h>
2010
++
2011
++#define HIF_NAPI_STATS
2012
++
2013
++#define HIF_CLIENT_QUEUES_MAX	16
2014
++#define HIF_RX_POLL_WEIGHT	64
2015
++
2016
++#define HIF_RX_PKT_MIN_SIZE 0x800 /* 2KB */
2017
++#define HIF_RX_PKT_MIN_SIZE_MASK ~(HIF_RX_PKT_MIN_SIZE - 1)
2018
++#define ROUND_MIN_RX_SIZE(_sz) (((_sz) + (HIF_RX_PKT_MIN_SIZE - 1)) \
2019
++					& HIF_RX_PKT_MIN_SIZE_MASK)
2020
++#define PRESENT_OFST_IN_PAGE(_buf) (((unsigned long int)(_buf) & (PAGE_SIZE \
2021
++					- 1)) & HIF_RX_PKT_MIN_SIZE_MASK)
2022
++
2023
++enum {
2024
++	NAPI_SCHED_COUNT = 0,
2025
++	NAPI_POLL_COUNT,
2026
++	NAPI_PACKET_COUNT,
2027
++	NAPI_DESC_COUNT,
2028
++	NAPI_FULL_BUDGET_COUNT,
2029
++	NAPI_CLIENT_FULL_COUNT,
2030
++	NAPI_MAX_COUNT
2031
++};
2032
++
2033
++/*
2034
++ * HIF_TX_DESC_NT value should be always greter than 4,
2035
++ * Otherwise HIF_TX_POLL_MARK will become zero.
2036
++ */
2037
++#define HIF_RX_DESC_NT		256
2038
++#define HIF_TX_DESC_NT		2048
2039
++
2040
++#define HIF_FIRST_BUFFER	BIT(0)
2041
++#define HIF_LAST_BUFFER		BIT(1)
2042
++#define HIF_DONT_DMA_MAP	BIT(2)
2043
++#define HIF_DATA_VALID		BIT(3)
2044
++#define HIF_TSO			BIT(4)
2045
++
2046
++enum {
2047
++	PFE_CL_GEM0 = 0,
2048
++	PFE_CL_GEM1,
2049
++	HIF_CLIENTS_MAX
2050
++};
2051
++
2052
++/*structure to store client queue info */
2053
++struct hif_rx_queue {
2054
++	struct rx_queue_desc *base;
2055
++	u32	size;
2056
++	u32	write_idx;
2057
++};
2058
++
2059
++struct hif_tx_queue {
2060
++	struct tx_queue_desc *base;
2061
++	u32	size;
2062
++	u32	ack_idx;
2063
++};
2064
++
2065
++/*Structure to store the client info */
2066
++struct hif_client {
2067
++	int	rx_qn;
2068
++	struct hif_rx_queue	rx_q[HIF_CLIENT_QUEUES_MAX];
2069
++	int	tx_qn;
2070
++	struct hif_tx_queue	tx_q[HIF_CLIENT_QUEUES_MAX];
2071
++};
2072
++
2073
++/*HIF hardware buffer descriptor */
2074
++struct hif_desc {
2075
++	u32 ctrl;
2076
++	u32 status;
2077
++	u32 data;
2078
++	u32 next;
2079
++};
2080
++
2081
++struct __hif_desc {
2082
++	u32 ctrl;
2083
++	u32 status;
2084
++	u32 data;
2085
++};
2086
++
2087
++struct hif_desc_sw {
2088
++	dma_addr_t data;
2089
++	u16 len;
2090
++	u8 client_id;
2091
++	u8 q_no;
2092
++	u16 flags;
2093
++};
2094
++
2095
++struct hif_hdr {
2096
++	u8 client_id;
2097
++	u8 q_num;
2098
++	u16 client_ctrl;
2099
++	u16 client_ctrl1;
2100
++};
2101
++
2102
++struct __hif_hdr {
2103
++	union {
2104
++		struct hif_hdr hdr;
2105
++		u32 word[2];
2106
++	};
2107
++};
2108
++
2109
++struct hif_ipsec_hdr {
2110
++	u16	sa_handle[2];
2111
++} __packed;
2112
++
2113
++/*  HIF_CTRL_TX... defines */
2114
++#define HIF_CTRL_TX_CHECKSUM		BIT(2)
2115
++
2116
++/*  HIF_CTRL_RX... defines */
2117
++#define HIF_CTRL_RX_OFFSET_OFST         (24)
2118
++#define HIF_CTRL_RX_CHECKSUMMED		BIT(2)
2119
++#define HIF_CTRL_RX_CONTINUED		BIT(1)
2120
++
2121
++struct pfe_hif {
2122
++	/* To store registered clients in hif layer */
2123
++	struct hif_client client[HIF_CLIENTS_MAX];
2124
++	struct hif_shm *shm;
2125
++	int	irq;
2126
++
2127
++	void	*descr_baseaddr_v;
2128
++	unsigned long	descr_baseaddr_p;
2129
++
2130
++	struct hif_desc *rx_base;
2131
++	u32	rx_ring_size;
2132
++	u32	rxtoclean_index;
2133
++	void	*rx_buf_addr[HIF_RX_DESC_NT];
2134
++	int	rx_buf_len[HIF_RX_DESC_NT];
2135
++	unsigned int qno;
2136
++	unsigned int client_id;
2137
++	unsigned int client_ctrl;
2138
++	unsigned int started;
2139
++
2140
++	struct hif_desc *tx_base;
2141
++	u32	tx_ring_size;
2142
++	u32	txtosend;
2143
++	u32	txtoclean;
2144
++	u32	txavail;
2145
++	u32	txtoflush;
2146
++	struct hif_desc_sw tx_sw_queue[HIF_TX_DESC_NT];
2147
++
2148
++/* tx_lock synchronizes hif packet tx as well as pfe_hif structure access */
2149
++	spinlock_t tx_lock;
2150
++/* lock synchronizes hif rx queue processing */
2151
++	spinlock_t lock;
2152
++	struct net_device	dummy_dev;
2153
++	struct napi_struct	napi;
2154
++	struct device *dev;
2155
++
2156
++#ifdef HIF_NAPI_STATS
2157
++	unsigned int napi_counters[NAPI_MAX_COUNT];
2158
++#endif
2159
++	struct tasklet_struct	tx_cleanup_tasklet;
2160
++};
2161
++
2162
++void __hif_xmit_pkt(struct pfe_hif *hif, unsigned int client_id, unsigned int
2163
++			q_no, void *data, u32 len, unsigned int flags);
2164
++int hif_xmit_pkt(struct pfe_hif *hif, unsigned int client_id, unsigned int q_no,
2165
++		 void *data, unsigned int len);
2166
++void __hif_tx_done_process(struct pfe_hif *hif, int count);
2167
++void hif_process_client_req(struct pfe_hif *hif, int req, int data1, int
2168
++				data2);
2169
++int pfe_hif_init(struct pfe *pfe);
2170
++void pfe_hif_exit(struct pfe *pfe);
2171
++void pfe_hif_rx_idle(struct pfe_hif *hif);
2172
++static inline void hif_tx_done_process(struct pfe_hif *hif, int count)
2173
++{
2174
++	spin_lock_bh(&hif->tx_lock);
2175
++	__hif_tx_done_process(hif, count);
2176
++	spin_unlock_bh(&hif->tx_lock);
2177
++}
2178
++
2179
++static inline void hif_tx_lock(struct pfe_hif *hif)
2180
++{
2181
++	spin_lock_bh(&hif->tx_lock);
2182
++}
2183
++
2184
++static inline void hif_tx_unlock(struct pfe_hif *hif)
2185
++{
2186
++	spin_unlock_bh(&hif->tx_lock);
2187
++}
2188
++
2189
++static inline int __hif_tx_avail(struct pfe_hif *hif)
2190
++{
2191
++	return hif->txavail;
2192
++}
2193
++
2194
++#define __memcpy8(dst, src)		memcpy(dst, src, 8)
2195
++#define __memcpy12(dst, src)		memcpy(dst, src, 12)
2196
++#define __memcpy(dst, src, len)		memcpy(dst, src, len)
2197
++
2198
++#endif /* _PFE_HIF_H_ */
2199
+diff --git a/drivers/staging/fsl_ppfe/pfe_hif_lib.h b/drivers/staging/fsl_ppfe/pfe_hif_lib.h
2200
+new file mode 100644
2201
+index 000000000000..49e7b5f1f9c3
2202
+--- /dev/null
2203
+@@ -0,0 +1,239 @@
2204
++/*
2205
++ * Copyright 2015-2016 Freescale Semiconductor, Inc.
2206
++ * Copyright 2017 NXP
2207
++ *
2208
++ * This program is free software; you can redistribute it and/or modify
2209
++ * it under the terms of the GNU General Public License as published by
2210
++ * the Free Software Foundation; either version 2 of the License, or
2211
++ * (at your option) any later version.
2212
++ *
2213
++ * This program is distributed in the hope that it will be useful,
2214
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2215
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2216
++ * GNU General Public License for more details.
2217
++ *
2218
++ * You should have received a copy of the GNU General Public License
2219
++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
2220
++ */
2221
++
2222
++#ifndef _PFE_HIF_LIB_H_
2223
++#define _PFE_HIF_LIB_H_
2224
++
2225
++#include "pfe_hif.h"
2226
++
2227
++#define HIF_CL_REQ_TIMEOUT	10
2228
++#define GFP_DMA_PFE 0
2229
++
2230
++enum {
2231
++	REQUEST_CL_REGISTER = 0,
2232
++	REQUEST_CL_UNREGISTER,
2233
++	HIF_REQUEST_MAX
2234
++};
2235
++
2236
++enum {
2237
++	/* Event to indicate that client rx queue is reached water mark level */
2238
++	EVENT_HIGH_RX_WM = 0,
2239
++	/* Event to indicate that, packet received for client */
2240
++	EVENT_RX_PKT_IND,
2241
++	/* Event to indicate that, packet tx done for client */
2242
++	EVENT_TXDONE_IND,
2243
++	HIF_EVENT_MAX
2244
++};
2245
++
2246
++/*structure to store client queue info */
2247
++
2248
++/*structure to store client queue info */
2249
++struct hif_client_rx_queue {
2250
++	struct rx_queue_desc *base;
2251
++	u32	size;
2252
++	u32	read_idx;
2253
++	u32	write_idx;
2254
++};
2255
++
2256
++struct hif_client_tx_queue {
2257
++	struct tx_queue_desc *base;
2258
++	u32	size;
2259
++	u32	read_idx;
2260
++	u32	write_idx;
2261
++	u32	tx_pending;
2262
++	unsigned long jiffies_last_packet;
2263
++	u32	nocpy_flag;
2264
++	u32	prev_tmu_tx_pkts;
2265
++	u32	done_tmu_tx_pkts;
2266
++};
2267
++
2268
++struct hif_client_s {
2269
++	int	id;
2270
++	int	tx_qn;
2271
++	int	rx_qn;
2272
++	void	*rx_qbase;
2273
++	void	*tx_qbase;
2274
++	int	tx_qsize;
2275
++	int	rx_qsize;
2276
++	int	cpu_id;
2277
++	struct hif_client_tx_queue tx_q[HIF_CLIENT_QUEUES_MAX];
2278
++	struct hif_client_rx_queue rx_q[HIF_CLIENT_QUEUES_MAX];
2279
++	int (*event_handler)(void *priv, int event, int data);
2280
++	unsigned long queue_mask[HIF_EVENT_MAX];
2281
++	struct pfe *pfe;
2282
++	void *priv;
2283
++};
2284
++
2285
++/*
2286
++ * Client specific shared memory
2287
++ * It contains number of Rx/Tx queues, base addresses and queue sizes
2288
++ */
2289
++struct hif_client_shm {
2290
++	u32 ctrl; /*0-7: number of Rx queues, 8-15: number of tx queues */
2291
++	unsigned long rx_qbase; /*Rx queue base address */
2292
++	u32 rx_qsize; /*each Rx queue size, all Rx queues are of same size */
2293
++	unsigned long tx_qbase; /* Tx queue base address */
2294
++	u32 tx_qsize; /*each Tx queue size, all Tx queues are of same size */
2295
++};
2296
++
2297
++/*Client shared memory ctrl bit description */
2298
++#define CLIENT_CTRL_RX_Q_CNT_OFST	0
2299
++#define CLIENT_CTRL_TX_Q_CNT_OFST	8
2300
++#define CLIENT_CTRL_RX_Q_CNT(ctrl)	(((ctrl) >> CLIENT_CTRL_RX_Q_CNT_OFST) \
2301
++						& 0xFF)
2302
++#define CLIENT_CTRL_TX_Q_CNT(ctrl)	(((ctrl) >> CLIENT_CTRL_TX_Q_CNT_OFST) \
2303
++						& 0xFF)
2304
++
2305
++/*
2306
++ * Shared memory used to communicate between HIF driver and host/client drivers
2307
++ * Before starting the hif driver rx_buf_pool ans rx_buf_pool_cnt should be
2308
++ * initialized with host buffers and buffers count in the pool.
2309
++ * rx_buf_pool_cnt should be >= HIF_RX_DESC_NT.
2310
++ *
2311
++ */
2312
++struct hif_shm {
2313
++	u32 rx_buf_pool_cnt; /*Number of rx buffers available*/
2314
++	/*Rx buffers required to initialize HIF rx descriptors */
2315
++	void *rx_buf_pool[HIF_RX_DESC_NT];
2316
++	unsigned long g_client_status[2]; /*Global client status bit mask */
2317
++	/* Client specific shared memory */
2318
++	struct hif_client_shm client[HIF_CLIENTS_MAX];
2319
++};
2320
++
2321
++#define CL_DESC_OWN	BIT(31)
2322
++/* This sets owner ship to HIF driver */
2323
++#define CL_DESC_LAST	BIT(30)
2324
++/* This indicates last packet for multi buffers handling */
2325
++#define CL_DESC_FIRST	BIT(29)
2326
++/* This indicates first packet for multi buffers handling */
2327
++
2328
++#define CL_DESC_BUF_LEN(x)		((x) & 0xFFFF)
2329
++#define CL_DESC_FLAGS(x)		(((x) & 0xF) << 16)
2330
++#define CL_DESC_GET_FLAGS(x)		(((x) >> 16) & 0xF)
2331
++
2332
++struct rx_queue_desc {
2333
++	void *data;
2334
++	u32	ctrl; /*0-15bit len, 16-20bit flags, 31bit owner*/
2335
++	u32	client_ctrl;
2336
++};
2337
++
2338
++struct tx_queue_desc {
2339
++	void *data;
2340
++	u32	ctrl; /*0-15bit len, 16-20bit flags, 31bit owner*/
2341
++};
2342
++
2343
++/* HIF Rx is not working properly for 2-byte aligned buffers and
2344
++ * ip_header should be 4byte aligned for better iperformance.
2345
++ * "ip_header = 64 + 6(hif_header) + 14 (MAC Header)" will be 4byte aligned.
2346
++ */
2347
++#define PFE_PKT_HEADER_SZ	sizeof(struct hif_hdr)
2348
++/* must be big enough for headroom, pkt size and skb shared info */
2349
++#define PFE_BUF_SIZE		2048
2350
++#define PFE_PKT_HEADROOM	128
2351
++
2352
++#define SKB_SHARED_INFO_SIZE   (sizeof(struct skb_shared_info))
2353
++#define PFE_PKT_SIZE		(PFE_BUF_SIZE - PFE_PKT_HEADROOM \
2354
++				 - SKB_SHARED_INFO_SIZE)
2355
++#define MAX_L2_HDR_SIZE		14	/* Not correct for VLAN/PPPoE */
2356
++#define MAX_L3_HDR_SIZE		20	/* Not correct for IPv6 */
2357
++#define MAX_L4_HDR_SIZE		60	/* TCP with maximum options */
2358
++#define MAX_HDR_SIZE		(MAX_L2_HDR_SIZE + MAX_L3_HDR_SIZE \
2359
++				 + MAX_L4_HDR_SIZE)
2360
++/* Used in page mode to clamp packet size to the maximum supported by the hif
2361
++ *hw interface (<16KiB)
2362
++ */
2363
++#define MAX_PFE_PKT_SIZE	16380UL
2364
++
2365
++extern unsigned int pfe_pkt_size;
2366
++extern unsigned int pfe_pkt_headroom;
2367
++extern unsigned int page_mode;
2368
++extern unsigned int lro_mode;
2369
++extern unsigned int tx_qos;
2370
++extern unsigned int emac_txq_cnt;
2371
++
2372
++int pfe_hif_lib_init(struct pfe *pfe);
2373
++void pfe_hif_lib_exit(struct pfe *pfe);
2374
++int hif_lib_client_register(struct hif_client_s *client);
2375
++int hif_lib_client_unregister(struct  hif_client_s *client);
2376
++void __hif_lib_xmit_pkt(struct hif_client_s *client, unsigned int qno, void
2377
++				*data, unsigned int len, u32 client_ctrl,
2378
++				unsigned int flags, void *client_data);
2379
++int hif_lib_xmit_pkt(struct hif_client_s *client, unsigned int qno, void *data,
2380
++		     unsigned int len, u32 client_ctrl, void *client_data);
2381
++void hif_lib_indicate_client(int cl_id, int event, int data);
2382
++int hif_lib_event_handler_start(struct hif_client_s *client, int event, int
2383
++					data);
2384
++int hif_lib_tmu_queue_start(struct hif_client_s *client, int qno);
2385
++int hif_lib_tmu_queue_stop(struct hif_client_s *client, int qno);
2386
++void *hif_lib_tx_get_next_complete(struct hif_client_s *client, int qno,
2387
++				   unsigned int *flags, int count);
2388
++void *hif_lib_receive_pkt(struct hif_client_s *client, int qno, int *len, int
2389
++				*ofst, unsigned int *rx_ctrl,
2390
++				unsigned int *desc_ctrl, void **priv_data);
2391
++void hif_lib_set_rx_cpu_affinity(struct hif_client_s *client, int cpu_id);
2392
++void hif_lib_set_tx_queue_nocpy(struct hif_client_s *client, int qno, int
2393
++					enable);
2394
++static inline int hif_lib_tx_avail(struct hif_client_s *client, unsigned int
2395
++					qno)
2396
++{
2397
++	struct hif_client_tx_queue *queue = &client->tx_q[qno];
2398
++
2399
++	return (queue->size - queue->tx_pending);
2400
++}
2401
++
2402
++static inline int hif_lib_get_tx_wr_index(struct hif_client_s *client, unsigned
2403
++						int qno)
2404
++{
2405
++	struct hif_client_tx_queue *queue = &client->tx_q[qno];
2406
++
2407
++	return queue->write_idx;
2408
++}
2409
++
2410
++static inline int hif_lib_tx_pending(struct hif_client_s *client, unsigned int
2411
++					qno)
2412
++{
2413
++	struct hif_client_tx_queue *queue = &client->tx_q[qno];
2414
++
2415
++	return queue->tx_pending;
2416
++}
2417
++
2418
++#define hif_lib_tx_credit_avail(pfe, id, qno) \
2419
++				((pfe)->tmu_credit.tx_credit[id][qno])
2420
++
2421
++#define hif_lib_tx_credit_max(pfe, id, qno) \
2422
++				((pfe)->tmu_credit.tx_credit_max[id][qno])
2423
++
2424
++/*
2425
++ * Test comment
2426
++ */
2427
++#define hif_lib_tx_credit_use(pfe, id, qno, credit)			\
2428
++	({ typeof(pfe) pfe_ = pfe;					\
2429
++		typeof(id) id_ = id;					\
2430
++		typeof(qno) qno_ = qno_;				\
2431
++		typeof(credit) credit_ = credit;			\
2432
++		do {							\
2433
++			if (tx_qos) {					\
2434
++				(pfe_)->tmu_credit.tx_credit[id_][qno_]\
2435
++					 -= credit_;			\
2436
++				(pfe_)->tmu_credit.tx_packets[id_][qno_]\
2437
++					+= credit_;			\
2438
++			}						\
2439
++		} while (0);						\
2440
++	})
2441
++
2442
++#endif /* _PFE_HIF_LIB_H_ */
2443
+diff --git a/drivers/staging/fsl_ppfe/pfe_hw.h b/drivers/staging/fsl_ppfe/pfe_hw.h
2444
+new file mode 100644
2445
+index 000000000000..53b5fe1400ec
2446
+--- /dev/null
2447
+@@ -0,0 +1,27 @@
2448
++/*
2449
++ * Copyright 2015-2016 Freescale Semiconductor, Inc.
2450
++ * Copyright 2017 NXP
2451
++ *
2452
++ * This program is free software; you can redistribute it and/or modify
2453
++ * it under the terms of the GNU General Public License as published by
2454
++ * the Free Software Foundation; either version 2 of the License, or
2455
++ * (at your option) any later version.
2456
++ *
2457
++ * This program is distributed in the hope that it will be useful,
2458
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2459
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2460
++ * GNU General Public License for more details.
2461
++ *
2462
++ * You should have received a copy of the GNU General Public License
2463
++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
2464
++ */
2465
++
2466
++#ifndef _PFE_HW_H_
2467
++#define _PFE_HW_H_
2468
++
2469
++#define PE_SYS_CLK_RATIO	1	/* SYS/AXI = 250MHz, HFE = 500MHz */
2470
++
2471
++int pfe_hw_init(struct pfe *pfe, int resume);
2472
++void pfe_hw_exit(struct pfe *pfe);
2473
++
2474
++#endif /* _PFE_HW_H_ */
2475
+diff --git a/drivers/staging/fsl_ppfe/pfe_mod.h b/drivers/staging/fsl_ppfe/pfe_mod.h
2476
+new file mode 100644
2477
+index 000000000000..3012f17fef31
2478
+--- /dev/null
2479
+@@ -0,0 +1,112 @@
2480
++/*
2481
++ * Copyright 2015-2016 Freescale Semiconductor, Inc.
2482
++ * Copyright 2017 NXP
2483
++ *
2484
++ * This program is free software; you can redistribute it and/or modify
2485
++ * it under the terms of the GNU General Public License as published by
2486
++ * the Free Software Foundation; either version 2 of the License, or
2487
++ * (at your option) any later version.
2488
++ *
2489
++ * This program is distributed in the hope that it will be useful,
2490
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2491
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2492
++ * GNU General Public License for more details.
2493
++ *
2494
++ * You should have received a copy of the GNU General Public License
2495
++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
2496
++ */
2497
++
2498
++#ifndef _PFE_MOD_H_
2499
++#define _PFE_MOD_H_
2500
++
2501
++#include <linux/device.h>
2502
++#include <linux/elf.h>
2503
++
2504
++struct pfe;
2505
++
2506
++#include "pfe_hw.h"
2507
++#include "pfe_firmware.h"
2508
++#include "pfe_ctrl.h"
2509
++#include "pfe_hif.h"
2510
++#include "pfe_hif_lib.h"
2511
++#include "pfe_eth.h"
2512
++#include "pfe_sysfs.h"
2513
++#include "pfe_perfmon.h"
2514
++#include "pfe_debugfs.h"
2515
++
2516
++#define PHYID_MAX_VAL 32
2517
++
2518
++struct pfe_tmu_credit {
2519
++	/* Number of allowed TX packet in-flight, matches TMU queue size */
2520
++	unsigned int tx_credit[NUM_GEMAC_SUPPORT][EMAC_TXQ_CNT];
2521
++	unsigned int tx_credit_max[NUM_GEMAC_SUPPORT][EMAC_TXQ_CNT];
2522
++	unsigned int tx_packets[NUM_GEMAC_SUPPORT][EMAC_TXQ_CNT];
2523
++};
2524
++
2525
++struct pfe {
2526
++	struct regmap	*scfg;
2527
++	unsigned long ddr_phys_baseaddr;
2528
++	void *ddr_baseaddr;
2529
++	unsigned int ddr_size;
2530
++	void *cbus_baseaddr;
2531
++	void *apb_baseaddr;
2532
++	unsigned long iram_phys_baseaddr;
2533
++	void *iram_baseaddr;
2534
++	unsigned long ipsec_phys_baseaddr;
2535
++	void *ipsec_baseaddr;
2536
++	int hif_irq;
2537
++	int wol_irq;
2538
++	int hif_client_irq;
2539
++	struct device *dev;
2540
++	struct dentry *dentry;
2541
++	struct pfe_ctrl ctrl;
2542
++	struct pfe_hif hif;
2543
++	struct pfe_eth eth;
2544
++	struct hif_client_s *hif_client[HIF_CLIENTS_MAX];
2545
++#if defined(CFG_DIAGS)
2546
++	struct pfe_diags diags;
2547
++#endif
2548
++	struct pfe_tmu_credit tmu_credit;
2549
++	struct pfe_cpumon cpumon;
2550
++	struct pfe_memmon memmon;
2551
++	int wake;
2552
++	int mdio_muxval[PHYID_MAX_VAL];
2553
++	struct clk *hfe_clock;
2554
++};
2555
++
2556
++extern struct pfe *pfe;
2557
++
2558
++int pfe_probe(struct pfe *pfe);
2559
++int pfe_remove(struct pfe *pfe);
2560
++
2561
++/* DDR Mapping in reserved memory*/
2562
++#define ROUTE_TABLE_BASEADDR	0
2563
++#define ROUTE_TABLE_HASH_BITS	15	/* 32K entries */
2564
++#define ROUTE_TABLE_SIZE	((1 << ROUTE_TABLE_HASH_BITS) \
2565
++				  * CLASS_ROUTE_SIZE)
2566
++#define BMU2_DDR_BASEADDR	(ROUTE_TABLE_BASEADDR + ROUTE_TABLE_SIZE)
2567
++#define BMU2_BUF_COUNT		(4096 - 256)
2568
++/* This is to get a total DDR size of 12MiB */
2569
++#define BMU2_DDR_SIZE		(DDR_BUF_SIZE * BMU2_BUF_COUNT)
2570
++#define UTIL_CODE_BASEADDR	(BMU2_DDR_BASEADDR + BMU2_DDR_SIZE)
2571
++#define UTIL_CODE_SIZE		(128 * SZ_1K)
2572
++#define UTIL_DDR_DATA_BASEADDR	(UTIL_CODE_BASEADDR + UTIL_CODE_SIZE)
2573
++#define UTIL_DDR_DATA_SIZE	(64 * SZ_1K)
2574
++#define CLASS_DDR_DATA_BASEADDR	(UTIL_DDR_DATA_BASEADDR + UTIL_DDR_DATA_SIZE)
2575
++#define CLASS_DDR_DATA_SIZE	(32 * SZ_1K)
2576
++#define TMU_DDR_DATA_BASEADDR	(CLASS_DDR_DATA_BASEADDR + CLASS_DDR_DATA_SIZE)
2577
++#define TMU_DDR_DATA_SIZE	(32 * SZ_1K)
2578
++#define TMU_LLM_BASEADDR	(TMU_DDR_DATA_BASEADDR + TMU_DDR_DATA_SIZE)
2579
++#define TMU_LLM_QUEUE_LEN	(8 * 512)
2580
++/* Must be power of two and at least 16 * 8 = 128 bytes */
2581
++#define TMU_LLM_SIZE		(4 * 16 * TMU_LLM_QUEUE_LEN)
2582
++/* (4 TMU's x 16 queues x queue_len) */
2583
++
2584
++#define DDR_MAX_SIZE		(TMU_LLM_BASEADDR + TMU_LLM_SIZE)
2585
++
2586
++/* LMEM Mapping */
2587
++#define BMU1_LMEM_BASEADDR	0
2588
++#define BMU1_BUF_COUNT		256
2589
++#define BMU1_LMEM_SIZE		(LMEM_BUF_SIZE * BMU1_BUF_COUNT)
2590
++
2591
++#endif /* _PFE_MOD_H */
2592
+diff --git a/drivers/staging/fsl_ppfe/pfe_perfmon.h b/drivers/staging/fsl_ppfe/pfe_perfmon.h
2593
+new file mode 100644
2594
+index 000000000000..84908121a6fd
2595
+--- /dev/null
2596
+@@ -0,0 +1,38 @@
2597
++/*
2598
++ * Copyright 2015-2016 Freescale Semiconductor, Inc.
2599
++ * Copyright 2017 NXP
2600
++ *
2601
++ * This program is free software; you can redistribute it and/or modify
2602
++ * it under the terms of the GNU General Public License as published by
2603
++ * the Free Software Foundation; either version 2 of the License, or
2604
++ * (at your option) any later version.
2605
++ *
2606
++ * This program is distributed in the hope that it will be useful,
2607
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2608
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2609
++ * GNU General Public License for more details.
2610
++ *
2611
++ * You should have received a copy of the GNU General Public License
2612
++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
2613
++ */
2614
++
2615
++#ifndef _PFE_PERFMON_H_
2616
++#define _PFE_PERFMON_H_
2617
++
2618
++#include "pfe/pfe.h"
2619
++
2620
++#define	CT_CPUMON_INTERVAL	(1 * TIMER_TICKS_PER_SEC)
2621
++
2622
++struct pfe_cpumon {
2623
++	u32 cpu_usage_pct[MAX_PE];
2624
++	u32 class_usage_pct;
2625
++};
2626
++
2627
++struct pfe_memmon {
2628
++	u32 kernel_memory_allocated;
2629
++};
2630
++
2631
++int pfe_perfmon_init(struct pfe *pfe);
2632
++void pfe_perfmon_exit(struct pfe *pfe);
2633
++
2634
++#endif /* _PFE_PERFMON_H_ */
2635
+diff --git a/drivers/staging/fsl_ppfe/pfe_sysfs.h b/drivers/staging/fsl_ppfe/pfe_sysfs.h
2636
+new file mode 100644
2637
+index 000000000000..4fb39c93cbf9
2638
+--- /dev/null
2639
+@@ -0,0 +1,29 @@
2640
++/*
2641
++ * Copyright 2015-2016 Freescale Semiconductor, Inc.
2642
++ * Copyright 2017 NXP
2643
++ *
2644
++ * This program is free software; you can redistribute it and/or modify
2645
++ * it under the terms of the GNU General Public License as published by
2646
++ * the Free Software Foundation; either version 2 of the License, or
2647
++ * (at your option) any later version.
2648
++ *
2649
++ * This program is distributed in the hope that it will be useful,
2650
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2651
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2652
++ * GNU General Public License for more details.
2653
++ *
2654
++ * You should have received a copy of the GNU General Public License
2655
++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
2656
++ */
2657
++
2658
++#ifndef _PFE_SYSFS_H_
2659
++#define _PFE_SYSFS_H_
2660
++
2661
++#include <linux/proc_fs.h>
2662
++
2663
++u32 qm_read_drop_stat(u32 tmu, u32 queue, u32 *total_drops, int do_reset);
2664
++
2665
++int pfe_sysfs_init(struct pfe *pfe);
2666
++void pfe_sysfs_exit(struct pfe *pfe);
2667
++
2668
++#endif /* _PFE_SYSFS_H_ */
2669
+-- 
2670
+2.14.2
2671
+
0 2672
new file mode 100644
... ...
@@ -0,0 +1,8052 @@
0
+From 37dd30b10a56b9e26af0b7ae58e181d8845549c2 Mon Sep 17 00:00:00 2001
1
+From: Calvin Johnson <calvin.johnson@nxp.com>
2
+Date: Sat, 16 Sep 2017 14:22:17 +0530
3
+Subject: [PATCH 02/22] staging: fsl_ppfe/eth: introduce pfe driver
4
+
5
+	This patch introduces Linux support for NXP's LS1012A Packet
6
+Forwarding Engine (pfe_eth). LS1012A uses hardware packet forwarding
7
+engine to provide high performance Ethernet interfaces. The device
8
+includes two Ethernet ports.
9
+
10
+Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
11
+Signed-off-by: Anjaneyulu Jagarlmudi <anji.jagarlmudi@nxp.com>
12
+
13
+[ Srinidhi Rao : Ported this patch to photon linux from
14
+  qoriq-components linux 'linux-4.14-nxp'
15
+  (https://source.codeaurora.org/external/qoriq/qoriq-components/linux)
16
+]
17
+
18
+Signed-off-by: srinidhira0 <srinidhir@vmware.com>
19
+---
20
+ drivers/staging/fsl_ppfe/Kconfig                |   20 +
21
+ drivers/staging/fsl_ppfe/Makefile               |   19 +
22
+ drivers/staging/fsl_ppfe/TODO                   |    2 +
23
+ drivers/staging/fsl_ppfe/pfe_ctrl.c             |  238 +++
24
+ drivers/staging/fsl_ppfe/pfe_debugfs.c          |  111 ++
25
+ drivers/staging/fsl_ppfe/pfe_eth.c              | 2434 +++++++++++++++++++++++
26
+ drivers/staging/fsl_ppfe/pfe_firmware.c         |  314 +++
27
+ drivers/staging/fsl_ppfe/pfe_hal.c              | 1516 ++++++++++++++
28
+ drivers/staging/fsl_ppfe/pfe_hif.c              | 1094 ++++++++++
29
+ drivers/staging/fsl_ppfe/pfe_hif_lib.c          |  638 ++++++
30
+ drivers/staging/fsl_ppfe/pfe_hw.c               |  176 ++
31
+ drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c |  394 ++++
32
+ drivers/staging/fsl_ppfe/pfe_mod.c              |  141 ++
33
+ drivers/staging/fsl_ppfe/pfe_sysfs.c            |  818 ++++++++
34
+ 14 files changed, 7915 insertions(+)
35
+ create mode 100644 drivers/staging/fsl_ppfe/Kconfig
36
+ create mode 100644 drivers/staging/fsl_ppfe/Makefile
37
+ create mode 100644 drivers/staging/fsl_ppfe/TODO
38
+ create mode 100644 drivers/staging/fsl_ppfe/pfe_ctrl.c
39
+ create mode 100644 drivers/staging/fsl_ppfe/pfe_debugfs.c
40
+ create mode 100644 drivers/staging/fsl_ppfe/pfe_eth.c
41
+ create mode 100644 drivers/staging/fsl_ppfe/pfe_firmware.c
42
+ create mode 100644 drivers/staging/fsl_ppfe/pfe_hal.c
43
+ create mode 100644 drivers/staging/fsl_ppfe/pfe_hif.c
44
+ create mode 100644 drivers/staging/fsl_ppfe/pfe_hif_lib.c
45
+ create mode 100644 drivers/staging/fsl_ppfe/pfe_hw.c
46
+ create mode 100644 drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c
47
+ create mode 100644 drivers/staging/fsl_ppfe/pfe_mod.c
48
+ create mode 100644 drivers/staging/fsl_ppfe/pfe_sysfs.c
49
+
50
+diff --git a/drivers/staging/fsl_ppfe/Kconfig b/drivers/staging/fsl_ppfe/Kconfig
51
+new file mode 100644
52
+index 000000000000..e40964354cad
53
+--- /dev/null
54
+@@ -0,0 +1,20 @@
55
++#
56
++# Freescale Programmable Packet Forwarding Engine driver
57
++#
58
++config FSL_PPFE
59
++	bool "Freescale PPFE Driver"
60
++	default n
61
++	---help---
62
++	Freescale LS1012A SoC has a Programmable Packet Forwarding Engine.
63
++	It provides two high performance ethernet interfaces.
64
++	This driver initializes, programs and controls the PPFE.
65
++	Use this driver to enable network connectivity on LS1012A platforms.
66
++
67
++if FSL_PPFE
68
++
69
++config FSL_PPFE_UTIL_DISABLED
70
++	bool "Disable PPFE UTIL Processor Engine"
71
++	---help---
72
++	UTIL PE has to be enabled only if required.
73
++
74
++endif # FSL_PPFE
75
+diff --git a/drivers/staging/fsl_ppfe/Makefile b/drivers/staging/fsl_ppfe/Makefile
76
+new file mode 100644
77
+index 000000000000..07cd351b9221
78
+--- /dev/null
79
+@@ -0,0 +1,19 @@
80
++#
81
++# Makefile for Freesecale PPFE driver
82
++#
83
++
84
++ccflags-y +=  -I$(src)/include  -I$(src)
85
++
86
++obj-m += pfe.o
87
++
88
++pfe-y += pfe_mod.o \
89
++	pfe_hw.o \
90
++	pfe_firmware.o \
91
++	pfe_ctrl.o \
92
++	pfe_hif.o \
93
++	pfe_hif_lib.o\
94
++	pfe_eth.o \
95
++	pfe_sysfs.o \
96
++	pfe_debugfs.o \
97
++	pfe_ls1012a_platform.o \
98
++	pfe_hal.o
99
+diff --git a/drivers/staging/fsl_ppfe/TODO b/drivers/staging/fsl_ppfe/TODO
100
+new file mode 100644
101
+index 000000000000..43c48ccdf81a
102
+--- /dev/null
103
+@@ -0,0 +1,2 @@
104
++TODO:
105
++	- provide pfe pe monitoring support
106
+diff --git a/drivers/staging/fsl_ppfe/pfe_ctrl.c b/drivers/staging/fsl_ppfe/pfe_ctrl.c
107
+new file mode 100644
108
+index 000000000000..dfa8547cb7b4
109
+--- /dev/null
110
+@@ -0,0 +1,238 @@
111
++/*
112
++ * Copyright 2015-2016 Freescale Semiconductor, Inc.
113
++ * Copyright 2017 NXP
114
++ *
115
++ * This program is free software; you can redistribute it and/or modify
116
++ * it under the terms of the GNU General Public License as published by
117
++ * the Free Software Foundation; either version 2 of the License, or
118
++ * (at your option) any later version.
119
++ *
120
++ * This program is distributed in the hope that it will be useful,
121
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
122
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
123
++ * GNU General Public License for more details.
124
++ *
125
++ * You should have received a copy of the GNU General Public License
126
++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
127
++ */
128
++
129
++#include <linux/kernel.h>
130
++#include <linux/sched.h>
131
++#include <linux/module.h>
132
++#include <linux/list.h>
133
++#include <linux/kthread.h>
134
++
135
++#include "pfe_mod.h"
136
++#include "pfe_ctrl.h"
137
++
138
++#define TIMEOUT_MS	1000
139
++
140
++int relax(unsigned long end)
141
++{
142
++	if (time_after(jiffies, end)) {
143
++		if (time_after(jiffies, end + (TIMEOUT_MS * HZ) / 1000))
144
++			return -1;
145
++
146
++		if (need_resched())
147
++			schedule();
148
++	}
149
++
150
++	return 0;
151
++}
152
++
153
++void pfe_ctrl_suspend(struct pfe_ctrl *ctrl)
154
++{
155
++	int id;
156
++
157
++	mutex_lock(&ctrl->mutex);
158
++
159
++	for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++)
160
++		pe_dmem_write(id, cpu_to_be32(0x1), CLASS_DM_RESUME, 4);
161
++
162
++	for (id = TMU0_ID; id <= TMU_MAX_ID; id++) {
163
++		if (id == TMU2_ID)
164
++			continue;
165
++		pe_dmem_write(id, cpu_to_be32(0x1), TMU_DM_RESUME, 4);
166
++	}
167
++
168
++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
169
++	pe_dmem_write(UTIL_ID, cpu_to_be32(0x1), UTIL_DM_RESUME, 4);
170
++#endif
171
++	mutex_unlock(&ctrl->mutex);
172
++}
173
++
174
++void pfe_ctrl_resume(struct pfe_ctrl *ctrl)
175
++{
176
++	int pe_mask = CLASS_MASK | TMU_MASK;
177
++
178
++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
179
++	pe_mask |= UTIL_MASK;
180
++#endif
181
++	mutex_lock(&ctrl->mutex);
182
++	pe_start(&pfe->ctrl, pe_mask);
183
++	mutex_unlock(&ctrl->mutex);
184
++}
185
++
186
++/* PE sync stop.
187
++ * Stops packet processing for a list of PE's (specified using a bitmask).
188
++ * The caller must hold ctrl->mutex.
189
++ *
190
++ * @param ctrl		Control context
191
++ * @param pe_mask	Mask of PE id's to stop
192
++ *
193
++ */
194
++int pe_sync_stop(struct pfe_ctrl *ctrl, int pe_mask)
195
++{
196
++	struct pe_sync_mailbox *mbox;
197
++	int pe_stopped = 0;
198
++	unsigned long end = jiffies + 2;
199
++	int i;
200
++
201
++	pe_mask &= 0x2FF;  /*Exclude Util + TMU2 */
202
++
203
++	for (i = 0; i < MAX_PE; i++)
204
++		if (pe_mask & (1 << i)) {
205
++			mbox = (void *)ctrl->sync_mailbox_baseaddr[i];
206
++
207
++			pe_dmem_write(i, cpu_to_be32(0x1), (unsigned
208
++					long)&mbox->stop, 4);
209
++		}
210
++
211
++	while (pe_stopped != pe_mask) {
212
++		for (i = 0; i < MAX_PE; i++)
213
++			if ((pe_mask & (1 << i)) && !(pe_stopped & (1 << i))) {
214
++				mbox = (void *)ctrl->sync_mailbox_baseaddr[i];
215
++
216
++				if (pe_dmem_read(i, (unsigned
217
++					long)&mbox->stopped, 4) &
218
++					cpu_to_be32(0x1))
219
++					pe_stopped |= (1 << i);
220
++			}
221
++
222
++		if (relax(end) < 0)
223
++			goto err;
224
++	}
225
++
226
++	return 0;
227
++
228
++err:
229
++	pr_err("%s: timeout, %x %x\n", __func__, pe_mask, pe_stopped);
230
++
231
++	for (i = 0; i < MAX_PE; i++)
232
++		if (pe_mask & (1 << i)) {
233
++			mbox = (void *)ctrl->sync_mailbox_baseaddr[i];
234
++
235
++			pe_dmem_write(i, cpu_to_be32(0x0), (unsigned
236
++					long)&mbox->stop, 4);
237
++	}
238
++
239
++	return -EIO;
240
++}
241
++
242
++/* PE start.
243
++ * Starts packet processing for a list of PE's (specified using a bitmask).
244
++ * The caller must hold ctrl->mutex.
245
++ *
246
++ * @param ctrl		Control context
247
++ * @param pe_mask	Mask of PE id's to start
248
++ *
249
++ */
250
++void pe_start(struct pfe_ctrl *ctrl, int pe_mask)
251
++{
252
++	struct pe_sync_mailbox *mbox;
253
++	int i;
254
++
255
++	for (i = 0; i < MAX_PE; i++)
256
++		if (pe_mask & (1 << i)) {
257
++			mbox = (void *)ctrl->sync_mailbox_baseaddr[i];
258
++
259
++			pe_dmem_write(i, cpu_to_be32(0x0), (unsigned
260
++					long)&mbox->stop, 4);
261
++		}
262
++}
263
++
264
++/* This function will ensure all PEs are put in to idle state */
265
++int pe_reset_all(struct pfe_ctrl *ctrl)
266
++{
267
++	struct pe_sync_mailbox *mbox;
268
++	int pe_stopped = 0;
269
++	unsigned long end = jiffies + 2;
270
++	int i;
271
++	int pe_mask  = CLASS_MASK | TMU_MASK;
272
++
273
++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
274
++	pe_mask |= UTIL_MASK;
275
++#endif
276
++
277
++	for (i = 0; i < MAX_PE; i++)
278
++		if (pe_mask & (1 << i)) {
279
++			mbox = (void *)ctrl->sync_mailbox_baseaddr[i];
280
++
281
++			pe_dmem_write(i, cpu_to_be32(0x2), (unsigned
282
++					long)&mbox->stop, 4);
283
++		}
284
++
285
++	while (pe_stopped != pe_mask) {
286
++		for (i = 0; i < MAX_PE; i++)
287
++			if ((pe_mask & (1 << i)) && !(pe_stopped & (1 << i))) {
288
++				mbox = (void *)ctrl->sync_mailbox_baseaddr[i];
289
++
290
++				if (pe_dmem_read(i, (unsigned long)
291
++							&mbox->stopped, 4) &
292
++						cpu_to_be32(0x1))
293
++					pe_stopped |= (1 << i);
294
++			}
295
++
296
++		if (relax(end) < 0)
297
++			goto err;
298
++	}
299
++
300
++	return 0;
301
++
302
++err:
303
++	pr_err("%s: timeout, %x %x\n", __func__, pe_mask, pe_stopped);
304
++	return -EIO;
305
++}
306
++
307
++int pfe_ctrl_init(struct pfe *pfe)
308
++{
309
++	struct pfe_ctrl *ctrl = &pfe->ctrl;
310
++	int id;
311
++
312
++	pr_info("%s\n", __func__);
313
++
314
++	mutex_init(&ctrl->mutex);
315
++	spin_lock_init(&ctrl->lock);
316
++
317
++	for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++) {
318
++		ctrl->sync_mailbox_baseaddr[id] = CLASS_DM_SYNC_MBOX;
319
++		ctrl->msg_mailbox_baseaddr[id] = CLASS_DM_MSG_MBOX;
320
++	}
321
++
322
++	for (id = TMU0_ID; id <= TMU_MAX_ID; id++) {
323
++		if (id == TMU2_ID)
324
++			continue;
325
++		ctrl->sync_mailbox_baseaddr[id] = TMU_DM_SYNC_MBOX;
326
++		ctrl->msg_mailbox_baseaddr[id] = TMU_DM_MSG_MBOX;
327
++	}
328
++
329
++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
330
++	ctrl->sync_mailbox_baseaddr[UTIL_ID] = UTIL_DM_SYNC_MBOX;
331
++	ctrl->msg_mailbox_baseaddr[UTIL_ID] = UTIL_DM_MSG_MBOX;
332
++#endif
333
++
334
++	ctrl->hash_array_baseaddr = pfe->ddr_baseaddr + ROUTE_TABLE_BASEADDR;
335
++	ctrl->hash_array_phys_baseaddr = pfe->ddr_phys_baseaddr +
336
++						ROUTE_TABLE_BASEADDR;
337
++
338
++	ctrl->dev = pfe->dev;
339
++
340
++	pr_info("%s finished\n", __func__);
341
++
342
++	return 0;
343
++}
344
++
345
++void pfe_ctrl_exit(struct pfe *pfe)
346
++{
347
++	pr_info("%s\n", __func__);
348
++}
349
+diff --git a/drivers/staging/fsl_ppfe/pfe_debugfs.c b/drivers/staging/fsl_ppfe/pfe_debugfs.c
350
+new file mode 100644
351
+index 000000000000..4156610ddbb3
352
+--- /dev/null
353
+@@ -0,0 +1,111 @@
354
++/*
355
++ * Copyright 2015-2016 Freescale Semiconductor, Inc.
356
++ * Copyright 2017 NXP
357
++ *
358
++ * This program is free software; you can redistribute it and/or modify
359
++ * it under the terms of the GNU General Public License as published by
360
++ * the Free Software Foundation; either version 2 of the License, or
361
++ * (at your option) any later version.
362
++ *
363
++ * This program is distributed in the hope that it will be useful,
364
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
365
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
366
++ * GNU General Public License for more details.
367
++ *
368
++ * You should have received a copy of the GNU General Public License
369
++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
370
++ */
371
++
372
++#include <linux/module.h>
373
++#include <linux/debugfs.h>
374
++#include <linux/platform_device.h>
375
++
376
++#include "pfe_mod.h"
377
++
378
++static int dmem_show(struct seq_file *s, void *unused)
379
++{
380
++	u32 dmem_addr, val;
381
++	int id = (long int)s->private;
382
++	int i;
383
++
384
++	for (dmem_addr = 0; dmem_addr < CLASS_DMEM_SIZE; dmem_addr += 8 * 4) {
385
++		seq_printf(s, "%04x:", dmem_addr);
386
++
387
++		for (i = 0; i < 8; i++) {
388
++			val = pe_dmem_read(id, dmem_addr + i * 4, 4);
389
++			seq_printf(s, " %02x %02x %02x %02x", val & 0xff,
390
++				   (val >> 8) & 0xff, (val >> 16) & 0xff,
391
++				   (val >> 24) & 0xff);
392
++		}
393
++
394
++		seq_puts(s, "\n");
395
++	}
396
++
397
++	return 0;
398
++}
399
++
400
++static int dmem_open(struct inode *inode, struct file *file)
401
++{
402
++	return single_open(file, dmem_show, inode->i_private);
403
++}
404
++
405
++static const struct file_operations dmem_fops = {
406
++	.open		= dmem_open,
407
++	.read		= seq_read,
408
++	.llseek		= seq_lseek,
409
++	.release	= single_release,
410
++};
411
++
412
++int pfe_debugfs_init(struct pfe *pfe)
413
++{
414
++	struct dentry *d;
415
++
416
++	pr_info("%s\n", __func__);
417
++
418
++	pfe->dentry = debugfs_create_dir("pfe", NULL);
419
++	if (IS_ERR_OR_NULL(pfe->dentry))
420
++		goto err_dir;
421
++
422
++	d = debugfs_create_file("pe0_dmem", 0444, pfe->dentry, (void *)0,
423
++				&dmem_fops);
424
++	if (IS_ERR_OR_NULL(d))
425
++		goto err_pe;
426
++
427
++	d = debugfs_create_file("pe1_dmem", 0444, pfe->dentry, (void *)1,
428
++				&dmem_fops);
429
++	if (IS_ERR_OR_NULL(d))
430
++		goto err_pe;
431
++
432
++	d = debugfs_create_file("pe2_dmem", 0444, pfe->dentry, (void *)2,
433
++				&dmem_fops);
434
++	if (IS_ERR_OR_NULL(d))
435
++		goto err_pe;
436
++
437
++	d = debugfs_create_file("pe3_dmem", 0444, pfe->dentry, (void *)3,
438
++				&dmem_fops);
439
++	if (IS_ERR_OR_NULL(d))
440
++		goto err_pe;
441
++
442
++	d = debugfs_create_file("pe4_dmem", 0444, pfe->dentry, (void *)4,
443
++				&dmem_fops);
444
++	if (IS_ERR_OR_NULL(d))
445
++		goto err_pe;
446
++
447
++	d = debugfs_create_file("pe5_dmem", 0444, pfe->dentry, (void *)5,
448
++				&dmem_fops);
449
++	if (IS_ERR_OR_NULL(d))
450
++		goto err_pe;
451
++
452
++	return 0;
453
++
454
++err_pe:
455
++	debugfs_remove_recursive(pfe->dentry);
456
++
457
++err_dir:
458
++	return -1;
459
++}
460
++
461
++void pfe_debugfs_exit(struct pfe *pfe)
462
++{
463
++	debugfs_remove_recursive(pfe->dentry);
464
++}
465
+diff --git a/drivers/staging/fsl_ppfe/pfe_eth.c b/drivers/staging/fsl_ppfe/pfe_eth.c
466
+new file mode 100644
467
+index 000000000000..5aa718be42c2
468
+--- /dev/null
469
+@@ -0,0 +1,2434 @@
470
++/*
471
++ * Copyright 2015-2016 Freescale Semiconductor, Inc.
472
++ * Copyright 2017 NXP
473
++ *
474
++ * This program is free software; you can redistribute it and/or modify
475
++ * it under the terms of the GNU General Public License as published by
476
++ * the Free Software Foundation; either version 2 of the License, or
477
++ * (at your option) any later version.
478
++ *
479
++ * This program is distributed in the hope that it will be useful,
480
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
481
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
482
++ * GNU General Public License for more details.
483
++ *
484
++ * You should have received a copy of the GNU General Public License
485
++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
486
++ */
487
++
488
++/* @pfe_eth.c.
489
++ *  Ethernet driver for to handle exception path for PFE.
490
++ *  - uses HIF functions to send/receive packets.
491
++ *  - uses ctrl function to start/stop interfaces.
492
++ *  - uses direct register accesses to control phy operation.
493
++ */
494
++#include <linux/version.h>
495
++#include <linux/kernel.h>
496
++#include <linux/interrupt.h>
497
++#include <linux/dma-mapping.h>
498
++#include <linux/dmapool.h>
499
++#include <linux/netdevice.h>
500
++#include <linux/etherdevice.h>
501
++#include <linux/ethtool.h>
502
++#include <linux/mii.h>
503
++#include <linux/phy.h>
504
++#include <linux/timer.h>
505
++#include <linux/hrtimer.h>
506
++#include <linux/platform_device.h>
507
++
508
++#include <net/ip.h>
509
++#include <net/sock.h>
510
++
511
++#include <linux/io.h>
512
++#include <asm/irq.h>
513
++#include <linux/delay.h>
514
++#include <linux/regmap.h>
515
++#include <linux/i2c.h>
516
++
517
++#if defined(CONFIG_NF_CONNTRACK_MARK)
518
++#include <net/netfilter/nf_conntrack.h>
519
++#endif
520
++
521
++#include "pfe_mod.h"
522
++#include "pfe_eth.h"
523
++
524
++static void *cbus_emac_base[3];
525
++static void *cbus_gpi_base[3];
526
++
527
++/* Forward Declaration */
528
++static void pfe_eth_exit_one(struct pfe_eth_priv_s *priv);
529
++static void pfe_eth_flush_tx(struct pfe_eth_priv_s *priv);
530
++static void pfe_eth_flush_txQ(struct pfe_eth_priv_s *priv, int tx_q_num, int
531
++				from_tx, int n_desc);
532
++
533
++unsigned int gemac_regs[] = {
534
++	0x0004, /* Interrupt event */
535
++	0x0008, /* Interrupt mask */
536
++	0x0024, /* Ethernet control */
537
++	0x0064, /* MIB Control/Status */
538
++	0x0084, /* Receive control/status */
539
++	0x00C4, /* Transmit control */
540
++	0x00E4, /* Physical address low */
541
++	0x00E8, /* Physical address high */
542
++	0x0144, /* Transmit FIFO Watermark and Store and Forward Control*/
543
++	0x0190, /* Receive FIFO Section Full Threshold */
544
++	0x01A0, /* Transmit FIFO Section Empty Threshold */
545
++	0x01B0, /* Frame Truncation Length */
546
++};
547
++
548
++/********************************************************************/
549
++/*                   SYSFS INTERFACE				    */
550
++/********************************************************************/
551
++
552
++#ifdef PFE_ETH_NAPI_STATS
553
++/*
554
++ * pfe_eth_show_napi_stats
555
++ */
556
++static ssize_t pfe_eth_show_napi_stats(struct device *dev,
557
++				       struct device_attribute *attr,
558
++				       char *buf)
559
++{
560
++	struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev));
561
++	ssize_t len = 0;
562
++
563
++	len += sprintf(buf + len, "sched:  %u\n",
564
++			priv->napi_counters[NAPI_SCHED_COUNT]);
565
++	len += sprintf(buf + len, "poll:   %u\n",
566
++			priv->napi_counters[NAPI_POLL_COUNT]);
567
++	len += sprintf(buf + len, "packet: %u\n",
568
++			priv->napi_counters[NAPI_PACKET_COUNT]);
569
++	len += sprintf(buf + len, "budget: %u\n",
570
++			priv->napi_counters[NAPI_FULL_BUDGET_COUNT]);
571
++	len += sprintf(buf + len, "desc:   %u\n",
572
++			priv->napi_counters[NAPI_DESC_COUNT]);
573
++
574
++	return len;
575
++}
576
++
577
++/*
578
++ * pfe_eth_set_napi_stats
579
++ */
580
++static ssize_t pfe_eth_set_napi_stats(struct device *dev,
581
++				      struct device_attribute *attr,
582
++				      const char *buf, size_t count)
583
++{
584
++	struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev));
585
++
586
++	memset(priv->napi_counters, 0, sizeof(priv->napi_counters));
587
++
588
++	return count;
589
++}
590
++#endif
591
++#ifdef PFE_ETH_TX_STATS
592
++/* pfe_eth_show_tx_stats
593
++ *
594
++ */
595
++static ssize_t pfe_eth_show_tx_stats(struct device *dev,
596
++				     struct device_attribute *attr,
597
++				     char *buf)
598
++{
599
++	struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev));
600
++	ssize_t len = 0;
601
++	int i;
602
++
603
++	len += sprintf(buf + len, "TX queues stats:\n");
604
++
605
++	for (i = 0; i < emac_txq_cnt; i++) {
606
++		struct netdev_queue *tx_queue = netdev_get_tx_queue(priv->ndev,
607
++									i);
608
++
609
++		len += sprintf(buf + len, "\n");
610
++		__netif_tx_lock_bh(tx_queue);
611
++
612
++		hif_tx_lock(&pfe->hif);
613
++		len += sprintf(buf + len,
614
++				"Queue %2d :  credits               = %10d\n"
615
++				, i, hif_lib_tx_credit_avail(pfe, priv->id, i));
616
++		len += sprintf(buf + len,
617
++				 "            tx packets            = %10d\n"
618
++				,  pfe->tmu_credit.tx_packets[priv->id][i]);
619
++		hif_tx_unlock(&pfe->hif);
620
++
621
++		/* Don't output additionnal stats if queue never used */
622
++		if (!pfe->tmu_credit.tx_packets[priv->id][i])
623
++			goto skip;
624
++
625
++		len += sprintf(buf + len,
626
++				 "            clean_fail            = %10d\n"
627
++				, priv->clean_fail[i]);
628
++		len += sprintf(buf + len,
629
++				 "            stop_queue            = %10d\n"
630
++				, priv->stop_queue_total[i]);
631
++		len += sprintf(buf + len,
632
++				 "            stop_queue_hif        = %10d\n"
633
++				, priv->stop_queue_hif[i]);
634
++		len += sprintf(buf + len,
635
++				"            stop_queue_hif_client = %10d\n"
636
++				, priv->stop_queue_hif_client[i]);
637
++		len += sprintf(buf + len,
638
++				 "            stop_queue_credit     = %10d\n"
639
++				, priv->stop_queue_credit[i]);
640
++skip:
641
++		__netif_tx_unlock_bh(tx_queue);
642
++	}
643
++	return len;
644
++}
645
++
646
++/* pfe_eth_set_tx_stats
647
++ *
648
++ */
649
++static ssize_t pfe_eth_set_tx_stats(struct device *dev,
650
++				    struct device_attribute *attr,
651
++				    const char *buf, size_t count)
652
++{
653
++	struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev));
654
++	int i;
655
++
656
++	for (i = 0; i < emac_txq_cnt; i++) {
657
++		struct netdev_queue *tx_queue = netdev_get_tx_queue(priv->ndev,
658
++									i);
659
++
660
++		__netif_tx_lock_bh(tx_queue);
661
++		priv->clean_fail[i] = 0;
662
++		priv->stop_queue_total[i] = 0;
663
++		priv->stop_queue_hif[i] = 0;
664
++		priv->stop_queue_hif_client[i] = 0;
665
++		priv->stop_queue_credit[i] = 0;
666
++		__netif_tx_unlock_bh(tx_queue);
667
++	}
668
++
669
++	return count;
670
++}
671
++#endif
672
++/* pfe_eth_show_txavail
673
++ *
674
++ */
675
++static ssize_t pfe_eth_show_txavail(struct device *dev,
676
++				    struct device_attribute *attr,
677
++				    char *buf)
678
++{
679
++	struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev));
680
++	ssize_t len = 0;
681
++	int i;
682
++
683
++	for (i = 0; i < emac_txq_cnt; i++) {
684
++		struct netdev_queue *tx_queue = netdev_get_tx_queue(priv->ndev,
685
++									i);
686
++
687
++		__netif_tx_lock_bh(tx_queue);
688
++
689
++		len += sprintf(buf + len, "%d",
690
++				hif_lib_tx_avail(&priv->client, i));
691
++
692
++		__netif_tx_unlock_bh(tx_queue);
693
++
694
++		if (i == (emac_txq_cnt - 1))
695
++			len += sprintf(buf + len, "\n");
696
++		else
697
++			len += sprintf(buf + len, " ");
698
++	}
699
++
700
++	return len;
701
++}
702
++
703
++/* pfe_eth_show_default_priority
704
++ *
705
++ */
706
++static ssize_t pfe_eth_show_default_priority(struct device *dev,
707
++					     struct device_attribute *attr,
708
++						char *buf)
709
++{
710
++	struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev));
711
++	unsigned long flags;
712
++	int rc;
713
++
714
++	spin_lock_irqsave(&priv->lock, flags);
715
++	rc = sprintf(buf, "%d\n", priv->default_priority);
716
++	spin_unlock_irqrestore(&priv->lock, flags);
717
++
718
++	return rc;
719
++}
720
++
721
++/* pfe_eth_set_default_priority
722
++ *
723
++ */
724
++
725
++static ssize_t pfe_eth_set_default_priority(struct device *dev,
726
++					    struct device_attribute *attr,
727
++					    const char *buf, size_t count)
728
++{
729
++	struct pfe_eth_priv_s *priv = netdev_priv(to_net_dev(dev));
730
++	unsigned long flags;
731
++
732
++	spin_lock_irqsave(&priv->lock, flags);
733
++	priv->default_priority = kstrtoul(buf, 0, 0);
734
++	spin_unlock_irqrestore(&priv->lock, flags);
735
++
736
++	return count;
737
++}
738
++
739
++static DEVICE_ATTR(txavail, 0444, pfe_eth_show_txavail, NULL);
740
++static DEVICE_ATTR(default_priority, 0644, pfe_eth_show_default_priority,
741
++			pfe_eth_set_default_priority);
742
++
743
++#ifdef PFE_ETH_NAPI_STATS
744
++static DEVICE_ATTR(napi_stats, 0644, pfe_eth_show_napi_stats,
745
++			pfe_eth_set_napi_stats);
746
++#endif
747
++
748
++#ifdef PFE_ETH_TX_STATS
749
++static DEVICE_ATTR(tx_stats, 0644, pfe_eth_show_tx_stats,
750
++			pfe_eth_set_tx_stats);
751
++#endif
752
++
753
++/*
754
++ * pfe_eth_sysfs_init
755
++ *
756
++ */
757
++static int pfe_eth_sysfs_init(struct net_device *ndev)
758
++{
759
++	struct pfe_eth_priv_s *priv = netdev_priv(ndev);
760
++	int err;
761
++
762
++	/* Initialize the default values */
763
++
764
++	/*
765
++	 * By default, packets without conntrack will use this default high
766
++	 * priority queue
767
++	 */
768
++	priv->default_priority = 15;
769
++
770
++	/* Create our sysfs files */
771
++	err = device_create_file(&ndev->dev, &dev_attr_default_priority);
772
++	if (err) {
773
++		netdev_err(ndev,
774
++			   "failed to create default_priority sysfs files\n");
775
++		goto err_priority;
776
++	}
777
++
778
++	err = device_create_file(&ndev->dev, &dev_attr_txavail);
779
++	if (err) {
780
++		netdev_err(ndev,
781
++			   "failed to create default_priority sysfs files\n");
782
++		goto err_txavail;
783
++	}
784
++
785
++#ifdef PFE_ETH_NAPI_STATS
786
++	err = device_create_file(&ndev->dev, &dev_attr_napi_stats);
787
++	if (err) {
788
++		netdev_err(ndev, "failed to create napi stats sysfs files\n");
789
++		goto err_napi;
790
++	}
791
++#endif
792
++
793
++#ifdef PFE_ETH_TX_STATS
794
++	err = device_create_file(&ndev->dev, &dev_attr_tx_stats);
795
++	if (err) {
796
++		netdev_err(ndev, "failed to create tx stats sysfs files\n");
797
++		goto err_tx;
798
++	}
799
++#endif
800
++
801
++	return 0;
802
++
803
++#ifdef PFE_ETH_TX_STATS
804
++err_tx:
805
++#endif
806
++#ifdef PFE_ETH_NAPI_STATS
807
++	device_remove_file(&ndev->dev, &dev_attr_napi_stats);
808
++
809
++err_napi:
810
++#endif
811
++	device_remove_file(&ndev->dev, &dev_attr_txavail);
812
++
813
++err_txavail:
814
++	device_remove_file(&ndev->dev, &dev_attr_default_priority);
815
++
816
++err_priority:
817
++	return -1;
818
++}
819
++
820
++/* pfe_eth_sysfs_exit
821
++ *
822
++ */
823
++void pfe_eth_sysfs_exit(struct net_device *ndev)
824
++{
825
++#ifdef PFE_ETH_TX_STATS
826
++	device_remove_file(&ndev->dev, &dev_attr_tx_stats);
827
++#endif
828
++
829
++#ifdef PFE_ETH_NAPI_STATS
830
++	device_remove_file(&ndev->dev, &dev_attr_napi_stats);
831
++#endif
832
++	device_remove_file(&ndev->dev, &dev_attr_txavail);
833
++	device_remove_file(&ndev->dev, &dev_attr_default_priority);
834
++}
835
++
836
++/*************************************************************************/
837
++/*		ETHTOOL INTERCAE					 */
838
++/*************************************************************************/
839
++
840
++/*MTIP GEMAC */
841
++static const struct fec_stat {
842
++	char name[ETH_GSTRING_LEN];
843
++	u16 offset;
844
++} fec_stats[] = {
845
++	/* RMON TX */
846
++	{ "tx_dropped", RMON_T_DROP },
847
++	{ "tx_packets", RMON_T_PACKETS },
848
++	{ "tx_broadcast", RMON_T_BC_PKT },
849
++	{ "tx_multicast", RMON_T_MC_PKT },
850
++	{ "tx_crc_errors", RMON_T_CRC_ALIGN },
851
++	{ "tx_undersize", RMON_T_UNDERSIZE },
852
++	{ "tx_oversize", RMON_T_OVERSIZE },
853
++	{ "tx_fragment", RMON_T_FRAG },
854
++	{ "tx_jabber", RMON_T_JAB },
855
++	{ "tx_collision", RMON_T_COL },
856
++	{ "tx_64byte", RMON_T_P64 },
857
++	{ "tx_65to127byte", RMON_T_P65TO127 },
858
++	{ "tx_128to255byte", RMON_T_P128TO255 },
859
++	{ "tx_256to511byte", RMON_T_P256TO511 },
860
++	{ "tx_512to1023byte", RMON_T_P512TO1023 },
861
++	{ "tx_1024to2047byte", RMON_T_P1024TO2047 },
862
++	{ "tx_GTE2048byte", RMON_T_P_GTE2048 },
863
++	{ "tx_octets", RMON_T_OCTETS },
864
++
865
++	/* IEEE TX */
866
++	{ "IEEE_tx_drop", IEEE_T_DROP },
867
++	{ "IEEE_tx_frame_ok", IEEE_T_FRAME_OK },
868
++	{ "IEEE_tx_1col", IEEE_T_1COL },
869
++	{ "IEEE_tx_mcol", IEEE_T_MCOL },
870
++	{ "IEEE_tx_def", IEEE_T_DEF },
871
++	{ "IEEE_tx_lcol", IEEE_T_LCOL },
872
++	{ "IEEE_tx_excol", IEEE_T_EXCOL },
873
++	{ "IEEE_tx_macerr", IEEE_T_MACERR },
874
++	{ "IEEE_tx_cserr", IEEE_T_CSERR },
875
++	{ "IEEE_tx_sqe", IEEE_T_SQE },
876
++	{ "IEEE_tx_fdxfc", IEEE_T_FDXFC },
877
++	{ "IEEE_tx_octets_ok", IEEE_T_OCTETS_OK },
878
++
879
++	/* RMON RX */
880
++	{ "rx_packets", RMON_R_PACKETS },
881
++	{ "rx_broadcast", RMON_R_BC_PKT },
882
++	{ "rx_multicast", RMON_R_MC_PKT },
883
++	{ "rx_crc_errors", RMON_R_CRC_ALIGN },
884
++	{ "rx_undersize", RMON_R_UNDERSIZE },
885
++	{ "rx_oversize", RMON_R_OVERSIZE },
886
++	{ "rx_fragment", RMON_R_FRAG },
887
++	{ "rx_jabber", RMON_R_JAB },
888
++	{ "rx_64byte", RMON_R_P64 },
889
++	{ "rx_65to127byte", RMON_R_P65TO127 },
890
++	{ "rx_128to255byte", RMON_R_P128TO255 },
891
++	{ "rx_256to511byte", RMON_R_P256TO511 },
892
++	{ "rx_512to1023byte", RMON_R_P512TO1023 },
893
++	{ "rx_1024to2047byte", RMON_R_P1024TO2047 },
894
++	{ "rx_GTE2048byte", RMON_R_P_GTE2048 },
895
++	{ "rx_octets", RMON_R_OCTETS },
896
++
897
++	/* IEEE RX */
898
++	{ "IEEE_rx_drop", IEEE_R_DROP },
899
++	{ "IEEE_rx_frame_ok", IEEE_R_FRAME_OK },
900
++	{ "IEEE_rx_crc", IEEE_R_CRC },
901
++	{ "IEEE_rx_align", IEEE_R_ALIGN },
902
++	{ "IEEE_rx_macerr", IEEE_R_MACERR },
903
++	{ "IEEE_rx_fdxfc", IEEE_R_FDXFC },
904
++	{ "IEEE_rx_octets_ok", IEEE_R_OCTETS_OK },
905
++};
906
++
907
++static void pfe_eth_fill_stats(struct net_device *ndev, struct ethtool_stats
908
++				*stats, u64 *data)
909
++{
910
++	struct pfe_eth_priv_s *priv = netdev_priv(ndev);
911
++	int i;
912
++
913
++	for (i = 0; i < ARRAY_SIZE(fec_stats); i++)
914
++		data[i] = readl(priv->EMAC_baseaddr + fec_stats[i].offset);
915
++}
916
++
917
++static void pfe_eth_gstrings(struct net_device *netdev,
918
++			     u32 stringset, u8 *data)
919
++{
920
++	int i;
921
++
922
++	switch (stringset) {
923
++	case ETH_SS_STATS:
924
++		for (i = 0; i < ARRAY_SIZE(fec_stats); i++)
925
++			memcpy(data + i * ETH_GSTRING_LEN,
926
++			       fec_stats[i].name, ETH_GSTRING_LEN);
927
++		break;
928
++	}
929
++}
930
++
931
++static int pfe_eth_stats_count(struct net_device *ndev, int sset)
932
++{
933
++	switch (sset) {
934
++	case ETH_SS_STATS:
935
++		return ARRAY_SIZE(fec_stats);
936
++	default:
937
++		return -EOPNOTSUPP;
938
++	}
939
++}
940
++
941
++/*
942
++ * pfe_eth_gemac_reglen - Return the length of the register structure.
943
++ *
944
++ */
945
++static int pfe_eth_gemac_reglen(struct net_device *ndev)
946
++{
947
++	pr_info("%s()\n", __func__);
948
++	return (sizeof(gemac_regs) / sizeof(u32));
949
++}
950
++
951
++/*
952
++ * pfe_eth_gemac_get_regs - Return the gemac register structure.
953
++ *
954
++ */
955
++static void  pfe_eth_gemac_get_regs(struct net_device *ndev, struct ethtool_regs
956
++					*regs, void *regbuf)
957
++{
958
++	int i;
959
++
960
++	struct pfe_eth_priv_s *priv = netdev_priv(ndev);
961
++	u32 *buf = (u32 *)regbuf;
962
++
963
++	pr_info("%s()\n", __func__);
964
++	for (i = 0; i < sizeof(gemac_regs) / sizeof(u32); i++)
965
++		buf[i] = readl(priv->EMAC_baseaddr + gemac_regs[i]);
966
++}
967
++
968
++/*
969
++ * pfe_eth_set_wol - Set the magic packet option, in WoL register.
970
++ *
971
++ */
972
++static int pfe_eth_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
973
++{
974
++	struct pfe_eth_priv_s *priv = netdev_priv(ndev);
975
++
976
++	if (wol->wolopts & ~WAKE_MAGIC)
977
++		return -EOPNOTSUPP;
978
++
979
++	/* for MTIP we store wol->wolopts */
980
++	priv->wol = wol->wolopts;
981
++
982
++	device_set_wakeup_enable(&ndev->dev, wol->wolopts & WAKE_MAGIC);
983
++
984
++	return 0;
985
++}
986
++
987
++/*
988
++ *
989
++ * pfe_eth_get_wol - Get the WoL options.
990
++ *
991
++ */
992
++static void pfe_eth_get_wol(struct net_device *ndev, struct ethtool_wolinfo
993
++				*wol)
994
++{
995
++	struct pfe_eth_priv_s *priv = netdev_priv(ndev);
996
++
997
++	wol->supported = WAKE_MAGIC;
998
++	wol->wolopts = 0;
999
++
1000
++	if (priv->wol & WAKE_MAGIC)
1001
++		wol->wolopts = WAKE_MAGIC;
1002
++
1003
++	memset(&wol->sopass, 0, sizeof(wol->sopass));
1004
++}
1005
++
1006
++/*
1007
++ * pfe_eth_get_drvinfo -  Fills in the drvinfo structure with some basic info
1008
++ *
1009
++ */
1010
++static void pfe_eth_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo
1011
++				*drvinfo)
1012
++{
1013
++	strlcpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
1014
++	strlcpy(drvinfo->version, DRV_VERSION, sizeof(drvinfo->version));
1015
++	strlcpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version));
1016
++	strlcpy(drvinfo->bus_info, "N/A", sizeof(drvinfo->bus_info));
1017
++}
1018
++
1019
++/*
1020
++ * pfe_eth_set_settings - Used to send commands to PHY.
1021
++ *
1022
++ */
1023
++static int pfe_eth_set_settings(struct net_device *ndev,
1024
++				const struct ethtool_link_ksettings *cmd)
1025
++{
1026
++	struct pfe_eth_priv_s *priv = netdev_priv(ndev);
1027
++	struct phy_device *phydev = priv->phydev;
1028
++
1029
++	if (!phydev)
1030
++		return -ENODEV;
1031
++
1032
++	return phy_ethtool_ksettings_set(phydev, cmd);
1033
++}
1034
++
1035
++/*
1036
++ * pfe_eth_getsettings - Return the current settings in the ethtool_cmd
1037
++ * structure.
1038
++ *
1039
++ */
1040
++static int pfe_eth_get_settings(struct net_device *ndev,
1041
++				struct ethtool_link_ksettings *cmd)
1042
++{
1043
++	struct pfe_eth_priv_s *priv = netdev_priv(ndev);
1044
++	struct phy_device *phydev = priv->phydev;
1045
++
1046
++	if (!phydev)
1047
++		return -ENODEV;
1048
++
1049
++	return phy_ethtool_ksettings_get(phydev, cmd);
1050
++}
1051
++
1052
++/*
1053
++ * pfe_eth_get_msglevel - Gets the debug message mask.
1054
++ *
1055
++ */
1056
++static uint32_t pfe_eth_get_msglevel(struct net_device *ndev)
1057
++{
1058
++	struct pfe_eth_priv_s *priv = netdev_priv(ndev);
1059
++
1060
++	return priv->msg_enable;
1061
++}
1062
++
1063
++/*
1064
++ * pfe_eth_set_msglevel - Sets the debug message mask.
1065
++ *
1066
++ */
1067
++static void pfe_eth_set_msglevel(struct net_device *ndev, uint32_t data)
1068
++{
1069
++	struct pfe_eth_priv_s *priv = netdev_priv(ndev);
1070
++
1071
++	priv->msg_enable = data;
1072
++}
1073
++
1074
++#define HIF_RX_COAL_MAX_CLKS		(~(1 << 31))
1075
++#define HIF_RX_COAL_CLKS_PER_USEC	(pfe->ctrl.sys_clk / 1000)
1076
++#define HIF_RX_COAL_MAX_USECS		(HIF_RX_COAL_MAX_CLKS	/ \
1077
++						HIF_RX_COAL_CLKS_PER_USEC)
1078
++
1079
++/*
1080
++ * pfe_eth_set_coalesce - Sets rx interrupt coalescing timer.
1081
++ *
1082
++ */
1083
++static int pfe_eth_set_coalesce(struct net_device *ndev,
1084
++				struct ethtool_coalesce *ec)
1085
++{
1086
++	if (ec->rx_coalesce_usecs > HIF_RX_COAL_MAX_USECS)
1087
++		return -EINVAL;
1088
++
1089
++	if (!ec->rx_coalesce_usecs) {
1090
++		writel(0, HIF_INT_COAL);
1091
++		return 0;
1092
++	}
1093
++
1094
++	writel((ec->rx_coalesce_usecs * HIF_RX_COAL_CLKS_PER_USEC) |
1095
++			HIF_INT_COAL_ENABLE, HIF_INT_COAL);
1096
++
1097
++	return 0;
1098
++}
1099
++
1100
++/*
1101
++ * pfe_eth_get_coalesce - Gets rx interrupt coalescing timer value.
1102
++ *
1103
++ */
1104
++static int pfe_eth_get_coalesce(struct net_device *ndev,
1105
++				struct ethtool_coalesce *ec)
1106
++{
1107
++	int reg_val = readl(HIF_INT_COAL);
1108
++
1109
++	if (reg_val & HIF_INT_COAL_ENABLE)
1110
++		ec->rx_coalesce_usecs = (reg_val & HIF_RX_COAL_MAX_CLKS) /
1111
++						HIF_RX_COAL_CLKS_PER_USEC;
1112
++	else
1113
++		ec->rx_coalesce_usecs = 0;
1114
++
1115
++	return 0;
1116
++}
1117
++
1118
++/*
1119
++ * pfe_eth_set_pauseparam - Sets pause parameters
1120
++ *
1121
++ */
1122
++static int pfe_eth_set_pauseparam(struct net_device *ndev,
1123
++				  struct ethtool_pauseparam *epause)
1124
++{
1125
++	struct pfe_eth_priv_s *priv = netdev_priv(ndev);
1126
++
1127
++	if (epause->tx_pause != epause->rx_pause) {
1128
++		netdev_info(ndev,
1129
++			    "hardware only support enable/disable both tx and rx\n");
1130
++		return -EINVAL;
1131
++	}
1132
++
1133
++	priv->pause_flag = 0;
1134
++	priv->pause_flag |= epause->rx_pause ? PFE_PAUSE_FLAG_ENABLE : 0;
1135
++	priv->pause_flag |= epause->autoneg ? PFE_PAUSE_FLAG_AUTONEG : 0;
1136
++
1137
++	if (epause->rx_pause || epause->autoneg) {
1138
++		gemac_enable_pause_rx(priv->EMAC_baseaddr);
1139
++		writel((readl(priv->GPI_baseaddr + GPI_TX_PAUSE_TIME) |
1140
++					EGPI_PAUSE_ENABLE),
1141
++				priv->GPI_baseaddr + GPI_TX_PAUSE_TIME);
1142
++		if (priv->phydev) {
1143
++			priv->phydev->supported |= ADVERTISED_Pause |
1144
++							ADVERTISED_Asym_Pause;
1145
++			priv->phydev->advertising |= ADVERTISED_Pause |
1146
++							ADVERTISED_Asym_Pause;
1147
++		}
1148
++	} else {
1149
++		gemac_disable_pause_rx(priv->EMAC_baseaddr);
1150
++		writel((readl(priv->GPI_baseaddr + GPI_TX_PAUSE_TIME) &
1151
++					~EGPI_PAUSE_ENABLE),
1152
++				priv->GPI_baseaddr + GPI_TX_PAUSE_TIME);
1153
++		if (priv->phydev) {
1154
++			priv->phydev->supported &= ~(ADVERTISED_Pause |
1155
++							ADVERTISED_Asym_Pause);
1156
++			priv->phydev->advertising &= ~(ADVERTISED_Pause |
1157
++							ADVERTISED_Asym_Pause);
1158
++		}
1159
++	}
1160
++
1161
++	return 0;
1162
++}
1163
++
1164
++/*
1165
++ * pfe_eth_get_pauseparam - Gets pause parameters
1166
++ *
1167
++ */
1168
++static void pfe_eth_get_pauseparam(struct net_device *ndev,
1169
++				   struct ethtool_pauseparam *epause)
1170
++{
1171
++	struct pfe_eth_priv_s *priv = netdev_priv(ndev);
1172
++
1173
++	epause->autoneg = (priv->pause_flag & PFE_PAUSE_FLAG_AUTONEG) != 0;
1174
++	epause->tx_pause = (priv->pause_flag & PFE_PAUSE_FLAG_ENABLE) != 0;
1175
++	epause->rx_pause = epause->tx_pause;
1176
++}
1177
++
1178
++/*
1179
++ * pfe_eth_get_hash
1180
++ */
1181
++#define PFE_HASH_BITS	6		/* #bits in hash */
1182
++#define CRC32_POLY	0xEDB88320
1183
++
1184
++static int pfe_eth_get_hash(u8 *addr)
1185
++{
1186
++	unsigned int i, bit, data, crc, hash;
1187
++
1188
++	/* calculate crc32 value of mac address */
1189
++	crc = 0xffffffff;
1190
++
1191
++	for (i = 0; i < 6; i++) {
1192
++		data = addr[i];
1193
++		for (bit = 0; bit < 8; bit++, data >>= 1) {
1194
++			crc = (crc >> 1) ^
1195
++				(((crc ^ data) & 1) ? CRC32_POLY : 0);
1196
++		}
1197
++	}
1198
++
1199
++	/*
1200
++	 * only upper 6 bits (PFE_HASH_BITS) are used
1201
++	 * which point to specific bit in the hash registers
1202
++	 */
1203
++	hash = (crc >> (32 - PFE_HASH_BITS)) & 0x3f;
1204
++
1205
++	return hash;
1206
++}
1207
++
1208
++const struct ethtool_ops pfe_ethtool_ops = {
1209
++	.get_drvinfo = pfe_eth_get_drvinfo,
1210
++	.get_regs_len = pfe_eth_gemac_reglen,
1211
++	.get_regs = pfe_eth_gemac_get_regs,
1212
++	.get_link = ethtool_op_get_link,
1213
++	.get_wol  = pfe_eth_get_wol,
1214
++	.set_wol  = pfe_eth_set_wol,
1215
++	.set_pauseparam = pfe_eth_set_pauseparam,
1216
++	.get_pauseparam = pfe_eth_get_pauseparam,
1217
++	.get_strings = pfe_eth_gstrings,
1218
++	.get_sset_count = pfe_eth_stats_count,
1219
++	.get_ethtool_stats = pfe_eth_fill_stats,
1220
++	.get_msglevel = pfe_eth_get_msglevel,
1221
++	.set_msglevel = pfe_eth_set_msglevel,
1222
++	.set_coalesce = pfe_eth_set_coalesce,
1223
++	.get_coalesce = pfe_eth_get_coalesce,
1224
++	.get_link_ksettings = pfe_eth_get_settings,
1225
++	.set_link_ksettings = pfe_eth_set_settings,
1226
++};
1227
++
1228
++/* pfe_eth_mdio_reset
1229
++ */
1230
++int pfe_eth_mdio_reset(struct mii_bus *bus)
1231
++{
1232
++	struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv;
1233
++	u32 phy_speed;
1234
++
1235
++	netif_info(priv, hw, priv->ndev, "%s\n", __func__);
1236
++
1237
++	mutex_lock(&bus->mdio_lock);
1238
++
1239
++	/*
1240
++	 * Set MII speed to 2.5 MHz (= clk_get_rate() / 2 * phy_speed)
1241
++	 *
1242
++	 * The formula for FEC MDC is 'ref_freq / (MII_SPEED x 2)' while
1243
++	 * for ENET-MAC is 'ref_freq / ((MII_SPEED + 1) x 2)'.
1244
++	 */
1245
++	phy_speed = (DIV_ROUND_UP((pfe->ctrl.sys_clk * 1000), 4000000)
1246
++		     << EMAC_MII_SPEED_SHIFT);
1247
++	phy_speed |= EMAC_HOLDTIME(0x5);
1248
++	__raw_writel(phy_speed, priv->PHY_baseaddr + EMAC_MII_CTRL_REG);
1249
++
1250
++	mutex_unlock(&bus->mdio_lock);
1251
++
1252
++	return 0;
1253
++}
1254
++
1255
++/* pfe_eth_gemac_phy_timeout
1256
++ *
1257
++ */
1258
++static int pfe_eth_gemac_phy_timeout(struct pfe_eth_priv_s *priv, int timeout)
1259
++{
1260
++	while (!(__raw_readl(priv->PHY_baseaddr + EMAC_IEVENT_REG) &
1261
++			EMAC_IEVENT_MII)) {
1262
++		if (timeout-- <= 0)
1263
++			return -1;
1264
++		usleep_range(10, 20);
1265
++	}
1266
++	__raw_writel(EMAC_IEVENT_MII, priv->PHY_baseaddr + EMAC_IEVENT_REG);
1267
++	return 0;
1268
++}
1269
++
1270
++static int pfe_eth_mdio_mux(u8 muxval)
1271
++{
1272
++	struct i2c_adapter *a;
1273
++	struct i2c_msg msg;
1274
++	unsigned char buf[2];
1275
++	int ret;
1276
++
1277
++	a = i2c_get_adapter(0);
1278
++	if (!a)
1279
++		return -ENODEV;
1280
++
1281
++	/* set bit 1 (the second bit) of chip at 0x09, register 0x13 */
1282
++	buf[0] = 0x54; /* reg number */
1283
++	buf[1] = (muxval << 6) | 0x3; /* data */
1284
++	msg.addr = 0x66;
1285
++	msg.buf = buf;
1286
++	msg.len = 2;
1287
++	msg.flags = 0;
1288
++	ret = i2c_transfer(a, &msg, 1);
1289
++	i2c_put_adapter(a);
1290
++	if (ret != 1)
1291
++		return -ENODEV;
1292
++	return 0;
1293
++}
1294
++
1295
++static int pfe_eth_mdio_write_addr(struct mii_bus *bus, int mii_id,
1296
++				   int dev_addr, int regnum)
1297
++{
1298
++	struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv;
1299
++
1300
++	__raw_writel(EMAC_MII_DATA_PA(mii_id) |
1301
++		     EMAC_MII_DATA_RA(dev_addr) |
1302
++		     EMAC_MII_DATA_TA | EMAC_MII_DATA(regnum),
1303
++		     priv->PHY_baseaddr + EMAC_MII_DATA_REG);
1304
++
1305
++	if (pfe_eth_gemac_phy_timeout(priv, EMAC_MDIO_TIMEOUT)) {
1306
++		netdev_err(priv->ndev, "%s: phy MDIO address write timeout\n",
1307
++			   __func__);
1308
++		return -1;
1309
++	}
1310
++
1311
++	return 0;
1312
++}
1313
++
1314
++static int pfe_eth_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
1315
++			      u16 value)
1316
++{
1317
++	struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv;
1318
++
1319
++	/*To access external PHYs on QDS board mux needs to be configured*/
1320
++	if ((mii_id) && (pfe->mdio_muxval[mii_id]))
1321
++		pfe_eth_mdio_mux(pfe->mdio_muxval[mii_id]);
1322
++
1323
++	if (regnum & MII_ADDR_C45) {
1324
++		pfe_eth_mdio_write_addr(bus, mii_id, (regnum >> 16) & 0x1f,
1325
++					regnum & 0xffff);
1326
++		__raw_writel(EMAC_MII_DATA_OP_CL45_WR |
1327
++			     EMAC_MII_DATA_PA(mii_id) |
1328
++			     EMAC_MII_DATA_RA((regnum >> 16) & 0x1f) |
1329
++			     EMAC_MII_DATA_TA | EMAC_MII_DATA(value),
1330
++			     priv->PHY_baseaddr + EMAC_MII_DATA_REG);
1331
++	} else {
1332
++		/* start a write op */
1333
++		__raw_writel(EMAC_MII_DATA_ST | EMAC_MII_DATA_OP_WR |
1334
++			     EMAC_MII_DATA_PA(mii_id) |
1335
++			     EMAC_MII_DATA_RA(regnum) |
1336
++			     EMAC_MII_DATA_TA | EMAC_MII_DATA(value),
1337
++			     priv->PHY_baseaddr + EMAC_MII_DATA_REG);
1338
++	}
1339
++
1340
++	if (pfe_eth_gemac_phy_timeout(priv, EMAC_MDIO_TIMEOUT)) {
1341
++		netdev_err(priv->ndev, "%s: phy MDIO write timeout\n",
1342
++			   __func__);
1343
++		return -1;
1344
++	}
1345
++	netif_info(priv, hw, priv->ndev, "%s: phy %x reg %x val %x\n", __func__,
1346
++		   mii_id, regnum, value);
1347
++
1348
++	return 0;
1349
++}
1350
++
1351
++static int pfe_eth_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
1352
++{
1353
++	struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv;
1354
++	u16 value = 0;
1355
++
1356
++	/*To access external PHYs on QDS board mux needs to be configured*/
1357
++	if ((mii_id) && (pfe->mdio_muxval[mii_id]))
1358
++		pfe_eth_mdio_mux(pfe->mdio_muxval[mii_id]);
1359
++
1360
++	if (regnum & MII_ADDR_C45) {
1361
++		pfe_eth_mdio_write_addr(bus, mii_id, (regnum >> 16) & 0x1f,
1362
++					regnum & 0xffff);
1363
++		__raw_writel(EMAC_MII_DATA_OP_CL45_RD |
1364
++			     EMAC_MII_DATA_PA(mii_id) |
1365
++			     EMAC_MII_DATA_RA((regnum >> 16) & 0x1f) |
1366
++			     EMAC_MII_DATA_TA,
1367
++			     priv->PHY_baseaddr + EMAC_MII_DATA_REG);
1368
++	} else {
1369
++		/* start a read op */
1370
++		__raw_writel(EMAC_MII_DATA_ST | EMAC_MII_DATA_OP_RD |
1371
++			     EMAC_MII_DATA_PA(mii_id) |
1372
++			     EMAC_MII_DATA_RA(regnum) |
1373
++			     EMAC_MII_DATA_TA, priv->PHY_baseaddr +
1374
++			     EMAC_MII_DATA_REG);
1375
++	}
1376
++
1377
++	if (pfe_eth_gemac_phy_timeout(priv, EMAC_MDIO_TIMEOUT)) {
1378
++		netdev_err(priv->ndev, "%s: phy MDIO read timeout\n", __func__);
1379
++		return -1;
1380
++	}
1381
++
1382
++	value = EMAC_MII_DATA(__raw_readl(priv->PHY_baseaddr +
1383
++						EMAC_MII_DATA_REG));
1384
++	netif_info(priv, hw, priv->ndev, "%s: phy %x reg %x val %x\n", __func__,
1385
++		   mii_id, regnum, value);
1386
++	return value;
1387
++}
1388
++
1389
++static int pfe_eth_mdio_init(struct pfe_eth_priv_s *priv,
1390
++			     struct ls1012a_mdio_platform_data *minfo)
1391
++{
1392
++	struct mii_bus *bus;
1393
++	int rc;
1394
++
1395
++	netif_info(priv, drv, priv->ndev, "%s\n", __func__);
1396
++	pr_info("%s\n", __func__);
1397
++
1398
++	bus = mdiobus_alloc();
1399
++	if (!bus) {
1400
++		netdev_err(priv->ndev, "mdiobus_alloc() failed\n");
1401
++		rc = -ENOMEM;
1402
++		goto err0;
1403
++	}
1404
++
1405
++	bus->name = "ls1012a MDIO Bus";
1406
++	bus->read = &pfe_eth_mdio_read;
1407
++	bus->write = &pfe_eth_mdio_write;
1408
++	bus->reset = &pfe_eth_mdio_reset;
1409
++	snprintf(bus->id, MII_BUS_ID_SIZE, "ls1012a-%x", priv->id);
1410
++	bus->priv = priv;
1411
++
1412
++	bus->phy_mask = minfo->phy_mask;
1413
++	priv->mdc_div = minfo->mdc_div;
1414
++
1415
++	if (!priv->mdc_div)
1416
++		priv->mdc_div = 64;
1417
++
1418
++	bus->irq[0] = minfo->irq[0];
1419
++
1420
++	bus->parent = priv->pfe->dev;
1421
++
1422
++	netif_info(priv, drv, priv->ndev, "%s: mdc_div: %d, phy_mask: %x\n",
1423
++		   __func__, priv->mdc_div, bus->phy_mask);
1424
++	rc = mdiobus_register(bus);
1425
++	if (rc) {
1426
++		netdev_err(priv->ndev, "mdiobus_register(%s) failed\n",
1427
++			   bus->name);
1428
++		goto err1;
1429
++	}
1430
++
1431
++	priv->mii_bus = bus;
1432
++	pfe_eth_mdio_reset(bus);
1433
++
1434
++	return 0;
1435
++
1436
++err1:
1437
++	mdiobus_free(bus);
1438
++err0:
1439
++	return rc;
1440
++}
1441
++
1442
++/* pfe_eth_mdio_exit
1443
++ */
1444
++static void pfe_eth_mdio_exit(struct mii_bus *bus)
1445
++{
1446
++	if (!bus)
1447
++		return;
1448
++
1449
++	netif_info((struct pfe_eth_priv_s *)bus->priv, drv, ((struct
1450
++			pfe_eth_priv_s *)(bus->priv))->ndev, "%s\n", __func__);
1451
++
1452
++	mdiobus_unregister(bus);
1453
++	mdiobus_free(bus);
1454
++}
1455
++
1456
++/* pfe_get_phydev_speed
1457
++ */
1458
++static int pfe_get_phydev_speed(struct phy_device *phydev)
1459
++{
1460
++	switch (phydev->speed) {
1461
++	case 10:
1462
++			return SPEED_10M;
1463
++	case 100:
1464
++			return SPEED_100M;
1465
++	case 1000:
1466
++	default:
1467
++			return SPEED_1000M;
1468
++	}
1469
++}
1470
++
1471
++/* pfe_set_rgmii_speed
1472
++ */
1473
++#define RGMIIPCR	0x434
1474
++/* RGMIIPCR bit definitions*/
1475
++#define SCFG_RGMIIPCR_EN_AUTO           (0x00000008)
1476
++#define SCFG_RGMIIPCR_SETSP_1000M       (0x00000004)
1477
++#define SCFG_RGMIIPCR_SETSP_100M        (0x00000000)
1478
++#define SCFG_RGMIIPCR_SETSP_10M         (0x00000002)
1479
++#define SCFG_RGMIIPCR_SETFD             (0x00000001)
1480
++
1481
++static void pfe_set_rgmii_speed(struct phy_device *phydev)
1482
++{
1483
++	u32 rgmii_pcr;
1484
++
1485
++	regmap_read(pfe->scfg, RGMIIPCR, &rgmii_pcr);
1486
++	rgmii_pcr  &= ~(SCFG_RGMIIPCR_SETSP_1000M | SCFG_RGMIIPCR_SETSP_10M);
1487
++
1488
++	switch (phydev->speed) {
1489
++	case 10:
1490
++			rgmii_pcr |= SCFG_RGMIIPCR_SETSP_10M;
1491
++			break;
1492
++	case 1000:
1493
++			rgmii_pcr |= SCFG_RGMIIPCR_SETSP_1000M;
1494
++			break;
1495
++	case 100:
1496
++	default:
1497
++			/* Default is 100M */
1498
++			break;
1499
++	}
1500
++	regmap_write(pfe->scfg, RGMIIPCR, rgmii_pcr);
1501
++}
1502
++
1503
++/* pfe_get_phydev_duplex
1504
++ */
1505
++static int pfe_get_phydev_duplex(struct phy_device *phydev)
1506
++{
1507
++	/*return (phydev->duplex == DUPLEX_HALF) ? DUP_HALF:DUP_FULL ; */
1508
++	return DUPLEX_FULL;
1509
++}
1510
++
1511
++/* pfe_eth_adjust_link
1512
++ */
1513
++static void pfe_eth_adjust_link(struct net_device *ndev)
1514
++{
1515
++	struct pfe_eth_priv_s *priv = netdev_priv(ndev);
1516
++	unsigned long flags;
1517
++	struct phy_device *phydev = priv->phydev;
1518
++	int new_state = 0;
1519
++
1520
++	netif_info(priv, drv, ndev, "%s\n", __func__);
1521
++
1522
++	spin_lock_irqsave(&priv->lock, flags);
1523
++
1524
++	if (phydev->link) {
1525
++		/*
1526
++		 * Now we make sure that we can be in full duplex mode.
1527
++		 * If not, we operate in half-duplex mode.
1528
++		 */
1529
++		if (phydev->duplex != priv->oldduplex) {
1530
++			new_state = 1;
1531
++			gemac_set_duplex(priv->EMAC_baseaddr,
1532
++					 pfe_get_phydev_duplex(phydev));
1533
++			priv->oldduplex = phydev->duplex;
1534
++		}
1535
++
1536
++		if (phydev->speed != priv->oldspeed) {
1537
++			new_state = 1;
1538
++			gemac_set_speed(priv->EMAC_baseaddr,
1539
++					pfe_get_phydev_speed(phydev));
1540
++			if (priv->einfo->mii_config == PHY_INTERFACE_MODE_RGMII)
1541
++				pfe_set_rgmii_speed(phydev);
1542
++			priv->oldspeed = phydev->speed;
1543
++		}
1544
++
1545
++		if (!priv->oldlink) {
1546
++			new_state = 1;
1547
++			priv->oldlink = 1;
1548
++		}
1549
++
1550
++	} else if (priv->oldlink) {
1551
++		new_state = 1;
1552
++		priv->oldlink = 0;
1553
++		priv->oldspeed = 0;
1554
++		priv->oldduplex = -1;
1555
++	}
1556
++
1557
++	if (new_state && netif_msg_link(priv))
1558
++		phy_print_status(phydev);
1559
++
1560
++	spin_unlock_irqrestore(&priv->lock, flags);
1561
++}
1562
++
1563
++/* pfe_phy_exit
1564
++ */
1565
++static void pfe_phy_exit(struct net_device *ndev)
1566
++{
1567
++	struct pfe_eth_priv_s *priv = netdev_priv(ndev);
1568
++
1569
++	netif_info(priv, drv, ndev, "%s\n", __func__);
1570
++
1571
++	phy_disconnect(priv->phydev);
1572
++	priv->phydev = NULL;
1573
++}
1574
++
1575
++/* pfe_eth_stop
1576
++ */
1577
++static void pfe_eth_stop(struct net_device *ndev, int wake)
1578
++{
1579
++	struct pfe_eth_priv_s *priv = netdev_priv(ndev);
1580
++
1581
++	netif_info(priv, drv, ndev, "%s\n", __func__);
1582
++
1583
++	if (wake) {
1584
++		gemac_tx_disable(priv->EMAC_baseaddr);
1585
++	} else {
1586
++		gemac_disable(priv->EMAC_baseaddr);
1587
++		gpi_disable(priv->GPI_baseaddr);
1588
++
1589
++		if (priv->phydev)
1590
++			phy_stop(priv->phydev);
1591
++	}
1592
++}
1593
++
1594
++/* pfe_eth_start
1595
++ */
1596
++static int pfe_eth_start(struct pfe_eth_priv_s *priv)
1597
++{
1598
++	netif_info(priv, drv, priv->ndev, "%s\n", __func__);
1599
++
1600
++	if (priv->phydev)
1601
++		phy_start(priv->phydev);
1602
++
1603
++	gpi_enable(priv->GPI_baseaddr);
1604
++	gemac_enable(priv->EMAC_baseaddr);
1605
++
1606
++	return 0;
1607
++}
1608
++
1609
++/*
1610
++ * Configure on chip serdes through mdio
1611
++ */
1612
++static void ls1012a_configure_serdes(struct net_device *ndev)
1613
++{
1614
++	struct pfe_eth_priv_s *priv = pfe->eth.eth_priv[0];
1615
++	int sgmii_2500 = 0;
1616
++	struct mii_bus *bus = priv->mii_bus;
1617
++
1618
++	if (priv->einfo->mii_config == PHY_INTERFACE_MODE_SGMII_2500)
1619
++		sgmii_2500 = 1;
1620
++
1621
++	netif_info(priv, drv, ndev, "%s\n", __func__);
1622
++	/* PCS configuration done with corresponding GEMAC */
1623
++
1624
++	pfe_eth_mdio_read(bus, 0, 0);
1625
++	pfe_eth_mdio_read(bus, 0, 1);
1626
++
1627
++       /*These settings taken from validtion team */
1628
++	pfe_eth_mdio_write(bus, 0, 0x0, 0x8000);
1629
++	if (sgmii_2500) {
1630
++		pfe_eth_mdio_write(bus, 0, 0x14, 0x9);
1631
++		pfe_eth_mdio_write(bus, 0, 0x4, 0x4001);
1632
++		pfe_eth_mdio_write(bus, 0, 0x12, 0xa120);
1633
++		pfe_eth_mdio_write(bus, 0, 0x13, 0x7);
1634
++	} else {
1635
++		pfe_eth_mdio_write(bus, 0, 0x14, 0xb);
1636
++		pfe_eth_mdio_write(bus, 0, 0x4, 0x1a1);
1637
++		pfe_eth_mdio_write(bus, 0, 0x12, 0x400);
1638
++		pfe_eth_mdio_write(bus, 0, 0x13, 0x0);
1639
++	}
1640
++
1641
++	pfe_eth_mdio_write(bus, 0, 0x0, 0x1140);
1642
++}
1643
++
1644
++/*
1645
++ * pfe_phy_init
1646
++ *
1647
++ */
1648
++static int pfe_phy_init(struct net_device *ndev)
1649
++{
1650
++	struct pfe_eth_priv_s *priv = netdev_priv(ndev);
1651
++	struct phy_device *phydev;
1652
++	char phy_id[MII_BUS_ID_SIZE + 3];
1653
++	char bus_id[MII_BUS_ID_SIZE];
1654
++	phy_interface_t interface;
1655
++
1656
++	priv->oldlink = 0;
1657
++	priv->oldspeed = 0;
1658
++	priv->oldduplex = -1;
1659
++
1660
++	snprintf(bus_id, MII_BUS_ID_SIZE, "ls1012a-%d", 0);
1661
++	snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id,
1662
++		 priv->einfo->phy_id);
1663
++
1664
++	netif_info(priv, drv, ndev, "%s: %s\n", __func__, phy_id);
1665
++	interface = priv->einfo->mii_config;
1666
++	if ((interface == PHY_INTERFACE_MODE_SGMII) ||
1667
++	    (interface == PHY_INTERFACE_MODE_SGMII_2500)) {
1668
++		/*Configure SGMII PCS */
1669
++		if (pfe->scfg) {
1670
++			/*Config MDIO from serdes */
1671
++			regmap_write(pfe->scfg, 0x484, 0x00000000);
1672
++		}
1673
++		ls1012a_configure_serdes(ndev);
1674
++	}
1675
++
1676
++	if (pfe->scfg) {
1677
++		/*Config MDIO from PAD */
1678
++		regmap_write(pfe->scfg, 0x484, 0x80000000);
1679
++	}
1680
++
1681
++	priv->oldlink = 0;
1682
++	priv->oldspeed = 0;
1683
++	priv->oldduplex = -1;
1684
++	pr_info("%s interface %x\n", __func__, interface);
1685
++	phydev = phy_connect(ndev, phy_id, &pfe_eth_adjust_link, interface);
1686
++
1687
++	if (IS_ERR(phydev)) {
1688
++		netdev_err(ndev, "phy_connect() failed\n");
1689
++		return PTR_ERR(phydev);
1690
++	}
1691
++
1692
++	priv->phydev = phydev;
1693
++	phydev->irq = PHY_POLL;
1694
++
1695
++	return 0;
1696
++}
1697
++
1698
++/* pfe_gemac_init
1699
++ */
1700
++static int pfe_gemac_init(struct pfe_eth_priv_s *priv)
1701
++{
1702
++	struct gemac_cfg cfg;
1703
++
1704
++	netif_info(priv, ifup, priv->ndev, "%s\n", __func__);
1705
++
1706
++	cfg.speed = SPEED_1000M;
1707
++	cfg.duplex = DUPLEX_FULL;
1708
++
1709
++	gemac_set_config(priv->EMAC_baseaddr, &cfg);
1710
++	gemac_allow_broadcast(priv->EMAC_baseaddr);
1711
++	gemac_enable_1536_rx(priv->EMAC_baseaddr);
1712
++	gemac_enable_rx_jmb(priv->EMAC_baseaddr);
1713
++	gemac_enable_stacked_vlan(priv->EMAC_baseaddr);
1714
++	gemac_enable_pause_rx(priv->EMAC_baseaddr);
1715
++	gemac_set_bus_width(priv->EMAC_baseaddr, 64);
1716
++
1717
++	/*GEM will perform checksum verifications*/
1718
++	if (priv->ndev->features & NETIF_F_RXCSUM)
1719
++		gemac_enable_rx_checksum_offload(priv->EMAC_baseaddr);
1720
++	else
1721
++		gemac_disable_rx_checksum_offload(priv->EMAC_baseaddr);
1722
++
1723
++	return 0;
1724
++}
1725
++
1726
++/* pfe_eth_event_handler
1727
++ */
1728
++static int pfe_eth_event_handler(void *data, int event, int qno)
1729
++{
1730
++	struct pfe_eth_priv_s *priv = data;
1731
++
1732
++	switch (event) {
1733
++	case EVENT_RX_PKT_IND:
1734
++
1735
++		if (qno == 0) {
1736
++			if (napi_schedule_prep(&priv->high_napi)) {
1737
++				netif_info(priv, intr, priv->ndev,
1738
++					   "%s: schedule high prio poll\n"
1739
++					   , __func__);
1740
++
1741
++#ifdef PFE_ETH_NAPI_STATS
1742
++				priv->napi_counters[NAPI_SCHED_COUNT]++;
1743
++#endif
1744
++
1745
++				__napi_schedule(&priv->high_napi);
1746
++			}
1747
++		} else if (qno == 1) {
1748
++			if (napi_schedule_prep(&priv->low_napi)) {
1749
++				netif_info(priv, intr, priv->ndev,
1750
++					   "%s: schedule low prio poll\n"
1751
++					   , __func__);
1752
++
1753
++#ifdef PFE_ETH_NAPI_STATS
1754
++				priv->napi_counters[NAPI_SCHED_COUNT]++;
1755
++#endif
1756
++				__napi_schedule(&priv->low_napi);
1757
++			}
1758
++		} else if (qno == 2) {
1759
++			if (napi_schedule_prep(&priv->lro_napi)) {
1760
++				netif_info(priv, intr, priv->ndev,
1761
++					   "%s: schedule lro prio poll\n"
1762
++					   , __func__);
1763
++
1764
++#ifdef PFE_ETH_NAPI_STATS
1765
++				priv->napi_counters[NAPI_SCHED_COUNT]++;
1766
++#endif
1767
++				__napi_schedule(&priv->lro_napi);
1768
++			}
1769
++		}
1770
++
1771
++		break;
1772
++
1773
++	case EVENT_TXDONE_IND:
1774
++		pfe_eth_flush_tx(priv);
1775
++		hif_lib_event_handler_start(&priv->client, EVENT_TXDONE_IND, 0);
1776
++		break;
1777
++	case EVENT_HIGH_RX_WM:
1778
++	default:
1779
++		break;
1780
++	}
1781
++
1782
++	return 0;
1783
++}
1784
++
1785
++/* pfe_eth_open
1786
++ */
1787
++static int pfe_eth_open(struct net_device *ndev)
1788
++{
1789
++	struct pfe_eth_priv_s *priv = netdev_priv(ndev);
1790
++	struct hif_client_s *client;
1791
++	int rc;
1792
++
1793
++	netif_info(priv, ifup, ndev, "%s\n", __func__);
1794
++
1795
++	/* Register client driver with HIF */
1796
++	client = &priv->client;
1797
++	memset(client, 0, sizeof(*client));
1798
++	client->id = PFE_CL_GEM0 + priv->id;
1799
++	client->tx_qn = emac_txq_cnt;
1800
++	client->rx_qn = EMAC_RXQ_CNT;
1801
++	client->priv = priv;
1802
++	client->pfe = priv->pfe;
1803
++	client->event_handler = pfe_eth_event_handler;
1804
++
1805
++	client->tx_qsize = EMAC_TXQ_DEPTH;
1806
++	client->rx_qsize = EMAC_RXQ_DEPTH;
1807
++
1808
++	rc = hif_lib_client_register(client);
1809
++	if (rc) {
1810
++		netdev_err(ndev, "%s: hif_lib_client_register(%d) failed\n",
1811
++			   __func__, client->id);
1812
++		goto err0;
1813
++	}
1814
++
1815
++	netif_info(priv, drv, ndev, "%s: registered client: %p\n", __func__,
1816
++		   client);
1817
++
1818
++	pfe_gemac_init(priv);
1819
++
1820
++	if (!is_valid_ether_addr(ndev->dev_addr)) {
1821
++		netdev_err(ndev, "%s: invalid MAC address\n", __func__);
1822
++		rc = -EADDRNOTAVAIL;
1823
++		goto err1;
1824
++	}
1825
++
1826
++	gemac_set_laddrN(priv->EMAC_baseaddr,
1827
++			 (struct pfe_mac_addr *)ndev->dev_addr, 1);
1828
++
1829
++	napi_enable(&priv->high_napi);
1830
++	napi_enable(&priv->low_napi);
1831
++	napi_enable(&priv->lro_napi);
1832
++
1833
++	rc = pfe_eth_start(priv);
1834
++
1835
++	netif_tx_wake_all_queues(ndev);
1836
++
1837
++	return rc;
1838
++
1839
++err1:
1840
++	hif_lib_client_unregister(&priv->client);
1841
++
1842
++err0:
1843
++	return rc;
1844
++}
1845
++
1846
++/*
1847
++ *  pfe_eth_shutdown
1848
++ */
1849
++int pfe_eth_shutdown(struct net_device *ndev, int wake)
1850
++{
1851
++	struct pfe_eth_priv_s *priv = netdev_priv(ndev);
1852
++	int i, qstatus;
1853
++	unsigned long next_poll = jiffies + 1, end = jiffies +
1854
++				(TX_POLL_TIMEOUT_MS * HZ) / 1000;
1855
++	int tx_pkts, prv_tx_pkts;
1856
++
1857
++	netif_info(priv, ifdown, ndev, "%s\n", __func__);
1858
++
1859
++	for (i = 0; i < emac_txq_cnt; i++)
1860
++		hrtimer_cancel(&priv->fast_tx_timeout[i].timer);
1861
++
1862
++	netif_tx_stop_all_queues(ndev);
1863
++
1864
++	do {
1865
++		tx_pkts = 0;
1866
++		pfe_eth_flush_tx(priv);
1867
++
1868
++		for (i = 0; i < emac_txq_cnt; i++)
1869
++			tx_pkts += hif_lib_tx_pending(&priv->client, i);
1870
++
1871
++		if (tx_pkts) {
1872
++			/*Don't wait forever, break if we cross max timeout */
1873
++			if (time_after(jiffies, end)) {
1874
++				pr_err(
1875
++					"(%s)Tx is not complete after %dmsec\n",
1876
++					ndev->name, TX_POLL_TIMEOUT_MS);
1877
++				break;
1878
++			}
1879
++
1880
++			pr_info("%s : (%s) Waiting for tx packets to free. Pending tx pkts = %d.\n"
1881
++				, __func__, ndev->name, tx_pkts);
1882
++			if (need_resched())
1883
++				schedule();
1884
++		}
1885
++
1886
++	} while (tx_pkts);
1887
++
1888
++	end = jiffies + (TX_POLL_TIMEOUT_MS * HZ) / 1000;
1889
++
1890
++	prv_tx_pkts = tmu_pkts_processed(priv->id);
1891
++	/*
1892
++	 * Wait till TMU transmits all pending packets
1893
++	 * poll tmu_qstatus and pkts processed by TMU for every 10ms
1894
++	 * Consider TMU is busy, If we see TMU qeueu pending or any packets
1895
++	 * processed by TMU
1896
++	 */
1897
++	while (1) {
1898
++		if (time_after(jiffies, next_poll)) {
1899
++			tx_pkts = tmu_pkts_processed(priv->id);
1900
++			qstatus = tmu_qstatus(priv->id) & 0x7ffff;
1901
++
1902
++			if (!qstatus && (tx_pkts == prv_tx_pkts))
1903
++				break;
1904
++			/* Don't wait forever, break if we cross max
1905
++			 * timeout(TX_POLL_TIMEOUT_MS)
1906
++			 */
1907
++			if (time_after(jiffies, end)) {
1908
++				pr_err("TMU%d is busy after %dmsec\n",
1909
++				       priv->id, TX_POLL_TIMEOUT_MS);
1910
++				break;
1911
++			}
1912
++			prv_tx_pkts = tx_pkts;
1913
++			next_poll++;
1914
++		}
1915
++		if (need_resched())
1916
++			schedule();
1917
++	}
1918
++	/* Wait for some more time to complete transmitting packet if any */
1919
++	next_poll = jiffies + 1;
1920
++	while (1) {
1921
++		if (time_after(jiffies, next_poll))
1922
++			break;
1923
++		if (need_resched())
1924
++			schedule();
1925
++	}
1926
++
1927
++	pfe_eth_stop(ndev, wake);
1928
++
1929
++	napi_disable(&priv->lro_napi);
1930
++	napi_disable(&priv->low_napi);
1931
++	napi_disable(&priv->high_napi);
1932
++
1933
++	hif_lib_client_unregister(&priv->client);
1934
++
1935
++	return 0;
1936
++}
1937
++
1938
++/* pfe_eth_close
1939
++ *
1940
++ */
1941
++static int pfe_eth_close(struct net_device *ndev)
1942
++{
1943
++	pfe_eth_shutdown(ndev, 0);
1944
++
1945
++	return 0;
1946
++}
1947
++
1948
++/* pfe_eth_suspend
1949
++ *
1950
++ * return value : 1 if netdevice is configured to wakeup system
1951
++ *                0 otherwise
1952
++ */
1953
++int pfe_eth_suspend(struct net_device *ndev)
1954
++{
1955
++	struct pfe_eth_priv_s *priv = netdev_priv(ndev);
1956
++	int retval = 0;
1957
++
1958
++	if (priv->wol) {
1959
++		gemac_set_wol(priv->EMAC_baseaddr, priv->wol);
1960
++		retval = 1;
1961
++	}
1962
++	pfe_eth_shutdown(ndev, priv->wol);
1963
++
1964
++	return retval;
1965
++}
1966
++
1967
++/* pfe_eth_resume
1968
++ *
1969
++ */
1970
++int pfe_eth_resume(struct net_device *ndev)
1971
++{
1972
++	struct pfe_eth_priv_s *priv = netdev_priv(ndev);
1973
++
1974
++	if (priv->wol)
1975
++		gemac_set_wol(priv->EMAC_baseaddr, 0);
1976
++	gemac_tx_enable(priv->EMAC_baseaddr);
1977
++
1978
++	return pfe_eth_open(ndev);
1979
++}
1980
++
1981
++/* pfe_eth_get_queuenum
1982
++ */
1983
++static int pfe_eth_get_queuenum(struct pfe_eth_priv_s *priv, struct sk_buff
1984
++					*skb)
1985
++{
1986
++	int queuenum = 0;
1987
++	unsigned long flags;
1988
++
1989
++	/* Get the Fast Path queue number */
1990
++	/*
1991
++	 * Use conntrack mark (if conntrack exists), then packet mark (if any),
1992
++	 * then fallback to default
1993
++	 */
1994
++#if defined(CONFIG_IP_NF_CONNTRACK_MARK) || defined(CONFIG_NF_CONNTRACK_MARK)
1995
++	if (skb->_nfct) {
1996
++		enum ip_conntrack_info cinfo;
1997
++		struct nf_conn *ct;
1998
++
1999
++		ct = nf_ct_get(skb, &cinfo);
2000
++
2001
++		if (ct) {
2002
++			u32 connmark;
2003
++
2004
++			connmark = ct->mark;
2005
++
2006
++			if ((connmark & 0x80000000) && priv->id != 0)
2007
++				connmark >>= 16;
2008
++
2009
++			queuenum = connmark & EMAC_QUEUENUM_MASK;
2010
++		}
2011
++	} else  {/* continued after #endif ... */
2012
++#endif
2013
++		if (skb->mark) {
2014
++			queuenum = skb->mark & EMAC_QUEUENUM_MASK;
2015
++		} else {
2016
++			spin_lock_irqsave(&priv->lock, flags);
2017
++			queuenum = priv->default_priority & EMAC_QUEUENUM_MASK;
2018
++			spin_unlock_irqrestore(&priv->lock, flags);
2019
++		}
2020
++#if defined(CONFIG_IP_NF_CONNTRACK_MARK) || defined(CONFIG_NF_CONNTRACK_MARK)
2021
++	}
2022
++#endif
2023
++	return queuenum;
2024
++}
2025
++
2026
++/* pfe_eth_might_stop_tx
2027
++ *
2028
++ */
2029
++static int pfe_eth_might_stop_tx(struct pfe_eth_priv_s *priv, int queuenum,
2030
++				 struct netdev_queue *tx_queue,
2031
++				 unsigned int n_desc,
2032
++				 unsigned int n_segs)
2033
++{
2034
++	ktime_t kt;
2035
++
2036
++	if (unlikely((__hif_tx_avail(&pfe->hif) < n_desc) ||
2037
++		     (hif_lib_tx_avail(&priv->client, queuenum) < n_desc) ||
2038
++	(hif_lib_tx_credit_avail(pfe, priv->id, queuenum) < n_segs))) {
2039
++#ifdef PFE_ETH_TX_STATS
2040
++		if (__hif_tx_avail(&pfe->hif) < n_desc) {
2041
++			priv->stop_queue_hif[queuenum]++;
2042
++		} else if (hif_lib_tx_avail(&priv->client, queuenum) < n_desc) {
2043
++			priv->stop_queue_hif_client[queuenum]++;
2044
++		} else if (hif_lib_tx_credit_avail(pfe, priv->id, queuenum) <
2045
++			n_segs) {
2046
++			priv->stop_queue_credit[queuenum]++;
2047
++		}
2048
++		priv->stop_queue_total[queuenum]++;
2049
++#endif
2050
++		netif_tx_stop_queue(tx_queue);
2051
++
2052
++		kt = ktime_set(0, LS1012A_TX_FAST_RECOVERY_TIMEOUT_MS *
2053
++				NSEC_PER_MSEC);
2054
++		hrtimer_start(&priv->fast_tx_timeout[queuenum].timer, kt,
2055
++			      HRTIMER_MODE_REL);
2056
++		return -1;
2057
++	} else {
2058
++		return 0;
2059
++	}
2060
++}
2061
++
2062
++#define SA_MAX_OP 2
2063
++/* pfe_hif_send_packet
2064
++ *
2065
++ * At this level if TX fails we drop the packet
2066
++ */
2067
++static void pfe_hif_send_packet(struct sk_buff *skb, struct  pfe_eth_priv_s
2068
++					*priv, int queuenum)
2069
++{
2070
++	struct skb_shared_info *sh = skb_shinfo(skb);
2071
++	unsigned int nr_frags;
2072
++	u32 ctrl = 0;
2073
++
2074
++	netif_info(priv, tx_queued, priv->ndev, "%s\n", __func__);
2075
++
2076
++	if (skb_is_gso(skb)) {
2077
++		priv->stats.tx_dropped++;
2078
++		return;
2079
++	}
2080
++
2081
++	if (skb->ip_summed == CHECKSUM_PARTIAL)
2082
++		ctrl = HIF_CTRL_TX_CHECKSUM;
2083
++
2084
++	nr_frags = sh->nr_frags;
2085
++
2086
++	if (nr_frags) {
2087
++		skb_frag_t *f;
2088
++		int i;
2089
++
2090
++		__hif_lib_xmit_pkt(&priv->client, queuenum, skb->data,
2091
++				   skb_headlen(skb), ctrl, HIF_FIRST_BUFFER,
2092
++				   skb);
2093
++
2094
++		for (i = 0; i < nr_frags - 1; i++) {
2095
++			f = &sh->frags[i];
2096
++			__hif_lib_xmit_pkt(&priv->client, queuenum,
2097
++					   skb_frag_address(f),
2098
++					   skb_frag_size(f),
2099
++					   0x0, 0x0, skb);
2100
++		}
2101
++
2102
++		f = &sh->frags[i];
2103
++
2104
++		__hif_lib_xmit_pkt(&priv->client, queuenum,
2105
++				   skb_frag_address(f), skb_frag_size(f),
2106
++				   0x0, HIF_LAST_BUFFER | HIF_DATA_VALID,
2107
++				   skb);
2108
++
2109
++		netif_info(priv, tx_queued, priv->ndev,
2110
++			   "%s: pkt sent successfully skb:%p nr_frags:%d len:%d\n",
2111
++			   __func__, skb, nr_frags, skb->len);
2112
++	} else {
2113
++		__hif_lib_xmit_pkt(&priv->client, queuenum, skb->data,
2114
++				   skb->len, ctrl, HIF_FIRST_BUFFER |
2115
++				   HIF_LAST_BUFFER | HIF_DATA_VALID,
2116
++				   skb);
2117
++		netif_info(priv, tx_queued, priv->ndev,
2118
++			   "%s: pkt sent successfully skb:%p len:%d\n",
2119
++			   __func__, skb, skb->len);
2120
++	}
2121
++	hif_tx_dma_start();
2122
++	priv->stats.tx_packets++;
2123
++	priv->stats.tx_bytes += skb->len;
2124
++	hif_lib_tx_credit_use(pfe, priv->id, queuenum, 1);
2125
++}
2126
++
2127
++/* pfe_eth_flush_txQ
2128
++ */
2129
++static void pfe_eth_flush_txQ(struct pfe_eth_priv_s *priv, int tx_q_num, int
2130
++				from_tx, int n_desc)
2131
++{
2132
++	struct sk_buff *skb;
2133
++	struct netdev_queue *tx_queue = netdev_get_tx_queue(priv->ndev,
2134
++								tx_q_num);
2135
++	unsigned int flags;
2136
++
2137
++	netif_info(priv, tx_done, priv->ndev, "%s\n", __func__);
2138
++
2139
++	if (!from_tx)
2140
++		__netif_tx_lock_bh(tx_queue);
2141
++
2142
++	/* Clean HIF and client queue */
2143
++	while ((skb = hif_lib_tx_get_next_complete(&priv->client,
2144
++						   tx_q_num, &flags,
2145
++						   HIF_TX_DESC_NT))) {
2146
++		if (flags & HIF_DATA_VALID)
2147
++			dev_kfree_skb_any(skb);
2148
++	}
2149
++	if (!from_tx)
2150
++		__netif_tx_unlock_bh(tx_queue);
2151
++}
2152
++
2153
++/* pfe_eth_flush_tx
2154
++ */
2155
++static void pfe_eth_flush_tx(struct pfe_eth_priv_s *priv)
2156
++{
2157
++	int ii;
2158
++
2159
++	netif_info(priv, tx_done, priv->ndev, "%s\n", __func__);
2160
++
2161
++	for (ii = 0; ii < emac_txq_cnt; ii++)
2162
++		pfe_eth_flush_txQ(priv, ii, 0, 0);
2163
++}
2164
++
2165
++void pfe_tx_get_req_desc(struct sk_buff *skb, unsigned int *n_desc, unsigned int
2166
++				*n_segs)
2167
++{
2168
++	struct skb_shared_info *sh = skb_shinfo(skb);
2169
++
2170
++	/* Scattered data */
2171
++	if (sh->nr_frags) {
2172
++		*n_desc = sh->nr_frags + 1;
2173
++		*n_segs = 1;
2174
++	/* Regular case */
2175
++	} else {
2176
++		*n_desc = 1;
2177
++		*n_segs = 1;
2178
++	}
2179
++}
2180
++
2181
++/* pfe_eth_send_packet
2182
++ */
2183
++static int pfe_eth_send_packet(struct sk_buff *skb, struct net_device *ndev)
2184
++{
2185
++	struct pfe_eth_priv_s *priv = netdev_priv(ndev);
2186
++	int tx_q_num = skb_get_queue_mapping(skb);
2187
++	int n_desc, n_segs;
2188
++	struct netdev_queue *tx_queue = netdev_get_tx_queue(priv->ndev,
2189
++								tx_q_num);
2190
++
2191
++	netif_info(priv, tx_queued, ndev, "%s\n", __func__);
2192
++
2193
++	if ((!skb_is_gso(skb)) && (skb_headroom(skb) < (PFE_PKT_HEADER_SZ +
2194
++			sizeof(unsigned long)))) {
2195
++		netif_warn(priv, tx_err, priv->ndev, "%s: copying skb\n",
2196
++			   __func__);
2197
++
2198
++		if (pskb_expand_head(skb, (PFE_PKT_HEADER_SZ + sizeof(unsigned
2199
++					long)), 0, GFP_ATOMIC)) {
2200
++			/* No need to re-transmit, no way to recover*/
2201
++			kfree_skb(skb);
2202
++			priv->stats.tx_dropped++;
2203
++			return NETDEV_TX_OK;
2204
++		}
2205
++	}
2206
++
2207
++	pfe_tx_get_req_desc(skb, &n_desc, &n_segs);
2208
++
2209
++	hif_tx_lock(&pfe->hif);
2210
++	if (unlikely(pfe_eth_might_stop_tx(priv, tx_q_num, tx_queue, n_desc,
2211
++					   n_segs))) {
2212
++#ifdef PFE_ETH_TX_STATS
2213
++		if (priv->was_stopped[tx_q_num]) {
2214
++			priv->clean_fail[tx_q_num]++;
2215
++			priv->was_stopped[tx_q_num] = 0;
2216
++		}
2217
++#endif
2218
++		hif_tx_unlock(&pfe->hif);
2219
++		return NETDEV_TX_BUSY;
2220
++	}
2221
++
2222
++	pfe_hif_send_packet(skb, priv, tx_q_num);
2223
++
2224
++	hif_tx_unlock(&pfe->hif);
2225
++
2226
++	tx_queue->trans_start = jiffies;
2227
++
2228
++#ifdef PFE_ETH_TX_STATS
2229
++	priv->was_stopped[tx_q_num] = 0;
2230
++#endif
2231
++
2232
++	return NETDEV_TX_OK;
2233
++}
2234
++
2235
++/* pfe_eth_select_queue
2236
++ *
2237
++ */
2238
++static u16 pfe_eth_select_queue(struct net_device *ndev, struct sk_buff *skb,
2239
++				void *accel_priv,
2240
++				select_queue_fallback_t fallback)
2241
++{
2242
++	struct pfe_eth_priv_s *priv = netdev_priv(ndev);
2243
++
2244
++	return pfe_eth_get_queuenum(priv, skb);
2245
++}
2246
++
2247
++/* pfe_eth_get_stats
2248
++ */
2249
++static struct net_device_stats *pfe_eth_get_stats(struct net_device *ndev)
2250
++{
2251
++	struct pfe_eth_priv_s *priv = netdev_priv(ndev);
2252
++
2253
++	netif_info(priv, drv, ndev, "%s\n", __func__);
2254
++
2255
++	return &priv->stats;
2256
++}
2257
++
2258
++/* pfe_eth_set_mac_address
2259
++ */
2260
++static int pfe_eth_set_mac_address(struct net_device *ndev, void *addr)
2261
++{
2262
++	struct pfe_eth_priv_s *priv = netdev_priv(ndev);
2263
++	struct sockaddr *sa = addr;
2264
++
2265
++	netif_info(priv, drv, ndev, "%s\n", __func__);
2266
++
2267
++	if (!is_valid_ether_addr(sa->sa_data))
2268
++		return -EADDRNOTAVAIL;
2269
++
2270
++	memcpy(ndev->dev_addr, sa->sa_data, ETH_ALEN);
2271
++
2272
++	gemac_set_laddrN(priv->EMAC_baseaddr,
2273
++			 (struct pfe_mac_addr *)ndev->dev_addr, 1);
2274
++
2275
++	return 0;
2276
++}
2277
++
2278
++/* pfe_eth_enet_addr_byte_mac
2279
++ */
2280
++int pfe_eth_enet_addr_byte_mac(u8 *enet_byte_addr,
2281
++			       struct pfe_mac_addr *enet_addr)
2282
++{
2283
++	if (!enet_byte_addr || !enet_addr) {
2284
++		return -1;
2285
++
2286
++	} else {
2287
++		enet_addr->bottom = enet_byte_addr[0] |
2288
++			(enet_byte_addr[1] << 8) |
2289
++			(enet_byte_addr[2] << 16) |
2290
++			(enet_byte_addr[3] << 24);
2291
++		enet_addr->top = enet_byte_addr[4] |
2292
++			(enet_byte_addr[5] << 8);
2293
++		return 0;
2294
++	}
2295
++}
2296
++
2297
++/* pfe_eth_set_multi
2298
++ */
2299
++static void pfe_eth_set_multi(struct net_device *ndev)
2300
++{
2301
++	struct pfe_eth_priv_s *priv = netdev_priv(ndev);
2302
++	struct pfe_mac_addr    hash_addr; /* hash register structure */
2303
++	/* specific mac address	register structure */
2304
++	struct pfe_mac_addr    spec_addr;
2305
++	int		result; /* index into hash register to set.. */
2306
++	int		uc_count = 0;
2307
++	struct netdev_hw_addr *ha;
2308
++
2309
++	if (ndev->flags & IFF_PROMISC) {
2310
++		netif_info(priv, drv, ndev, "entering promiscuous mode\n");
2311
++
2312
++		priv->promisc = 1;
2313
++		gemac_enable_copy_all(priv->EMAC_baseaddr);
2314
++	} else {
2315
++		priv->promisc = 0;
2316
++		gemac_disable_copy_all(priv->EMAC_baseaddr);
2317
++	}
2318
++
2319
++	/* Enable broadcast frame reception if required. */
2320
++	if (ndev->flags & IFF_BROADCAST) {
2321
++		gemac_allow_broadcast(priv->EMAC_baseaddr);
2322
++	} else {
2323
++		netif_info(priv, drv, ndev,
2324
++			   "disabling broadcast frame reception\n");
2325
++
2326
++		gemac_no_broadcast(priv->EMAC_baseaddr);
2327
++	}
2328
++
2329
++	if (ndev->flags & IFF_ALLMULTI) {
2330
++		/* Set the hash to rx all multicast frames */
2331
++		hash_addr.bottom = 0xFFFFFFFF;
2332
++		hash_addr.top = 0xFFFFFFFF;
2333
++		gemac_set_hash(priv->EMAC_baseaddr, &hash_addr);
2334
++		netdev_for_each_uc_addr(ha, ndev) {
2335
++			if (uc_count >= MAX_UC_SPEC_ADDR_REG)
2336
++				break;
2337
++			pfe_eth_enet_addr_byte_mac(ha->addr, &spec_addr);
2338
++			gemac_set_laddrN(priv->EMAC_baseaddr, &spec_addr,
2339
++					 uc_count + 2);
2340
++			uc_count++;
2341
++		}
2342
++	} else if ((netdev_mc_count(ndev) > 0)  || (netdev_uc_count(ndev))) {
2343
++		u8 *addr;
2344
++
2345
++		hash_addr.bottom = 0;
2346
++		hash_addr.top = 0;
2347
++
2348
++		netdev_for_each_mc_addr(ha, ndev) {
2349
++			addr = ha->addr;
2350
++
2351
++			netif_info(priv, drv, ndev,
2352
++				   "adding multicast address %X:%X:%X:%X:%X:%X to gem filter\n",
2353
++				addr[0], addr[1], addr[2],
2354
++				addr[3], addr[4], addr[5]);
2355
++
2356
++			result = pfe_eth_get_hash(addr);
2357
++
2358
++			if (result < EMAC_HASH_REG_BITS) {
2359
++				if (result < 32)
2360
++					hash_addr.bottom |= (1 << result);
2361
++				else
2362
++					hash_addr.top |= (1 << (result - 32));
2363
++			} else {
2364
++				break;
2365
++			}
2366
++		}
2367
++
2368
++		uc_count = -1;
2369
++		netdev_for_each_uc_addr(ha, ndev) {
2370
++			addr = ha->addr;
2371
++
2372
++			if (++uc_count < MAX_UC_SPEC_ADDR_REG)   {
2373
++				netdev_info(ndev,
2374
++					    "adding unicast address %02x:%02x:%02x:%02x:%02x:%02x to gem filter\n",
2375
++					    addr[0], addr[1], addr[2],
2376
++					    addr[3], addr[4], addr[5]);
2377
++				pfe_eth_enet_addr_byte_mac(addr, &spec_addr);
2378
++				gemac_set_laddrN(priv->EMAC_baseaddr,
2379
++						 &spec_addr, uc_count + 2);
2380
++			} else {
2381
++				netif_info(priv, drv, ndev,
2382
++					   "adding unicast address %02x:%02x:%02x:%02x:%02x:%02x to gem hash\n",
2383
++					   addr[0], addr[1], addr[2],
2384
++					   addr[3], addr[4], addr[5]);
2385
++
2386
++				result = pfe_eth_get_hash(addr);
2387
++				if (result >= EMAC_HASH_REG_BITS) {
2388
++					break;
2389
++
2390
++				} else {
2391
++					if (result < 32)
2392
++						hash_addr.bottom |= (1 <<
2393
++								result);
2394
++					else
2395
++						hash_addr.top |= (1 <<
2396
++								(result - 32));
2397
++				}
2398
++			}
2399
++		}
2400
++
2401
++		gemac_set_hash(priv->EMAC_baseaddr, &hash_addr);
2402
++	}
2403
++
2404
++	if (!(netdev_uc_count(ndev) >= MAX_UC_SPEC_ADDR_REG)) {
2405
++		/*
2406
++		 *  Check if there are any specific address HW registers that
2407
++		 * need to be flushed
2408
++		 */
2409
++		for (uc_count = netdev_uc_count(ndev); uc_count <
2410
++			MAX_UC_SPEC_ADDR_REG; uc_count++)
2411
++			gemac_clear_laddrN(priv->EMAC_baseaddr, uc_count + 2);
2412
++	}
2413
++
2414
++	if (ndev->flags & IFF_LOOPBACK)
2415
++		gemac_set_loop(priv->EMAC_baseaddr, LB_LOCAL);
2416
++}
2417
++
2418
++/* pfe_eth_set_features
2419
++ */
2420
++static int pfe_eth_set_features(struct net_device *ndev, netdev_features_t
2421
++					features)
2422
++{
2423
++	struct pfe_eth_priv_s *priv = netdev_priv(ndev);
2424
++	int rc = 0;
2425
++
2426
++	if (features & NETIF_F_RXCSUM)
2427
++		gemac_enable_rx_checksum_offload(priv->EMAC_baseaddr);
2428
++	else
2429
++		gemac_disable_rx_checksum_offload(priv->EMAC_baseaddr);
2430
++	return rc;
2431
++}
2432
++
2433
++/* pfe_eth_fast_tx_timeout
2434
++ */
2435
++static enum hrtimer_restart pfe_eth_fast_tx_timeout(struct hrtimer *timer)
2436
++{
2437
++	struct pfe_eth_fast_timer *fast_tx_timeout = container_of(timer, struct
2438
++							pfe_eth_fast_timer,
2439
++							timer);
2440
++	struct pfe_eth_priv_s *priv =  container_of(fast_tx_timeout->base,
2441
++							struct pfe_eth_priv_s,
2442
++							fast_tx_timeout);
2443
++	struct netdev_queue *tx_queue = netdev_get_tx_queue(priv->ndev,
2444
++						fast_tx_timeout->queuenum);
2445
++
2446
++	if (netif_tx_queue_stopped(tx_queue)) {
2447
++#ifdef PFE_ETH_TX_STATS
2448
++		priv->was_stopped[fast_tx_timeout->queuenum] = 1;
2449
++#endif
2450
++		netif_tx_wake_queue(tx_queue);
2451
++	}
2452
++
2453
++	return HRTIMER_NORESTART;
2454
++}
2455
++
2456
++/* pfe_eth_fast_tx_timeout_init
2457
++ */
2458
++static void pfe_eth_fast_tx_timeout_init(struct pfe_eth_priv_s *priv)
2459
++{
2460
++	int i;
2461
++
2462
++	for (i = 0; i < emac_txq_cnt; i++) {
2463
++		priv->fast_tx_timeout[i].queuenum = i;
2464
++		hrtimer_init(&priv->fast_tx_timeout[i].timer, CLOCK_MONOTONIC,
2465
++			     HRTIMER_MODE_REL);
2466
++		priv->fast_tx_timeout[i].timer.function =
2467
++				pfe_eth_fast_tx_timeout;
2468
++		priv->fast_tx_timeout[i].base = priv->fast_tx_timeout;
2469
++	}
2470
++}
2471
++
2472
++static struct sk_buff *pfe_eth_rx_skb(struct net_device *ndev,
2473
++				      struct	pfe_eth_priv_s *priv,
2474
++				      unsigned int qno)
2475
++{
2476
++	void *buf_addr;
2477
++	unsigned int rx_ctrl;
2478
++	unsigned int desc_ctrl = 0;
2479
++	struct hif_ipsec_hdr *ipsec_hdr = NULL;
2480
++	struct sk_buff *skb;
2481
++	struct sk_buff *skb_frag, *skb_frag_last = NULL;
2482
++	int length = 0, offset;
2483
++
2484
++	skb = priv->skb_inflight[qno];
2485
++
2486
++	if (skb) {
2487
++		skb_frag_last = skb_shinfo(skb)->frag_list;
2488
++		if (skb_frag_last) {
2489
++			while (skb_frag_last->next)
2490
++				skb_frag_last = skb_frag_last->next;
2491
++		}
2492
++	}
2493
++
2494
++	while (!(desc_ctrl & CL_DESC_LAST)) {
2495
++		buf_addr = hif_lib_receive_pkt(&priv->client, qno, &length,
2496
++					       &offset, &rx_ctrl, &desc_ctrl,
2497
++					       (void **)&ipsec_hdr);
2498
++		if (!buf_addr)
2499
++			goto incomplete;
2500
++
2501
++#ifdef PFE_ETH_NAPI_STATS
2502
++		priv->napi_counters[NAPI_DESC_COUNT]++;
2503
++#endif
2504
++
2505
++		/* First frag */
2506
++		if (desc_ctrl & CL_DESC_FIRST) {
2507
++			skb = build_skb(buf_addr, 0);
2508
++			if (unlikely(!skb))
2509
++				goto pkt_drop;
2510
++
2511
++			skb_reserve(skb, offset);
2512
++			skb_put(skb, length);
2513
++			skb->dev = ndev;
2514
++
2515
++			if ((ndev->features & NETIF_F_RXCSUM) && (rx_ctrl &
2516
++					HIF_CTRL_RX_CHECKSUMMED))
2517
++				skb->ip_summed = CHECKSUM_UNNECESSARY;
2518
++			else
2519
++				skb_checksum_none_assert(skb);
2520
++
2521
++		} else {
2522
++			/* Next frags */
2523
++			if (unlikely(!skb)) {
2524
++				pr_err("%s: NULL skb_inflight\n",
2525
++				       __func__);
2526
++				goto pkt_drop;
2527
++			}
2528
++
2529
++			skb_frag = build_skb(buf_addr, 0);
2530
++
2531
++			if (unlikely(!skb_frag)) {
2532
++				kfree(buf_addr);
2533
++				goto pkt_drop;
2534
++			}
2535
++
2536
++			skb_reserve(skb_frag, offset);
2537
++			skb_put(skb_frag, length);
2538
++
2539
++			skb_frag->dev = ndev;
2540
++
2541
++			if (skb_shinfo(skb)->frag_list)
2542
++				skb_frag_last->next = skb_frag;
2543
++			else
2544
++				skb_shinfo(skb)->frag_list = skb_frag;
2545
++
2546
++			skb->truesize += skb_frag->truesize;
2547
++			skb->data_len += length;
2548
++			skb->len += length;
2549
++			skb_frag_last = skb_frag;
2550
++		}
2551
++	}
2552
++
2553
++	priv->skb_inflight[qno] = NULL;
2554
++	return skb;
2555
++
2556
++incomplete:
2557
++	priv->skb_inflight[qno] = skb;
2558
++	return NULL;
2559
++
2560
++pkt_drop:
2561
++	priv->skb_inflight[qno] = NULL;
2562
++
2563
++	if (skb)
2564
++		kfree_skb(skb);
2565
++	else
2566
++		kfree(buf_addr);
2567
++
2568
++	priv->stats.rx_errors++;
2569
++
2570
++	return NULL;
2571
++}
2572
++
2573
++/* pfe_eth_poll
2574
++ */
2575
++static int pfe_eth_poll(struct pfe_eth_priv_s *priv, struct napi_struct *napi,
2576
++			unsigned int qno, int budget)
2577
++{
2578
++	struct net_device *ndev = priv->ndev;
2579
++	struct sk_buff *skb;
2580
++	int work_done = 0;
2581
++	unsigned int len;
2582
++
2583
++	netif_info(priv, intr, priv->ndev, "%s\n", __func__);
2584
++
2585
++#ifdef PFE_ETH_NAPI_STATS
2586
++	priv->napi_counters[NAPI_POLL_COUNT]++;
2587
++#endif
2588
++
2589
++	do {
2590
++		skb = pfe_eth_rx_skb(ndev, priv, qno);
2591
++
2592
++		if (!skb)
2593
++			break;
2594
++
2595
++		len = skb->len;
2596
++
2597
++		/* Packet will be processed */
2598
++		skb->protocol = eth_type_trans(skb, ndev);
2599
++
2600
++		netif_receive_skb(skb);
2601
++
2602
++		priv->stats.rx_packets++;
2603
++		priv->stats.rx_bytes += len;
2604
++
2605
++		work_done++;
2606
++
2607
++#ifdef PFE_ETH_NAPI_STATS
2608
++		priv->napi_counters[NAPI_PACKET_COUNT]++;
2609
++#endif
2610
++
2611
++	} while (work_done < budget);
2612
++
2613
++	/*
2614
++	 * If no Rx receive nor cleanup work was done, exit polling mode.
2615
++	 * No more netif_running(dev) check is required here , as this is
2616
++	 * checked in net/core/dev.c (2.6.33.5 kernel specific).
2617
++	 */
2618
++	if (work_done < budget) {
2619
++		napi_complete(napi);
2620
++
2621
++		hif_lib_event_handler_start(&priv->client, EVENT_RX_PKT_IND,
2622
++					    qno);
2623
++	}
2624
++#ifdef PFE_ETH_NAPI_STATS
2625
++	else
2626
++		priv->napi_counters[NAPI_FULL_BUDGET_COUNT]++;
2627
++#endif
2628
++
2629
++	return work_done;
2630
++}
2631
++
2632
++/*
2633
++ * pfe_eth_lro_poll
2634
++ */
2635
++static int pfe_eth_lro_poll(struct napi_struct *napi, int budget)
2636
++{
2637
++	struct pfe_eth_priv_s *priv = container_of(napi, struct pfe_eth_priv_s,
2638
++							lro_napi);
2639
++
2640
++	netif_info(priv, intr, priv->ndev, "%s\n", __func__);
2641
++
2642
++	return pfe_eth_poll(priv, napi, 2, budget);
2643
++}
2644
++
2645
++/* pfe_eth_low_poll
2646
++ */
2647
++static int pfe_eth_low_poll(struct napi_struct *napi, int budget)
2648
++{
2649
++	struct pfe_eth_priv_s *priv = container_of(napi, struct pfe_eth_priv_s,
2650
++							low_napi);
2651
++
2652
++	netif_info(priv, intr, priv->ndev, "%s\n", __func__);
2653
++
2654
++	return pfe_eth_poll(priv, napi, 1, budget);
2655
++}
2656
++
2657
++/* pfe_eth_high_poll
2658
++ */
2659
++static int pfe_eth_high_poll(struct napi_struct *napi, int budget)
2660
++{
2661
++	struct pfe_eth_priv_s *priv = container_of(napi, struct pfe_eth_priv_s,
2662
++							high_napi);
2663
++
2664
++	netif_info(priv, intr, priv->ndev, "%s\n", __func__);
2665
++
2666
++	return pfe_eth_poll(priv, napi, 0, budget);
2667
++}
2668
++
2669
++static const struct net_device_ops pfe_netdev_ops = {
2670
++	.ndo_open = pfe_eth_open,
2671
++	.ndo_stop = pfe_eth_close,
2672
++	.ndo_start_xmit = pfe_eth_send_packet,
2673
++	.ndo_select_queue = pfe_eth_select_queue,
2674
++	.ndo_get_stats = pfe_eth_get_stats,
2675
++	.ndo_set_mac_address = pfe_eth_set_mac_address,
2676
++	.ndo_set_rx_mode = pfe_eth_set_multi,
2677
++	.ndo_set_features = pfe_eth_set_features,
2678
++	.ndo_validate_addr = eth_validate_addr,
2679
++};
2680
++
2681
++/* pfe_eth_init_one
2682
++ */
2683
++static int pfe_eth_init_one(struct pfe *pfe, int id)
2684
++{
2685
++	struct net_device *ndev = NULL;
2686
++	struct pfe_eth_priv_s *priv = NULL;
2687
++	struct ls1012a_eth_platform_data *einfo;
2688
++	struct ls1012a_mdio_platform_data *minfo;
2689
++	struct ls1012a_pfe_platform_data *pfe_info;
2690
++	int err;
2691
++
2692
++	/* Extract pltform data */
2693
++	pfe_info = (struct ls1012a_pfe_platform_data *)
2694
++					pfe->dev->platform_data;
2695
++	if (!pfe_info) {
2696
++		pr_err(
2697
++			"%s: pfe missing additional platform data\n"
2698
++			, __func__);
2699
++		err = -ENODEV;
2700
++		goto err0;
2701
++	}
2702
++
2703
++	einfo = (struct ls1012a_eth_platform_data *)
2704
++				pfe_info->ls1012a_eth_pdata;
2705
++
2706
++	/* einfo never be NULL, but no harm in having this check */
2707
++	if (!einfo) {
2708
++		pr_err(
2709
++			"%s: pfe missing additional gemacs platform data\n"
2710
++			, __func__);
2711
++		err = -ENODEV;
2712
++		goto err0;
2713
++	}
2714
++
2715
++	minfo = (struct ls1012a_mdio_platform_data *)
2716
++				pfe_info->ls1012a_mdio_pdata;
2717
++
2718
++	/* einfo never be NULL, but no harm in having this check */
2719
++	if (!minfo) {
2720
++		pr_err(
2721
++			"%s: pfe missing additional mdios platform data\n",
2722
++			 __func__);
2723
++		err = -ENODEV;
2724
++		goto err0;
2725
++	}
2726
++
2727
++	/* Create an ethernet device instance */
2728
++	ndev = alloc_etherdev_mq(sizeof(*priv), emac_txq_cnt);
2729
++
2730
++	if (!ndev) {
2731
++		pr_err("%s: gemac %d device allocation failed\n",
2732
++		       __func__, einfo[id].gem_id);
2733
++		err = -ENOMEM;
2734
++		goto err0;
2735
++	}
2736
++
2737
++	priv = netdev_priv(ndev);
2738
++	priv->ndev = ndev;
2739
++	priv->id = einfo[id].gem_id;
2740
++	priv->pfe = pfe;
2741
++
2742
++	SET_NETDEV_DEV(priv->ndev, priv->pfe->dev);
2743
++
2744
++	pfe->eth.eth_priv[id] = priv;
2745
++
2746
++	/* Set the info in the priv to the current info */
2747
++	priv->einfo = &einfo[id];
2748
++	priv->EMAC_baseaddr = cbus_emac_base[id];
2749
++	priv->PHY_baseaddr = cbus_emac_base[0];
2750
++	priv->GPI_baseaddr = cbus_gpi_base[id];
2751
++
2752
++#define HIF_GEMAC_TMUQ_BASE	6
2753
++	priv->low_tmu_q	=  HIF_GEMAC_TMUQ_BASE + (id * 2);
2754
++	priv->high_tmu_q	=  priv->low_tmu_q + 1;
2755
++
2756
++	spin_lock_init(&priv->lock);
2757
++
2758
++	pfe_eth_fast_tx_timeout_init(priv);
2759
++
2760
++	/* Copy the station address into the dev structure, */
2761
++	memcpy(ndev->dev_addr, einfo[id].mac_addr, ETH_ALEN);
2762
++
2763
++	/* Initialize mdio */
2764
++	if (minfo[id].enabled) {
2765
++		err = pfe_eth_mdio_init(priv, &minfo[id]);
2766
++		if (err) {
2767
++			netdev_err(ndev, "%s: pfe_eth_mdio_init() failed\n",
2768
++				   __func__);
2769
++			goto err2;
2770
++		}
2771
++	}
2772
++
2773
++	ndev->mtu = 1500;
2774
++
2775
++	/* Set MTU limits */
2776
++	ndev->min_mtu = ETH_MIN_MTU;
2777
++	ndev->max_mtu = JUMBO_FRAME_SIZE;
2778
++
2779
++	/* supported features */
2780
++	ndev->hw_features = NETIF_F_SG;
2781
++
2782
++	/*Enable after checksum offload is validated */
2783
++	ndev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM |
2784
++		NETIF_F_IPV6_CSUM | NETIF_F_SG;
2785
++
2786
++	/* enabled by default */
2787
++	ndev->features = ndev->hw_features;
2788
++
2789
++	priv->usr_features = ndev->features;
2790
++
2791
++	ndev->netdev_ops = &pfe_netdev_ops;
2792
++
2793
++	ndev->ethtool_ops = &pfe_ethtool_ops;
2794
++
2795
++	/* Enable basic messages by default */
2796
++	priv->msg_enable = NETIF_MSG_IFUP | NETIF_MSG_IFDOWN | NETIF_MSG_LINK |
2797
++				NETIF_MSG_PROBE;
2798
++
2799
++	netif_napi_add(ndev, &priv->low_napi, pfe_eth_low_poll,
2800
++		       HIF_RX_POLL_WEIGHT - 16);
2801
++	netif_napi_add(ndev, &priv->high_napi, pfe_eth_high_poll,
2802
++		       HIF_RX_POLL_WEIGHT - 16);
2803
++	netif_napi_add(ndev, &priv->lro_napi, pfe_eth_lro_poll,
2804
++		       HIF_RX_POLL_WEIGHT - 16);
2805
++
2806
++	err = register_netdev(ndev);
2807
++
2808
++	if (err) {
2809
++		netdev_err(ndev, "register_netdev() failed\n");
2810
++		goto err3;
2811
++	}
2812
++	device_init_wakeup(&ndev->dev, WAKE_MAGIC);
2813
++
2814
++	if (!(priv->einfo->phy_flags & GEMAC_NO_PHY)) {
2815
++		err = pfe_phy_init(ndev);
2816
++		if (err) {
2817
++			netdev_err(ndev, "%s: pfe_phy_init() failed\n",
2818
++				   __func__);
2819
++			goto err4;
2820
++		}
2821
++	}
2822
++
2823
++	netif_carrier_on(ndev);
2824
++
2825
++	/* Create all the sysfs files */
2826
++	if (pfe_eth_sysfs_init(ndev))
2827
++		goto err4;
2828
++
2829
++	netif_info(priv, probe, ndev, "%s: created interface, baseaddr: %p\n",
2830
++		   __func__, priv->EMAC_baseaddr);
2831
++
2832
++	return 0;
2833
++err4:
2834
++	unregister_netdev(ndev);
2835
++err3:
2836
++	pfe_eth_mdio_exit(priv->mii_bus);
2837
++err2:
2838
++	free_netdev(priv->ndev);
2839
++err0:
2840
++	return err;
2841
++}
2842
++
2843
++/* pfe_eth_init
2844
++ */
2845
++int pfe_eth_init(struct pfe *pfe)
2846
++{
2847
++	int ii = 0;
2848
++	int err;
2849
++
2850
++	pr_info("%s\n", __func__);
2851
++
2852
++	cbus_emac_base[0] = EMAC1_BASE_ADDR;
2853
++	cbus_emac_base[1] = EMAC2_BASE_ADDR;
2854
++
2855
++	cbus_gpi_base[0] = EGPI1_BASE_ADDR;
2856
++	cbus_gpi_base[1] = EGPI2_BASE_ADDR;
2857
++
2858
++	for (ii = 0; ii < NUM_GEMAC_SUPPORT; ii++) {
2859
++		err = pfe_eth_init_one(pfe, ii);
2860
++		if (err)
2861
++			goto err0;
2862
++	}
2863
++
2864
++	return 0;
2865
++
2866
++err0:
2867
++	while (ii--)
2868
++		pfe_eth_exit_one(pfe->eth.eth_priv[ii]);
2869
++
2870
++	/* Register three network devices in the kernel */
2871
++	return err;
2872
++}
2873
++
2874
++/* pfe_eth_exit_one
2875
++ */
2876
++static void pfe_eth_exit_one(struct pfe_eth_priv_s *priv)
2877
++{
2878
++	netif_info(priv, probe, priv->ndev, "%s\n", __func__);
2879
++
2880
++	pfe_eth_sysfs_exit(priv->ndev);
2881
++
2882
++	unregister_netdev(priv->ndev);
2883
++
2884
++	if (!(priv->einfo->phy_flags & GEMAC_NO_PHY))
2885
++		pfe_phy_exit(priv->ndev);
2886
++
2887
++	if (priv->mii_bus)
2888
++		pfe_eth_mdio_exit(priv->mii_bus);
2889
++
2890
++	free_netdev(priv->ndev);
2891
++}
2892
++
2893
++/* pfe_eth_exit
2894
++ */
2895
++void pfe_eth_exit(struct pfe *pfe)
2896
++{
2897
++	int ii;
2898
++
2899
++	pr_info("%s\n", __func__);
2900
++
2901
++	for (ii = NUM_GEMAC_SUPPORT - 1; ii >= 0; ii--)
2902
++		pfe_eth_exit_one(pfe->eth.eth_priv[ii]);
2903
++}
2904
+diff --git a/drivers/staging/fsl_ppfe/pfe_firmware.c b/drivers/staging/fsl_ppfe/pfe_firmware.c
2905
+new file mode 100644
2906
+index 000000000000..47462b9fe2ea
2907
+--- /dev/null
2908
+@@ -0,0 +1,314 @@
2909
++/*
2910
++ * Copyright 2015-2016 Freescale Semiconductor, Inc.
2911
++ * Copyright 2017 NXP
2912
++ *
2913
++ * This program is free software; you can redistribute it and/or modify
2914
++ * it under the terms of the GNU General Public License as published by
2915
++ * the Free Software Foundation; either version 2 of the License, or
2916
++ * (at your option) any later version.
2917
++ *
2918
++ * This program is distributed in the hope that it will be useful,
2919
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2920
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2921
++ * GNU General Public License for more details.
2922
++ *
2923
++ * You should have received a copy of the GNU General Public License
2924
++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
2925
++ */
2926
++
2927
++/*
2928
++ * @file
2929
++ * Contains all the functions to handle parsing and loading of PE firmware
2930
++ * files.
2931
++ */
2932
++#include <linux/firmware.h>
2933
++
2934
++#include "pfe_mod.h"
2935
++#include "pfe_firmware.h"
2936
++#include "pfe/pfe.h"
2937
++
2938
++static struct elf32_shdr *get_elf_section_header(const struct firmware *fw,
2939
++						 const char *section)
2940
++{
2941
++	struct elf32_hdr *elf_hdr = (struct elf32_hdr *)fw->data;
2942
++	struct elf32_shdr *shdr;
2943
++	struct elf32_shdr *shdr_shstr;
2944
++	Elf32_Off e_shoff = be32_to_cpu(elf_hdr->e_shoff);
2945
++	Elf32_Half e_shentsize = be16_to_cpu(elf_hdr->e_shentsize);
2946
++	Elf32_Half e_shnum = be16_to_cpu(elf_hdr->e_shnum);
2947
++	Elf32_Half e_shstrndx = be16_to_cpu(elf_hdr->e_shstrndx);
2948
++	Elf32_Off shstr_offset;
2949
++	Elf32_Word sh_name;
2950
++	const char *name;
2951
++	int i;
2952
++
2953
++	/* Section header strings */
2954
++	shdr_shstr = (struct elf32_shdr *)(fw->data + e_shoff + e_shstrndx *
2955
++					e_shentsize);
2956
++	shstr_offset = be32_to_cpu(shdr_shstr->sh_offset);
2957
++
2958
++	for (i = 0; i < e_shnum; i++) {
2959
++		shdr = (struct elf32_shdr *)(fw->data + e_shoff
2960
++					     + i * e_shentsize);
2961
++
2962
++		sh_name = be32_to_cpu(shdr->sh_name);
2963
++
2964
++		name = (const char *)(fw->data + shstr_offset + sh_name);
2965
++
2966
++		if (!strcmp(name, section))
2967
++			return shdr;
2968
++	}
2969
++
2970
++	pr_err("%s: didn't find section %s\n", __func__, section);
2971
++
2972
++	return NULL;
2973
++}
2974
++
2975
++#if defined(CFG_DIAGS)
2976
++static int pfe_get_diags_info(const struct firmware *fw, struct pfe_diags_info
2977
++				*diags_info)
2978
++{
2979
++	struct elf32_shdr *shdr;
2980
++	unsigned long offset, size;
2981
++
2982
++	shdr = get_elf_section_header(fw, ".pfe_diags_str");
2983
++	if (shdr) {
2984
++		offset = be32_to_cpu(shdr->sh_offset);
2985
++		size = be32_to_cpu(shdr->sh_size);
2986
++		diags_info->diags_str_base = be32_to_cpu(shdr->sh_addr);
2987
++		diags_info->diags_str_size = size;
2988
++		diags_info->diags_str_array = kmalloc(size, GFP_KERNEL);
2989
++		memcpy(diags_info->diags_str_array, fw->data + offset, size);
2990
++
2991
++		return 0;
2992
++	} else {
2993
++		return -1;
2994
++	}
2995
++}
2996
++#endif
2997
++
2998
++static void pfe_check_version_info(const struct firmware *fw)
2999
++{
3000
++	/*static char *version = NULL;*/
3001
++	static char *version;
3002
++
3003
++	struct elf32_shdr *shdr = get_elf_section_header(fw, ".version");
3004
++
3005
++	if (shdr) {
3006
++		if (!version) {
3007
++			/*
3008
++			 * this is the first fw we load, use its version
3009
++			 * string as reference (whatever it is)
3010
++			 */
3011
++			version = (char *)(fw->data +
3012
++					be32_to_cpu(shdr->sh_offset));
3013
++
3014
++			pr_info("PFE binary version: %s\n", version);
3015
++		} else {
3016
++			/*
3017
++			 * already have loaded at least one firmware, check
3018
++			 * sequence can start now
3019
++			 */
3020
++			if (strcmp(version, (char *)(fw->data +
3021
++				be32_to_cpu(shdr->sh_offset)))) {
3022
++				pr_info(
3023
++				"WARNING: PFE firmware binaries from incompatible version\n");
3024
++			}
3025
++		}
3026
++	} else {
3027
++		/*
3028
++		 * version cannot be verified, a potential issue that should
3029
++		 * be reported
3030
++		 */
3031
++		pr_info(
3032
++			 "WARNING: PFE firmware binaries from incompatible version\n");
3033
++	}
3034
++}
3035
++
3036
++/* PFE elf firmware loader.
3037
++ * Loads an elf firmware image into a list of PE's (specified using a bitmask)
3038
++ *
3039
++ * @param pe_mask	Mask of PE id's to load firmware to
3040
++ * @param fw		Pointer to the firmware image
3041
++ *
3042
++ * @return		0 on success, a negative value on error
3043
++ *
3044
++ */
3045
++int pfe_load_elf(int pe_mask, const struct firmware *fw, struct pfe *pfe)
3046
++{
3047
++	struct elf32_hdr *elf_hdr = (struct elf32_hdr *)fw->data;
3048
++	Elf32_Half sections = be16_to_cpu(elf_hdr->e_shnum);
3049
++	struct elf32_shdr *shdr = (struct elf32_shdr *)(fw->data +
3050
++					be32_to_cpu(elf_hdr->e_shoff));
3051
++	int id, section;
3052
++	int rc;
3053
++
3054
++	pr_info("%s\n", __func__);
3055
++
3056
++	/* Some sanity checks */
3057
++	if (strncmp(&elf_hdr->e_ident[EI_MAG0], ELFMAG, SELFMAG)) {
3058
++		pr_err("%s: incorrect elf magic number\n", __func__);
3059
++		return -EINVAL;
3060
++	}
3061
++
3062
++	if (elf_hdr->e_ident[EI_CLASS] != ELFCLASS32) {
3063
++		pr_err("%s: incorrect elf class(%x)\n", __func__,
3064
++		       elf_hdr->e_ident[EI_CLASS]);
3065
++		return -EINVAL;
3066
++	}
3067
++
3068
++	if (elf_hdr->e_ident[EI_DATA] != ELFDATA2MSB) {
3069
++		pr_err("%s: incorrect elf data(%x)\n", __func__,
3070
++		       elf_hdr->e_ident[EI_DATA]);
3071
++		return -EINVAL;
3072
++	}
3073
++
3074
++	if (be16_to_cpu(elf_hdr->e_type) != ET_EXEC) {
3075
++		pr_err("%s: incorrect elf file type(%x)\n", __func__,
3076
++		       be16_to_cpu(elf_hdr->e_type));
3077
++		return -EINVAL;
3078
++	}
3079
++
3080
++	for (section = 0; section < sections; section++, shdr++) {
3081
++		if (!(be32_to_cpu(shdr->sh_flags) & (SHF_WRITE | SHF_ALLOC |
3082
++			SHF_EXECINSTR)))
3083
++			continue;
3084
++
3085
++		for (id = 0; id < MAX_PE; id++)
3086
++			if (pe_mask & (1 << id)) {
3087
++				rc = pe_load_elf_section(id, fw->data, shdr,
3088
++							 pfe->dev);
3089
++				if (rc < 0)
3090
++					goto err;
3091
++			}
3092
++	}
3093
++
3094
++	pfe_check_version_info(fw);
3095
++
3096
++	return 0;
3097
++
3098
++err:
3099
++	return rc;
3100
++}
3101
++
3102
++/* PFE firmware initialization.
3103
++ * Loads different firmware files from filesystem.
3104
++ * Initializes PE IMEM/DMEM and UTIL-PE DDR
3105
++ * Initializes control path symbol addresses (by looking them up in the elf
3106
++ * firmware files
3107
++ * Takes PE's out of reset
3108
++ *
3109
++ * @return	0 on success, a negative value on error
3110
++ *
3111
++ */
3112
++int pfe_firmware_init(struct pfe *pfe)
3113
++{
3114
++	const struct firmware *class_fw, *tmu_fw;
3115
++	int rc = 0;
3116
++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
3117
++	const char *util_fw_name;
3118
++	const struct firmware *util_fw;
3119
++#endif
3120
++
3121
++	pr_info("%s\n", __func__);
3122
++
3123
++	if (request_firmware(&class_fw, CLASS_FIRMWARE_FILENAME, pfe->dev)) {
3124
++		pr_err("%s: request firmware %s failed\n", __func__,
3125
++		       CLASS_FIRMWARE_FILENAME);
3126
++		rc = -ETIMEDOUT;
3127
++		goto err0;
3128
++	}
3129
++
3130
++	if (request_firmware(&tmu_fw, TMU_FIRMWARE_FILENAME, pfe->dev)) {
3131
++		pr_err("%s: request firmware %s failed\n", __func__,
3132
++		       TMU_FIRMWARE_FILENAME);
3133
++		rc = -ETIMEDOUT;
3134
++		goto err1;
3135
++}
3136
++
3137
++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
3138
++	util_fw_name = UTIL_FIRMWARE_FILENAME;
3139
++
3140
++	if (request_firmware(&util_fw, util_fw_name, pfe->dev)) {
3141
++		pr_err("%s: request firmware %s failed\n", __func__,
3142
++		       util_fw_name);
3143
++		rc = -ETIMEDOUT;
3144
++		goto err2;
3145
++	}
3146
++#endif
3147
++	rc = pfe_load_elf(CLASS_MASK, class_fw, pfe);
3148
++	if (rc < 0) {
3149
++		pr_err("%s: class firmware load failed\n", __func__);
3150
++		goto err3;
3151
++	}
3152
++
3153
++#if defined(CFG_DIAGS)
3154
++	rc = pfe_get_diags_info(class_fw, &pfe->diags.class_diags_info);
3155
++	if (rc < 0) {
3156
++		pr_warn(
3157
++			"PFE diags won't be available for class PEs\n");
3158
++		rc = 0;
3159
++	}
3160
++#endif
3161
++
3162
++	rc = pfe_load_elf(TMU_MASK, tmu_fw, pfe);
3163
++	if (rc < 0) {
3164
++		pr_err("%s: tmu firmware load failed\n", __func__);
3165
++		goto err3;
3166
++	}
3167
++
3168
++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
3169
++	rc = pfe_load_elf(UTIL_MASK, util_fw, pfe);
3170
++	if (rc < 0) {
3171
++		pr_err("%s: util firmware load failed\n", __func__);
3172
++		goto err3;
3173
++	}
3174
++
3175
++#if defined(CFG_DIAGS)
3176
++	rc = pfe_get_diags_info(util_fw, &pfe->diags.util_diags_info);
3177
++	if (rc < 0) {
3178
++		pr_warn(
3179
++			"PFE diags won't be available for util PE\n");
3180
++		rc = 0;
3181
++	}
3182
++#endif
3183
++
3184
++	util_enable();
3185
++#endif
3186
++
3187
++	tmu_enable(0xf);
3188
++	class_enable();
3189
++
3190
++err3:
3191
++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
3192
++	release_firmware(util_fw);
3193
++
3194
++err2:
3195
++#endif
3196
++	release_firmware(tmu_fw);
3197
++
3198
++err1:
3199
++	release_firmware(class_fw);
3200
++
3201
++err0:
3202
++	return rc;
3203
++}
3204
++
3205
++/* PFE firmware cleanup
3206
++ * Puts PE's in reset
3207
++ *
3208
++ *
3209
++ */
3210
++void pfe_firmware_exit(struct pfe *pfe)
3211
++{
3212
++	pr_info("%s\n", __func__);
3213
++
3214
++	if (pe_reset_all(&pfe->ctrl) != 0)
3215
++		pr_err("Error: Failed to stop PEs, PFE reload may not work correctly\n");
3216
++
3217
++	class_disable();
3218
++	tmu_disable(0xf);
3219
++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
3220
++	util_disable();
3221
++#endif
3222
++}
3223
+diff --git a/drivers/staging/fsl_ppfe/pfe_hal.c b/drivers/staging/fsl_ppfe/pfe_hal.c
3224
+new file mode 100644
3225
+index 000000000000..0915034b281b
3226
+--- /dev/null
3227
+@@ -0,0 +1,1516 @@
3228
++/*
3229
++ * Copyright 2015-2016 Freescale Semiconductor, Inc.
3230
++ * Copyright 2017 NXP
3231
++ *
3232
++ * This program is free software; you can redistribute it and/or modify
3233
++ * it under the terms of the GNU General Public License as published by
3234
++ * the Free Software Foundation; either version 2 of the License, or
3235
++ * (at your option) any later version.
3236
++ *
3237
++ * This program is distributed in the hope that it will be useful,
3238
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3239
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
3240
++ * GNU General Public License for more details.
3241
++ *
3242
++ * You should have received a copy of the GNU General Public License
3243
++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
3244
++ */
3245
++
3246
++#include "pfe_mod.h"
3247
++#include "pfe/pfe.h"
3248
++
3249
++void *cbus_base_addr;
3250
++void *ddr_base_addr;
3251
++unsigned long ddr_phys_base_addr;
3252
++unsigned int ddr_size;
3253
++
3254
++static struct pe_info pe[MAX_PE];
3255
++
3256
++/* Initializes the PFE library.
3257
++ * Must be called before using any of the library functions.
3258
++ *
3259
++ * @param[in] cbus_base		CBUS virtual base address (as mapped in
3260
++ * the host CPU address space)
3261
++ * @param[in] ddr_base		PFE DDR range virtual base address (as
3262
++ * mapped in the host CPU address space)
3263
++ * @param[in] ddr_phys_base	PFE DDR range physical base address (as
3264
++ * mapped in platform)
3265
++ * @param[in] size		PFE DDR range size (as defined by the host
3266
++ * software)
3267
++ */
3268
++void pfe_lib_init(void *cbus_base, void *ddr_base, unsigned long ddr_phys_base,
3269
++		  unsigned int size)
3270
++{
3271
++	cbus_base_addr = cbus_base;
3272
++	ddr_base_addr = ddr_base;
3273
++	ddr_phys_base_addr = ddr_phys_base;
3274
++	ddr_size = size;
3275
++
3276
++	pe[CLASS0_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(0);
3277
++	pe[CLASS0_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(0);
3278
++	pe[CLASS0_ID].pmem_size = CLASS_IMEM_SIZE;
3279
++	pe[CLASS0_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA;
3280
++	pe[CLASS0_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR;
3281
++	pe[CLASS0_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA;
3282
++
3283
++	pe[CLASS1_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(1);
3284
++	pe[CLASS1_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(1);
3285
++	pe[CLASS1_ID].pmem_size = CLASS_IMEM_SIZE;
3286
++	pe[CLASS1_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA;
3287
++	pe[CLASS1_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR;
3288
++	pe[CLASS1_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA;
3289
++
3290
++	pe[CLASS2_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(2);
3291
++	pe[CLASS2_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(2);
3292
++	pe[CLASS2_ID].pmem_size = CLASS_IMEM_SIZE;
3293
++	pe[CLASS2_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA;
3294
++	pe[CLASS2_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR;
3295
++	pe[CLASS2_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA;
3296
++
3297
++	pe[CLASS3_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(3);
3298
++	pe[CLASS3_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(3);
3299
++	pe[CLASS3_ID].pmem_size = CLASS_IMEM_SIZE;
3300
++	pe[CLASS3_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA;
3301
++	pe[CLASS3_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR;
3302
++	pe[CLASS3_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA;
3303
++
3304
++	pe[CLASS4_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(4);
3305
++	pe[CLASS4_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(4);
3306
++	pe[CLASS4_ID].pmem_size = CLASS_IMEM_SIZE;
3307
++	pe[CLASS4_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA;
3308
++	pe[CLASS4_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR;
3309
++	pe[CLASS4_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA;
3310
++
3311
++	pe[CLASS5_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(5);
3312
++	pe[CLASS5_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(5);
3313
++	pe[CLASS5_ID].pmem_size = CLASS_IMEM_SIZE;
3314
++	pe[CLASS5_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA;
3315
++	pe[CLASS5_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR;
3316
++	pe[CLASS5_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA;
3317
++
3318
++	pe[TMU0_ID].dmem_base_addr = TMU_DMEM_BASE_ADDR(0);
3319
++	pe[TMU0_ID].pmem_base_addr = TMU_IMEM_BASE_ADDR(0);
3320
++	pe[TMU0_ID].pmem_size = TMU_IMEM_SIZE;
3321
++	pe[TMU0_ID].mem_access_wdata = TMU_MEM_ACCESS_WDATA;
3322
++	pe[TMU0_ID].mem_access_addr = TMU_MEM_ACCESS_ADDR;
3323
++	pe[TMU0_ID].mem_access_rdata = TMU_MEM_ACCESS_RDATA;
3324
++
3325
++	pe[TMU1_ID].dmem_base_addr = TMU_DMEM_BASE_ADDR(1);
3326
++	pe[TMU1_ID].pmem_base_addr = TMU_IMEM_BASE_ADDR(1);
3327
++	pe[TMU1_ID].pmem_size = TMU_IMEM_SIZE;
3328
++	pe[TMU1_ID].mem_access_wdata = TMU_MEM_ACCESS_WDATA;
3329
++	pe[TMU1_ID].mem_access_addr = TMU_MEM_ACCESS_ADDR;
3330
++	pe[TMU1_ID].mem_access_rdata = TMU_MEM_ACCESS_RDATA;
3331
++
3332
++	pe[TMU3_ID].dmem_base_addr = TMU_DMEM_BASE_ADDR(3);
3333
++	pe[TMU3_ID].pmem_base_addr = TMU_IMEM_BASE_ADDR(3);
3334
++	pe[TMU3_ID].pmem_size = TMU_IMEM_SIZE;
3335
++	pe[TMU3_ID].mem_access_wdata = TMU_MEM_ACCESS_WDATA;
3336
++	pe[TMU3_ID].mem_access_addr = TMU_MEM_ACCESS_ADDR;
3337
++	pe[TMU3_ID].mem_access_rdata = TMU_MEM_ACCESS_RDATA;
3338
++
3339
++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
3340
++	pe[UTIL_ID].dmem_base_addr = UTIL_DMEM_BASE_ADDR;
3341
++	pe[UTIL_ID].mem_access_wdata = UTIL_MEM_ACCESS_WDATA;
3342
++	pe[UTIL_ID].mem_access_addr = UTIL_MEM_ACCESS_ADDR;
3343
++	pe[UTIL_ID].mem_access_rdata = UTIL_MEM_ACCESS_RDATA;
3344
++#endif
3345
++}
3346
++
3347
++/* Writes a buffer to PE internal memory from the host
3348
++ * through indirect access registers.
3349
++ *
3350
++ * @param[in] id		PE identification (CLASS0_ID, ..., TMU0_ID,
3351
++ * ..., UTIL_ID)
3352
++ * @param[in] src		Buffer source address
3353
++ * @param[in] mem_access_addr	DMEM destination address (must be 32bit
3354
++ * aligned)
3355
++ * @param[in] len		Number of bytes to copy
3356
++ */
3357
++void pe_mem_memcpy_to32(int id, u32 mem_access_addr, const void *src, unsigned
3358
++int len)
3359
++{
3360
++	u32 offset = 0, val, addr;
3361
++	unsigned int len32 = len >> 2;
3362
++	int i;
3363
++
3364
++	addr = mem_access_addr | PE_MEM_ACCESS_WRITE |
3365
++		PE_MEM_ACCESS_BYTE_ENABLE(0, 4);
3366
++
3367
++	for (i = 0; i < len32; i++, offset += 4, src += 4) {
3368
++		val = *(u32 *)src;
3369
++		writel(cpu_to_be32(val), pe[id].mem_access_wdata);
3370
++		writel(addr + offset, pe[id].mem_access_addr);
3371
++	}
3372
++
3373
++	len = (len & 0x3);
3374
++	if (len) {
3375
++		val = 0;
3376
++
3377
++		addr = (mem_access_addr | PE_MEM_ACCESS_WRITE |
3378
++			PE_MEM_ACCESS_BYTE_ENABLE(0, len)) + offset;
3379
++
3380
++		for (i = 0; i < len; i++, src++)
3381
++			val |= (*(u8 *)src) << (8 * i);
3382
++
3383
++		writel(cpu_to_be32(val), pe[id].mem_access_wdata);
3384
++		writel(addr, pe[id].mem_access_addr);
3385
++	}
3386
++}
3387
++
3388
++/* Writes a buffer to PE internal data memory (DMEM) from the host
3389
++ * through indirect access registers.
3390
++ * @param[in] id		PE identification (CLASS0_ID, ..., TMU0_ID,
3391
++ * ..., UTIL_ID)
3392
++ * @param[in] src		Buffer source address
3393
++ * @param[in] dst		DMEM destination address (must be 32bit
3394
++ * aligned)
3395
++ * @param[in] len		Number of bytes to copy
3396
++ */
3397
++void pe_dmem_memcpy_to32(int id, u32 dst, const void *src, unsigned int len)
3398
++{
3399
++	pe_mem_memcpy_to32(id, pe[id].dmem_base_addr | dst |
3400
++				PE_MEM_ACCESS_DMEM, src, len);
3401
++}
3402
++
3403
++/* Writes a buffer to PE internal program memory (PMEM) from the host
3404
++ * through indirect access registers.
3405
++ * @param[in] id		PE identification (CLASS0_ID, ..., TMU0_ID,
3406
++ * ..., TMU3_ID)
3407
++ * @param[in] src		Buffer source address
3408
++ * @param[in] dst		PMEM destination address (must be 32bit
3409
++ * aligned)
3410
++ * @param[in] len		Number of bytes to copy
3411
++ */
3412
++void pe_pmem_memcpy_to32(int id, u32 dst, const void *src, unsigned int len)
3413
++{
3414
++	pe_mem_memcpy_to32(id, pe[id].pmem_base_addr | (dst & (pe[id].pmem_size
3415
++				- 1)) | PE_MEM_ACCESS_IMEM, src, len);
3416
++}
3417
++
3418
++/* Reads PE internal program memory (IMEM) from the host
3419
++ * through indirect access registers.
3420
++ * @param[in] id		PE identification (CLASS0_ID, ..., TMU0_ID,
3421
++ * ..., TMU3_ID)
3422
++ * @param[in] addr		PMEM read address (must be aligned on size)
3423
++ * @param[in] size		Number of bytes to read (maximum 4, must not
3424
++ * cross 32bit boundaries)
3425
++ * @return			the data read (in PE endianness, i.e BE).
3426
++ */
3427
++u32 pe_pmem_read(int id, u32 addr, u8 size)
3428
++{
3429
++	u32 offset = addr & 0x3;
3430
++	u32 mask = 0xffffffff >> ((4 - size) << 3);
3431
++	u32 val;
3432
++
3433
++	addr = pe[id].pmem_base_addr | ((addr & ~0x3) & (pe[id].pmem_size - 1))
3434
++		| PE_MEM_ACCESS_IMEM | PE_MEM_ACCESS_BYTE_ENABLE(offset, size);
3435
++
3436
++	writel(addr, pe[id].mem_access_addr);
3437
++	val = be32_to_cpu(readl(pe[id].mem_access_rdata));
3438
++
3439
++	return (val >> (offset << 3)) & mask;
3440
++}
3441
++
3442
++/* Writes PE internal data memory (DMEM) from the host
3443
++ * through indirect access registers.
3444
++ * @param[in] id		PE identification (CLASS0_ID, ..., TMU0_ID,
3445
++ * ..., UTIL_ID)
3446
++ * @param[in] addr		DMEM write address (must be aligned on size)
3447
++ * @param[in] val		Value to write (in PE endianness, i.e BE)
3448
++ * @param[in] size		Number of bytes to write (maximum 4, must not
3449
++ * cross 32bit boundaries)
3450
++ */
3451
++void pe_dmem_write(int id, u32 val, u32 addr, u8 size)
3452
++{
3453
++	u32 offset = addr & 0x3;
3454
++
3455
++	addr = pe[id].dmem_base_addr | (addr & ~0x3) | PE_MEM_ACCESS_WRITE |
3456
++		PE_MEM_ACCESS_DMEM | PE_MEM_ACCESS_BYTE_ENABLE(offset, size);
3457
++
3458
++	/* Indirect access interface is byte swapping data being written */
3459
++	writel(cpu_to_be32(val << (offset << 3)), pe[id].mem_access_wdata);
3460
++	writel(addr, pe[id].mem_access_addr);
3461
++}
3462
++
3463
++/* Reads PE internal data memory (DMEM) from the host
3464
++ * through indirect access registers.
3465
++ * @param[in] id		PE identification (CLASS0_ID, ..., TMU0_ID,
3466
++ * ..., UTIL_ID)
3467
++ * @param[in] addr		DMEM read address (must be aligned on size)
3468
++ * @param[in] size		Number of bytes to read (maximum 4, must not
3469
++ * cross 32bit boundaries)
3470
++ * @return			the data read (in PE endianness, i.e BE).
3471
++ */
3472
++u32 pe_dmem_read(int id, u32 addr, u8 size)
3473
++{
3474
++	u32 offset = addr & 0x3;
3475
++	u32 mask = 0xffffffff >> ((4 - size) << 3);
3476
++	u32 val;
3477
++
3478
++	addr = pe[id].dmem_base_addr | (addr & ~0x3) | PE_MEM_ACCESS_DMEM |
3479
++			PE_MEM_ACCESS_BYTE_ENABLE(offset, size);
3480
++
3481
++	writel(addr, pe[id].mem_access_addr);
3482
++
3483
++	/* Indirect access interface is byte swapping data being read */
3484
++	val = be32_to_cpu(readl(pe[id].mem_access_rdata));
3485
++
3486
++	return (val >> (offset << 3)) & mask;
3487
++}
3488
++
3489
++/* This function is used to write to CLASS internal bus peripherals (ccu,
3490
++ * pe-lem) from the host
3491
++ * through indirect access registers.
3492
++ * @param[in]	val	value to write
3493
++ * @param[in]	addr	Address to write to (must be aligned on size)
3494
++ * @param[in]	size	Number of bytes to write (1, 2 or 4)
3495
++ *
3496
++ */
3497
++void class_bus_write(u32 val, u32 addr, u8 size)
3498
++{
3499
++	u32 offset = addr & 0x3;
3500
++
3501
++	writel((addr & CLASS_BUS_ACCESS_BASE_MASK), CLASS_BUS_ACCESS_BASE);
3502
++
3503
++	addr = (addr & ~CLASS_BUS_ACCESS_BASE_MASK) | PE_MEM_ACCESS_WRITE |
3504
++			(size << 24);
3505
++
3506
++	writel(cpu_to_be32(val << (offset << 3)), CLASS_BUS_ACCESS_WDATA);
3507
++	writel(addr, CLASS_BUS_ACCESS_ADDR);
3508
++}
3509
++
3510
++/* Reads from CLASS internal bus peripherals (ccu, pe-lem) from the host
3511
++ * through indirect access registers.
3512
++ * @param[in] addr	Address to read from (must be aligned on size)
3513
++ * @param[in] size	Number of bytes to read (1, 2 or 4)
3514
++ * @return		the read data
3515
++ *
3516
++ */
3517
++u32 class_bus_read(u32 addr, u8 size)
3518
++{
3519
++	u32 offset = addr & 0x3;
3520
++	u32 mask = 0xffffffff >> ((4 - size) << 3);
3521
++	u32 val;
3522
++
3523
++	writel((addr & CLASS_BUS_ACCESS_BASE_MASK), CLASS_BUS_ACCESS_BASE);
3524
++
3525
++	addr = (addr & ~CLASS_BUS_ACCESS_BASE_MASK) | (size << 24);
3526
++
3527
++	writel(addr, CLASS_BUS_ACCESS_ADDR);
3528
++	val = be32_to_cpu(readl(CLASS_BUS_ACCESS_RDATA));
3529
++
3530
++	return (val >> (offset << 3)) & mask;
3531
++}
3532
++
3533
++/* Writes data to the cluster memory (PE_LMEM)
3534
++ * @param[in] dst	PE LMEM destination address (must be 32bit aligned)
3535
++ * @param[in] src	Buffer source address
3536
++ * @param[in] len	Number of bytes to copy
3537
++ */
3538
++void class_pe_lmem_memcpy_to32(u32 dst, const void *src, unsigned int len)
3539
++{
3540
++	u32 len32 = len >> 2;
3541
++	int i;
3542
++
3543
++	for (i = 0; i < len32; i++, src += 4, dst += 4)
3544
++		class_bus_write(*(u32 *)src, dst, 4);
3545
++
3546
++	if (len & 0x2) {
3547
++		class_bus_write(*(u16 *)src, dst, 2);
3548
++		src += 2;
3549
++		dst += 2;
3550
++	}
3551
++
3552
++	if (len & 0x1) {
3553
++		class_bus_write(*(u8 *)src, dst, 1);
3554
++		src++;
3555
++		dst++;
3556
++	}
3557
++}
3558
++
3559
++/* Writes value to the cluster memory (PE_LMEM)
3560
++ * @param[in] dst	PE LMEM destination address (must be 32bit aligned)
3561
++ * @param[in] val	Value to write
3562
++ * @param[in] len	Number of bytes to write
3563
++ */
3564
++void class_pe_lmem_memset(u32 dst, int val, unsigned int len)
3565
++{
3566
++	u32 len32 = len >> 2;
3567
++	int i;
3568
++
3569
++	val = val | (val << 8) | (val << 16) | (val << 24);
3570
++
3571
++	for (i = 0; i < len32; i++, dst += 4)
3572
++		class_bus_write(val, dst, 4);
3573
++
3574
++	if (len & 0x2) {
3575
++		class_bus_write(val, dst, 2);
3576
++		dst += 2;
3577
++	}
3578
++
3579
++	if (len & 0x1) {
3580
++		class_bus_write(val, dst, 1);
3581
++		dst++;
3582
++	}
3583
++}
3584
++
3585
++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
3586
++
3587
++/* Writes UTIL program memory (DDR) from the host.
3588
++ *
3589
++ * @param[in] addr	Address to write (virtual, must be aligned on size)
3590
++ * @param[in] val		Value to write (in PE endianness, i.e BE)
3591
++ * @param[in] size		Number of bytes to write (2 or 4)
3592
++ */
3593
++static void util_pmem_write(u32 val, void *addr, u8 size)
3594
++{
3595
++	void *addr64 = (void *)((unsigned long)addr & ~0x7);
3596
++	unsigned long off = 8 - ((unsigned long)addr & 0x7) - size;
3597
++
3598
++	/*
3599
++	 * IMEM should  be loaded as a 64bit swapped value in a 64bit aligned
3600
++	 * location
3601
++	 */
3602
++	if (size == 4)
3603
++		writel(be32_to_cpu(val), addr64 + off);
3604
++	else
3605
++		writew(be16_to_cpu((u16)val), addr64 + off);
3606
++}
3607
++
3608
++/* Writes a buffer to UTIL program memory (DDR) from the host.
3609
++ *
3610
++ * @param[in] dst	Address to write (virtual, must be at least 16bit
3611
++ * aligned)
3612
++ * @param[in] src	Buffer to write (in PE endianness, i.e BE, must have
3613
++ * same alignment as dst)
3614
++ * @param[in] len	Number of bytes to write (must be at least 16bit
3615
++ * aligned)
3616
++ */
3617
++static void util_pmem_memcpy(void *dst, const void *src, unsigned int len)
3618
++{
3619
++	unsigned int len32;
3620
++	int i;
3621
++
3622
++	if ((unsigned long)src & 0x2) {
3623
++		util_pmem_write(*(u16 *)src, dst, 2);
3624
++		src += 2;
3625
++		dst += 2;
3626
++		len -= 2;
3627
++	}
3628
++
3629
++	len32 = len >> 2;
3630
++
3631
++	for (i = 0; i < len32; i++, dst += 4, src += 4)
3632
++		util_pmem_write(*(u32 *)src, dst, 4);
3633
++
3634
++	if (len & 0x2)
3635
++		util_pmem_write(*(u16 *)src, dst, len & 0x2);
3636
++}
3637
++#endif
3638
++
3639
++/* Loads an elf section into pmem
3640
++ * Code needs to be at least 16bit aligned and only PROGBITS sections are
3641
++ * supported
3642
++ *
3643
++ * @param[in] id	PE identification (CLASS0_ID, ..., TMU0_ID, ...,
3644
++ * TMU3_ID)
3645
++ * @param[in] data	pointer to the elf firmware
3646
++ * @param[in] shdr	pointer to the elf section header
3647
++ *
3648
++ */
3649
++static int pe_load_pmem_section(int id, const void *data,
3650
++				struct elf32_shdr *shdr)
3651
++{
3652
++	u32 offset = be32_to_cpu(shdr->sh_offset);
3653
++	u32 addr = be32_to_cpu(shdr->sh_addr);
3654
++	u32 size = be32_to_cpu(shdr->sh_size);
3655
++	u32 type = be32_to_cpu(shdr->sh_type);
3656
++
3657
++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
3658
++	if (id == UTIL_ID) {
3659
++		pr_err("%s: unsupported pmem section for UTIL\n",
3660
++		       __func__);
3661
++		return -EINVAL;
3662
++	}
3663
++#endif
3664
++
3665
++	if (((unsigned long)(data + offset) & 0x3) != (addr & 0x3)) {
3666
++		pr_err(
3667
++			"%s: load address(%x) and elf file address(%lx) don't have the same alignment\n"
3668
++			, __func__, addr, (unsigned long)data + offset);
3669
++
3670
++		return -EINVAL;
3671
++	}
3672
++
3673
++	if (addr & 0x1) {
3674
++		pr_err("%s: load address(%x) is not 16bit aligned\n",
3675
++		       __func__, addr);
3676
++		return -EINVAL;
3677
++	}
3678
++
3679
++	if (size & 0x1) {
3680
++		pr_err("%s: load size(%x) is not 16bit aligned\n",
3681
++		       __func__, size);
3682
++		return -EINVAL;
3683
++	}
3684
++
3685
++	switch (type) {
3686
++	case SHT_PROGBITS:
3687
++		pe_pmem_memcpy_to32(id, addr, data + offset, size);
3688
++
3689
++		break;
3690
++
3691
++	default:
3692
++		pr_err("%s: unsupported section type(%x)\n", __func__,
3693
++		       type);
3694
++		return -EINVAL;
3695
++	}
3696
++
3697
++	return 0;
3698
++}
3699
++
3700
++/* Loads an elf section into dmem
3701
++ * Data needs to be at least 32bit aligned, NOBITS sections are correctly
3702
++ * initialized to 0
3703
++ *
3704
++ * @param[in] id		PE identification (CLASS0_ID, ..., TMU0_ID,
3705
++ * ..., UTIL_ID)
3706
++ * @param[in] data		pointer to the elf firmware
3707
++ * @param[in] shdr		pointer to the elf section header
3708
++ *
3709
++ */
3710
++static int pe_load_dmem_section(int id, const void *data,
3711
++				struct elf32_shdr *shdr)
3712
++{
3713
++	u32 offset = be32_to_cpu(shdr->sh_offset);
3714
++	u32 addr = be32_to_cpu(shdr->sh_addr);
3715
++	u32 size = be32_to_cpu(shdr->sh_size);
3716
++	u32 type = be32_to_cpu(shdr->sh_type);
3717
++	u32 size32 = size >> 2;
3718
++	int i;
3719
++
3720
++	if (((unsigned long)(data + offset) & 0x3) != (addr & 0x3)) {
3721
++		pr_err(
3722
++			"%s: load address(%x) and elf file address(%lx) don't have the same alignment\n",
3723
++			__func__, addr, (unsigned long)data + offset);
3724
++
3725
++		return -EINVAL;
3726
++	}
3727
++
3728
++	if (addr & 0x3) {
3729
++		pr_err("%s: load address(%x) is not 32bit aligned\n",
3730
++		       __func__, addr);
3731
++		return -EINVAL;
3732
++	}
3733
++
3734
++	switch (type) {
3735
++	case SHT_PROGBITS:
3736
++		pe_dmem_memcpy_to32(id, addr, data + offset, size);
3737
++		break;
3738
++
3739
++	case SHT_NOBITS:
3740
++		for (i = 0; i < size32; i++, addr += 4)
3741
++			pe_dmem_write(id, 0, addr, 4);
3742
++
3743
++		if (size & 0x3)
3744
++			pe_dmem_write(id, 0, addr, size & 0x3);
3745
++
3746
++		break;
3747
++
3748
++	default:
3749
++		pr_err("%s: unsupported section type(%x)\n", __func__,
3750
++		       type);
3751
++		return -EINVAL;
3752
++	}
3753
++
3754
++	return 0;
3755
++}
3756
++
3757
++/* Loads an elf section into DDR
3758
++ * Data needs to be at least 32bit aligned, NOBITS sections are correctly
3759
++ * initialized to 0
3760
++ *
3761
++ * @param[in] id		PE identification (CLASS0_ID, ..., TMU0_ID,
3762
++ * ..., UTIL_ID)
3763
++ * @param[in] data		pointer to the elf firmware
3764
++ * @param[in] shdr		pointer to the elf section header
3765
++ *
3766
++ */
3767
++static int pe_load_ddr_section(int id, const void *data,
3768
++			       struct elf32_shdr *shdr,
3769
++			       struct device *dev) {
3770
++	u32 offset = be32_to_cpu(shdr->sh_offset);
3771
++	u32 addr = be32_to_cpu(shdr->sh_addr);
3772
++	u32 size = be32_to_cpu(shdr->sh_size);
3773
++	u32 type = be32_to_cpu(shdr->sh_type);
3774
++	u32 flags = be32_to_cpu(shdr->sh_flags);
3775
++
3776
++	switch (type) {
3777
++	case SHT_PROGBITS:
3778
++		if (flags & SHF_EXECINSTR) {
3779
++			if (id <= CLASS_MAX_ID) {
3780
++				/* DO the loading only once in DDR */
3781
++				if (id == CLASS0_ID) {
3782
++					pr_err(
3783
++						"%s: load address(%x) and elf file address(%lx) rcvd\n",
3784
++						__func__, addr,
3785
++						(unsigned long)data + offset);
3786
++					if (((unsigned long)(data + offset)
3787
++						& 0x3) != (addr & 0x3)) {
3788
++						pr_err(
3789
++							"%s: load address(%x) and elf file address(%lx) don't have the same alignment\n"
3790
++							, __func__, addr,
3791
++						(unsigned long)data + offset);
3792
++
3793
++						return -EINVAL;
3794
++					}
3795
++
3796
++					if (addr & 0x1) {
3797
++						pr_err(
3798
++							"%s: load address(%x) is not 16bit aligned\n"
3799
++							, __func__, addr);
3800
++						return -EINVAL;
3801
++					}
3802
++
3803
++					if (size & 0x1) {
3804
++						pr_err(
3805
++							"%s: load length(%x) is not 16bit aligned\n"
3806
++							, __func__, size);
3807
++						return -EINVAL;
3808
++					}
3809
++					memcpy(DDR_PHYS_TO_VIRT(
3810
++						DDR_PFE_TO_PHYS(addr)),
3811
++						data + offset, size);
3812
++				}
3813
++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
3814
++			} else if (id == UTIL_ID) {
3815
++				if (((unsigned long)(data + offset) & 0x3)
3816
++					!= (addr & 0x3)) {
3817
++					pr_err(
3818
++						"%s: load address(%x) and elf file address(%lx) don't have the same alignment\n"
3819
++						, __func__, addr,
3820
++						(unsigned long)data + offset);
3821
++
3822
++					return -EINVAL;
3823
++				}
3824
++
3825
++				if (addr & 0x1) {
3826
++					pr_err(
3827
++						"%s: load address(%x) is not 16bit aligned\n"
3828
++						, __func__, addr);
3829
++					return -EINVAL;
3830
++				}
3831
++
3832
++				if (size & 0x1) {
3833
++					pr_err(
3834
++						"%s: load length(%x) is not 16bit aligned\n"
3835
++						, __func__, size);
3836
++					return -EINVAL;
3837
++				}
3838
++
3839
++				util_pmem_memcpy(DDR_PHYS_TO_VIRT(
3840
++							DDR_PFE_TO_PHYS(addr)),
3841
++							data + offset, size);
3842
++			}
3843
++#endif
3844
++			} else {
3845
++				pr_err(
3846
++					"%s: unsupported ddr section type(%x) for PE(%d)\n"
3847
++						, __func__, type, id);
3848
++				return -EINVAL;
3849
++			}
3850
++
3851
++		} else {
3852
++			memcpy(DDR_PHYS_TO_VIRT(DDR_PFE_TO_PHYS(addr)), data
3853
++				+ offset, size);
3854
++		}
3855
++
3856
++		break;
3857
++
3858
++	case SHT_NOBITS:
3859
++		memset(DDR_PHYS_TO_VIRT(DDR_PFE_TO_PHYS(addr)), 0, size);
3860
++
3861
++		break;
3862
++
3863
++	default:
3864
++		pr_err("%s: unsupported section type(%x)\n", __func__,
3865
++		       type);
3866
++		return -EINVAL;
3867
++	}
3868
++
3869
++	return 0;
3870
++}
3871
++
3872
++/* Loads an elf section into pe lmem
3873
++ * Data needs to be at least 32bit aligned, NOBITS sections are correctly
3874
++ * initialized to 0
3875
++ *
3876
++ * @param[in] id		PE identification (CLASS0_ID,..., CLASS5_ID)
3877
++ * @param[in] data		pointer to the elf firmware
3878
++ * @param[in] shdr		pointer to the elf section header
3879
++ *
3880
++ */
3881
++static int pe_load_pe_lmem_section(int id, const void *data,
3882
++				   struct elf32_shdr *shdr)
3883
++{
3884
++	u32 offset = be32_to_cpu(shdr->sh_offset);
3885
++	u32 addr = be32_to_cpu(shdr->sh_addr);
3886
++	u32 size = be32_to_cpu(shdr->sh_size);
3887
++	u32 type = be32_to_cpu(shdr->sh_type);
3888
++
3889
++	if (id > CLASS_MAX_ID) {
3890
++		pr_err(
3891
++			"%s: unsupported pe-lmem section type(%x) for PE(%d)\n",
3892
++			 __func__, type, id);
3893
++		return -EINVAL;
3894
++	}
3895
++
3896
++	if (((unsigned long)(data + offset) & 0x3) != (addr & 0x3)) {
3897
++		pr_err(
3898
++			"%s: load address(%x) and elf file address(%lx) don't have the same alignment\n",
3899
++			__func__, addr, (unsigned long)data + offset);
3900
++
3901
++		return -EINVAL;
3902
++	}
3903
++
3904
++	if (addr & 0x3) {
3905
++		pr_err("%s: load address(%x) is not 32bit aligned\n",
3906
++		       __func__, addr);
3907
++		return -EINVAL;
3908
++	}
3909
++
3910
++	switch (type) {
3911
++	case SHT_PROGBITS:
3912
++		class_pe_lmem_memcpy_to32(addr, data + offset, size);
3913
++		break;
3914
++
3915
++	case SHT_NOBITS:
3916
++		class_pe_lmem_memset(addr, 0, size);
3917
++		break;
3918
++
3919
++	default:
3920
++		pr_err("%s: unsupported section type(%x)\n", __func__,
3921
++		       type);
3922
++		return -EINVAL;
3923
++	}
3924
++
3925
++	return 0;
3926
++}
3927
++
3928
++/* Loads an elf section into a PE
3929
++ * For now only supports loading a section to dmem (all PE's), pmem (class and
3930
++ * tmu PE's),
3931
++ * DDDR (util PE code)
3932
++ *
3933
++ * @param[in] id		PE identification (CLASS0_ID, ..., TMU0_ID,
3934
++ * ..., UTIL_ID)
3935
++ * @param[in] data		pointer to the elf firmware
3936
++ * @param[in] shdr		pointer to the elf section header
3937
++ *
3938
++ */
3939
++int pe_load_elf_section(int id, const void *data, struct elf32_shdr *shdr,
3940
++			struct device *dev) {
3941
++	u32 addr = be32_to_cpu(shdr->sh_addr);
3942
++	u32 size = be32_to_cpu(shdr->sh_size);
3943
++
3944
++	if (IS_DMEM(addr, size))
3945
++		return pe_load_dmem_section(id, data, shdr);
3946
++	else if (IS_PMEM(addr, size))
3947
++		return pe_load_pmem_section(id, data, shdr);
3948
++	else if (IS_PFE_LMEM(addr, size))
3949
++		return 0;
3950
++	else if (IS_PHYS_DDR(addr, size))
3951
++		return pe_load_ddr_section(id, data, shdr, dev);
3952
++	else if (IS_PE_LMEM(addr, size))
3953
++		return pe_load_pe_lmem_section(id, data, shdr);
3954
++
3955
++	pr_err("%s: unsupported memory range(%x)\n", __func__,
3956
++	       addr);
3957
++	return 0;
3958
++}
3959
++
3960
++/**************************** BMU ***************************/
3961
++
3962
++/* Initializes a BMU block.
3963
++ * @param[in] base	BMU block base address
3964
++ * @param[in] cfg	BMU configuration
3965
++ */
3966
++void bmu_init(void *base, struct BMU_CFG *cfg)
3967
++{
3968
++	bmu_disable(base);
3969
++
3970
++	bmu_set_config(base, cfg);
3971
++
3972
++	bmu_reset(base);
3973
++}
3974
++
3975
++/* Resets a BMU block.
3976
++ * @param[in] base	BMU block base address
3977
++ */
3978
++void bmu_reset(void *base)
3979
++{
3980
++	writel(CORE_SW_RESET, base + BMU_CTRL);
3981
++
3982
++	/* Wait for self clear */
3983
++	while (readl(base + BMU_CTRL) & CORE_SW_RESET)
3984
++		;
3985
++}
3986
++
3987
++/* Enabled a BMU block.
3988
++ * @param[in] base	BMU block base address
3989
++ */
3990
++void bmu_enable(void *base)
3991
++{
3992
++	writel(CORE_ENABLE, base + BMU_CTRL);
3993
++}
3994
++
3995
++/* Disables a BMU block.
3996
++ * @param[in] base	BMU block base address
3997
++ */
3998
++void bmu_disable(void *base)
3999
++{
4000
++	writel(CORE_DISABLE, base + BMU_CTRL);
4001
++}
4002
++
4003
++/* Sets the configuration of a BMU block.
4004
++ * @param[in] base	BMU block base address
4005
++ * @param[in] cfg	BMU configuration
4006
++ */
4007
++void bmu_set_config(void *base, struct BMU_CFG *cfg)
4008
++{
4009
++	writel(cfg->baseaddr, base + BMU_UCAST_BASE_ADDR);
4010
++	writel(cfg->count & 0xffff, base + BMU_UCAST_CONFIG);
4011
++	writel(cfg->size & 0xffff, base + BMU_BUF_SIZE);
4012
++
4013
++	/* Interrupts are never used */
4014
++	writel(cfg->low_watermark, base + BMU_LOW_WATERMARK);
4015
++	writel(cfg->high_watermark, base + BMU_HIGH_WATERMARK);
4016
++	writel(0x0, base + BMU_INT_ENABLE);
4017
++}
4018
++
4019
++/**************************** MTIP GEMAC ***************************/
4020
++
4021
++/* Enable Rx Checksum Engine. With this enabled, Frame with bad IP,
4022
++ *   TCP or UDP checksums are discarded
4023
++ *
4024
++ * @param[in] base	GEMAC base address.
4025
++ */
4026
++void gemac_enable_rx_checksum_offload(void *base)
4027
++{
4028
++	/*Do not find configuration to do this */
4029
++}
4030
++
4031
++/* Disable Rx Checksum Engine.
4032
++ *
4033
++ * @param[in] base	GEMAC base address.
4034
++ */
4035
++void gemac_disable_rx_checksum_offload(void *base)
4036
++{
4037
++	/*Do not find configuration to do this */
4038
++}
4039
++
4040
++/* GEMAC set speed.
4041
++ * @param[in] base	GEMAC base address
4042
++ * @param[in] speed	GEMAC speed (10, 100 or 1000 Mbps)
4043
++ */
4044
++void gemac_set_speed(void *base, enum mac_speed gem_speed)
4045
++{
4046
++	u32 ecr = readl(base + EMAC_ECNTRL_REG) & ~EMAC_ECNTRL_SPEED;
4047
++	u32 rcr = readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_RMII_10T;
4048
++
4049
++	switch (gem_speed) {
4050
++	case SPEED_10M:
4051
++			rcr |= EMAC_RCNTRL_RMII_10T;
4052
++			break;
4053
++
4054
++	case SPEED_1000M:
4055
++			ecr |= EMAC_ECNTRL_SPEED;
4056
++			break;
4057
++
4058
++	case SPEED_100M:
4059
++	default:
4060
++			/*It is in 100M mode */
4061
++			break;
4062
++	}
4063
++	writel(ecr, (base + EMAC_ECNTRL_REG));
4064
++	writel(rcr, (base + EMAC_RCNTRL_REG));
4065
++}
4066
++
4067
++/* GEMAC set duplex.
4068
++ * @param[in] base	GEMAC base address
4069
++ * @param[in] duplex	GEMAC duplex mode (Full, Half)
4070
++ */
4071
++void gemac_set_duplex(void *base, int duplex)
4072
++{
4073
++	if (duplex == DUPLEX_HALF) {
4074
++		writel(readl(base + EMAC_TCNTRL_REG) & ~EMAC_TCNTRL_FDEN, base
4075
++			+ EMAC_TCNTRL_REG);
4076
++		writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_DRT, (base
4077
++			+ EMAC_RCNTRL_REG));
4078
++	} else{
4079
++		writel(readl(base + EMAC_TCNTRL_REG) | EMAC_TCNTRL_FDEN, base
4080
++			+ EMAC_TCNTRL_REG);
4081
++		writel(readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_DRT, (base
4082
++			+ EMAC_RCNTRL_REG));
4083
++	}
4084
++}
4085
++
4086
++/* GEMAC set mode.
4087
++ * @param[in] base	GEMAC base address
4088
++ * @param[in] mode	GEMAC operation mode (MII, RMII, RGMII, SGMII)
4089
++ */
4090
++void gemac_set_mode(void *base, int mode)
4091
++{
4092
++	u32 val = readl(base + EMAC_RCNTRL_REG);
4093
++
4094
++	/*Remove loopbank*/
4095
++	val &= ~EMAC_RCNTRL_LOOP;
4096
++
4097
++	/*Enable flow control and MII mode*/
4098
++	val |= (EMAC_RCNTRL_FCE | EMAC_RCNTRL_MII_MODE);
4099
++
4100
++	writel(val, base + EMAC_RCNTRL_REG);
4101
++}
4102
++
4103
++/* GEMAC enable function.
4104
++ * @param[in] base	GEMAC base address
4105
++ */
4106
++void gemac_enable(void *base)
4107
++{
4108
++	writel(readl(base + EMAC_ECNTRL_REG) | EMAC_ECNTRL_ETHER_EN, base +
4109
++		EMAC_ECNTRL_REG);
4110
++}
4111
++
4112
++/* GEMAC disable function.
4113
++ * @param[in] base	GEMAC base address
4114
++ */
4115
++void gemac_disable(void *base)
4116
++{
4117
++	writel(readl(base + EMAC_ECNTRL_REG) & ~EMAC_ECNTRL_ETHER_EN, base +
4118
++		EMAC_ECNTRL_REG);
4119
++}
4120
++
4121
++/* GEMAC TX disable function.
4122
++ * @param[in] base	GEMAC base address
4123
++ */
4124
++void gemac_tx_disable(void *base)
4125
++{
4126
++	writel(readl(base + EMAC_TCNTRL_REG) | EMAC_TCNTRL_GTS, base +
4127
++		EMAC_TCNTRL_REG);
4128
++}
4129
++
4130
++void gemac_tx_enable(void *base)
4131
++{
4132
++	writel(readl(base + EMAC_TCNTRL_REG) & ~EMAC_TCNTRL_GTS, base +
4133
++			EMAC_TCNTRL_REG);
4134
++}
4135
++
4136
++/* Sets the hash register of the MAC.
4137
++ * This register is used for matching unicast and multicast frames.
4138
++ *
4139
++ * @param[in] base	GEMAC base address.
4140
++ * @param[in] hash	64-bit hash to be configured.
4141
++ */
4142
++void gemac_set_hash(void *base, struct pfe_mac_addr *hash)
4143
++{
4144
++	writel(hash->bottom,  base + EMAC_GALR);
4145
++	writel(hash->top, base + EMAC_GAUR);
4146
++}
4147
++
4148
++void gemac_set_laddrN(void *base, struct pfe_mac_addr *address,
4149
++		      unsigned int entry_index)
4150
++{
4151
++	if ((entry_index < 1) || (entry_index > EMAC_SPEC_ADDR_MAX))
4152
++		return;
4153
++
4154
++	entry_index = entry_index - 1;
4155
++	if (entry_index < 1) {
4156
++		writel(htonl(address->bottom),  base + EMAC_PHY_ADDR_LOW);
4157
++		writel((htonl(address->top) | 0x8808), base +
4158
++			EMAC_PHY_ADDR_HIGH);
4159
++	} else {
4160
++		writel(htonl(address->bottom),  base + ((entry_index - 1) * 8)
4161
++			+ EMAC_SMAC_0_0);
4162
++		writel((htonl(address->top) | 0x8808), base + ((entry_index -
4163
++			1) * 8) + EMAC_SMAC_0_1);
4164
++	}
4165
++}
4166
++
4167
++void gemac_clear_laddrN(void *base, unsigned int entry_index)
4168
++{
4169
++	if ((entry_index < 1) || (entry_index > EMAC_SPEC_ADDR_MAX))
4170
++		return;
4171
++
4172
++	entry_index = entry_index - 1;
4173
++	if (entry_index < 1) {
4174
++		writel(0, base + EMAC_PHY_ADDR_LOW);
4175
++		writel(0, base + EMAC_PHY_ADDR_HIGH);
4176
++	} else {
4177
++		writel(0,  base + ((entry_index - 1) * 8) + EMAC_SMAC_0_0);
4178
++		writel(0, base + ((entry_index - 1) * 8) + EMAC_SMAC_0_1);
4179
++	}
4180
++}
4181
++
4182
++/* Set the loopback mode of the MAC.  This can be either no loopback for
4183
++ * normal operation, local loopback through MAC internal loopback module or PHY
4184
++ *   loopback for external loopback through a PHY.  This asserts the external
4185
++ * loop pin.
4186
++ *
4187
++ * @param[in] base	GEMAC base address.
4188
++ * @param[in] gem_loop	Loopback mode to be enabled. LB_LOCAL - MAC
4189
++ * Loopback,
4190
++ *			LB_EXT - PHY Loopback.
4191
++ */
4192
++void gemac_set_loop(void *base, enum mac_loop gem_loop)
4193
++{
4194
++	pr_info("%s()\n", __func__);
4195
++	writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_LOOP, (base +
4196
++		EMAC_RCNTRL_REG));
4197
++}
4198
++
4199
++/* GEMAC allow frames
4200
++ * @param[in] base	GEMAC base address
4201
++ */
4202
++void gemac_enable_copy_all(void *base)
4203
++{
4204
++	writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_PROM, (base +
4205
++		EMAC_RCNTRL_REG));
4206
++}
4207
++
4208
++/* GEMAC do not allow frames
4209
++ * @param[in] base	GEMAC base address
4210
++ */
4211
++void gemac_disable_copy_all(void *base)
4212
++{
4213
++	writel(readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_PROM, (base +
4214
++		EMAC_RCNTRL_REG));
4215
++}
4216
++
4217
++/* GEMAC allow broadcast function.
4218
++ * @param[in] base	GEMAC base address
4219
++ */
4220
++void gemac_allow_broadcast(void *base)
4221
++{
4222
++	writel(readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_BC_REJ, base +
4223
++		EMAC_RCNTRL_REG);
4224
++}
4225
++
4226
++/* GEMAC no broadcast function.
4227
++ * @param[in] base	GEMAC base address
4228
++ */
4229
++void gemac_no_broadcast(void *base)
4230
++{
4231
++	writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_BC_REJ, base +
4232
++		EMAC_RCNTRL_REG);
4233
++}
4234
++
4235
++/* GEMAC enable 1536 rx function.
4236
++ * @param[in]	base	GEMAC base address
4237
++ */
4238
++void gemac_enable_1536_rx(void *base)
4239
++{
4240
++	/* Set 1536 as Maximum frame length */
4241
++	writel(readl(base + EMAC_RCNTRL_REG) | (1536 << 16), base +
4242
++		EMAC_RCNTRL_REG);
4243
++}
4244
++
4245
++/* GEMAC enable jumbo function.
4246
++ * @param[in]	base	GEMAC base address
4247
++ */
4248
++void gemac_enable_rx_jmb(void *base)
4249
++{
4250
++	writel(readl(base + EMAC_RCNTRL_REG) | (JUMBO_FRAME_SIZE << 16), base
4251
++		+ EMAC_RCNTRL_REG);
4252
++}
4253
++
4254
++/* GEMAC enable stacked vlan function.
4255
++ * @param[in]	base	GEMAC base address
4256
++ */
4257
++void gemac_enable_stacked_vlan(void *base)
4258
++{
4259
++	/* MTIP doesn't support stacked vlan */
4260
++}
4261
++
4262
++/* GEMAC enable pause rx function.
4263
++ * @param[in] base	GEMAC base address
4264
++ */
4265
++void gemac_enable_pause_rx(void *base)
4266
++{
4267
++	writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_FCE,
4268
++	       base + EMAC_RCNTRL_REG);
4269
++}
4270
++
4271
++/* GEMAC disable pause rx function.
4272
++ * @param[in] base	GEMAC base address
4273
++ */
4274
++void gemac_disable_pause_rx(void *base)
4275
++{
4276
++	writel(readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_FCE,
4277
++	       base + EMAC_RCNTRL_REG);
4278
++}
4279
++
4280
++/* GEMAC enable pause tx function.
4281
++ * @param[in] base GEMAC base address
4282
++ */
4283
++void gemac_enable_pause_tx(void *base)
4284
++{
4285
++	writel(EMAC_RX_SECTION_EMPTY_V, base + EMAC_RX_SECTION_EMPTY);
4286
++}
4287
++
4288
++/* GEMAC disable pause tx function.
4289
++ * @param[in] base GEMAC base address
4290
++ */
4291
++void gemac_disable_pause_tx(void *base)
4292
++{
4293
++	writel(0x0, base + EMAC_RX_SECTION_EMPTY);
4294
++}
4295
++
4296
++/* GEMAC wol configuration
4297
++ * @param[in] base	GEMAC base address
4298
++ * @param[in] wol_conf	WoL register configuration
4299
++ */
4300
++void gemac_set_wol(void *base, u32 wol_conf)
4301
++{
4302
++	u32  val = readl(base + EMAC_ECNTRL_REG);
4303
++
4304
++	if (wol_conf)
4305
++		val |= (EMAC_ECNTRL_MAGIC_ENA | EMAC_ECNTRL_SLEEP);
4306
++	else
4307
++		val &= ~(EMAC_ECNTRL_MAGIC_ENA | EMAC_ECNTRL_SLEEP);
4308
++	writel(val, base + EMAC_ECNTRL_REG);
4309
++}
4310
++
4311
++/* Sets Gemac bus width to 64bit
4312
++ * @param[in] base       GEMAC base address
4313
++ * @param[in] width     gemac bus width to be set possible values are 32/64/128
4314
++ */
4315
++void gemac_set_bus_width(void *base, int width)
4316
++{
4317
++}
4318
++
4319
++/* Sets Gemac configuration.
4320
++ * @param[in] base	GEMAC base address
4321
++ * @param[in] cfg	GEMAC configuration
4322
++ */
4323
++void gemac_set_config(void *base, struct gemac_cfg *cfg)
4324
++{
4325
++	/*GEMAC config taken from VLSI */
4326
++	writel(0x00000004, base + EMAC_TFWR_STR_FWD);
4327
++	writel(0x00000005, base + EMAC_RX_SECTION_FULL);
4328
++	writel(0x00003fff, base + EMAC_TRUNC_FL);
4329
++	writel(0x00000030, base + EMAC_TX_SECTION_EMPTY);
4330
++	writel(0x00000000, base + EMAC_MIB_CTRL_STS_REG);
4331
++
4332
++	gemac_set_mode(base, cfg->mode);
4333
++
4334
++	gemac_set_speed(base, cfg->speed);
4335
++
4336
++	gemac_set_duplex(base, cfg->duplex);
4337
++}
4338
++
4339
++/**************************** GPI ***************************/
4340
++
4341
++/* Initializes a GPI block.
4342
++ * @param[in] base	GPI base address
4343
++ * @param[in] cfg	GPI configuration
4344
++ */
4345
++void gpi_init(void *base, struct gpi_cfg *cfg)
4346
++{
4347
++	gpi_reset(base);
4348
++
4349
++	gpi_disable(base);
4350
++
4351
++	gpi_set_config(base, cfg);
4352
++}
4353
++
4354
++/* Resets a GPI block.
4355
++ * @param[in] base	GPI base address
4356
++ */
4357
++void gpi_reset(void *base)
4358
++{
4359
++	writel(CORE_SW_RESET, base + GPI_CTRL);
4360
++}
4361
++
4362
++/* Enables a GPI block.
4363
++ * @param[in] base	GPI base address
4364
++ */
4365
++void gpi_enable(void *base)
4366
++{
4367
++	writel(CORE_ENABLE, base + GPI_CTRL);
4368
++}
4369
++
4370
++/* Disables a GPI block.
4371
++ * @param[in] base	GPI base address
4372
++ */
4373
++void gpi_disable(void *base)
4374
++{
4375
++	writel(CORE_DISABLE, base + GPI_CTRL);
4376
++}
4377
++
4378
++/* Sets the configuration of a GPI block.
4379
++ * @param[in] base	GPI base address
4380
++ * @param[in] cfg	GPI configuration
4381
++ */
4382
++void gpi_set_config(void *base, struct gpi_cfg *cfg)
4383
++{
4384
++	writel(CBUS_VIRT_TO_PFE(BMU1_BASE_ADDR + BMU_ALLOC_CTRL),	base
4385
++		+ GPI_LMEM_ALLOC_ADDR);
4386
++	writel(CBUS_VIRT_TO_PFE(BMU1_BASE_ADDR + BMU_FREE_CTRL),	base
4387
++		+ GPI_LMEM_FREE_ADDR);
4388
++	writel(CBUS_VIRT_TO_PFE(BMU2_BASE_ADDR + BMU_ALLOC_CTRL),	base
4389
++		+ GPI_DDR_ALLOC_ADDR);
4390
++	writel(CBUS_VIRT_TO_PFE(BMU2_BASE_ADDR + BMU_FREE_CTRL),	base
4391
++		+ GPI_DDR_FREE_ADDR);
4392
++	writel(CBUS_VIRT_TO_PFE(CLASS_INQ_PKTPTR), base + GPI_CLASS_ADDR);
4393
++	writel(DDR_HDR_SIZE, base + GPI_DDR_DATA_OFFSET);
4394
++	writel(LMEM_HDR_SIZE, base + GPI_LMEM_DATA_OFFSET);
4395
++	writel(0, base + GPI_LMEM_SEC_BUF_DATA_OFFSET);
4396
++	writel(0, base + GPI_DDR_SEC_BUF_DATA_OFFSET);
4397
++	writel((DDR_HDR_SIZE << 16) |	LMEM_HDR_SIZE,	base + GPI_HDR_SIZE);
4398
++	writel((DDR_BUF_SIZE << 16) |	LMEM_BUF_SIZE,	base + GPI_BUF_SIZE);
4399
++
4400
++	writel(((cfg->lmem_rtry_cnt << 16) | (GPI_DDR_BUF_EN << 1) |
4401
++		GPI_LMEM_BUF_EN), base + GPI_RX_CONFIG);
4402
++	writel(cfg->tmlf_txthres, base + GPI_TMLF_TX);
4403
++	writel(cfg->aseq_len,	base + GPI_DTX_ASEQ);
4404
++	writel(1, base + GPI_TOE_CHKSUM_EN);
4405
++
4406
++	if (cfg->mtip_pause_reg) {
4407
++		writel(cfg->mtip_pause_reg, base + GPI_CSR_MTIP_PAUSE_REG);
4408
++		writel(EGPI_PAUSE_TIME, base + GPI_TX_PAUSE_TIME);
4409
++	}
4410
++}
4411
++
4412
++/**************************** CLASSIFIER ***************************/
4413
++
4414
++/* Initializes CLASSIFIER block.
4415
++ * @param[in] cfg	CLASSIFIER configuration
4416
++ */
4417
++void class_init(struct class_cfg *cfg)
4418
++{
4419
++	class_reset();
4420
++
4421
++	class_disable();
4422
++
4423
++	class_set_config(cfg);
4424
++}
4425
++
4426
++/* Resets CLASSIFIER block.
4427
++ *
4428
++ */
4429
++void class_reset(void)
4430
++{
4431
++	writel(CORE_SW_RESET, CLASS_TX_CTRL);
4432
++}
4433
++
4434
++/* Enables all CLASS-PE's cores.
4435
++ *
4436
++ */
4437
++void class_enable(void)
4438
++{
4439
++	writel(CORE_ENABLE, CLASS_TX_CTRL);
4440
++}
4441
++
4442
++/* Disables all CLASS-PE's cores.
4443
++ *
4444
++ */
4445
++void class_disable(void)
4446
++{
4447
++	writel(CORE_DISABLE, CLASS_TX_CTRL);
4448
++}
4449
++
4450
++/*
4451
++ * Sets the configuration of the CLASSIFIER block.
4452
++ * @param[in] cfg	CLASSIFIER configuration
4453
++ */
4454
++void class_set_config(struct class_cfg *cfg)
4455
++{
4456
++	u32 val;
4457
++
4458
++	/* Initialize route table */
4459
++	if (!cfg->resume)
4460
++		memset(DDR_PHYS_TO_VIRT(cfg->route_table_baseaddr), 0, (1 <<
4461
++		cfg->route_table_hash_bits) * CLASS_ROUTE_SIZE);
4462
++
4463
++#if !defined(LS1012A_PFE_RESET_WA)
4464
++	writel(cfg->pe_sys_clk_ratio,	CLASS_PE_SYS_CLK_RATIO);
4465
++#endif
4466
++
4467
++	writel((DDR_HDR_SIZE << 16) | LMEM_HDR_SIZE,	CLASS_HDR_SIZE);
4468
++	writel(LMEM_BUF_SIZE,				CLASS_LMEM_BUF_SIZE);
4469
++	writel(CLASS_ROUTE_ENTRY_SIZE(CLASS_ROUTE_SIZE) |
4470
++		CLASS_ROUTE_HASH_SIZE(cfg->route_table_hash_bits),
4471
++		CLASS_ROUTE_HASH_ENTRY_SIZE);
4472
++	writel(HIF_PKT_CLASS_EN | HIF_PKT_OFFSET(sizeof(struct hif_hdr)),
4473
++	       CLASS_HIF_PARSE);
4474
++
4475
++	val = HASH_CRC_PORT_IP | QB2BUS_LE;
4476
++
4477
++#if defined(CONFIG_IP_ALIGNED)
4478
++	val |= IP_ALIGNED;
4479
++#endif
4480
++
4481
++	/*
4482
++	 *  Class PE packet steering will only work if TOE mode, bridge fetch or
4483
++	 * route fetch are enabled (see class/qb_fet.v). Route fetch would
4484
++	 * trigger additional memory copies (likely from DDR because of hash
4485
++	 * table size, which cannot be reduced because PE software still
4486
++	 * relies on hash value computed in HW), so when not in TOE mode we
4487
++	 * simply enable HW bridge fetch even though we don't use it.
4488
++	 */
4489
++	if (cfg->toe_mode)
4490
++		val |= CLASS_TOE;
4491
++	else
4492
++		val |= HW_BRIDGE_FETCH;
4493
++
4494
++	writel(val, CLASS_ROUTE_MULTI);
4495
++
4496
++	writel(DDR_PHYS_TO_PFE(cfg->route_table_baseaddr),
4497
++	       CLASS_ROUTE_TABLE_BASE);
4498
++	writel(CLASS_PE0_RO_DM_ADDR0_VAL,		CLASS_PE0_RO_DM_ADDR0);
4499
++	writel(CLASS_PE0_RO_DM_ADDR1_VAL,		CLASS_PE0_RO_DM_ADDR1);
4500
++	writel(CLASS_PE0_QB_DM_ADDR0_VAL,		CLASS_PE0_QB_DM_ADDR0);
4501
++	writel(CLASS_PE0_QB_DM_ADDR1_VAL,		CLASS_PE0_QB_DM_ADDR1);
4502
++	writel(CBUS_VIRT_TO_PFE(TMU_PHY_INQ_PKTPTR),	CLASS_TM_INQ_ADDR);
4503
++
4504
++	writel(23, CLASS_AFULL_THRES);
4505
++	writel(23, CLASS_TSQ_FIFO_THRES);
4506
++
4507
++	writel(24, CLASS_MAX_BUF_CNT);
4508
++	writel(24, CLASS_TSQ_MAX_CNT);
4509
++}
4510
++
4511
++/**************************** TMU ***************************/
4512
++
4513
++void tmu_reset(void)
4514
++{
4515
++	writel(SW_RESET, TMU_CTRL);
4516
++}
4517
++
4518
++/* Initializes TMU block.
4519
++ * @param[in] cfg	TMU configuration
4520
++ */
4521
++void tmu_init(struct tmu_cfg *cfg)
4522
++{
4523
++	int q, phyno;
4524
++
4525
++	tmu_disable(0xF);
4526
++	mdelay(10);
4527
++
4528
++#if !defined(LS1012A_PFE_RESET_WA)
4529
++	/* keep in soft reset */
4530
++	writel(SW_RESET, TMU_CTRL);
4531
++#endif
4532
++	writel(0x3, TMU_SYS_GENERIC_CONTROL);
4533
++	writel(750, TMU_INQ_WATERMARK);
4534
++	writel(CBUS_VIRT_TO_PFE(EGPI1_BASE_ADDR +
4535
++		GPI_INQ_PKTPTR),	TMU_PHY0_INQ_ADDR);
4536
++	writel(CBUS_VIRT_TO_PFE(EGPI2_BASE_ADDR +
4537
++		GPI_INQ_PKTPTR),	TMU_PHY1_INQ_ADDR);
4538
++	writel(CBUS_VIRT_TO_PFE(HGPI_BASE_ADDR +
4539
++		GPI_INQ_PKTPTR),	TMU_PHY3_INQ_ADDR);
4540
++	writel(CBUS_VIRT_TO_PFE(HIF_NOCPY_RX_INQ0_PKTPTR), TMU_PHY4_INQ_ADDR);
4541
++	writel(CBUS_VIRT_TO_PFE(UTIL_INQ_PKTPTR), TMU_PHY5_INQ_ADDR);
4542
++	writel(CBUS_VIRT_TO_PFE(BMU2_BASE_ADDR + BMU_FREE_CTRL),
4543
++	       TMU_BMU_INQ_ADDR);
4544
++
4545
++	writel(0x3FF,	TMU_TDQ0_SCH_CTRL);	/*
4546
++						 * enabling all 10
4547
++						 * schedulers [9:0] of each TDQ
4548
++						 */
4549
++	writel(0x3FF,	TMU_TDQ1_SCH_CTRL);
4550
++	writel(0x3FF,	TMU_TDQ3_SCH_CTRL);
4551
++
4552
++#if !defined(LS1012A_PFE_RESET_WA)
4553
++	writel(cfg->pe_sys_clk_ratio,	TMU_PE_SYS_CLK_RATIO);
4554
++#endif
4555
++
4556
++#if !defined(LS1012A_PFE_RESET_WA)
4557
++	writel(DDR_PHYS_TO_PFE(cfg->llm_base_addr),	TMU_LLM_BASE_ADDR);
4558
++	/* Extra packet pointers will be stored from this address onwards */
4559
++
4560
++	writel(cfg->llm_queue_len,	TMU_LLM_QUE_LEN);
4561
++	writel(5,			TMU_TDQ_IIFG_CFG);
4562
++	writel(DDR_BUF_SIZE,		TMU_BMU_BUF_SIZE);
4563
++
4564
++	writel(0x0,			TMU_CTRL);
4565
++
4566
++	/* MEM init */
4567
++	pr_info("%s: mem init\n", __func__);
4568
++	writel(MEM_INIT,	TMU_CTRL);
4569
++
4570
++	while (!(readl(TMU_CTRL) & MEM_INIT_DONE))
4571
++		;
4572
++
4573
++	/* LLM init */
4574
++	pr_info("%s: lmem init\n", __func__);
4575
++	writel(LLM_INIT,	TMU_CTRL);
4576
++
4577
++	while (!(readl(TMU_CTRL) & LLM_INIT_DONE))
4578
++		;
4579
++#endif
4580
++	/* set up each queue for tail drop */
4581
++	for (phyno = 0; phyno < 4; phyno++) {
4582
++		if (phyno == 2)
4583
++			continue;
4584
++		for (q = 0; q < 16; q++) {
4585
++			u32 qdepth;
4586
++
4587
++			writel((phyno << 8) | q, TMU_TEQ_CTRL);
4588
++			writel(1 << 22, TMU_TEQ_QCFG); /*Enable tail drop */
4589
++
4590
++			if (phyno == 3)
4591
++				qdepth = DEFAULT_TMU3_QDEPTH;
4592
++			else
4593
++				qdepth = (q == 0) ? DEFAULT_Q0_QDEPTH :
4594
++						DEFAULT_MAX_QDEPTH;
4595
++
4596
++			/* LOG: 68855 */
4597
++			/*
4598
++			 * The following is a workaround for the reordered
4599
++			 * packet and BMU2 buffer leakage issue.
4600
++			 */
4601
++			if (CHIP_REVISION() == 0)
4602
++				qdepth = 31;
4603
++
4604
++			writel(qdepth << 18, TMU_TEQ_HW_PROB_CFG2);
4605
++			writel(qdepth >> 14, TMU_TEQ_HW_PROB_CFG3);
4606
++		}
4607
++	}
4608
++
4609
++#ifdef CFG_LRO
4610
++	/* Set TMU-3 queue 5 (LRO) in no-drop mode */
4611
++	writel((3 << 8) | TMU_QUEUE_LRO, TMU_TEQ_CTRL);
4612
++	writel(0, TMU_TEQ_QCFG);
4613
++#endif
4614
++
4615
++	writel(0x05, TMU_TEQ_DISABLE_DROPCHK);
4616
++
4617
++	writel(0x0, TMU_CTRL);
4618
++}
4619
++
4620
++/* Enables TMU-PE cores.
4621
++ * @param[in] pe_mask	TMU PE mask
4622
++ */
4623
++void tmu_enable(u32 pe_mask)
4624
++{
4625
++	writel(readl(TMU_TX_CTRL) | (pe_mask & 0xF), TMU_TX_CTRL);
4626
++}
4627
++
4628
++/* Disables TMU cores.
4629
++ * @param[in] pe_mask	TMU PE mask
4630
++ */
4631
++void tmu_disable(u32 pe_mask)
4632
++{
4633
++	writel(readl(TMU_TX_CTRL) & ~(pe_mask & 0xF), TMU_TX_CTRL);
4634
++}
4635
++
4636
++/* This will return the tmu queue status
4637
++ * @param[in] if_id	gem interface id or TMU index
4638
++ * @return		returns the bit mask of busy queues, zero means all
4639
++ * queues are empty
4640
++ */
4641
++u32 tmu_qstatus(u32 if_id)
4642
++{
4643
++	return cpu_to_be32(pe_dmem_read(TMU0_ID + if_id, TMU_DM_PESTATUS +
4644
++		offsetof(struct pe_status, tmu_qstatus), 4));
4645
++}
4646
++
4647
++u32 tmu_pkts_processed(u32 if_id)
4648
++{
4649
++	return cpu_to_be32(pe_dmem_read(TMU0_ID + if_id, TMU_DM_PESTATUS +
4650
++		offsetof(struct pe_status, rx), 4));
4651
++}
4652
++
4653
++/**************************** UTIL ***************************/
4654
++
4655
++/* Resets UTIL block.
4656
++ */
4657
++void util_reset(void)
4658
++{
4659
++	writel(CORE_SW_RESET, UTIL_TX_CTRL);
4660
++}
4661
++
4662
++/* Initializes UTIL block.
4663
++ * @param[in] cfg	UTIL configuration
4664
++ */
4665
++void util_init(struct util_cfg *cfg)
4666
++{
4667
++	writel(cfg->pe_sys_clk_ratio,   UTIL_PE_SYS_CLK_RATIO);
4668
++}
4669
++
4670
++/* Enables UTIL-PE core.
4671
++ *
4672
++ */
4673
++void util_enable(void)
4674
++{
4675
++	writel(CORE_ENABLE, UTIL_TX_CTRL);
4676
++}
4677
++
4678
++/* Disables UTIL-PE core.
4679
++ *
4680
++ */
4681
++void util_disable(void)
4682
++{
4683
++	writel(CORE_DISABLE, UTIL_TX_CTRL);
4684
++}
4685
++
4686
++/**************************** HIF ***************************/
4687
++/* Initializes HIF copy block.
4688
++ *
4689
++ */
4690
++void hif_init(void)
4691
++{
4692
++	/*Initialize HIF registers*/
4693
++	writel((HIF_RX_POLL_CTRL_CYCLE << 16) | HIF_TX_POLL_CTRL_CYCLE,
4694
++	       HIF_POLL_CTRL);
4695
++}
4696
++
4697
++/* Enable hif tx DMA and interrupt
4698
++ *
4699
++ */
4700
++void hif_tx_enable(void)
4701
++{
4702
++	writel(HIF_CTRL_DMA_EN, HIF_TX_CTRL);
4703
++	writel((readl(HIF_INT_ENABLE) | HIF_INT_EN | HIF_TXPKT_INT_EN),
4704
++	       HIF_INT_ENABLE);
4705
++}
4706
++
4707
++/* Disable hif tx DMA and interrupt
4708
++ *
4709
++ */
4710
++void hif_tx_disable(void)
4711
++{
4712
++	u32	hif_int;
4713
++
4714
++	writel(0, HIF_TX_CTRL);
4715
++
4716
++	hif_int = readl(HIF_INT_ENABLE);
4717
++	hif_int &= HIF_TXPKT_INT_EN;
4718
++	writel(hif_int, HIF_INT_ENABLE);
4719
++}
4720
++
4721
++/* Enable hif rx DMA and interrupt
4722
++ *
4723
++ */
4724
++void hif_rx_enable(void)
4725
++{
4726
++	hif_rx_dma_start();
4727
++	writel((readl(HIF_INT_ENABLE) | HIF_INT_EN | HIF_RXPKT_INT_EN),
4728
++	       HIF_INT_ENABLE);
4729
++}
4730
++
4731
++/* Disable hif rx DMA and interrupt
4732
++ *
4733
++ */
4734
++void hif_rx_disable(void)
4735
++{
4736
++	u32	hif_int;
4737
++
4738
++	writel(0, HIF_RX_CTRL);
4739
++
4740
++	hif_int = readl(HIF_INT_ENABLE);
4741
++	hif_int &= HIF_RXPKT_INT_EN;
4742
++	writel(hif_int, HIF_INT_ENABLE);
4743
++}
4744
+diff --git a/drivers/staging/fsl_ppfe/pfe_hif.c b/drivers/staging/fsl_ppfe/pfe_hif.c
4745
+new file mode 100644
4746
+index 000000000000..6844595da9f1
4747
+--- /dev/null
4748
+@@ -0,0 +1,1094 @@
4749
++/*
4750
++ * Copyright 2015-2016 Freescale Semiconductor, Inc.
4751
++ * Copyright 2017 NXP
4752
++ *
4753
++ * This program is free software; you can redistribute it and/or modify
4754
++ * it under the terms of the GNU General Public License as published by
4755
++ * the Free Software Foundation; either version 2 of the License, or
4756
++ * (at your option) any later version.
4757
++ *
4758
++ * This program is distributed in the hope that it will be useful,
4759
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4760
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
4761
++ * GNU General Public License for more details.
4762
++ *
4763
++ * You should have received a copy of the GNU General Public License
4764
++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
4765
++ */
4766
++
4767
++#include <linux/kernel.h>
4768
++#include <linux/interrupt.h>
4769
++#include <linux/dma-mapping.h>
4770
++#include <linux/dmapool.h>
4771
++#include <linux/sched.h>
4772
++#include <linux/module.h>
4773
++#include <linux/list.h>
4774
++#include <linux/kthread.h>
4775
++#include <linux/slab.h>
4776
++
4777
++#include <linux/io.h>
4778
++#include <asm/irq.h>
4779
++
4780
++#include "pfe_mod.h"
4781
++
4782
++#define HIF_INT_MASK	(HIF_INT | HIF_RXPKT_INT | HIF_TXPKT_INT)
4783
++
4784
++unsigned char napi_first_batch;
4785
++
4786
++static void pfe_tx_do_cleanup(unsigned long data);
4787
++
4788
++static int pfe_hif_alloc_descr(struct pfe_hif *hif)
4789
++{
4790
++	void *addr;
4791
++	dma_addr_t dma_addr;
4792
++	int err = 0;
4793
++
4794
++	pr_info("%s\n", __func__);
4795
++	addr = dma_alloc_coherent(pfe->dev,
4796
++				  HIF_RX_DESC_NT * sizeof(struct hif_desc) +
4797
++				  HIF_TX_DESC_NT * sizeof(struct hif_desc),
4798
++				  &dma_addr, GFP_KERNEL);
4799
++
4800
++	if (!addr) {
4801
++		pr_err("%s: Could not allocate buffer descriptors!\n"
4802
++			, __func__);
4803
++		err = -ENOMEM;
4804
++		goto err0;
4805
++	}
4806
++
4807
++	hif->descr_baseaddr_p = dma_addr;
4808
++	hif->descr_baseaddr_v = addr;
4809
++	hif->rx_ring_size = HIF_RX_DESC_NT;
4810
++	hif->tx_ring_size = HIF_TX_DESC_NT;
4811
++
4812
++	return 0;
4813
++
4814
++err0:
4815
++	return err;
4816
++}
4817
++
4818
++#if defined(LS1012A_PFE_RESET_WA)
4819
++static void pfe_hif_disable_rx_desc(struct pfe_hif *hif)
4820
++{
4821
++	int ii;
4822
++	struct hif_desc	*desc = hif->rx_base;
4823
++
4824
++	/*Mark all descriptors as LAST_BD */
4825
++	for (ii = 0; ii < hif->rx_ring_size; ii++) {
4826
++		desc->ctrl |= BD_CTRL_LAST_BD;
4827
++		desc++;
4828
++	}
4829
++}
4830
++
4831
++struct class_rx_hdr_t {
4832
++	u32     next_ptr;       /* ptr to the start of the first DDR buffer */
4833
++	u16     length;         /* total packet length */
4834
++	u16     phyno;          /* input physical port number */
4835
++	u32     status;         /* gemac status bits */
4836
++	u32     status2;            /* reserved for software usage */
4837
++};
4838
++
4839
++/* STATUS_BAD_FRAME_ERR is set for all errors (including checksums if enabled)
4840
++ * except overflow
4841
++ */
4842
++#define STATUS_BAD_FRAME_ERR            BIT(16)
4843
++#define STATUS_LENGTH_ERR               BIT(17)
4844
++#define STATUS_CRC_ERR                  BIT(18)
4845
++#define STATUS_TOO_SHORT_ERR            BIT(19)
4846
++#define STATUS_TOO_LONG_ERR             BIT(20)
4847
++#define STATUS_CODE_ERR                 BIT(21)
4848
++#define STATUS_MC_HASH_MATCH            BIT(22)
4849
++#define STATUS_CUMULATIVE_ARC_HIT       BIT(23)
4850
++#define STATUS_UNICAST_HASH_MATCH       BIT(24)
4851
++#define STATUS_IP_CHECKSUM_CORRECT      BIT(25)
4852
++#define STATUS_TCP_CHECKSUM_CORRECT     BIT(26)
4853
++#define STATUS_UDP_CHECKSUM_CORRECT     BIT(27)
4854
++#define STATUS_OVERFLOW_ERR             BIT(28) /* GPI error */
4855
++#define MIN_PKT_SIZE			64
4856
++
4857
++static inline void copy_to_lmem(u32 *dst, u32 *src, int len)
4858
++{
4859
++	int i;
4860
++
4861
++	for (i = 0; i < len; i += sizeof(u32))	{
4862
++		*dst = htonl(*src);
4863
++		dst++; src++;
4864
++	}
4865
++}
4866
++
4867
++static void send_dummy_pkt_to_hif(void)
4868
++{
4869
++	void *lmem_ptr, *ddr_ptr, *lmem_virt_addr;
4870
++	u32 physaddr;
4871
++	struct class_rx_hdr_t local_hdr;
4872
++	static u32 dummy_pkt[] =  {
4873
++		0x33221100, 0x2b785544, 0xd73093cb, 0x01000608,
4874
++		0x04060008, 0x2b780200, 0xd73093cb, 0x0a01a8c0,
4875
++		0x33221100, 0xa8c05544, 0x00000301, 0x00000000,
4876
++		0x00000000, 0x00000000, 0x00000000, 0xbe86c51f };
4877
++
4878
++	ddr_ptr = (void *)((u64)readl(BMU2_BASE_ADDR + BMU_ALLOC_CTRL));
4879
++	if (!ddr_ptr)
4880
++		return;
4881
++
4882
++	lmem_ptr = (void *)((u64)readl(BMU1_BASE_ADDR + BMU_ALLOC_CTRL));
4883
++	if (!lmem_ptr)
4884
++		return;
4885
++
4886
++	pr_info("Sending a dummy pkt to HIF %p %p\n", ddr_ptr, lmem_ptr);
4887
++	physaddr = (u32)DDR_VIRT_TO_PFE(ddr_ptr);
4888
++
4889
++	lmem_virt_addr = (void *)CBUS_PFE_TO_VIRT((unsigned long int)lmem_ptr);
4890
++
4891
++	local_hdr.phyno = htons(0); /* RX_PHY_0 */
4892
++	local_hdr.length = htons(MIN_PKT_SIZE);
4893
++
4894
++	local_hdr.next_ptr = htonl((u32)physaddr);
4895
++	/*Mark checksum is correct */
4896
++	local_hdr.status = htonl((STATUS_IP_CHECKSUM_CORRECT |
4897
++				STATUS_UDP_CHECKSUM_CORRECT |
4898
++				STATUS_TCP_CHECKSUM_CORRECT |
4899
++				STATUS_UNICAST_HASH_MATCH |
4900
++				STATUS_CUMULATIVE_ARC_HIT));
4901
++	copy_to_lmem((u32 *)lmem_virt_addr, (u32 *)&local_hdr,
4902
++		     sizeof(local_hdr));
4903
++
4904
++	copy_to_lmem((u32 *)(lmem_virt_addr + LMEM_HDR_SIZE), (u32 *)dummy_pkt,
4905
++		     0x40);
4906
++
4907
++	writel((unsigned long int)lmem_ptr, CLASS_INQ_PKTPTR);
4908
++}
4909
++
4910
++void pfe_hif_rx_idle(struct pfe_hif *hif)
4911
++{
4912
++	int hif_stop_loop = 10;
4913
++	u32 rx_status;
4914
++
4915
++	pfe_hif_disable_rx_desc(hif);
4916
++	pr_info("Bringing hif to idle state...");
4917
++	writel(0, HIF_INT_ENABLE);
4918
++	/*If HIF Rx BDP is busy send a dummy packet */
4919
++	do {
4920
++		rx_status = readl(HIF_RX_STATUS);
4921
++		if (rx_status & BDP_CSR_RX_DMA_ACTV)
4922
++			send_dummy_pkt_to_hif();
4923
++
4924
++		usleep_range(100, 150);
4925
++	} while (--hif_stop_loop);
4926
++
4927
++	if (readl(HIF_RX_STATUS) & BDP_CSR_RX_DMA_ACTV)
4928
++		pr_info("Failed\n");
4929
++	else
4930
++		pr_info("Done\n");
4931
++}
4932
++#endif
4933
++
4934
++static void pfe_hif_free_descr(struct pfe_hif *hif)
4935
++{
4936
++	pr_info("%s\n", __func__);
4937
++
4938
++	dma_free_coherent(pfe->dev,
4939
++			  hif->rx_ring_size * sizeof(struct hif_desc) +
4940
++			  hif->tx_ring_size * sizeof(struct hif_desc),
4941
++			  hif->descr_baseaddr_v, hif->descr_baseaddr_p);
4942
++}
4943
++
4944
++void pfe_hif_desc_dump(struct pfe_hif *hif)
4945
++{
4946
++	struct hif_desc	*desc;
4947
++	unsigned long desc_p;
4948
++	int ii = 0;
4949
++
4950
++	pr_info("%s\n", __func__);
4951
++
4952
++	desc = hif->rx_base;
4953
++	desc_p = (u32)((u64)desc - (u64)hif->descr_baseaddr_v +
4954
++			hif->descr_baseaddr_p);
4955
++
4956
++	pr_info("HIF Rx desc base %p physical %x\n", desc, (u32)desc_p);
4957
++	for (ii = 0; ii < hif->rx_ring_size; ii++) {
4958
++		pr_info("status: %08x, ctrl: %08x, data: %08x, next: %x\n",
4959
++			readl(&desc->status), readl(&desc->ctrl),
4960
++			readl(&desc->data), readl(&desc->next));
4961
++			desc++;
4962
++	}
4963
++
4964
++	desc = hif->tx_base;
4965
++	desc_p = ((u64)desc - (u64)hif->descr_baseaddr_v +
4966
++			hif->descr_baseaddr_p);
4967
++
4968
++	pr_info("HIF Tx desc base %p physical %x\n", desc, (u32)desc_p);
4969
++	for (ii = 0; ii < hif->tx_ring_size; ii++) {
4970
++		pr_info("status: %08x, ctrl: %08x, data: %08x, next: %x\n",
4971
++			readl(&desc->status), readl(&desc->ctrl),
4972
++			readl(&desc->data), readl(&desc->next));
4973
++		desc++;
4974
++	}
4975
++}
4976
++
4977
++/* pfe_hif_release_buffers */
4978
++static void pfe_hif_release_buffers(struct pfe_hif *hif)
4979
++{
4980
++	struct hif_desc	*desc;
4981
++	int i = 0;
4982
++
4983
++	hif->rx_base = hif->descr_baseaddr_v;
4984
++
4985
++	pr_info("%s\n", __func__);
4986
++
4987
++	/*Free Rx buffers */
4988
++	desc = hif->rx_base;
4989
++	for (i = 0; i < hif->rx_ring_size; i++) {
4990
++		if (readl(&desc->data)) {
4991
++			if ((i < hif->shm->rx_buf_pool_cnt) &&
4992
++			    (!hif->shm->rx_buf_pool[i])) {
4993
++				/*
4994
++				 * dma_unmap_single(hif->dev, desc->data,
4995
++				 * hif->rx_buf_len[i], DMA_FROM_DEVICE);
4996
++				 */
4997
++				dma_unmap_single(hif->dev,
4998
++						 DDR_PFE_TO_PHYS(
4999
++						 readl(&desc->data)),
5000
++						 hif->rx_buf_len[i],
5001
++						 DMA_FROM_DEVICE);
5002
++				hif->shm->rx_buf_pool[i] = hif->rx_buf_addr[i];
5003
++			} else {
5004
++				pr_err("%s: buffer pool already full\n"
5005
++					, __func__);
5006
++			}
5007
++		}
5008
++
5009
++		writel(0, &desc->data);
5010
++		writel(0, &desc->status);
5011
++		writel(0, &desc->ctrl);
5012
++		desc++;
5013
++	}
5014
++}
5015
++
5016
++/*
5017
++ * pfe_hif_init_buffers
5018
++ * This function initializes the HIF Rx/Tx ring descriptors and
5019
++ * initialize Rx queue with buffers.
5020
++ */
5021
++static int pfe_hif_init_buffers(struct pfe_hif *hif)
5022
++{
5023
++	struct hif_desc	*desc, *first_desc_p;
5024
++	u32 data;
5025
++	int i = 0;
5026
++
5027
++	pr_info("%s\n", __func__);
5028
++
5029
++	/* Check enough Rx buffers available in the shared memory */
5030
++	if (hif->shm->rx_buf_pool_cnt < hif->rx_ring_size)
5031
++		return -ENOMEM;
5032
++
5033
++	hif->rx_base = hif->descr_baseaddr_v;
5034
++	memset(hif->rx_base, 0, hif->rx_ring_size * sizeof(struct hif_desc));
5035
++
5036
++	/*Initialize Rx descriptors */
5037
++	desc = hif->rx_base;
5038
++	first_desc_p = (struct hif_desc *)hif->descr_baseaddr_p;
5039
++
5040
++	for (i = 0; i < hif->rx_ring_size; i++) {
5041
++		/* Initialize Rx buffers from the shared memory */
5042
++
5043
++		data = (u32)dma_map_single(hif->dev, hif->shm->rx_buf_pool[i],
5044
++				pfe_pkt_size, DMA_FROM_DEVICE);
5045
++		hif->rx_buf_addr[i] = hif->shm->rx_buf_pool[i];
5046
++		hif->rx_buf_len[i] = pfe_pkt_size;
5047
++		hif->shm->rx_buf_pool[i] = NULL;
5048
++
5049
++		if (likely(dma_mapping_error(hif->dev, data) == 0)) {
5050
++			writel(DDR_PHYS_TO_PFE(data), &desc->data);
5051
++		} else {
5052
++			pr_err("%s : low on mem\n",  __func__);
5053
++
5054
++			goto err;
5055
++		}
5056
++
5057
++		writel(0, &desc->status);
5058
++
5059
++		/*
5060
++		 * Ensure everything else is written to DDR before
5061
++		 * writing bd->ctrl
5062
++		 */
5063
++		wmb();
5064
++
5065
++		writel((BD_CTRL_PKT_INT_EN | BD_CTRL_LIFM
5066
++			| BD_CTRL_DIR | BD_CTRL_DESC_EN
5067
++			| BD_BUF_LEN(pfe_pkt_size)), &desc->ctrl);
5068
++
5069
++		/* Chain descriptors */
5070
++		writel((u32)DDR_PHYS_TO_PFE(first_desc_p + i + 1), &desc->next);
5071
++		desc++;
5072
++	}
5073
++
5074
++	/* Overwrite last descriptor to chain it to first one*/
5075
++	desc--;
5076
++	writel((u32)DDR_PHYS_TO_PFE(first_desc_p), &desc->next);
5077
++
5078
++	hif->rxtoclean_index = 0;
5079
++
5080
++	/*Initialize Rx buffer descriptor ring base address */
5081
++	writel(DDR_PHYS_TO_PFE(hif->descr_baseaddr_p), HIF_RX_BDP_ADDR);
5082
++
5083
++	hif->tx_base = hif->rx_base + hif->rx_ring_size;
5084
++	first_desc_p = (struct hif_desc *)hif->descr_baseaddr_p +
5085
++				hif->rx_ring_size;
5086
++	memset(hif->tx_base, 0, hif->tx_ring_size * sizeof(struct hif_desc));
5087
++
5088
++	/*Initialize tx descriptors */
5089
++	desc = hif->tx_base;
5090
++
5091
++	for (i = 0; i < hif->tx_ring_size; i++) {
5092
++		/* Chain descriptors */
5093
++		writel((u32)DDR_PHYS_TO_PFE(first_desc_p + i + 1), &desc->next);
5094
++		writel(0, &desc->ctrl);
5095
++		desc++;
5096
++	}
5097
++
5098
++	/* Overwrite last descriptor to chain it to first one */
5099
++	desc--;
5100
++	writel((u32)DDR_PHYS_TO_PFE(first_desc_p), &desc->next);
5101
++	hif->txavail = hif->tx_ring_size;
5102
++	hif->txtosend = 0;
5103
++	hif->txtoclean = 0;
5104
++	hif->txtoflush = 0;
5105
++
5106
++	/*Initialize Tx buffer descriptor ring base address */
5107
++	writel((u32)DDR_PHYS_TO_PFE(first_desc_p), HIF_TX_BDP_ADDR);
5108
++
5109
++	return 0;
5110
++
5111
++err:
5112
++	pfe_hif_release_buffers(hif);
5113
++	return -ENOMEM;
5114
++}
5115
++
5116
++/*
5117
++ * pfe_hif_client_register
5118
++ *
5119
++ * This function used to register a client driver with the HIF driver.
5120
++ *
5121
++ * Return value:
5122
++ * 0 - on Successful registration
5123
++ */
5124
++static int pfe_hif_client_register(struct pfe_hif *hif, u32 client_id,
5125
++				   struct hif_client_shm *client_shm)
5126
++{
5127
++	struct hif_client *client = &hif->client[client_id];
5128
++	u32 i, cnt;
5129
++	struct rx_queue_desc *rx_qbase;
5130
++	struct tx_queue_desc *tx_qbase;
5131
++	struct hif_rx_queue *rx_queue;
5132
++	struct hif_tx_queue *tx_queue;
5133
++	int err = 0;
5134
++
5135
++	pr_info("%s\n", __func__);
5136
++
5137
++	spin_lock_bh(&hif->tx_lock);
5138
++
5139
++	if (test_bit(client_id, &hif->shm->g_client_status[0])) {
5140
++		pr_err("%s: client %d already registered\n",
5141
++		       __func__, client_id);
5142
++		err = -1;
5143
++		goto unlock;
5144
++	}
5145
++
5146
++	memset(client, 0, sizeof(struct hif_client));
5147
++
5148
++	/* Initialize client Rx queues baseaddr, size */
5149
++
5150
++	cnt = CLIENT_CTRL_RX_Q_CNT(client_shm->ctrl);
5151
++	/* Check if client is requesting for more queues than supported */
5152
++	if (cnt > HIF_CLIENT_QUEUES_MAX)
5153
++		cnt = HIF_CLIENT_QUEUES_MAX;
5154
++
5155
++	client->rx_qn = cnt;
5156
++	rx_qbase = (struct rx_queue_desc *)client_shm->rx_qbase;
5157
++	for (i = 0; i < cnt; i++) {
5158
++		rx_queue = &client->rx_q[i];
5159
++		rx_queue->base = rx_qbase + i * client_shm->rx_qsize;
5160
++		rx_queue->size = client_shm->rx_qsize;
5161
++		rx_queue->write_idx = 0;
5162
++	}
5163
++
5164
++	/* Initialize client Tx queues baseaddr, size */
5165
++	cnt = CLIENT_CTRL_TX_Q_CNT(client_shm->ctrl);
5166
++
5167
++	/* Check if client is requesting for more queues than supported */
5168
++	if (cnt > HIF_CLIENT_QUEUES_MAX)
5169
++		cnt = HIF_CLIENT_QUEUES_MAX;
5170
++
5171
++	client->tx_qn = cnt;
5172
++	tx_qbase = (struct tx_queue_desc *)client_shm->tx_qbase;
5173
++	for (i = 0; i < cnt; i++) {
5174
++		tx_queue = &client->tx_q[i];
5175
++		tx_queue->base = tx_qbase + i * client_shm->tx_qsize;
5176
++		tx_queue->size = client_shm->tx_qsize;
5177
++		tx_queue->ack_idx = 0;
5178
++	}
5179
++
5180
++	set_bit(client_id, &hif->shm->g_client_status[0]);
5181
++
5182
++unlock:
5183
++	spin_unlock_bh(&hif->tx_lock);
5184
++
5185
++	return err;
5186
++}
5187
++
5188
++/*
5189
++ * pfe_hif_client_unregister
5190
++ *
5191
++ * This function used to unregister a client  from the HIF driver.
5192
++ *
5193
++ */
5194
++static void pfe_hif_client_unregister(struct pfe_hif *hif, u32 client_id)
5195
++{
5196
++	pr_info("%s\n", __func__);
5197
++
5198
++	/*
5199
++	 * Mark client as no longer available (which prevents further packet
5200
++	 * receive for this client)
5201
++	 */
5202
++	spin_lock_bh(&hif->tx_lock);
5203
++
5204
++	if (!test_bit(client_id, &hif->shm->g_client_status[0])) {
5205
++		pr_err("%s: client %d not registered\n", __func__,
5206
++		       client_id);
5207
++
5208
++		spin_unlock_bh(&hif->tx_lock);
5209
++		return;
5210
++	}
5211
++
5212
++	clear_bit(client_id, &hif->shm->g_client_status[0]);
5213
++
5214
++	spin_unlock_bh(&hif->tx_lock);
5215
++}
5216
++
5217
++/*
5218
++ * client_put_rxpacket-
5219
++ * This functions puts the Rx pkt  in the given client Rx queue.
5220
++ * It actually swap the Rx pkt in the client Rx descriptor buffer
5221
++ * and returns the free buffer from it.
5222
++ *
5223
++ * If the function returns NULL means client Rx queue is full and
5224
++ * packet couldn't send to client queue.
5225
++ */
5226
++static void *client_put_rxpacket(struct hif_rx_queue *queue, void *pkt, u32 len,
5227
++				 u32 flags, u32 client_ctrl, u32 *rem_len)
5228
++{
5229
++	void *free_pkt = NULL;
5230
++	struct rx_queue_desc *desc = queue->base + queue->write_idx;
5231
++
5232
++	if (readl(&desc->ctrl) & CL_DESC_OWN) {
5233
++		if (page_mode) {
5234
++			int rem_page_size = PAGE_SIZE -
5235
++					PRESENT_OFST_IN_PAGE(pkt);
5236
++			int cur_pkt_size = ROUND_MIN_RX_SIZE(len +
5237
++					pfe_pkt_headroom);
5238
++			*rem_len = (rem_page_size - cur_pkt_size);
5239
++			if (*rem_len) {
5240
++				free_pkt = pkt + cur_pkt_size;
5241
++				get_page(virt_to_page(free_pkt));
5242
++			} else {
5243
++				free_pkt = (void
5244
++				*)__get_free_page(GFP_ATOMIC | GFP_DMA_PFE);
5245
++				*rem_len = pfe_pkt_size;
5246
++			}
5247
++		} else {
5248
++			free_pkt = kmalloc(PFE_BUF_SIZE, GFP_ATOMIC |
5249
++					GFP_DMA_PFE);
5250
++			*rem_len = PFE_BUF_SIZE - pfe_pkt_headroom;
5251
++		}
5252
++
5253
++		if (free_pkt) {
5254
++			desc->data = pkt;
5255
++			desc->client_ctrl = client_ctrl;
5256
++			/*
5257
++			 * Ensure everything else is written to DDR before
5258
++			 * writing bd->ctrl
5259
++			 */
5260
++			smp_wmb();
5261
++			writel(CL_DESC_BUF_LEN(len) | flags, &desc->ctrl);
5262
++			/* queue->write_idx = (queue->write_idx + 1)
5263
++			 *		       & (queue->size - 1);
5264
++			 */
5265
++			free_pkt += pfe_pkt_headroom;
5266
++		}
5267
++	}
5268
++
5269
++	return free_pkt;
5270
++}
5271
++
5272
++/*
5273
++ * pfe_hif_rx_process-
5274
++ * This function does pfe hif rx queue processing.
5275
++ * Dequeue packet from Rx queue and send it to corresponding client queue
5276
++ */
5277
++static int pfe_hif_rx_process(struct pfe_hif *hif, int budget)
5278
++{
5279
++	struct hif_desc	*desc;
5280
++	struct hif_hdr *pkt_hdr;
5281
++	struct __hif_hdr hif_hdr;
5282
++	void *free_buf;
5283
++	int rtc, len, rx_processed = 0;
5284
++	struct __hif_desc local_desc;
5285
++	int flags;
5286
++	unsigned int desc_p;
5287
++	unsigned int buf_size = 0;
5288
++
5289
++	spin_lock_bh(&hif->lock);
5290
++
5291
++	rtc = hif->rxtoclean_index;
5292
++
5293
++	while (rx_processed < budget) {
5294
++		desc = hif->rx_base + rtc;
5295
++
5296
++		__memcpy12(&local_desc, desc);
5297
++
5298
++		/* ACK pending Rx interrupt */
5299
++		if (local_desc.ctrl & BD_CTRL_DESC_EN) {
5300
++			writel(HIF_INT | HIF_RXPKT_INT, HIF_INT_SRC);
5301
++
5302
++			if (rx_processed == 0) {
5303
++				if (napi_first_batch == 1) {
5304
++					desc_p = hif->descr_baseaddr_p +
5305
++					((unsigned long int)(desc) -
5306
++					(unsigned long
5307
++					int)hif->descr_baseaddr_v);
5308
++					napi_first_batch = 0;
5309
++				}
5310
++			}
5311
++
5312
++			__memcpy12(&local_desc, desc);
5313
++
5314
++			if (local_desc.ctrl & BD_CTRL_DESC_EN)
5315
++				break;
5316
++		}
5317
++
5318
++		napi_first_batch = 0;
5319
++
5320
++#ifdef HIF_NAPI_STATS
5321
++		hif->napi_counters[NAPI_DESC_COUNT]++;
5322
++#endif
5323
++		len = BD_BUF_LEN(local_desc.ctrl);
5324
++		/*
5325
++		 * dma_unmap_single(hif->dev, DDR_PFE_TO_PHYS(local_desc.data),
5326
++		 * hif->rx_buf_len[rtc], DMA_FROM_DEVICE);
5327
++		 */
5328
++		dma_unmap_single(hif->dev, DDR_PFE_TO_PHYS(local_desc.data),
5329
++				 hif->rx_buf_len[rtc], DMA_FROM_DEVICE);
5330
++
5331
++		pkt_hdr = (struct hif_hdr *)hif->rx_buf_addr[rtc];
5332
++
5333
++		/* Track last HIF header received */
5334
++		if (!hif->started) {
5335
++			hif->started = 1;
5336
++
5337
++			__memcpy8(&hif_hdr, pkt_hdr);
5338
++
5339
++			hif->qno = hif_hdr.hdr.q_num;
5340
++			hif->client_id = hif_hdr.hdr.client_id;
5341
++			hif->client_ctrl = (hif_hdr.hdr.client_ctrl1 << 16) |
5342
++						hif_hdr.hdr.client_ctrl;
5343
++			flags = CL_DESC_FIRST;
5344
++
5345
++		} else {
5346
++			flags = 0;
5347
++		}
5348
++
5349
++		if (local_desc.ctrl & BD_CTRL_LIFM)
5350
++			flags |= CL_DESC_LAST;
5351
++
5352
++		/* Check for valid client id and still registered */
5353
++		if ((hif->client_id >= HIF_CLIENTS_MAX) ||
5354
++		    !(test_bit(hif->client_id,
5355
++			&hif->shm->g_client_status[0]))) {
5356
++			printk_ratelimited("%s: packet with invalid client id %d q_num %d\n",
5357
++					   __func__,
5358
++					   hif->client_id,
5359
++					   hif->qno);
5360
++
5361
++			free_buf = pkt_hdr;
5362
++
5363
++			goto pkt_drop;
5364
++		}
5365
++
5366
++		/* Check to valid queue number */
5367
++		if (hif->client[hif->client_id].rx_qn <= hif->qno) {
5368
++			pr_info("%s: packet with invalid queue: %d\n"
5369
++				, __func__, hif->qno);
5370
++			hif->qno = 0;
5371
++		}
5372
++
5373
++		free_buf =
5374
++		client_put_rxpacket(&hif->client[hif->client_id].rx_q[hif->qno],
5375
++				    (void *)pkt_hdr, len, flags,
5376
++			hif->client_ctrl, &buf_size);
5377
++
5378
++		hif_lib_indicate_client(hif->client_id, EVENT_RX_PKT_IND,
5379
++					hif->qno);
5380
++
5381
++		if (unlikely(!free_buf)) {
5382
++#ifdef HIF_NAPI_STATS
5383
++			hif->napi_counters[NAPI_CLIENT_FULL_COUNT]++;
5384
++#endif
5385
++			/*
5386
++			 * If we want to keep in polling mode to retry later,
5387
++			 * we need to tell napi that we consumed
5388
++			 * the full budget or we will hit a livelock scenario.
5389
++			 * The core code keeps this napi instance
5390
++			 * at the head of the list and none of the other
5391
++			 * instances get to run
5392
++			 */
5393
++			rx_processed = budget;
5394
++
5395
++			if (flags & CL_DESC_FIRST)
5396
++				hif->started = 0;
5397
++
5398
++			break;
5399
++		}
5400
++
5401
++pkt_drop:
5402
++		/*Fill free buffer in the descriptor */
5403
++		hif->rx_buf_addr[rtc] = free_buf;
5404
++		hif->rx_buf_len[rtc] = min(pfe_pkt_size, buf_size);
5405
++		writel((DDR_PHYS_TO_PFE
5406
++			((u32)dma_map_single(hif->dev,
5407
++			free_buf, hif->rx_buf_len[rtc], DMA_FROM_DEVICE))),
5408
++			&desc->data);
5409
++		/*
5410
++		 * Ensure everything else is written to DDR before
5411
++		 * writing bd->ctrl
5412
++		 */
5413
++		wmb();
5414
++		writel((BD_CTRL_PKT_INT_EN | BD_CTRL_LIFM | BD_CTRL_DIR |
5415
++			BD_CTRL_DESC_EN | BD_BUF_LEN(hif->rx_buf_len[rtc])),
5416
++			&desc->ctrl);
5417
++
5418
++		rtc = (rtc + 1) & (hif->rx_ring_size - 1);
5419
++
5420
++		if (local_desc.ctrl & BD_CTRL_LIFM) {
5421
++			if (!(hif->client_ctrl & HIF_CTRL_RX_CONTINUED)) {
5422
++				rx_processed++;
5423
++
5424
++#ifdef HIF_NAPI_STATS
5425
++				hif->napi_counters[NAPI_PACKET_COUNT]++;
5426
++#endif
5427
++			}
5428
++			hif->started = 0;
5429
++		}
5430
++	}
5431
++
5432
++	hif->rxtoclean_index = rtc;
5433
++	spin_unlock_bh(&hif->lock);
5434
++
5435
++	/* we made some progress, re-start rx dma in case it stopped */
5436
++	hif_rx_dma_start();
5437
++
5438
++	return rx_processed;
5439
++}
5440
++
5441
++/*
5442
++ * client_ack_txpacket-
5443
++ * This function ack the Tx packet in the give client Tx queue by resetting
5444
++ * ownership bit in the descriptor.
5445
++ */
5446
++static int client_ack_txpacket(struct pfe_hif *hif, unsigned int client_id,
5447
++			       unsigned int q_no)
5448
++{
5449
++	struct hif_tx_queue *queue = &hif->client[client_id].tx_q[q_no];
5450
++	struct tx_queue_desc *desc = queue->base + queue->ack_idx;
5451
++
5452
++	if (readl(&desc->ctrl) & CL_DESC_OWN) {
5453
++		writel((readl(&desc->ctrl) & ~CL_DESC_OWN), &desc->ctrl);
5454
++		/* queue->ack_idx = (queue->ack_idx + 1) & (queue->size - 1); */
5455
++
5456
++		return 0;
5457
++
5458
++	} else {
5459
++		/*This should not happen */
5460
++		pr_err("%s: %d %d %d %d %d %p %d\n", __func__,
5461
++		       hif->txtosend, hif->txtoclean, hif->txavail,
5462
++			client_id, q_no, queue, queue->ack_idx);
5463
++		WARN(1, "%s: doesn't own this descriptor", __func__);
5464
++		return 1;
5465
++	}
5466
++}
5467
++
5468
++void __hif_tx_done_process(struct pfe_hif *hif, int count)
5469
++{
5470
++	struct hif_desc *desc;
5471
++	struct hif_desc_sw *desc_sw;
5472
++	int ttc, tx_avl;
5473
++	int pkts_done[HIF_CLIENTS_MAX] = {0, 0};
5474
++
5475
++	ttc = hif->txtoclean;
5476
++	tx_avl = hif->txavail;
5477
++
5478
++	while ((tx_avl < hif->tx_ring_size) && count--) {
5479
++		desc = hif->tx_base + ttc;
5480
++
5481
++		if (readl(&desc->ctrl) & BD_CTRL_DESC_EN)
5482
++			break;
5483
++
5484
++		desc_sw = &hif->tx_sw_queue[ttc];
5485
++
5486
++		if (desc_sw->data) {
5487
++			/*
5488
++			 * dmap_unmap_single(hif->dev, desc_sw->data,
5489
++			 * desc_sw->len, DMA_TO_DEVICE);
5490
++			 */
5491
++			dma_unmap_single(hif->dev, desc_sw->data,
5492
++					 desc_sw->len, DMA_TO_DEVICE);
5493
++		}
5494
++
5495
++		if (desc_sw->client_id > HIF_CLIENTS_MAX)
5496
++			pr_err("Invalid cl id %d\n", desc_sw->client_id);
5497
++
5498
++		pkts_done[desc_sw->client_id]++;
5499
++
5500
++		client_ack_txpacket(hif, desc_sw->client_id, desc_sw->q_no);
5501
++
5502
++		ttc = (ttc + 1) & (hif->tx_ring_size - 1);
5503
++		tx_avl++;
5504
++	}
5505
++
5506
++	if (pkts_done[0])
5507
++		hif_lib_indicate_client(0, EVENT_TXDONE_IND, 0);
5508
++	if (pkts_done[1])
5509
++		hif_lib_indicate_client(1, EVENT_TXDONE_IND, 0);
5510
++
5511
++	hif->txtoclean = ttc;
5512
++	hif->txavail = tx_avl;
5513
++
5514
++	if (!count) {
5515
++		tasklet_schedule(&hif->tx_cleanup_tasklet);
5516
++	} else {
5517
++		/*Enable Tx done interrupt */
5518
++		writel(readl_relaxed(HIF_INT_ENABLE) | HIF_TXPKT_INT,
5519
++		       HIF_INT_ENABLE);
5520
++	}
5521
++}
5522
++
5523
++static void pfe_tx_do_cleanup(unsigned long data)
5524
++{
5525
++	struct pfe_hif *hif = (struct pfe_hif *)data;
5526
++
5527
++	writel(HIF_INT | HIF_TXPKT_INT, HIF_INT_SRC);
5528
++
5529
++	hif_tx_done_process(hif, 64);
5530
++}
5531
++
5532
++/*
5533
++ * __hif_xmit_pkt -
5534
++ * This function puts one packet in the HIF Tx queue
5535
++ */
5536
++void __hif_xmit_pkt(struct pfe_hif *hif, unsigned int client_id, unsigned int
5537
++			q_no, void *data, u32 len, unsigned int flags)
5538
++{
5539
++	struct hif_desc	*desc;
5540
++	struct hif_desc_sw *desc_sw;
5541
++
5542
++	desc = hif->tx_base + hif->txtosend;
5543
++	desc_sw = &hif->tx_sw_queue[hif->txtosend];
5544
++
5545
++	desc_sw->len = len;
5546
++	desc_sw->client_id = client_id;
5547
++	desc_sw->q_no = q_no;
5548
++	desc_sw->flags = flags;
5549
++
5550
++	if (flags & HIF_DONT_DMA_MAP) {
5551
++		desc_sw->data = 0;
5552
++		writel((u32)DDR_PHYS_TO_PFE(data), &desc->data);
5553
++	} else {
5554
++		desc_sw->data = dma_map_single(hif->dev, data, len,
5555
++						DMA_TO_DEVICE);
5556
++		writel((u32)DDR_PHYS_TO_PFE(desc_sw->data), &desc->data);
5557
++	}
5558
++
5559
++	hif->txtosend = (hif->txtosend + 1) & (hif->tx_ring_size - 1);
5560
++	hif->txavail--;
5561
++
5562
++	if ((!((flags & HIF_DATA_VALID) && (flags &
5563
++				HIF_LAST_BUFFER))))
5564
++		goto skip_tx;
5565
++
5566
++	/*
5567
++	 * Ensure everything else is written to DDR before
5568
++	 * writing bd->ctrl
5569
++	 */
5570
++	wmb();
5571
++
5572
++	do {
5573
++		desc_sw = &hif->tx_sw_queue[hif->txtoflush];
5574
++		desc = hif->tx_base + hif->txtoflush;
5575
++
5576
++		if (desc_sw->flags & HIF_LAST_BUFFER) {
5577
++			writel((BD_CTRL_LIFM |
5578
++			       BD_CTRL_BRFETCH_DISABLE | BD_CTRL_RTFETCH_DISABLE
5579
++			       | BD_CTRL_PARSE_DISABLE | BD_CTRL_DESC_EN |
5580
++				BD_CTRL_PKT_INT_EN | BD_BUF_LEN(desc_sw->len)),
5581
++				&desc->ctrl);
5582
++		} else {
5583
++			writel((BD_CTRL_DESC_EN |
5584
++				BD_BUF_LEN(desc_sw->len)), &desc->ctrl);
5585
++		}
5586
++		hif->txtoflush = (hif->txtoflush + 1) & (hif->tx_ring_size - 1);
5587
++	}
5588
++	while (hif->txtoflush != hif->txtosend)
5589
++		;
5590
++
5591
++skip_tx:
5592
++	return;
5593
++}
5594
++
5595
++int hif_xmit_pkt(struct pfe_hif *hif, unsigned int client_id, unsigned int q_no,
5596
++		 void *data, unsigned int len)
5597
++{
5598
++	int rc = 0;
5599
++
5600
++	spin_lock_bh(&hif->tx_lock);
5601
++
5602
++	if (!hif->txavail) {
5603
++		rc = 1;
5604
++	} else {
5605
++		__hif_xmit_pkt(hif, client_id, q_no, data, len,
5606
++			       HIF_FIRST_BUFFER | HIF_LAST_BUFFER);
5607
++		hif_tx_dma_start();
5608
++	}
5609
++
5610
++	if (hif->txavail < (hif->tx_ring_size >> 1))
5611
++		__hif_tx_done_process(hif, TX_FREE_MAX_COUNT);
5612
++
5613
++	spin_unlock_bh(&hif->tx_lock);
5614
++
5615
++	return rc;
5616
++}
5617
++
5618
++static irqreturn_t wol_isr(int irq, void *dev_id)
5619
++{
5620
++	pr_info("WoL\n");
5621
++	gemac_set_wol(EMAC1_BASE_ADDR, 0);
5622
++	gemac_set_wol(EMAC2_BASE_ADDR, 0);
5623
++	return IRQ_HANDLED;
5624
++}
5625
++
5626
++/*
5627
++ * hif_isr-
5628
++ * This ISR routine processes Rx/Tx done interrupts from the HIF hardware block
5629
++ */
5630
++static irqreturn_t hif_isr(int irq, void *dev_id)
5631
++{
5632
++	struct pfe_hif *hif = (struct pfe_hif *)dev_id;
5633
++	int int_status;
5634
++	int int_enable_mask;
5635
++
5636
++	/*Read hif interrupt source register */
5637
++	int_status = readl_relaxed(HIF_INT_SRC);
5638
++	int_enable_mask = readl_relaxed(HIF_INT_ENABLE);
5639
++
5640
++	if ((int_status & HIF_INT) == 0)
5641
++		return IRQ_NONE;
5642
++
5643
++	int_status &= ~(HIF_INT);
5644
++
5645
++	if (int_status & HIF_RXPKT_INT) {
5646
++		int_status &= ~(HIF_RXPKT_INT);
5647
++		int_enable_mask &= ~(HIF_RXPKT_INT);
5648
++
5649
++		napi_first_batch = 1;
5650
++
5651
++		if (napi_schedule_prep(&hif->napi)) {
5652
++#ifdef HIF_NAPI_STATS
5653
++			hif->napi_counters[NAPI_SCHED_COUNT]++;
5654
++#endif
5655
++			__napi_schedule(&hif->napi);
5656
++		}
5657
++	}
5658
++	if (int_status & HIF_TXPKT_INT) {
5659
++		int_status &= ~(HIF_TXPKT_INT);
5660
++		int_enable_mask &= ~(HIF_TXPKT_INT);
5661
++		/*Schedule tx cleanup tassklet */
5662
++		tasklet_schedule(&hif->tx_cleanup_tasklet);
5663
++	}
5664
++
5665
++	/*Disable interrupts, they will be enabled after they are serviced */
5666
++	writel_relaxed(int_enable_mask, HIF_INT_ENABLE);
5667
++
5668
++	if (int_status) {
5669
++		pr_info("%s : Invalid interrupt : %d\n", __func__,
5670
++			int_status);
5671
++		writel(int_status, HIF_INT_SRC);
5672
++	}
5673
++
5674
++	return IRQ_HANDLED;
5675
++}
5676
++
5677
++void hif_process_client_req(struct pfe_hif *hif, int req, int data1, int data2)
5678
++{
5679
++	unsigned int client_id = data1;
5680
++
5681
++	if (client_id >= HIF_CLIENTS_MAX) {
5682
++		pr_err("%s: client id %d out of bounds\n", __func__,
5683
++		       client_id);
5684
++		return;
5685
++	}
5686
++
5687
++	switch (req) {
5688
++	case REQUEST_CL_REGISTER:
5689
++			/* Request for register a client */
5690
++			pr_info("%s: register client_id %d\n",
5691
++				__func__, client_id);
5692
++			pfe_hif_client_register(hif, client_id, (struct
5693
++				hif_client_shm *)&hif->shm->client[client_id]);
5694
++			break;
5695
++
5696
++	case REQUEST_CL_UNREGISTER:
5697
++			pr_info("%s: unregister client_id %d\n",
5698
++				__func__, client_id);
5699
++
5700
++			/* Request for unregister a client */
5701
++			pfe_hif_client_unregister(hif, client_id);
5702
++
5703
++			break;
5704
++
5705
++	default:
5706
++			pr_err("%s: unsupported request %d\n",
5707
++			       __func__, req);
5708
++			break;
5709
++	}
5710
++
5711
++	/*
5712
++	 * Process client Tx queues
5713
++	 * Currently we don't have checking for tx pending
5714
++	 */
5715
++}
5716
++
5717
++/*
5718
++ * pfe_hif_rx_poll
5719
++ *  This function is NAPI poll function to process HIF Rx queue.
5720
++ */
5721
++static int pfe_hif_rx_poll(struct napi_struct *napi, int budget)
5722
++{
5723
++	struct pfe_hif *hif = container_of(napi, struct pfe_hif, napi);
5724
++	int work_done;
5725
++
5726
++#ifdef HIF_NAPI_STATS
5727
++	hif->napi_counters[NAPI_POLL_COUNT]++;
5728
++#endif
5729
++
5730
++	work_done = pfe_hif_rx_process(hif, budget);
5731
++
5732
++	if (work_done < budget) {
5733
++		napi_complete(napi);
5734
++		writel(readl_relaxed(HIF_INT_ENABLE) | HIF_RXPKT_INT,
5735
++		       HIF_INT_ENABLE);
5736
++	}
5737
++#ifdef HIF_NAPI_STATS
5738
++	else
5739
++		hif->napi_counters[NAPI_FULL_BUDGET_COUNT]++;
5740
++#endif
5741
++
5742
++	return work_done;
5743
++}
5744
++
5745
++/*
5746
++ * pfe_hif_init
5747
++ * This function initializes the baseaddresses and irq, etc.
5748
++ */
5749
++int pfe_hif_init(struct pfe *pfe)
5750
++{
5751
++	struct pfe_hif *hif = &pfe->hif;
5752
++	int err;
5753
++
5754
++	pr_info("%s\n", __func__);
5755
++
5756
++	hif->dev = pfe->dev;
5757
++	hif->irq = pfe->hif_irq;
5758
++
5759
++	err = pfe_hif_alloc_descr(hif);
5760
++	if (err)
5761
++		goto err0;
5762
++
5763
++	if (pfe_hif_init_buffers(hif)) {
5764
++		pr_err("%s: Could not initialize buffer descriptors\n"
5765
++			, __func__);
5766
++		err = -ENOMEM;
5767
++		goto err1;
5768
++	}
5769
++
5770
++	/* Initialize NAPI for Rx processing */
5771
++	init_dummy_netdev(&hif->dummy_dev);
5772
++	netif_napi_add(&hif->dummy_dev, &hif->napi, pfe_hif_rx_poll,
5773
++		       HIF_RX_POLL_WEIGHT);
5774
++	napi_enable(&hif->napi);
5775
++
5776
++	spin_lock_init(&hif->tx_lock);
5777
++	spin_lock_init(&hif->lock);
5778
++
5779
++	hif_init();
5780
++	hif_rx_enable();
5781
++	hif_tx_enable();
5782
++
5783
++	/* Disable tx done interrupt */
5784
++	writel(HIF_INT_MASK, HIF_INT_ENABLE);
5785
++
5786
++	gpi_enable(HGPI_BASE_ADDR);
5787
++
5788
++	err = request_irq(hif->irq, hif_isr, 0, "pfe_hif", hif);
5789
++	if (err) {
5790
++		pr_err("%s: failed to get the hif IRQ = %d\n",
5791
++		       __func__, hif->irq);
5792
++		goto err1;
5793
++	}
5794
++
5795
++	err = request_irq(pfe->wol_irq, wol_isr, 0, "pfe_wol", pfe);
5796
++	if (err) {
5797
++		pr_err("%s: failed to get the wol IRQ = %d\n",
5798
++		       __func__, pfe->wol_irq);
5799
++		goto err1;
5800
++	}
5801
++
5802
++	tasklet_init(&hif->tx_cleanup_tasklet,
5803
++		     (void(*)(unsigned long))pfe_tx_do_cleanup,
5804
++		     (unsigned long)hif);
5805
++
5806
++	return 0;
5807
++err1:
5808
++	pfe_hif_free_descr(hif);
5809
++err0:
5810
++	return err;
5811
++}
5812
++
5813
++/* pfe_hif_exit- */
5814
++void pfe_hif_exit(struct pfe *pfe)
5815
++{
5816
++	struct pfe_hif *hif = &pfe->hif;
5817
++
5818
++	pr_info("%s\n", __func__);
5819
++
5820
++	tasklet_kill(&hif->tx_cleanup_tasklet);
5821
++
5822
++	spin_lock_bh(&hif->lock);
5823
++	hif->shm->g_client_status[0] = 0;
5824
++	/* Make sure all clients are disabled*/
5825
++	hif->shm->g_client_status[1] = 0;
5826
++
5827
++	spin_unlock_bh(&hif->lock);
5828
++
5829
++	/*Disable Rx/Tx */
5830
++	gpi_disable(HGPI_BASE_ADDR);
5831
++	hif_rx_disable();
5832
++	hif_tx_disable();
5833
++
5834
++	napi_disable(&hif->napi);
5835
++	netif_napi_del(&hif->napi);
5836
++
5837
++	free_irq(pfe->wol_irq, pfe);
5838
++	free_irq(hif->irq, hif);
5839
++
5840
++	pfe_hif_release_buffers(hif);
5841
++	pfe_hif_free_descr(hif);
5842
++}
5843
+diff --git a/drivers/staging/fsl_ppfe/pfe_hif_lib.c b/drivers/staging/fsl_ppfe/pfe_hif_lib.c
5844
+new file mode 100644
5845
+index 000000000000..4274a59257fe
5846
+--- /dev/null
5847
+@@ -0,0 +1,638 @@
5848
++/*
5849
++ * Copyright 2015-2016 Freescale Semiconductor, Inc.
5850
++ * Copyright 2017 NXP
5851
++ *
5852
++ * This program is free software; you can redistribute it and/or modify
5853
++ * it under the terms of the GNU General Public License as published by
5854
++ * the Free Software Foundation; either version 2 of the License, or
5855
++ * (at your option) any later version.
5856
++ *
5857
++ * This program is distributed in the hope that it will be useful,
5858
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5859
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
5860
++ * GNU General Public License for more details.
5861
++ *
5862
++ * You should have received a copy of the GNU General Public License
5863
++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
5864
++ */
5865
++
5866
++#include <linux/version.h>
5867
++#include <linux/kernel.h>
5868
++#include <linux/slab.h>
5869
++#include <linux/interrupt.h>
5870
++#include <linux/workqueue.h>
5871
++#include <linux/dma-mapping.h>
5872
++#include <linux/dmapool.h>
5873
++#include <linux/sched.h>
5874
++#include <linux/skbuff.h>
5875
++#include <linux/moduleparam.h>
5876
++#include <linux/cpu.h>
5877
++
5878
++#include "pfe_mod.h"
5879
++#include "pfe_hif.h"
5880
++#include "pfe_hif_lib.h"
5881
++
5882
++unsigned int lro_mode;
5883
++unsigned int page_mode;
5884
++unsigned int tx_qos;
5885
++unsigned int pfe_pkt_size;
5886
++unsigned int pfe_pkt_headroom;
5887
++unsigned int emac_txq_cnt;
5888
++
5889
++/*
5890
++ * @pfe_hal_lib.c.
5891
++ * Common functions used by HIF client drivers
5892
++ */
5893
++
5894
++/*HIF shared memory Global variable */
5895
++struct hif_shm ghif_shm;
5896
++
5897
++/* Cleanup the HIF shared memory, release HIF rx_buffer_pool.
5898
++ * This function should be called after pfe_hif_exit
5899
++ *
5900
++ * @param[in] hif_shm		Shared memory address location in DDR
5901
++ */
5902
++static void pfe_hif_shm_clean(struct hif_shm *hif_shm)
5903
++{
5904
++	int i;
5905
++	void *pkt;
5906
++
5907
++	for (i = 0; i < hif_shm->rx_buf_pool_cnt; i++) {
5908
++		pkt = hif_shm->rx_buf_pool[i];
5909
++		if (pkt) {
5910
++			hif_shm->rx_buf_pool[i] = NULL;
5911
++			pkt -= pfe_pkt_headroom;
5912
++
5913
++			if (page_mode)
5914
++				put_page(virt_to_page(pkt));
5915
++			else
5916
++				kfree(pkt);
5917
++		}
5918
++	}
5919
++}
5920
++
5921
++/* Initialize shared memory used between HIF driver and clients,
5922
++ * allocate rx_buffer_pool required for HIF Rx descriptors.
5923
++ * This function should be called before initializing HIF driver.
5924
++ *
5925
++ * @param[in] hif_shm		Shared memory address location in DDR
5926
++ * @rerurn			0 - on succes, <0 on fail to initialize
5927
++ */
5928
++static int pfe_hif_shm_init(struct hif_shm *hif_shm)
5929
++{
5930
++	int i;
5931
++	void *pkt;
5932
++
5933
++	memset(hif_shm, 0, sizeof(struct hif_shm));
5934
++	hif_shm->rx_buf_pool_cnt = HIF_RX_DESC_NT;
5935
++
5936
++	for (i = 0; i < hif_shm->rx_buf_pool_cnt; i++) {
5937
++		if (page_mode) {
5938
++			pkt = (void *)__get_free_page(GFP_KERNEL |
5939
++				GFP_DMA_PFE);
5940
++		} else {
5941
++			pkt = kmalloc(PFE_BUF_SIZE, GFP_KERNEL | GFP_DMA_PFE);
5942
++		}
5943
++
5944
++		if (pkt)
5945
++			hif_shm->rx_buf_pool[i] = pkt + pfe_pkt_headroom;
5946
++		else
5947
++			goto err0;
5948
++	}
5949
++
5950
++	return 0;
5951
++
5952
++err0:
5953
++	pr_err("%s Low memory\n", __func__);
5954
++	pfe_hif_shm_clean(hif_shm);
5955
++	return -ENOMEM;
5956
++}
5957
++
5958
++/*This function sends indication to HIF driver
5959
++ *
5960
++ * @param[in] hif	hif context
5961
++ */
5962
++static void hif_lib_indicate_hif(struct pfe_hif *hif, int req, int data1, int
5963
++					data2)
5964
++{
5965
++	hif_process_client_req(hif, req, data1, data2);
5966
++}
5967
++
5968
++void hif_lib_indicate_client(int client_id, int event_type, int qno)
5969
++{
5970
++	struct hif_client_s *client = pfe->hif_client[client_id];
5971
++
5972
++	if (!client || (event_type >= HIF_EVENT_MAX) || (qno >=
5973
++		HIF_CLIENT_QUEUES_MAX))
5974
++		return;
5975
++
5976
++	if (!test_and_set_bit(qno, &client->queue_mask[event_type]))
5977
++		client->event_handler(client->priv, event_type, qno);
5978
++}
5979
++
5980
++/*This function releases Rx queue descriptors memory and pre-filled buffers
5981
++ *
5982
++ * @param[in] client	hif_client context
5983
++ */
5984
++static void hif_lib_client_release_rx_buffers(struct hif_client_s *client)
5985
++{
5986
++	struct rx_queue_desc *desc;
5987
++	int qno, ii;
5988
++	void *buf;
5989
++
5990
++	for (qno = 0; qno < client->rx_qn; qno++) {
5991
++		desc = client->rx_q[qno].base;
5992
++
5993
++		for (ii = 0; ii < client->rx_q[qno].size; ii++) {
5994
++			buf = (void *)desc->data;
5995
++			if (buf) {
5996
++				buf -= pfe_pkt_headroom;
5997
++
5998
++				if (page_mode)
5999
++					free_page((unsigned long)buf);
6000
++				else
6001
++					kfree(buf);
6002
++
6003
++				desc->ctrl = 0;
6004
++			}
6005
++
6006
++			desc++;
6007
++		}
6008
++	}
6009
++
6010
++	kfree(client->rx_qbase);
6011
++}
6012
++
6013
++/*This function allocates memory for the rxq descriptors and pre-fill rx queues
6014
++ * with buffers.
6015
++ * @param[in] client	client context
6016
++ * @param[in] q_size	size of the rxQ, all queues are of same size
6017
++ */
6018
++static int hif_lib_client_init_rx_buffers(struct hif_client_s *client, int
6019
++						q_size)
6020
++{
6021
++	struct rx_queue_desc *desc;
6022
++	struct hif_client_rx_queue *queue;
6023
++	int ii, qno;
6024
++
6025
++	/*Allocate memory for the client queues */
6026
++	client->rx_qbase = kzalloc(client->rx_qn * q_size * sizeof(struct
6027
++				rx_queue_desc), GFP_KERNEL);
6028
++	if (!client->rx_qbase)
6029
++		goto err;
6030
++
6031
++	for (qno = 0; qno < client->rx_qn; qno++) {
6032
++		queue = &client->rx_q[qno];
6033
++
6034
++		queue->base = client->rx_qbase + qno * q_size * sizeof(struct
6035
++				rx_queue_desc);
6036
++		queue->size = q_size;
6037
++		queue->read_idx = 0;
6038
++		queue->write_idx = 0;
6039
++
6040
++		pr_debug("rx queue: %d, base: %p, size: %d\n", qno,
6041
++			 queue->base, queue->size);
6042
++	}
6043
++
6044
++	for (qno = 0; qno < client->rx_qn; qno++) {
6045
++		queue = &client->rx_q[qno];
6046
++		desc = queue->base;
6047
++
6048
++		for (ii = 0; ii < queue->size; ii++) {
6049
++			desc->ctrl = CL_DESC_BUF_LEN(pfe_pkt_size) |
6050
++					CL_DESC_OWN;
6051
++			desc++;
6052
++		}
6053
++	}
6054
++
6055
++	return 0;
6056
++
6057
++err:
6058
++	return 1;
6059
++}
6060
++
6061
++#define inc_cl_idx(idxname)					\
6062
++	({ typeof(idxname) idxname_ = (idxname);		\
6063
++	((idxname_) = (idxname_ + 1) & (queue->size - 1)); })
6064
++
6065
++static void hif_lib_client_cleanup_tx_queue(struct hif_client_tx_queue *queue)
6066
++{
6067
++	pr_debug("%s\n", __func__);
6068
++
6069
++	/*
6070
++	 * Check if there are any pending packets. Client must flush the tx
6071
++	 * queues before unregistering, by calling by calling
6072
++	 * hif_lib_tx_get_next_complete()
6073
++	 *
6074
++	 * Hif no longer calls since we are no longer registered
6075
++	 */
6076
++	if (queue->tx_pending)
6077
++		pr_err("%s: pending transmit packets\n", __func__);
6078
++}
6079
++
6080
++static void hif_lib_client_release_tx_buffers(struct hif_client_s *client)
6081
++{
6082
++	int qno;
6083
++
6084
++	pr_debug("%s\n", __func__);
6085
++
6086
++	for (qno = 0; qno < client->tx_qn; qno++)
6087
++		hif_lib_client_cleanup_tx_queue(&client->tx_q[qno]);
6088
++
6089
++	kfree(client->tx_qbase);
6090
++}
6091
++
6092
++static int hif_lib_client_init_tx_buffers(struct hif_client_s *client, int
6093
++						q_size)
6094
++{
6095
++	struct hif_client_tx_queue *queue;
6096
++	int qno;
6097
++
6098
++	client->tx_qbase = kzalloc(client->tx_qn * q_size * sizeof(struct
6099
++					tx_queue_desc), GFP_KERNEL);
6100
++	if (!client->tx_qbase)
6101
++		return 1;
6102
++
6103
++	for (qno = 0; qno < client->tx_qn; qno++) {
6104
++		queue = &client->tx_q[qno];
6105
++
6106
++		queue->base = client->tx_qbase + qno * q_size * sizeof(struct
6107
++				tx_queue_desc);
6108
++		queue->size = q_size;
6109
++		queue->read_idx = 0;
6110
++		queue->write_idx = 0;
6111
++		queue->tx_pending = 0;
6112
++		queue->nocpy_flag = 0;
6113
++		queue->prev_tmu_tx_pkts = 0;
6114
++		queue->done_tmu_tx_pkts = 0;
6115
++
6116
++		pr_debug("tx queue: %d, base: %p, size: %d\n", qno,
6117
++			 queue->base, queue->size);
6118
++	}
6119
++
6120
++	return 0;
6121
++}
6122
++
6123
++static int hif_lib_event_dummy(void *priv, int event_type, int qno)
6124
++{
6125
++	return 0;
6126
++}
6127
++
6128
++int hif_lib_client_register(struct hif_client_s *client)
6129
++{
6130
++	struct hif_shm *hif_shm;
6131
++	struct hif_client_shm *client_shm;
6132
++	int err, i;
6133
++	/* int loop_cnt = 0; */
6134
++
6135
++	pr_debug("%s\n", __func__);
6136
++
6137
++	/*Allocate memory before spin_lock*/
6138
++	if (hif_lib_client_init_rx_buffers(client, client->rx_qsize)) {
6139
++		err = -ENOMEM;
6140
++		goto err_rx;
6141
++	}
6142
++
6143
++	if (hif_lib_client_init_tx_buffers(client, client->tx_qsize)) {
6144
++		err = -ENOMEM;
6145
++		goto err_tx;
6146
++	}
6147
++
6148
++	spin_lock_bh(&pfe->hif.lock);
6149
++	if (!(client->pfe) || (client->id >= HIF_CLIENTS_MAX) ||
6150
++	    (pfe->hif_client[client->id])) {
6151
++		err = -EINVAL;
6152
++		goto err;
6153
++	}
6154
++
6155
++	hif_shm = client->pfe->hif.shm;
6156
++
6157
++	if (!client->event_handler)
6158
++		client->event_handler = hif_lib_event_dummy;
6159
++
6160
++	/*Initialize client specific shared memory */
6161
++	client_shm = (struct hif_client_shm *)&hif_shm->client[client->id];
6162
++	client_shm->rx_qbase = (unsigned long int)client->rx_qbase;
6163
++	client_shm->rx_qsize = client->rx_qsize;
6164
++	client_shm->tx_qbase = (unsigned long int)client->tx_qbase;
6165
++	client_shm->tx_qsize = client->tx_qsize;
6166
++	client_shm->ctrl = (client->tx_qn << CLIENT_CTRL_TX_Q_CNT_OFST) |
6167
++				(client->rx_qn << CLIENT_CTRL_RX_Q_CNT_OFST);
6168
++	/* spin_lock_init(&client->rx_lock); */
6169
++
6170
++	for (i = 0; i < HIF_EVENT_MAX; i++) {
6171
++		client->queue_mask[i] = 0;  /*
6172
++					     * By default all events are
6173
++					     * unmasked
6174
++					     */
6175
++	}
6176
++
6177
++	/*Indicate to HIF driver*/
6178
++	hif_lib_indicate_hif(&pfe->hif, REQUEST_CL_REGISTER, client->id, 0);
6179
++
6180
++	pr_debug("%s: client: %p, client_id: %d, tx_qsize: %d, rx_qsize: %d\n",
6181
++		 __func__, client, client->id, client->tx_qsize,
6182
++		 client->rx_qsize);
6183
++
6184
++	client->cpu_id = -1;
6185
++
6186
++	pfe->hif_client[client->id] = client;
6187
++	spin_unlock_bh(&pfe->hif.lock);
6188
++
6189
++	return 0;
6190
++
6191
++err:
6192
++	spin_unlock_bh(&pfe->hif.lock);
6193
++	hif_lib_client_release_tx_buffers(client);
6194
++
6195
++err_tx:
6196
++	hif_lib_client_release_rx_buffers(client);
6197
++
6198
++err_rx:
6199
++	return err;
6200
++}
6201
++
6202
++int hif_lib_client_unregister(struct hif_client_s *client)
6203
++{
6204
++	struct pfe *pfe = client->pfe;
6205
++	u32 client_id = client->id;
6206
++
6207
++	pr_info(
6208
++		"%s : client: %p, client_id: %d, txQ_depth: %d, rxQ_depth: %d\n"
6209
++		, __func__, client, client->id, client->tx_qsize,
6210
++		client->rx_qsize);
6211
++
6212
++	spin_lock_bh(&pfe->hif.lock);
6213
++	hif_lib_indicate_hif(&pfe->hif, REQUEST_CL_UNREGISTER, client->id, 0);
6214
++
6215
++	hif_lib_client_release_tx_buffers(client);
6216
++	hif_lib_client_release_rx_buffers(client);
6217
++	pfe->hif_client[client_id] = NULL;
6218
++	spin_unlock_bh(&pfe->hif.lock);
6219
++
6220
++	return 0;
6221
++}
6222
++
6223
++int hif_lib_event_handler_start(struct hif_client_s *client, int event,
6224
++				int qno)
6225
++{
6226
++	struct hif_client_rx_queue *queue = &client->rx_q[qno];
6227
++	struct rx_queue_desc *desc = queue->base + queue->read_idx;
6228
++
6229
++	if ((event >= HIF_EVENT_MAX) || (qno >= HIF_CLIENT_QUEUES_MAX)) {
6230
++		pr_debug("%s: Unsupported event : %d  queue number : %d\n",
6231
++			 __func__, event, qno);
6232
++		return -1;
6233
++	}
6234
++
6235
++	test_and_clear_bit(qno, &client->queue_mask[event]);
6236
++
6237
++	switch (event) {
6238
++	case EVENT_RX_PKT_IND:
6239
++		if (!(desc->ctrl & CL_DESC_OWN))
6240
++			hif_lib_indicate_client(client->id,
6241
++						EVENT_RX_PKT_IND, qno);
6242
++		break;
6243
++
6244
++	case EVENT_HIGH_RX_WM:
6245
++	case EVENT_TXDONE_IND:
6246
++	default:
6247
++		break;
6248
++	}
6249
++
6250
++	return 0;
6251
++}
6252
++
6253
++/*
6254
++ * This function gets one packet from the specified client queue
6255
++ * It also refill the rx buffer
6256
++ */
6257
++void *hif_lib_receive_pkt(struct hif_client_s *client, int qno, int *len, int
6258
++				*ofst, unsigned int *rx_ctrl,
6259
++				unsigned int *desc_ctrl, void **priv_data)
6260
++{
6261
++	struct hif_client_rx_queue *queue = &client->rx_q[qno];
6262
++	struct rx_queue_desc *desc;
6263
++	void *pkt = NULL;
6264
++
6265
++	/*
6266
++	 * Following lock is to protect rx queue access from,
6267
++	 * hif_lib_event_handler_start.
6268
++	 * In general below lock is not required, because hif_lib_xmit_pkt and
6269
++	 * hif_lib_event_handler_start are called from napi poll and which is
6270
++	 * not re-entrant. But if some client use in different way this lock is
6271
++	 * required.
6272
++	 */
6273
++	/*spin_lock_irqsave(&client->rx_lock, flags); */
6274
++	desc = queue->base + queue->read_idx;
6275
++	if (!(desc->ctrl & CL_DESC_OWN)) {
6276
++		pkt = desc->data - pfe_pkt_headroom;
6277
++
6278
++		*rx_ctrl = desc->client_ctrl;
6279
++		*desc_ctrl = desc->ctrl;
6280
++
6281
++		if (desc->ctrl & CL_DESC_FIRST) {
6282
++			u16 size = *rx_ctrl >> HIF_CTRL_RX_OFFSET_OFST;
6283
++
6284
++			if (size) {
6285
++				*len = CL_DESC_BUF_LEN(desc->ctrl) -
6286
++						PFE_PKT_HEADER_SZ - size;
6287
++				*ofst = pfe_pkt_headroom + PFE_PKT_HEADER_SZ
6288
++								+ size;
6289
++				*priv_data = desc->data + PFE_PKT_HEADER_SZ;
6290
++			} else {
6291
++				*len = CL_DESC_BUF_LEN(desc->ctrl) -
6292
++						PFE_PKT_HEADER_SZ;
6293
++				*ofst = pfe_pkt_headroom + PFE_PKT_HEADER_SZ;
6294
++				*priv_data = NULL;
6295
++			}
6296
++
6297
++		} else {
6298
++			*len = CL_DESC_BUF_LEN(desc->ctrl);
6299
++			*ofst = pfe_pkt_headroom;
6300
++		}
6301
++
6302
++		/*
6303
++		 * Needed so we don't free a buffer/page
6304
++		 * twice on module_exit
6305
++		 */
6306
++		desc->data = NULL;
6307
++
6308
++		/*
6309
++		 * Ensure everything else is written to DDR before
6310
++		 * writing bd->ctrl
6311
++		 */
6312
++		smp_wmb();
6313
++
6314
++		desc->ctrl = CL_DESC_BUF_LEN(pfe_pkt_size) | CL_DESC_OWN;
6315
++		inc_cl_idx(queue->read_idx);
6316
++	}
6317
++
6318
++	/*spin_unlock_irqrestore(&client->rx_lock, flags); */
6319
++	return pkt;
6320
++}
6321
++
6322
++static inline void hif_hdr_write(struct hif_hdr *pkt_hdr, unsigned int
6323
++					client_id, unsigned int qno,
6324
++					u32 client_ctrl)
6325
++{
6326
++	/* Optimize the write since the destinaton may be non-cacheable */
6327
++	if (!((unsigned long)pkt_hdr & 0x3)) {
6328
++		((u32 *)pkt_hdr)[0] = (client_ctrl << 16) | (qno << 8) |
6329
++					client_id;
6330
++	} else {
6331
++		((u16 *)pkt_hdr)[0] = (qno << 8) | (client_id & 0xFF);
6332
++		((u16 *)pkt_hdr)[1] = (client_ctrl & 0xFFFF);
6333
++	}
6334
++}
6335
++
6336
++/*This function puts the given packet in the specific client queue */
6337
++void __hif_lib_xmit_pkt(struct hif_client_s *client, unsigned int qno, void
6338
++				*data, unsigned int len, u32 client_ctrl,
6339
++				unsigned int flags, void *client_data)
6340
++{
6341
++	struct hif_client_tx_queue *queue = &client->tx_q[qno];
6342
++	struct tx_queue_desc *desc = queue->base + queue->write_idx;
6343
++
6344
++	/* First buffer */
6345
++	if (flags & HIF_FIRST_BUFFER) {
6346
++		data -= sizeof(struct hif_hdr);
6347
++		len += sizeof(struct hif_hdr);
6348
++
6349
++		hif_hdr_write(data, client->id, qno, client_ctrl);
6350
++	}
6351
++
6352
++	desc->data = client_data;
6353
++	desc->ctrl = CL_DESC_OWN | CL_DESC_FLAGS(flags);
6354
++
6355
++	__hif_xmit_pkt(&pfe->hif, client->id, qno, data, len, flags);
6356
++
6357
++	inc_cl_idx(queue->write_idx);
6358
++	queue->tx_pending++;
6359
++	queue->jiffies_last_packet = jiffies;
6360
++}
6361
++
6362
++/*This function puts the given packet in the specific client queue */
6363
++int hif_lib_xmit_pkt(struct hif_client_s *client, unsigned int qno, void *data,
6364
++		     unsigned int len, u32 client_ctrl, void *client_data)
6365
++{
6366
++	struct hif_client_tx_queue *queue = &client->tx_q[qno];
6367
++	struct tx_queue_desc *desc = queue->base + queue->write_idx;
6368
++
6369
++	if (queue->tx_pending < queue->size) {
6370
++		/*Construct pkt header */
6371
++
6372
++		data -= sizeof(struct hif_hdr);
6373
++		len += sizeof(struct hif_hdr);
6374
++
6375
++		hif_hdr_write(data, client->id, qno, client_ctrl);
6376
++
6377
++		desc->data = client_data;
6378
++		desc->ctrl = CL_DESC_OWN | CL_DESC_FLAGS(HIF_FIRST_BUFFER |
6379
++				HIF_LAST_BUFFER | HIF_DATA_VALID);
6380
++
6381
++		if (hif_xmit_pkt(&pfe->hif, client->id, qno, data, len))
6382
++			return 1;
6383
++
6384
++		inc_cl_idx(queue->write_idx);
6385
++		queue->tx_pending++;
6386
++		queue->jiffies_last_packet = jiffies;
6387
++
6388
++		return 0;
6389
++	}
6390
++
6391
++	pr_debug("%s Tx client %d qno %d is full\n", __func__, client->id,
6392
++		 qno);
6393
++	return 1;
6394
++}
6395
++
6396
++void *hif_lib_tx_get_next_complete(struct hif_client_s *client, int qno,
6397
++				   unsigned int *flags, int count)
6398
++{
6399
++	struct hif_client_tx_queue *queue = &client->tx_q[qno];
6400
++	struct tx_queue_desc *desc = queue->base + queue->read_idx;
6401
++
6402
++	pr_debug("%s: qno : %d rd_indx: %d pending:%d\n", __func__, qno,
6403
++		 queue->read_idx, queue->tx_pending);
6404
++
6405
++	if (!queue->tx_pending)
6406
++		return NULL;
6407
++
6408
++	if (queue->nocpy_flag && !queue->done_tmu_tx_pkts) {
6409
++		u32 tmu_tx_pkts = be32_to_cpu(pe_dmem_read(TMU0_ID +
6410
++			client->id, TMU_DM_TX_TRANS, 4));
6411
++
6412
++		if (queue->prev_tmu_tx_pkts > tmu_tx_pkts)
6413
++			queue->done_tmu_tx_pkts = UINT_MAX -
6414
++				queue->prev_tmu_tx_pkts + tmu_tx_pkts;
6415
++		else
6416
++			queue->done_tmu_tx_pkts = tmu_tx_pkts -
6417
++						queue->prev_tmu_tx_pkts;
6418
++
6419
++		queue->prev_tmu_tx_pkts  = tmu_tx_pkts;
6420
++
6421
++		if (!queue->done_tmu_tx_pkts)
6422
++			return NULL;
6423
++	}
6424
++
6425
++	if (desc->ctrl & CL_DESC_OWN)
6426
++		return NULL;
6427
++
6428
++	inc_cl_idx(queue->read_idx);
6429
++	queue->tx_pending--;
6430
++
6431
++	*flags = CL_DESC_GET_FLAGS(desc->ctrl);
6432
++
6433
++	if (queue->done_tmu_tx_pkts && (*flags & HIF_LAST_BUFFER))
6434
++		queue->done_tmu_tx_pkts--;
6435
++
6436
++	return desc->data;
6437
++}
6438
++
6439
++static void hif_lib_tmu_credit_init(struct pfe *pfe)
6440
++{
6441
++	int i, q;
6442
++
6443
++	for (i = 0; i < NUM_GEMAC_SUPPORT; i++)
6444
++		for (q = 0; q < emac_txq_cnt; q++) {
6445
++			pfe->tmu_credit.tx_credit_max[i][q] = (q == 0) ?
6446
++					DEFAULT_Q0_QDEPTH : DEFAULT_MAX_QDEPTH;
6447
++			pfe->tmu_credit.tx_credit[i][q] =
6448
++					pfe->tmu_credit.tx_credit_max[i][q];
6449
++		}
6450
++}
6451
++
6452
++int pfe_hif_lib_init(struct pfe *pfe)
6453
++{
6454
++	int rc;
6455
++
6456
++	pr_info("%s\n", __func__);
6457
++
6458
++	if (lro_mode) {
6459
++		page_mode = 1;
6460
++		pfe_pkt_size = min(PAGE_SIZE, MAX_PFE_PKT_SIZE);
6461
++		pfe_pkt_headroom = 0;
6462
++	} else {
6463
++		page_mode = 0;
6464
++		pfe_pkt_size = PFE_PKT_SIZE;
6465
++		pfe_pkt_headroom = PFE_PKT_HEADROOM;
6466
++	}
6467
++
6468
++	if (tx_qos)
6469
++		emac_txq_cnt = EMAC_TXQ_CNT / 2;
6470
++	else
6471
++		emac_txq_cnt = EMAC_TXQ_CNT;
6472
++
6473
++	hif_lib_tmu_credit_init(pfe);
6474
++	pfe->hif.shm = &ghif_shm;
6475
++	rc = pfe_hif_shm_init(pfe->hif.shm);
6476
++
6477
++	return rc;
6478
++}
6479
++
6480
++void pfe_hif_lib_exit(struct pfe *pfe)
6481
++{
6482
++	pr_info("%s\n", __func__);
6483
++
6484
++	pfe_hif_shm_clean(pfe->hif.shm);
6485
++}
6486
+diff --git a/drivers/staging/fsl_ppfe/pfe_hw.c b/drivers/staging/fsl_ppfe/pfe_hw.c
6487
+new file mode 100644
6488
+index 000000000000..16ea2c658257
6489
+--- /dev/null
6490
+@@ -0,0 +1,176 @@
6491
++/*
6492
++ * Copyright 2015-2016 Freescale Semiconductor, Inc.
6493
++ * Copyright 2017 NXP
6494
++ *
6495
++ * This program is free software; you can redistribute it and/or modify
6496
++ * it under the terms of the GNU General Public License as published by
6497
++ * the Free Software Foundation; either version 2 of the License, or
6498
++ * (at your option) any later version.
6499
++ *
6500
++ * This program is distributed in the hope that it will be useful,
6501
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6502
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
6503
++ * GNU General Public License for more details.
6504
++ *
6505
++ * You should have received a copy of the GNU General Public License
6506
++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
6507
++ */
6508
++
6509
++#include "pfe_mod.h"
6510
++#include "pfe_hw.h"
6511
++
6512
++/* Functions to handle most of pfe hw register initialization */
6513
++int pfe_hw_init(struct pfe *pfe, int resume)
6514
++{
6515
++	struct class_cfg class_cfg = {
6516
++		.pe_sys_clk_ratio = PE_SYS_CLK_RATIO,
6517
++		.route_table_baseaddr = pfe->ddr_phys_baseaddr +
6518
++					ROUTE_TABLE_BASEADDR,
6519
++		.route_table_hash_bits = ROUTE_TABLE_HASH_BITS,
6520
++	};
6521
++
6522
++	struct tmu_cfg tmu_cfg = {
6523
++		.pe_sys_clk_ratio = PE_SYS_CLK_RATIO,
6524
++		.llm_base_addr = pfe->ddr_phys_baseaddr + TMU_LLM_BASEADDR,
6525
++		.llm_queue_len = TMU_LLM_QUEUE_LEN,
6526
++	};
6527
++
6528
++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
6529
++	struct util_cfg util_cfg = {
6530
++		.pe_sys_clk_ratio = PE_SYS_CLK_RATIO,
6531
++	};
6532
++#endif
6533
++
6534
++	struct BMU_CFG bmu1_cfg = {
6535
++		.baseaddr = CBUS_VIRT_TO_PFE(LMEM_BASE_ADDR +
6536
++						BMU1_LMEM_BASEADDR),
6537
++		.count = BMU1_BUF_COUNT,
6538
++		.size = BMU1_BUF_SIZE,
6539
++		.low_watermark = 10,
6540
++		.high_watermark = 15,
6541
++	};
6542
++
6543
++	struct BMU_CFG bmu2_cfg = {
6544
++		.baseaddr = DDR_PHYS_TO_PFE(pfe->ddr_phys_baseaddr +
6545
++						BMU2_DDR_BASEADDR),
6546
++		.count = BMU2_BUF_COUNT,
6547
++		.size = BMU2_BUF_SIZE,
6548
++		.low_watermark = 250,
6549
++		.high_watermark = 253,
6550
++	};
6551
++
6552
++	struct gpi_cfg egpi1_cfg = {
6553
++		.lmem_rtry_cnt = EGPI1_LMEM_RTRY_CNT,
6554
++		.tmlf_txthres = EGPI1_TMLF_TXTHRES,
6555
++		.aseq_len = EGPI1_ASEQ_LEN,
6556
++		.mtip_pause_reg = CBUS_VIRT_TO_PFE(EMAC1_BASE_ADDR +
6557
++						EMAC_TCNTRL_REG),
6558
++	};
6559
++
6560
++	struct gpi_cfg egpi2_cfg = {
6561
++		.lmem_rtry_cnt = EGPI2_LMEM_RTRY_CNT,
6562
++		.tmlf_txthres = EGPI2_TMLF_TXTHRES,
6563
++		.aseq_len = EGPI2_ASEQ_LEN,
6564
++		.mtip_pause_reg = CBUS_VIRT_TO_PFE(EMAC2_BASE_ADDR +
6565
++						EMAC_TCNTRL_REG),
6566
++	};
6567
++
6568
++	struct gpi_cfg hgpi_cfg = {
6569
++		.lmem_rtry_cnt = HGPI_LMEM_RTRY_CNT,
6570
++		.tmlf_txthres = HGPI_TMLF_TXTHRES,
6571
++		.aseq_len = HGPI_ASEQ_LEN,
6572
++		.mtip_pause_reg = 0,
6573
++	};
6574
++
6575
++	pr_info("%s\n", __func__);
6576
++
6577
++#if !defined(LS1012A_PFE_RESET_WA)
6578
++	/* LS1012A needs this to make PE work correctly */
6579
++	writel(0x3,     CLASS_PE_SYS_CLK_RATIO);
6580
++	writel(0x3,     TMU_PE_SYS_CLK_RATIO);
6581
++	writel(0x3,     UTIL_PE_SYS_CLK_RATIO);
6582
++	usleep_range(10, 20);
6583
++#endif
6584
++
6585
++	pr_info("CLASS version: %x\n", readl(CLASS_VERSION));
6586
++	pr_info("TMU version: %x\n", readl(TMU_VERSION));
6587
++
6588
++	pr_info("BMU1 version: %x\n", readl(BMU1_BASE_ADDR +
6589
++		BMU_VERSION));
6590
++	pr_info("BMU2 version: %x\n", readl(BMU2_BASE_ADDR +
6591
++		BMU_VERSION));
6592
++
6593
++	pr_info("EGPI1 version: %x\n", readl(EGPI1_BASE_ADDR +
6594
++		GPI_VERSION));
6595
++	pr_info("EGPI2 version: %x\n", readl(EGPI2_BASE_ADDR +
6596
++		GPI_VERSION));
6597
++	pr_info("HGPI version: %x\n", readl(HGPI_BASE_ADDR +
6598
++		GPI_VERSION));
6599
++
6600
++	pr_info("HIF version: %x\n", readl(HIF_VERSION));
6601
++	pr_info("HIF NOPCY version: %x\n", readl(HIF_NOCPY_VERSION));
6602
++
6603
++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
6604
++	pr_info("UTIL version: %x\n", readl(UTIL_VERSION));
6605
++#endif
6606
++	while (!(readl(TMU_CTRL) & ECC_MEM_INIT_DONE))
6607
++		;
6608
++
6609
++	hif_rx_disable();
6610
++	hif_tx_disable();
6611
++
6612
++	bmu_init(BMU1_BASE_ADDR, &bmu1_cfg);
6613
++
6614
++	pr_info("bmu_init(1) done\n");
6615
++
6616
++	bmu_init(BMU2_BASE_ADDR, &bmu2_cfg);
6617
++
6618
++	pr_info("bmu_init(2) done\n");
6619
++
6620
++	class_cfg.resume = resume ? 1 : 0;
6621
++
6622
++	class_init(&class_cfg);
6623
++
6624
++	pr_info("class_init() done\n");
6625
++
6626
++	tmu_init(&tmu_cfg);
6627
++
6628
++	pr_info("tmu_init() done\n");
6629
++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
6630
++	util_init(&util_cfg);
6631
++
6632
++	pr_info("util_init() done\n");
6633
++#endif
6634
++	gpi_init(EGPI1_BASE_ADDR, &egpi1_cfg);
6635
++
6636
++	pr_info("gpi_init(1) done\n");
6637
++
6638
++	gpi_init(EGPI2_BASE_ADDR, &egpi2_cfg);
6639
++
6640
++	pr_info("gpi_init(2) done\n");
6641
++
6642
++	gpi_init(HGPI_BASE_ADDR, &hgpi_cfg);
6643
++
6644
++	pr_info("gpi_init(hif) done\n");
6645
++
6646
++	bmu_enable(BMU1_BASE_ADDR);
6647
++
6648
++	pr_info("bmu_enable(1) done\n");
6649
++
6650
++	bmu_enable(BMU2_BASE_ADDR);
6651
++
6652
++	pr_info("bmu_enable(2) done\n");
6653
++
6654
++	return 0;
6655
++}
6656
++
6657
++void pfe_hw_exit(struct pfe *pfe)
6658
++{
6659
++	pr_info("%s\n", __func__);
6660
++
6661
++	bmu_disable(BMU1_BASE_ADDR);
6662
++	bmu_reset(BMU1_BASE_ADDR);
6663
++
6664
++	bmu_disable(BMU2_BASE_ADDR);
6665
++	bmu_reset(BMU2_BASE_ADDR);
6666
++}
6667
+diff --git a/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c b/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c
6668
+new file mode 100644
6669
+index 000000000000..c579eb58f277
6670
+--- /dev/null
6671
+@@ -0,0 +1,394 @@
6672
++/*
6673
++ * Copyright 2015-2016 Freescale Semiconductor, Inc.
6674
++ * Copyright 2017 NXP
6675
++ *
6676
++ * This program is free software; you can redistribute it and/or modify
6677
++ * it under the terms of the GNU General Public License as published by
6678
++ * the Free Software Foundation; either version 2 of the License, or
6679
++ * (at your option) any later version.
6680
++ *
6681
++ * This program is distributed in the hope that it will be useful,
6682
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6683
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
6684
++ * GNU General Public License for more details.
6685
++ *
6686
++ * You should have received a copy of the GNU General Public License
6687
++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
6688
++ */
6689
++
6690
++#include <linux/module.h>
6691
++#include <linux/device.h>
6692
++#include <linux/of_net.h>
6693
++#include <linux/of_address.h>
6694
++#include <linux/platform_device.h>
6695
++#include <linux/slab.h>
6696
++#include <linux/clk.h>
6697
++#include <linux/mfd/syscon.h>
6698
++#include <linux/regmap.h>
6699
++
6700
++#include "pfe_mod.h"
6701
++
6702
++struct ls1012a_pfe_platform_data pfe_platform_data;
6703
++
6704
++static int pfe_get_gemac_if_proprties(struct device_node *parent, int port, int
6705
++					if_cnt,
6706
++					struct ls1012a_pfe_platform_data
6707
++					*pdata)
6708
++{
6709
++	struct device_node *gem = NULL, *phy = NULL;
6710
++	int size;
6711
++	int ii = 0, phy_id = 0;
6712
++	const u32 *addr;
6713
++	const void *mac_addr;
6714
++
6715
++	for (ii = 0; ii < if_cnt; ii++) {
6716
++		gem = of_get_next_child(parent, gem);
6717
++		if (!gem)
6718
++			goto err;
6719
++		addr = of_get_property(gem, "reg", &size);
6720
++		if (addr && (be32_to_cpup(addr) == port))
6721
++			break;
6722
++	}
6723
++
6724
++	if (ii >= if_cnt) {
6725
++		pr_err("%s:%d Failed to find interface = %d\n",
6726
++		       __func__, __LINE__, if_cnt);
6727
++		goto err;
6728
++	}
6729
++
6730
++	pdata->ls1012a_eth_pdata[port].gem_id = port;
6731
++
6732
++	mac_addr = of_get_mac_address(gem);
6733
++
6734
++	if (mac_addr) {
6735
++		memcpy(pdata->ls1012a_eth_pdata[port].mac_addr, mac_addr,
6736
++		       ETH_ALEN);
6737
++	}
6738
++
6739
++	pdata->ls1012a_eth_pdata[port].mii_config = of_get_phy_mode(gem);
6740
++
6741
++	if ((pdata->ls1012a_eth_pdata[port].mii_config) < 0)
6742
++		pr_err("%s:%d Incorrect Phy mode....\n", __func__,
6743
++		       __LINE__);
6744
++
6745
++	addr = of_get_property(gem, "fsl,gemac-bus-id", &size);
6746
++	if (!addr)
6747
++		pr_err("%s:%d Invalid gemac-bus-id....\n", __func__,
6748
++		       __LINE__);
6749
++	else
6750
++		pdata->ls1012a_eth_pdata[port].bus_id = be32_to_cpup(addr);
6751
++
6752
++	addr = of_get_property(gem, "fsl,gemac-phy-id", &size);
6753
++	if (!addr) {
6754
++		pr_err("%s:%d Invalid gemac-phy-id....\n", __func__,
6755
++		       __LINE__);
6756
++	} else {
6757
++		phy_id = be32_to_cpup(addr);
6758
++		pdata->ls1012a_eth_pdata[port].phy_id = phy_id;
6759
++		pdata->ls1012a_mdio_pdata[0].phy_mask &= ~(1 << phy_id);
6760
++	}
6761
++
6762
++	addr = of_get_property(gem, "fsl,mdio-mux-val", &size);
6763
++	if (!addr)
6764
++		pr_err("%s: Invalid mdio-mux-val....\n", __func__);
6765
++	else
6766
++		phy_id = be32_to_cpup(addr);
6767
++		pdata->ls1012a_eth_pdata[port].mdio_muxval = phy_id;
6768
++
6769
++	if (pdata->ls1012a_eth_pdata[port].phy_id < 32)
6770
++		pfe->mdio_muxval[pdata->ls1012a_eth_pdata[port].phy_id] =
6771
++			 pdata->ls1012a_eth_pdata[port].mdio_muxval;
6772
++
6773
++	addr = of_get_property(gem, "fsl,pfe-phy-if-flags", &size);
6774
++	if (!addr)
6775
++		pr_err("%s:%d Invalid pfe-phy-if-flags....\n",
6776
++		       __func__, __LINE__);
6777
++	else
6778
++		pdata->ls1012a_eth_pdata[port].phy_flags = be32_to_cpup(addr);
6779
++
6780
++	/* If PHY is enabled, read mdio properties */
6781
++	if (pdata->ls1012a_eth_pdata[port].phy_flags & GEMAC_NO_PHY)
6782
++		goto done;
6783
++
6784
++	phy = of_get_next_child(gem, NULL);
6785
++
6786
++	addr = of_get_property(phy, "reg", &size);
6787
++
6788
++	if (!addr)
6789
++		pr_err("%s:%d Invalid phy enable flag....\n",
6790
++		       __func__, __LINE__);
6791
++	else
6792
++		pdata->ls1012a_mdio_pdata[port].enabled = be32_to_cpup(addr);
6793
++
6794
++	pdata->ls1012a_mdio_pdata[port].irq[0] = PHY_POLL;
6795
++
6796
++done:
6797
++
6798
++	return 0;
6799
++
6800
++err:
6801
++	return -1;
6802
++}
6803
++
6804
++/*
6805
++ *
6806
++ * pfe_platform_probe -
6807
++ *
6808
++ *
6809
++ */
6810
++static int pfe_platform_probe(struct platform_device *pdev)
6811
++{
6812
++	struct resource res;
6813
++	int ii, rc, interface_count = 0, size = 0;
6814
++	const u32 *prop;
6815
++	struct device_node  *np;
6816
++	struct clk *pfe_clk;
6817
++
6818
++	np = pdev->dev.of_node;
6819
++
6820
++	if (!np) {
6821
++		pr_err("Invalid device node\n");
6822
++		return -EINVAL;
6823
++	}
6824
++
6825
++	pfe = kzalloc(sizeof(*pfe), GFP_KERNEL);
6826
++	if (!pfe) {
6827
++		rc = -ENOMEM;
6828
++		goto err_alloc;
6829
++	}
6830
++
6831
++	platform_set_drvdata(pdev, pfe);
6832
++
6833
++	dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
6834
++
6835
++	if (of_address_to_resource(np, 1, &res)) {
6836
++		rc = -ENOMEM;
6837
++		pr_err("failed to get ddr resource\n");
6838
++		goto err_ddr;
6839
++	}
6840
++
6841
++	pfe->ddr_phys_baseaddr = res.start;
6842
++	pfe->ddr_size = resource_size(&res);
6843
++
6844
++	pfe->ddr_baseaddr = phys_to_virt(res.start);
6845
++	if (!pfe->ddr_baseaddr) {
6846
++		pr_err("ioremap() ddr failed\n");
6847
++		rc = -ENOMEM;
6848
++		goto err_ddr;
6849
++	}
6850
++
6851
++	pfe->scfg =
6852
++		syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
6853
++						"fsl,pfe-scfg");
6854
++	if (IS_ERR(pfe->scfg)) {
6855
++		dev_err(&pdev->dev, "No syscfg phandle specified\n");
6856
++		return PTR_ERR(pfe->scfg);
6857
++	}
6858
++
6859
++	pfe->cbus_baseaddr = of_iomap(np, 0);
6860
++	if (!pfe->cbus_baseaddr) {
6861
++		rc = -ENOMEM;
6862
++		pr_err("failed to get axi resource\n");
6863
++		goto err_axi;
6864
++	}
6865
++
6866
++	pfe->hif_irq = platform_get_irq(pdev, 0);
6867
++	if (pfe->hif_irq < 0) {
6868
++		pr_err("platform_get_irq for hif failed\n");
6869
++		rc = pfe->hif_irq;
6870
++		goto err_hif_irq;
6871
++	}
6872
++
6873
++	pfe->wol_irq = platform_get_irq(pdev, 2);
6874
++	if (pfe->wol_irq < 0) {
6875
++		pr_err("platform_get_irq for WoL failed\n");
6876
++		rc = pfe->wol_irq;
6877
++		goto err_hif_irq;
6878
++	}
6879
++
6880
++	/* Read interface count */
6881
++	prop = of_get_property(np, "fsl,pfe-num-interfaces", &size);
6882
++	if (!prop) {
6883
++		pr_err("Failed to read number of interfaces\n");
6884
++		rc = -ENXIO;
6885
++		goto err_prop;
6886
++	}
6887
++
6888
++	interface_count = be32_to_cpup(prop);
6889
++	if (interface_count <= 0) {
6890
++		pr_err("No ethernet interface count : %d\n",
6891
++		       interface_count);
6892
++		rc = -ENXIO;
6893
++		goto err_prop;
6894
++	}
6895
++
6896
++	pfe_platform_data.ls1012a_mdio_pdata[0].phy_mask = 0xffffffff;
6897
++
6898
++	for (ii = 0; ii < interface_count; ii++) {
6899
++		pfe_get_gemac_if_proprties(np, ii, interface_count,
6900
++					   &pfe_platform_data);
6901
++	}
6902
++
6903
++	pfe->dev = &pdev->dev;
6904
++
6905
++	pfe->dev->platform_data = &pfe_platform_data;
6906
++
6907
++	/* declare WoL capabilities */
6908
++	device_init_wakeup(&pdev->dev, true);
6909
++
6910
++	/* find the clocks */
6911
++	pfe_clk = devm_clk_get(pfe->dev, "pfe");
6912
++	if (IS_ERR(pfe_clk))
6913
++		return PTR_ERR(pfe_clk);
6914
++
6915
++	/* PFE clock is (platform clock / 2) */
6916
++	/* save sys_clk value as KHz */
6917
++	pfe->ctrl.sys_clk = clk_get_rate(pfe_clk) / (2 * 1000);
6918
++
6919
++	rc = pfe_probe(pfe);
6920
++	if (rc < 0)
6921
++		goto err_probe;
6922
++
6923
++	return 0;
6924
++
6925
++err_probe:
6926
++err_prop:
6927
++err_hif_irq:
6928
++	iounmap(pfe->cbus_baseaddr);
6929
++
6930
++err_axi:
6931
++	iounmap(pfe->ddr_baseaddr);
6932
++
6933
++err_ddr:
6934
++	platform_set_drvdata(pdev, NULL);
6935
++
6936
++	kfree(pfe);
6937
++
6938
++err_alloc:
6939
++	return rc;
6940
++}
6941
++
6942
++/*
6943
++ * pfe_platform_remove -
6944
++ */
6945
++static int pfe_platform_remove(struct platform_device *pdev)
6946
++{
6947
++	struct pfe *pfe = platform_get_drvdata(pdev);
6948
++	int rc;
6949
++
6950
++	pr_info("%s\n", __func__);
6951
++
6952
++	rc = pfe_remove(pfe);
6953
++
6954
++	iounmap(pfe->cbus_baseaddr);
6955
++	iounmap(pfe->ddr_baseaddr);
6956
++
6957
++	platform_set_drvdata(pdev, NULL);
6958
++
6959
++	kfree(pfe);
6960
++
6961
++	return rc;
6962
++}
6963
++
6964
++#ifdef CONFIG_PM
6965
++#ifdef CONFIG_PM_SLEEP
6966
++int pfe_platform_suspend(struct device *dev)
6967
++{
6968
++	struct pfe *pfe = platform_get_drvdata(to_platform_device(dev));
6969
++	struct net_device *netdev;
6970
++	int i;
6971
++
6972
++	pfe->wake = 0;
6973
++
6974
++	for (i = 0; i < (NUM_GEMAC_SUPPORT); i++) {
6975
++		netdev = pfe->eth.eth_priv[i]->ndev;
6976
++
6977
++		netif_device_detach(netdev);
6978
++
6979
++		if (netif_running(netdev))
6980
++			if (pfe_eth_suspend(netdev))
6981
++				pfe->wake = 1;
6982
++	}
6983
++
6984
++	/* Shutdown PFE only if we're not waking up the system */
6985
++	if (!pfe->wake) {
6986
++#if defined(LS1012A_PFE_RESET_WA)
6987
++		pfe_hif_rx_idle(&pfe->hif);
6988
++#endif
6989
++		pfe_ctrl_suspend(&pfe->ctrl);
6990
++		pfe_firmware_exit(pfe);
6991
++
6992
++		pfe_hif_exit(pfe);
6993
++		pfe_hif_lib_exit(pfe);
6994
++
6995
++		pfe_hw_exit(pfe);
6996
++	}
6997
++
6998
++	return 0;
6999
++}
7000
++
7001
++static int pfe_platform_resume(struct device *dev)
7002
++{
7003
++	struct pfe *pfe = platform_get_drvdata(to_platform_device(dev));
7004
++	struct net_device *netdev;
7005
++	int i;
7006
++
7007
++	if (!pfe->wake) {
7008
++		pfe_hw_init(pfe, 1);
7009
++		pfe_hif_lib_init(pfe);
7010
++		pfe_hif_init(pfe);
7011
++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
7012
++		util_enable();
7013
++#endif
7014
++		tmu_enable(0xf);
7015
++		class_enable();
7016
++		pfe_ctrl_resume(&pfe->ctrl);
7017
++	}
7018
++
7019
++	for (i = 0; i < (NUM_GEMAC_SUPPORT); i++) {
7020
++		netdev = pfe->eth.eth_priv[i]->ndev;
7021
++
7022
++		if (pfe->eth.eth_priv[i]->mii_bus)
7023
++			pfe_eth_mdio_reset(pfe->eth.eth_priv[i]->mii_bus);
7024
++
7025
++		if (netif_running(netdev))
7026
++			pfe_eth_resume(netdev);
7027
++
7028
++		netif_device_attach(netdev);
7029
++	}
7030
++	return 0;
7031
++}
7032
++#else
7033
++#define pfe_platform_suspend NULL
7034
++#define pfe_platform_resume NULL
7035
++#endif
7036
++
7037
++static const struct dev_pm_ops pfe_platform_pm_ops = {
7038
++	SET_SYSTEM_SLEEP_PM_OPS(pfe_platform_suspend, pfe_platform_resume)
7039
++};
7040
++#endif
7041
++
7042
++static const struct of_device_id pfe_match[] = {
7043
++	{
7044
++		.compatible = "fsl,pfe",
7045
++	},
7046
++	{},
7047
++};
7048
++MODULE_DEVICE_TABLE(of, pfe_match);
7049
++
7050
++static struct platform_driver pfe_platform_driver = {
7051
++	.probe = pfe_platform_probe,
7052
++	.remove = pfe_platform_remove,
7053
++	.driver = {
7054
++		.name = "pfe",
7055
++		.of_match_table = pfe_match,
7056
++#ifdef CONFIG_PM
7057
++		.pm = &pfe_platform_pm_ops,
7058
++#endif
7059
++	},
7060
++};
7061
++
7062
++module_platform_driver(pfe_platform_driver);
7063
++MODULE_LICENSE("GPL");
7064
++MODULE_DESCRIPTION("PFE Ethernet driver");
7065
++MODULE_AUTHOR("NXP DNCPE");
7066
+diff --git a/drivers/staging/fsl_ppfe/pfe_mod.c b/drivers/staging/fsl_ppfe/pfe_mod.c
7067
+new file mode 100644
7068
+index 000000000000..d5ba56a3c73f
7069
+--- /dev/null
7070
+@@ -0,0 +1,141 @@
7071
++/*
7072
++ * Copyright 2015-2016 Freescale Semiconductor, Inc.
7073
++ * Copyright 2017 NXP
7074
++ *
7075
++ * This program is free software; you can redistribute it and/or modify
7076
++ * it under the terms of the GNU General Public License as published by
7077
++ * the Free Software Foundation; either version 2 of the License, or
7078
++ * (at your option) any later version.
7079
++ *
7080
++ * This program is distributed in the hope that it will be useful,
7081
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7082
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
7083
++ * GNU General Public License for more details.
7084
++ *
7085
++ * You should have received a copy of the GNU General Public License
7086
++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
7087
++ */
7088
++
7089
++#include <linux/dma-mapping.h>
7090
++#include "pfe_mod.h"
7091
++
7092
++struct pfe *pfe;
7093
++
7094
++/*
7095
++ * pfe_probe -
7096
++ */
7097
++int pfe_probe(struct pfe *pfe)
7098
++{
7099
++	int rc;
7100
++
7101
++	if (pfe->ddr_size < DDR_MAX_SIZE) {
7102
++		pr_err("%s: required DDR memory (%x) above platform ddr memory (%x)\n",
7103
++		       __func__, (unsigned int)DDR_MAX_SIZE, pfe->ddr_size);
7104
++		rc = -ENOMEM;
7105
++		goto err_hw;
7106
++	}
7107
++
7108
++	if (((int)(pfe->ddr_phys_baseaddr + BMU2_DDR_BASEADDR) &
7109
++			(8 * SZ_1M - 1)) != 0) {
7110
++		pr_err("%s: BMU2 base address (0x%x) must be aligned on 8MB boundary\n",
7111
++		       __func__, (int)pfe->ddr_phys_baseaddr +
7112
++			BMU2_DDR_BASEADDR);
7113
++		rc = -ENOMEM;
7114
++		goto err_hw;
7115
++	}
7116
++
7117
++	pr_info("cbus_baseaddr: %lx, ddr_baseaddr: %lx, ddr_phys_baseaddr: %lx, ddr_size: %x\n",
7118
++		(unsigned long)pfe->cbus_baseaddr,
7119
++		(unsigned long)pfe->ddr_baseaddr,
7120
++		pfe->ddr_phys_baseaddr, pfe->ddr_size);
7121
++
7122
++	pfe_lib_init(pfe->cbus_baseaddr, pfe->ddr_baseaddr,
7123
++		     pfe->ddr_phys_baseaddr, pfe->ddr_size);
7124
++
7125
++	rc = pfe_hw_init(pfe, 0);
7126
++	if (rc < 0)
7127
++		goto err_hw;
7128
++
7129
++	rc = pfe_hif_lib_init(pfe);
7130
++	if (rc < 0)
7131
++		goto err_hif_lib;
7132
++
7133
++	rc = pfe_hif_init(pfe);
7134
++	if (rc < 0)
7135
++		goto err_hif;
7136
++
7137
++	rc = pfe_firmware_init(pfe);
7138
++	if (rc < 0)
7139
++		goto err_firmware;
7140
++
7141
++	rc = pfe_ctrl_init(pfe);
7142
++	if (rc < 0)
7143
++		goto err_ctrl;
7144
++
7145
++	rc = pfe_eth_init(pfe);
7146
++	if (rc < 0)
7147
++		goto err_eth;
7148
++
7149
++	rc = pfe_sysfs_init(pfe);
7150
++	if (rc < 0)
7151
++		goto err_sysfs;
7152
++
7153
++	rc = pfe_debugfs_init(pfe);
7154
++	if (rc < 0)
7155
++		goto err_debugfs;
7156
++
7157
++	return 0;
7158
++
7159
++err_debugfs:
7160
++	pfe_sysfs_exit(pfe);
7161
++
7162
++err_sysfs:
7163
++	pfe_eth_exit(pfe);
7164
++
7165
++err_eth:
7166
++	pfe_ctrl_exit(pfe);
7167
++
7168
++err_ctrl:
7169
++	pfe_firmware_exit(pfe);
7170
++
7171
++err_firmware:
7172
++	pfe_hif_exit(pfe);
7173
++
7174
++err_hif:
7175
++	pfe_hif_lib_exit(pfe);
7176
++
7177
++err_hif_lib:
7178
++	pfe_hw_exit(pfe);
7179
++
7180
++err_hw:
7181
++	return rc;
7182
++}
7183
++
7184
++/*
7185
++ * pfe_remove -
7186
++ */
7187
++int pfe_remove(struct pfe *pfe)
7188
++{
7189
++	pr_info("%s\n", __func__);
7190
++
7191
++	pfe_debugfs_exit(pfe);
7192
++
7193
++	pfe_sysfs_exit(pfe);
7194
++
7195
++	pfe_eth_exit(pfe);
7196
++
7197
++	pfe_ctrl_exit(pfe);
7198
++
7199
++#if defined(LS1012A_PFE_RESET_WA)
7200
++	pfe_hif_rx_idle(&pfe->hif);
7201
++#endif
7202
++	pfe_firmware_exit(pfe);
7203
++
7204
++	pfe_hif_exit(pfe);
7205
++
7206
++	pfe_hif_lib_exit(pfe);
7207
++
7208
++	pfe_hw_exit(pfe);
7209
++
7210
++	return 0;
7211
++}
7212
+diff --git a/drivers/staging/fsl_ppfe/pfe_sysfs.c b/drivers/staging/fsl_ppfe/pfe_sysfs.c
7213
+new file mode 100644
7214
+index 000000000000..2a763844bdcb
7215
+--- /dev/null
7216
+@@ -0,0 +1,818 @@
7217
++/*
7218
++ * Copyright 2015-2016 Freescale Semiconductor, Inc.
7219
++ * Copyright 2017 NXP
7220
++ *
7221
++ * This program is free software; you can redistribute it and/or modify
7222
++ * it under the terms of the GNU General Public License as published by
7223
++ * the Free Software Foundation; either version 2 of the License, or
7224
++ * (at your option) any later version.
7225
++ *
7226
++ * This program is distributed in the hope that it will be useful,
7227
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
7228
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
7229
++ * GNU General Public License for more details.
7230
++ *
7231
++ * You should have received a copy of the GNU General Public License
7232
++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
7233
++ */
7234
++
7235
++#include <linux/module.h>
7236
++#include <linux/platform_device.h>
7237
++
7238
++#include "pfe_mod.h"
7239
++
7240
++#define PE_EXCEPTION_DUMP_ADDRESS 0x1fa8
7241
++#define NUM_QUEUES		16
7242
++
7243
++static char register_name[20][5] = {
7244
++	"EPC", "ECAS", "EID", "ED",
7245
++	"r0", "r1", "r2", "r3",
7246
++	"r4", "r5", "r6", "r7",
7247
++	"r8", "r9", "r10", "r11",
7248
++	"r12", "r13", "r14", "r15",
7249
++};
7250
++
7251
++static char exception_name[14][20] = {
7252
++	"Reset",
7253
++	"HardwareFailure",
7254
++	"NMI",
7255
++	"InstBreakpoint",
7256
++	"DataBreakpoint",
7257
++	"Unsupported",
7258
++	"PrivilegeViolation",
7259
++	"InstBusError",
7260
++	"DataBusError",
7261
++	"AlignmentError",
7262
++	"ArithmeticError",
7263
++	"SystemCall",
7264
++	"MemoryManagement",
7265
++	"Interrupt",
7266
++};
7267
++
7268
++static unsigned long class_do_clear;
7269
++static unsigned long tmu_do_clear;
7270
++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
7271
++static unsigned long util_do_clear;
7272
++#endif
7273
++
7274
++static ssize_t display_pe_status(char *buf, int id, u32 dmem_addr, unsigned long
7275
++					do_clear)
7276
++{
7277
++	ssize_t len = 0;
7278
++	u32 val;
7279
++	char statebuf[5];
7280
++	struct pfe_cpumon *cpumon = &pfe->cpumon;
7281
++	u32 debug_indicator;
7282
++	u32 debug[20];
7283
++
7284
++	*(u32 *)statebuf = pe_dmem_read(id, dmem_addr, 4);
7285
++	dmem_addr += 4;
7286
++
7287
++	statebuf[4] = '\0';
7288
++	len += sprintf(buf + len, "state=%4s ", statebuf);
7289
++
7290
++	val = pe_dmem_read(id, dmem_addr, 4);
7291
++	dmem_addr += 4;
7292
++	len += sprintf(buf + len, "ctr=%08x ", cpu_to_be32(val));
7293
++
7294
++	val = pe_dmem_read(id, dmem_addr, 4);
7295
++	if (do_clear && val)
7296
++		pe_dmem_write(id, 0, dmem_addr, 4);
7297
++	dmem_addr += 4;
7298
++	len += sprintf(buf + len, "rx=%u ", cpu_to_be32(val));
7299
++
7300
++	val = pe_dmem_read(id, dmem_addr, 4);
7301
++	if (do_clear && val)
7302
++		pe_dmem_write(id, 0, dmem_addr, 4);
7303
++	dmem_addr += 4;
7304
++	if (id >= TMU0_ID && id <= TMU_MAX_ID)
7305
++		len += sprintf(buf + len, "qstatus=%x", cpu_to_be32(val));
7306
++	else
7307
++		len += sprintf(buf + len, "tx=%u", cpu_to_be32(val));
7308
++
7309
++	val = pe_dmem_read(id, dmem_addr, 4);
7310
++	if (do_clear && val)
7311
++		pe_dmem_write(id, 0, dmem_addr, 4);
7312
++	dmem_addr += 4;
7313
++	if (val)
7314
++		len += sprintf(buf + len, " drop=%u", cpu_to_be32(val));
7315
++
7316
++	len += sprintf(buf + len, " load=%d%%", cpumon->cpu_usage_pct[id]);
7317
++
7318
++	len += sprintf(buf + len, "\n");
7319
++
7320
++	debug_indicator = pe_dmem_read(id, dmem_addr, 4);
7321
++	dmem_addr += 4;
7322
++	if (!strncmp((char *)&debug_indicator, "DBUG", 4)) {
7323
++		int j, last = 0;
7324
++
7325
++		for (j = 0; j < 16; j++) {
7326
++			debug[j] = pe_dmem_read(id, dmem_addr, 4);
7327
++			if (debug[j]) {
7328
++				if (do_clear)
7329
++					pe_dmem_write(id, 0, dmem_addr, 4);
7330
++				last = j + 1;
7331
++			}
7332
++			dmem_addr += 4;
7333
++		}
7334
++		for (j = 0; j < last; j++) {
7335
++			len += sprintf(buf + len, "%08x%s",
7336
++			cpu_to_be32(debug[j]),
7337
++			(j & 0x7) == 0x7 || j == last - 1 ? "\n" : " ");
7338
++		}
7339
++	}
7340
++
7341
++	if (!strncmp(statebuf, "DEAD", 4)) {
7342
++		u32 i, dump = PE_EXCEPTION_DUMP_ADDRESS;
7343
++
7344
++		len += sprintf(buf + len, "Exception details:\n");
7345
++		for (i = 0; i < 20; i++) {
7346
++			debug[i] = pe_dmem_read(id, dump, 4);
7347
++			dump += 4;
7348
++			if (i == 2)
7349
++				len += sprintf(buf + len, "%4s = %08x (=%s) ",
7350
++				register_name[i], cpu_to_be32(debug[i]),
7351
++				exception_name[min((u32)
7352
++				cpu_to_be32(debug[i]), (u32)13)]);
7353
++			else
7354
++				len += sprintf(buf + len, "%4s = %08x%s",
7355
++				register_name[i], cpu_to_be32(debug[i]),
7356
++				(i & 0x3) == 0x3 || i == 19 ? "\n" : " ");
7357
++		}
7358
++	}
7359
++
7360
++	return len;
7361
++}
7362
++
7363
++static ssize_t class_phy_stats(char *buf, int phy)
7364
++{
7365
++	ssize_t len = 0;
7366
++	int off1 = phy * 0x28;
7367
++	int off2 = phy * 0x10;
7368
++
7369
++	if (phy == 3)
7370
++		off1 = CLASS_PHY4_RX_PKTS - CLASS_PHY1_RX_PKTS;
7371
++
7372
++	len += sprintf(buf + len, "phy: %d\n", phy);
7373
++	len += sprintf(buf + len,
7374
++			"  rx:   %10u, tx:   %10u, intf:  %10u, ipv4:    %10u, ipv6: %10u\n",
7375
++			readl(CLASS_PHY1_RX_PKTS + off1),
7376
++			readl(CLASS_PHY1_TX_PKTS + off1),
7377
++			readl(CLASS_PHY1_INTF_MATCH_PKTS + off1),
7378
++			readl(CLASS_PHY1_V4_PKTS + off1),
7379
++			readl(CLASS_PHY1_V6_PKTS + off1));
7380
++
7381
++	len += sprintf(buf + len,
7382
++			"  icmp: %10u, igmp: %10u, tcp:   %10u, udp:     %10u\n",
7383
++			readl(CLASS_PHY1_ICMP_PKTS + off2),
7384
++			readl(CLASS_PHY1_IGMP_PKTS + off2),
7385
++			readl(CLASS_PHY1_TCP_PKTS + off2),
7386
++			readl(CLASS_PHY1_UDP_PKTS + off2));
7387
++
7388
++	len += sprintf(buf + len, "  err\n");
7389
++	len += sprintf(buf + len,
7390
++			"  lp:   %10u, intf: %10u, l3:    %10u, chcksum: %10u, ttl:  %10u\n",
7391
++			readl(CLASS_PHY1_LP_FAIL_PKTS + off1),
7392
++			readl(CLASS_PHY1_INTF_FAIL_PKTS + off1),
7393
++			readl(CLASS_PHY1_L3_FAIL_PKTS + off1),
7394
++			readl(CLASS_PHY1_CHKSUM_ERR_PKTS + off1),
7395
++			readl(CLASS_PHY1_TTL_ERR_PKTS + off1));
7396
++
7397
++	return len;
7398
++}
7399
++
7400
++/* qm_read_drop_stat
7401
++ * This function is used to read the drop statistics from the TMU
7402
++ * hw drop counter.  Since the hw counter is always cleared afer
7403
++ * reading, this function maintains the previous drop count, and
7404
++ * adds the new value to it.  That value can be retrieved by
7405
++ * passing a pointer to it with the total_drops arg.
7406
++ *
7407
++ * @param tmu		TMU number (0 - 3)
7408
++ * @param queue		queue number (0 - 15)
7409
++ * @param total_drops	pointer to location to store total drops (or NULL)
7410
++ * @param do_reset	if TRUE, clear total drops after updating
7411
++ */
7412
++u32 qm_read_drop_stat(u32 tmu, u32 queue, u32 *total_drops, int do_reset)
7413
++{
7414
++	static u32 qtotal[TMU_MAX_ID + 1][NUM_QUEUES];
7415
++	u32 val;
7416
++
7417
++	writel((tmu << 8) | queue, TMU_TEQ_CTRL);
7418
++	writel((tmu << 8) | queue, TMU_LLM_CTRL);
7419
++	val = readl(TMU_TEQ_DROP_STAT);
7420
++	qtotal[tmu][queue] += val;
7421
++	if (total_drops)
7422
++		*total_drops = qtotal[tmu][queue];
7423
++	if (do_reset)
7424
++		qtotal[tmu][queue] = 0;
7425
++	return val;
7426
++}
7427
++
7428
++static ssize_t tmu_queue_stats(char *buf, int tmu, int queue)
7429
++{
7430
++	ssize_t len = 0;
7431
++	u32 drops;
7432
++
7433
++	len += sprintf(buf + len, "%d-%02d, ", tmu, queue);
7434
++
7435
++	drops = qm_read_drop_stat(tmu, queue, NULL, 0);
7436
++
7437
++	/* Select queue */
7438
++	writel((tmu << 8) | queue, TMU_TEQ_CTRL);
7439
++	writel((tmu << 8) | queue, TMU_LLM_CTRL);
7440
++
7441
++	len += sprintf(buf + len,
7442
++			"(teq) drop: %10u, tx: %10u (llm) head: %08x, tail: %08x, drop: %10u\n",
7443
++		drops, readl(TMU_TEQ_TRANS_STAT),
7444
++		readl(TMU_LLM_QUE_HEADPTR), readl(TMU_LLM_QUE_TAILPTR),
7445
++		readl(TMU_LLM_QUE_DROPCNT));
7446
++
7447
++	return len;
7448
++}
7449
++
7450
++static ssize_t tmu_queues(char *buf, int tmu)
7451
++{
7452
++	ssize_t len = 0;
7453
++	int queue;
7454
++
7455
++	for (queue = 0; queue < 16; queue++)
7456
++		len += tmu_queue_stats(buf + len, tmu, queue);
7457
++
7458
++	return len;
7459
++}
7460
++
7461
++static ssize_t block_version(char *buf, void *addr)
7462
++{
7463
++	ssize_t len = 0;
7464
++	u32 val;
7465
++
7466
++	val = readl(addr);
7467
++	len += sprintf(buf + len, "revision: %x, version: %x, id: %x\n",
7468
++		(val >> 24) & 0xff, (val >> 16) & 0xff, val & 0xffff);
7469
++
7470
++	return len;
7471
++}
7472
++
7473
++static ssize_t bmu(char *buf, int id, void *base)
7474
++{
7475
++	ssize_t len = 0;
7476
++
7477
++	len += sprintf(buf + len, "%s: %d\n  ", __func__, id);
7478
++
7479
++	len += block_version(buf + len, base + BMU_VERSION);
7480
++
7481
++	len += sprintf(buf + len, "  buf size:  %x\n", (1 << readl(base +
7482
++			BMU_BUF_SIZE)));
7483
++	len += sprintf(buf + len, "  buf count: %x\n", readl(base +
7484
++			BMU_BUF_CNT));
7485
++	len += sprintf(buf + len, "  buf rem:   %x\n", readl(base +
7486
++			BMU_REM_BUF_CNT));
7487
++	len += sprintf(buf + len, "  buf curr:  %x\n", readl(base +
7488
++			BMU_CURR_BUF_CNT));
7489
++	len += sprintf(buf + len, "  free err:  %x\n", readl(base +
7490
++			BMU_FREE_ERR_ADDR));
7491
++
7492
++	return len;
7493
++}
7494
++
7495
++static ssize_t gpi(char *buf, int id, void *base)
7496
++{
7497
++	ssize_t len = 0;
7498
++	u32 val;
7499
++
7500
++	len += sprintf(buf + len, "%s%d:\n  ", __func__, id);
7501
++	len += block_version(buf + len, base + GPI_VERSION);
7502
++
7503
++	len += sprintf(buf + len, "  tx under stick: %x\n", readl(base +
7504
++			GPI_FIFO_STATUS));
7505
++	val = readl(base + GPI_FIFO_DEBUG);
7506
++	len += sprintf(buf + len, "  tx pkts:        %x\n", (val >> 23) &
7507
++			0x3f);
7508
++	len += sprintf(buf + len, "  rx pkts:        %x\n", (val >> 18) &
7509
++			0x3f);
7510
++	len += sprintf(buf + len, "  tx bytes:       %x\n", (val >> 9) &
7511
++			0x1ff);
7512
++	len += sprintf(buf + len, "  rx bytes:       %x\n", (val >> 0) &
7513
++			0x1ff);
7514
++	len += sprintf(buf + len, "  overrun:        %x\n", readl(base +
7515
++			GPI_OVERRUN_DROPCNT));
7516
++
7517
++	return len;
7518
++}
7519
++
7520
++static ssize_t pfe_set_class(struct device *dev, struct device_attribute *attr,
7521
++			     const char *buf, size_t count)
7522
++{
7523
++	class_do_clear = kstrtoul(buf, 0, 0);
7524
++	return count;
7525
++}
7526
++
7527
++static ssize_t pfe_show_class(struct device *dev, struct device_attribute *attr,
7528
++			      char *buf)
7529
++{
7530
++	ssize_t len = 0;
7531
++	int id;
7532
++	u32 val;
7533
++	struct pfe_cpumon *cpumon = &pfe->cpumon;
7534
++
7535
++	len += block_version(buf + len, CLASS_VERSION);
7536
++
7537
++	for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++) {
7538
++		len += sprintf(buf + len, "%d: ", id - CLASS0_ID);
7539
++
7540
++		val = readl(CLASS_PE0_DEBUG + id * 4);
7541
++		len += sprintf(buf + len, "pc=1%04x ", val & 0xffff);
7542
++
7543
++		len += display_pe_status(buf + len, id, CLASS_DM_PESTATUS,
7544
++						class_do_clear);
7545
++	}
7546
++	len += sprintf(buf + len, "aggregate load=%d%%\n\n",
7547
++			cpumon->class_usage_pct);
7548
++
7549
++	len += sprintf(buf + len, "pe status:   0x%x\n",
7550
++			readl(CLASS_PE_STATUS));
7551
++	len += sprintf(buf + len, "max buf cnt: 0x%x   afull thres: 0x%x\n",
7552
++			readl(CLASS_MAX_BUF_CNT), readl(CLASS_AFULL_THRES));
7553
++	len += sprintf(buf + len, "tsq max cnt: 0x%x   tsq fifo thres: 0x%x\n",
7554
++			readl(CLASS_TSQ_MAX_CNT), readl(CLASS_TSQ_FIFO_THRES));
7555
++	len += sprintf(buf + len, "state:       0x%x\n", readl(CLASS_STATE));
7556
++
7557
++	len += class_phy_stats(buf + len, 0);
7558
++	len += class_phy_stats(buf + len, 1);
7559
++	len += class_phy_stats(buf + len, 2);
7560
++	len += class_phy_stats(buf + len, 3);
7561
++
7562
++	return len;
7563
++}
7564
++
7565
++static ssize_t pfe_set_tmu(struct device *dev, struct device_attribute *attr,
7566
++			   const char *buf, size_t count)
7567
++{
7568
++	tmu_do_clear = kstrtoul(buf, 0, 0);
7569
++	return count;
7570
++}
7571
++
7572
++static ssize_t pfe_show_tmu(struct device *dev, struct device_attribute *attr,
7573
++			    char *buf)
7574
++{
7575
++	ssize_t len = 0;
7576
++	int id;
7577
++	u32 val;
7578
++
7579
++	len += block_version(buf + len, TMU_VERSION);
7580
++
7581
++	for (id = TMU0_ID; id <= TMU_MAX_ID; id++) {
7582
++		if (id == TMU2_ID)
7583
++			continue;
7584
++		len += sprintf(buf + len, "%d: ", id - TMU0_ID);
7585
++
7586
++		len += display_pe_status(buf + len, id, TMU_DM_PESTATUS,
7587
++						tmu_do_clear);
7588
++	}
7589
++
7590
++	len += sprintf(buf + len, "pe status:    %x\n", readl(TMU_PE_STATUS));
7591
++	len += sprintf(buf + len, "inq fifo cnt: %x\n",
7592
++			readl(TMU_PHY_INQ_FIFO_CNT));
7593
++	val = readl(TMU_INQ_STAT);
7594
++	len += sprintf(buf + len, "inq wr ptr:     %x\n", val & 0x3ff);
7595
++	len += sprintf(buf + len, "inq rd ptr:     %x\n", val >> 10);
7596
++
7597
++	return len;
7598
++}
7599
++
7600
++static unsigned long drops_do_clear;
7601
++static u32 class_drop_counter[CLASS_NUM_DROP_COUNTERS];
7602
++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
7603
++static u32 util_drop_counter[UTIL_NUM_DROP_COUNTERS];
7604
++#endif
7605
++
7606
++char *class_drop_description[CLASS_NUM_DROP_COUNTERS] = {
7607
++	"ICC",
7608
++	"Host Pkt Error",
7609
++	"Rx Error",
7610
++	"IPsec Outbound",
7611
++	"IPsec Inbound",
7612
++	"EXPT IPsec Error",
7613
++	"Reassembly",
7614
++	"Fragmenter",
7615
++	"NAT-T",
7616
++	"Socket",
7617
++	"Multicast",
7618
++	"NAT-PT",
7619
++	"Tx Disabled",
7620
++};
7621
++
7622
++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
7623
++char *util_drop_description[UTIL_NUM_DROP_COUNTERS] = {
7624
++	"IPsec Outbound",
7625
++	"IPsec Inbound",
7626
++	"IPsec Rate Limiter",
7627
++	"Fragmenter",
7628
++	"Socket",
7629
++	"Tx Disabled",
7630
++	"Rx Error",
7631
++};
7632
++#endif
7633
++
7634
++static ssize_t pfe_set_drops(struct device *dev, struct device_attribute *attr,
7635
++			     const char *buf, size_t count)
7636
++{
7637
++	drops_do_clear = kstrtoul(buf, 0, 0);
7638
++	return count;
7639
++}
7640
++
7641
++static u32 tmu_drops[4][16];
7642
++static ssize_t pfe_show_drops(struct device *dev, struct device_attribute *attr,
7643
++			      char *buf)
7644
++{
7645
++	ssize_t len = 0;
7646
++	int id, dropnum;
7647
++	int tmu, queue;
7648
++	u32 val;
7649
++	u32 dmem_addr;
7650
++	int num_class_drops = 0, num_tmu_drops = 0, num_util_drops = 0;
7651
++	struct pfe_ctrl *ctrl = &pfe->ctrl;
7652
++
7653
++	memset(class_drop_counter, 0, sizeof(class_drop_counter));
7654
++	for (id = CLASS0_ID; id <= CLASS_MAX_ID; id++) {
7655
++		if (drops_do_clear)
7656
++			pe_sync_stop(ctrl, (1 << id));
7657
++		for (dropnum = 0; dropnum < CLASS_NUM_DROP_COUNTERS;
7658
++			dropnum++) {
7659
++			dmem_addr = CLASS_DM_DROP_CNTR;
7660
++			val = be32_to_cpu(pe_dmem_read(id, dmem_addr, 4));
7661
++			class_drop_counter[dropnum] += val;
7662
++			num_class_drops += val;
7663
++			if (drops_do_clear)
7664
++				pe_dmem_write(id, 0, dmem_addr, 4);
7665
++		}
7666
++		if (drops_do_clear)
7667
++			pe_start(ctrl, (1 << id));
7668
++	}
7669
++
7670
++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
7671
++	if (drops_do_clear)
7672
++		pe_sync_stop(ctrl, (1 << UTIL_ID));
7673
++	for (dropnum = 0; dropnum < UTIL_NUM_DROP_COUNTERS; dropnum++) {
7674
++		dmem_addr = UTIL_DM_DROP_CNTR;
7675
++		val = be32_to_cpu(pe_dmem_read(UTIL_ID, dmem_addr, 4));
7676
++		util_drop_counter[dropnum] = val;
7677
++		num_util_drops += val;
7678
++		if (drops_do_clear)
7679
++			pe_dmem_write(UTIL_ID, 0, dmem_addr, 4);
7680
++	}
7681
++	if (drops_do_clear)
7682
++		pe_start(ctrl, (1 << UTIL_ID));
7683
++#endif
7684
++	for (tmu = 0; tmu < 4; tmu++) {
7685
++		for (queue = 0; queue < 16; queue++) {
7686
++			qm_read_drop_stat(tmu, queue, &tmu_drops[tmu][queue],
7687
++					  drops_do_clear);
7688
++			num_tmu_drops += tmu_drops[tmu][queue];
7689
++		}
7690
++	}
7691
++
7692
++	if (num_class_drops == 0 && num_util_drops == 0 && num_tmu_drops == 0)
7693
++		len += sprintf(buf + len, "No PE drops\n\n");
7694
++
7695
++	if (num_class_drops > 0) {
7696
++		len += sprintf(buf + len, "Class PE drops --\n");
7697
++		for (dropnum = 0; dropnum < CLASS_NUM_DROP_COUNTERS;
7698
++			dropnum++) {
7699
++			if (class_drop_counter[dropnum] > 0)
7700
++				len += sprintf(buf + len, "  %s: %d\n",
7701
++					class_drop_description[dropnum],
7702
++					class_drop_counter[dropnum]);
7703
++		}
7704
++		len += sprintf(buf + len, "\n");
7705
++	}
7706
++
7707
++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
7708
++	if (num_util_drops > 0) {
7709
++		len += sprintf(buf + len, "Util PE drops --\n");
7710
++		for (dropnum = 0; dropnum < UTIL_NUM_DROP_COUNTERS; dropnum++) {
7711
++			if (util_drop_counter[dropnum] > 0)
7712
++				len += sprintf(buf + len, "  %s: %d\n",
7713
++					util_drop_description[dropnum],
7714
++					util_drop_counter[dropnum]);
7715
++		}
7716
++		len += sprintf(buf + len, "\n");
7717
++	}
7718
++#endif
7719
++	if (num_tmu_drops > 0) {
7720
++		len += sprintf(buf + len, "TMU drops --\n");
7721
++		for (tmu = 0; tmu < 4; tmu++) {
7722
++			for (queue = 0; queue < 16; queue++) {
7723
++				if (tmu_drops[tmu][queue] > 0)
7724
++					len += sprintf(buf + len,
7725
++						"  TMU%d-Q%d: %d\n"
7726
++					, tmu, queue, tmu_drops[tmu][queue]);
7727
++			}
7728
++		}
7729
++		len += sprintf(buf + len, "\n");
7730
++	}
7731
++
7732
++	return len;
7733
++}
7734
++
7735
++static ssize_t pfe_show_tmu0_queues(struct device *dev, struct device_attribute
7736
++					*attr, char *buf)
7737
++{
7738
++	return tmu_queues(buf, 0);
7739
++}
7740
++
7741
++static ssize_t pfe_show_tmu1_queues(struct device *dev, struct device_attribute
7742
++					*attr, char *buf)
7743
++{
7744
++	return tmu_queues(buf, 1);
7745
++}
7746
++
7747
++static ssize_t pfe_show_tmu2_queues(struct device *dev, struct device_attribute
7748
++					*attr, char *buf)
7749
++{
7750
++	return tmu_queues(buf, 2);
7751
++}
7752
++
7753
++static ssize_t pfe_show_tmu3_queues(struct device *dev, struct device_attribute
7754
++					*attr, char *buf)
7755
++{
7756
++	return tmu_queues(buf, 3);
7757
++}
7758
++
7759
++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
7760
++static ssize_t pfe_set_util(struct device *dev, struct device_attribute *attr,
7761
++			    const char *buf, size_t count)
7762
++{
7763
++	util_do_clear = kstrtoul(buf, NULL, 0);
7764
++	return count;
7765
++}
7766
++
7767
++static ssize_t pfe_show_util(struct device *dev, struct device_attribute *attr,
7768
++			     char *buf)
7769
++{
7770
++	ssize_t len = 0;
7771
++	struct pfe_ctrl *ctrl = &pfe->ctrl;
7772
++
7773
++	len += block_version(buf + len, UTIL_VERSION);
7774
++
7775
++	pe_sync_stop(ctrl, (1 << UTIL_ID));
7776
++	len += display_pe_status(buf + len, UTIL_ID, UTIL_DM_PESTATUS,
7777
++					util_do_clear);
7778
++	pe_start(ctrl, (1 << UTIL_ID));
7779
++
7780
++	len += sprintf(buf + len, "pe status:   %x\n", readl(UTIL_PE_STATUS));
7781
++	len += sprintf(buf + len, "max buf cnt: %x\n",
7782
++			readl(UTIL_MAX_BUF_CNT));
7783
++	len += sprintf(buf + len, "tsq max cnt: %x\n",
7784
++			readl(UTIL_TSQ_MAX_CNT));
7785
++
7786
++	return len;
7787
++}
7788
++#endif
7789
++
7790
++static ssize_t pfe_show_bmu(struct device *dev, struct device_attribute *attr,
7791
++			    char *buf)
7792
++{
7793
++	ssize_t len = 0;
7794
++
7795
++	len += bmu(buf + len, 1, BMU1_BASE_ADDR);
7796
++	len += bmu(buf + len, 2, BMU2_BASE_ADDR);
7797
++
7798
++	return len;
7799
++}
7800
++
7801
++static ssize_t pfe_show_hif(struct device *dev, struct device_attribute *attr,
7802
++			    char *buf)
7803
++{
7804
++	ssize_t len = 0;
7805
++
7806
++	len += sprintf(buf + len, "hif:\n  ");
7807
++	len += block_version(buf + len, HIF_VERSION);
7808
++
7809
++	len += sprintf(buf + len, "  tx curr bd:    %x\n",
7810
++			readl(HIF_TX_CURR_BD_ADDR));
7811
++	len += sprintf(buf + len, "  tx status:     %x\n",
7812
++			readl(HIF_TX_STATUS));
7813
++	len += sprintf(buf + len, "  tx dma status: %x\n",
7814
++			readl(HIF_TX_DMA_STATUS));
7815
++
7816
++	len += sprintf(buf + len, "  rx curr bd:    %x\n",
7817
++			readl(HIF_RX_CURR_BD_ADDR));
7818
++	len += sprintf(buf + len, "  rx status:     %x\n",
7819
++			readl(HIF_RX_STATUS));
7820
++	len += sprintf(buf + len, "  rx dma status: %x\n",
7821
++			readl(HIF_RX_DMA_STATUS));
7822
++
7823
++	len += sprintf(buf + len, "hif nocopy:\n  ");
7824
++	len += block_version(buf + len, HIF_NOCPY_VERSION);
7825
++
7826
++	len += sprintf(buf + len, "  tx curr bd:    %x\n",
7827
++			readl(HIF_NOCPY_TX_CURR_BD_ADDR));
7828
++	len += sprintf(buf + len, "  tx status:     %x\n",
7829
++			readl(HIF_NOCPY_TX_STATUS));
7830
++	len += sprintf(buf + len, "  tx dma status: %x\n",
7831
++			readl(HIF_NOCPY_TX_DMA_STATUS));
7832
++
7833
++	len += sprintf(buf + len, "  rx curr bd:    %x\n",
7834
++			readl(HIF_NOCPY_RX_CURR_BD_ADDR));
7835
++	len += sprintf(buf + len, "  rx status:     %x\n",
7836
++			readl(HIF_NOCPY_RX_STATUS));
7837
++	len += sprintf(buf + len, "  rx dma status: %x\n",
7838
++			readl(HIF_NOCPY_RX_DMA_STATUS));
7839
++
7840
++	return len;
7841
++}
7842
++
7843
++static ssize_t pfe_show_gpi(struct device *dev, struct device_attribute *attr,
7844
++			    char *buf)
7845
++{
7846
++	ssize_t len = 0;
7847
++
7848
++	len += gpi(buf + len, 0, EGPI1_BASE_ADDR);
7849
++	len += gpi(buf + len, 1, EGPI2_BASE_ADDR);
7850
++	len += gpi(buf + len, 3, HGPI_BASE_ADDR);
7851
++
7852
++	return len;
7853
++}
7854
++
7855
++static ssize_t pfe_show_pfemem(struct device *dev, struct device_attribute
7856
++				*attr, char *buf)
7857
++{
7858
++	ssize_t len = 0;
7859
++	struct pfe_memmon *memmon = &pfe->memmon;
7860
++
7861
++	len += sprintf(buf + len, "Kernel Memory: %d Bytes (%d KB)\n",
7862
++		memmon->kernel_memory_allocated,
7863
++		(memmon->kernel_memory_allocated + 1023) / 1024);
7864
++
7865
++	return len;
7866
++}
7867
++
7868
++#ifdef HIF_NAPI_STATS
7869
++static ssize_t pfe_show_hif_napi_stats(struct device *dev,
7870
++				       struct device_attribute *attr,
7871
++				       char *buf)
7872
++{
7873
++	struct platform_device *pdev = to_platform_device(dev);
7874
++	struct pfe *pfe = platform_get_drvdata(pdev);
7875
++	ssize_t len = 0;
7876
++
7877
++	len += sprintf(buf + len, "sched:  %u\n",
7878
++			pfe->hif.napi_counters[NAPI_SCHED_COUNT]);
7879
++	len += sprintf(buf + len, "poll:   %u\n",
7880
++			pfe->hif.napi_counters[NAPI_POLL_COUNT]);
7881
++	len += sprintf(buf + len, "packet: %u\n",
7882
++			pfe->hif.napi_counters[NAPI_PACKET_COUNT]);
7883
++	len += sprintf(buf + len, "budget: %u\n",
7884
++			pfe->hif.napi_counters[NAPI_FULL_BUDGET_COUNT]);
7885
++	len += sprintf(buf + len, "desc:   %u\n",
7886
++			pfe->hif.napi_counters[NAPI_DESC_COUNT]);
7887
++	len += sprintf(buf + len, "full:   %u\n",
7888
++			pfe->hif.napi_counters[NAPI_CLIENT_FULL_COUNT]);
7889
++
7890
++	return len;
7891
++}
7892
++
7893
++static ssize_t pfe_set_hif_napi_stats(struct device *dev,
7894
++				      struct device_attribute *attr,
7895
++					const char *buf, size_t count)
7896
++{
7897
++	struct platform_device *pdev = to_platform_device(dev);
7898
++	struct pfe *pfe = platform_get_drvdata(pdev);
7899
++
7900
++	memset(pfe->hif.napi_counters, 0, sizeof(pfe->hif.napi_counters));
7901
++
7902
++	return count;
7903
++}
7904
++
7905
++static DEVICE_ATTR(hif_napi_stats, 0644, pfe_show_hif_napi_stats,
7906
++			pfe_set_hif_napi_stats);
7907
++#endif
7908
++
7909
++static DEVICE_ATTR(class, 0644, pfe_show_class, pfe_set_class);
7910
++static DEVICE_ATTR(tmu, 0644, pfe_show_tmu, pfe_set_tmu);
7911
++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
7912
++static DEVICE_ATTR(util, 0644, pfe_show_util, pfe_set_util);
7913
++#endif
7914
++static DEVICE_ATTR(bmu, 0444, pfe_show_bmu, NULL);
7915
++static DEVICE_ATTR(hif, 0444, pfe_show_hif, NULL);
7916
++static DEVICE_ATTR(gpi, 0444, pfe_show_gpi, NULL);
7917
++static DEVICE_ATTR(drops, 0644, pfe_show_drops, pfe_set_drops);
7918
++static DEVICE_ATTR(tmu0_queues, 0444, pfe_show_tmu0_queues, NULL);
7919
++static DEVICE_ATTR(tmu1_queues, 0444, pfe_show_tmu1_queues, NULL);
7920
++static DEVICE_ATTR(tmu2_queues, 0444, pfe_show_tmu2_queues, NULL);
7921
++static DEVICE_ATTR(tmu3_queues, 0444, pfe_show_tmu3_queues, NULL);
7922
++static DEVICE_ATTR(pfemem, 0444, pfe_show_pfemem, NULL);
7923
++
7924
++int pfe_sysfs_init(struct pfe *pfe)
7925
++{
7926
++	if (device_create_file(pfe->dev, &dev_attr_class))
7927
++		goto err_class;
7928
++
7929
++	if (device_create_file(pfe->dev, &dev_attr_tmu))
7930
++		goto err_tmu;
7931
++
7932
++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
7933
++	if (device_create_file(pfe->dev, &dev_attr_util))
7934
++		goto err_util;
7935
++#endif
7936
++
7937
++	if (device_create_file(pfe->dev, &dev_attr_bmu))
7938
++		goto err_bmu;
7939
++
7940
++	if (device_create_file(pfe->dev, &dev_attr_hif))
7941
++		goto err_hif;
7942
++
7943
++	if (device_create_file(pfe->dev, &dev_attr_gpi))
7944
++		goto err_gpi;
7945
++
7946
++	if (device_create_file(pfe->dev, &dev_attr_drops))
7947
++		goto err_drops;
7948
++
7949
++	if (device_create_file(pfe->dev, &dev_attr_tmu0_queues))
7950
++		goto err_tmu0_queues;
7951
++
7952
++	if (device_create_file(pfe->dev, &dev_attr_tmu1_queues))
7953
++		goto err_tmu1_queues;
7954
++
7955
++	if (device_create_file(pfe->dev, &dev_attr_tmu2_queues))
7956
++		goto err_tmu2_queues;
7957
++
7958
++	if (device_create_file(pfe->dev, &dev_attr_tmu3_queues))
7959
++		goto err_tmu3_queues;
7960
++
7961
++	if (device_create_file(pfe->dev, &dev_attr_pfemem))
7962
++		goto err_pfemem;
7963
++
7964
++#ifdef HIF_NAPI_STATS
7965
++	if (device_create_file(pfe->dev, &dev_attr_hif_napi_stats))
7966
++		goto err_hif_napi_stats;
7967
++#endif
7968
++
7969
++	return 0;
7970
++
7971
++#ifdef HIF_NAPI_STATS
7972
++err_hif_napi_stats:
7973
++	device_remove_file(pfe->dev, &dev_attr_pfemem);
7974
++#endif
7975
++
7976
++err_pfemem:
7977
++	device_remove_file(pfe->dev, &dev_attr_tmu3_queues);
7978
++
7979
++err_tmu3_queues:
7980
++	device_remove_file(pfe->dev, &dev_attr_tmu2_queues);
7981
++
7982
++err_tmu2_queues:
7983
++	device_remove_file(pfe->dev, &dev_attr_tmu1_queues);
7984
++
7985
++err_tmu1_queues:
7986
++	device_remove_file(pfe->dev, &dev_attr_tmu0_queues);
7987
++
7988
++err_tmu0_queues:
7989
++	device_remove_file(pfe->dev, &dev_attr_drops);
7990
++
7991
++err_drops:
7992
++	device_remove_file(pfe->dev, &dev_attr_gpi);
7993
++
7994
++err_gpi:
7995
++	device_remove_file(pfe->dev, &dev_attr_hif);
7996
++
7997
++err_hif:
7998
++	device_remove_file(pfe->dev, &dev_attr_bmu);
7999
++
8000
++err_bmu:
8001
++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
8002
++	device_remove_file(pfe->dev, &dev_attr_util);
8003
++
8004
++err_util:
8005
++#endif
8006
++	device_remove_file(pfe->dev, &dev_attr_tmu);
8007
++
8008
++err_tmu:
8009
++	device_remove_file(pfe->dev, &dev_attr_class);
8010
++
8011
++err_class:
8012
++	return -1;
8013
++}
8014
++
8015
++void pfe_sysfs_exit(struct pfe *pfe)
8016
++{
8017
++#ifdef HIF_NAPI_STATS
8018
++	device_remove_file(pfe->dev, &dev_attr_hif_napi_stats);
8019
++#endif
8020
++	device_remove_file(pfe->dev, &dev_attr_pfemem);
8021
++	device_remove_file(pfe->dev, &dev_attr_tmu3_queues);
8022
++	device_remove_file(pfe->dev, &dev_attr_tmu2_queues);
8023
++	device_remove_file(pfe->dev, &dev_attr_tmu1_queues);
8024
++	device_remove_file(pfe->dev, &dev_attr_tmu0_queues);
8025
++	device_remove_file(pfe->dev, &dev_attr_drops);
8026
++	device_remove_file(pfe->dev, &dev_attr_gpi);
8027
++	device_remove_file(pfe->dev, &dev_attr_hif);
8028
++	device_remove_file(pfe->dev, &dev_attr_bmu);
8029
++#if !defined(CONFIG_FSL_PPFE_UTIL_DISABLED)
8030
++	device_remove_file(pfe->dev, &dev_attr_util);
8031
++#endif
8032
++	device_remove_file(pfe->dev, &dev_attr_tmu);
8033
++	device_remove_file(pfe->dev, &dev_attr_class);
8034
++}
8035
+-- 
8036
+2.14.2
8037
+
0 8038
new file mode 100644
... ...
@@ -0,0 +1,42 @@
0
+From 76f019fd039a2329ce85ece89ef7e9fa6b0d0f11 Mon Sep 17 00:00:00 2001
1
+From: Calvin Johnson <calvin.johnson@nxp.com>
2
+Date: Wed, 11 Oct 2017 19:23:38 +0530
3
+Subject: [PATCH 03/22] staging: fsl_ppfe/eth: fix RGMII tx delay issue
4
+
5
+Recently logic to enable RGMII tx delay was changed by
6
+below patch.
7
+
8
+https://patchwork.kernel.org/patch/9447581/
9
+
10
+Based on the patch, appropriate change is made in PFE driver.
11
+
12
+Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
13
+Signed-off-by: Anjaneyulu Jagarlmudi <anji.jagarlmudi@nxp.com>
14
+
15
+[ Srinidhi Rao : Ported this patch to photon linux from
16
+  qoriq-components linux 'linux-4.14-nxp'
17
+  (https://source.codeaurora.org/external/qoriq/qoriq-components/linux)
18
+]
19
+
20
+Signed-off-by: srinidhira0 <srinidhir@vmware.com>
21
+---
22
+ drivers/staging/fsl_ppfe/pfe_eth.c | 3 ++-
23
+ 1 file changed, 2 insertions(+), 1 deletion(-)
24
+
25
+diff --git a/drivers/staging/fsl_ppfe/pfe_eth.c b/drivers/staging/fsl_ppfe/pfe_eth.c
26
+index 5aa718be42c2..a0171f3e7537 100644
27
+--- a/drivers/staging/fsl_ppfe/pfe_eth.c
28
+@@ -1068,7 +1068,8 @@ static void pfe_eth_adjust_link(struct net_device *ndev)
29
+ 			new_state = 1;
30
+ 			gemac_set_speed(priv->EMAC_baseaddr,
31
+ 					pfe_get_phydev_speed(phydev));
32
+-			if (priv->einfo->mii_config == PHY_INTERFACE_MODE_RGMII)
33
++			if (priv->einfo->mii_config ==
34
++					PHY_INTERFACE_MODE_RGMII_TXID)
35
+ 				pfe_set_rgmii_speed(phydev);
36
+ 			priv->oldspeed = phydev->speed;
37
+ 		}
38
+-- 
39
+2.14.2
40
+
0 41
new file mode 100644
... ...
@@ -0,0 +1,110 @@
0
+From 1ded4ecc39d6f6af69ff3724568c6564d20f17fb Mon Sep 17 00:00:00 2001
1
+From: Calvin Johnson <calvin.johnson@nxp.com>
2
+Date: Wed, 18 Oct 2017 14:29:30 +0530
3
+Subject: [PATCH 04/22] staging: fsl_ppfe/eth: remove unused functions
4
+
5
+Remove unused functions hif_xmit_pkt & hif_lib_xmit_pkt.
6
+
7
+Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
8
+
9
+[ Srinidhi Rao : Ported this patch to photon linux from
10
+  qoriq-components linux 'linux-4.14-nxp'
11
+  (https://source.codeaurora.org/external/qoriq/qoriq-components/linux)
12
+]
13
+
14
+Signed-off-by: srinidhira0 <srinidhir@vmware.com>
15
+---
16
+ drivers/staging/fsl_ppfe/pfe_hif.c     | 24 +-----------------------
17
+ drivers/staging/fsl_ppfe/pfe_hif_lib.c | 34 ----------------------------------
18
+ 2 files changed, 1 insertion(+), 57 deletions(-)
19
+
20
+diff --git a/drivers/staging/fsl_ppfe/pfe_hif.c b/drivers/staging/fsl_ppfe/pfe_hif.c
21
+index 6844595da9f1..61b4d57c8a34 100644
22
+--- a/drivers/staging/fsl_ppfe/pfe_hif.c
23
+@@ -844,29 +844,6 @@ void __hif_xmit_pkt(struct pfe_hif *hif, unsigned int client_id, unsigned int
24
+ 	return;
25
+ }
26
+ 
27
+-int hif_xmit_pkt(struct pfe_hif *hif, unsigned int client_id, unsigned int q_no,
28
+-		 void *data, unsigned int len)
29
+-{
30
+-	int rc = 0;
31
+-
32
+-	spin_lock_bh(&hif->tx_lock);
33
+-
34
+-	if (!hif->txavail) {
35
+-		rc = 1;
36
+-	} else {
37
+-		__hif_xmit_pkt(hif, client_id, q_no, data, len,
38
+-			       HIF_FIRST_BUFFER | HIF_LAST_BUFFER);
39
+-		hif_tx_dma_start();
40
+-	}
41
+-
42
+-	if (hif->txavail < (hif->tx_ring_size >> 1))
43
+-		__hif_tx_done_process(hif, TX_FREE_MAX_COUNT);
44
+-
45
+-	spin_unlock_bh(&hif->tx_lock);
46
+-
47
+-	return rc;
48
+-}
49
+-
50
+ static irqreturn_t wol_isr(int irq, void *dev_id)
51
+ {
52
+ 	pr_info("WoL\n");
53
+@@ -907,6 +884,7 @@ static irqreturn_t hif_isr(int irq, void *dev_id)
54
+ 			__napi_schedule(&hif->napi);
55
+ 		}
56
+ 	}
57
++
58
+ 	if (int_status & HIF_TXPKT_INT) {
59
+ 		int_status &= ~(HIF_TXPKT_INT);
60
+ 		int_enable_mask &= ~(HIF_TXPKT_INT);
61
+diff --git a/drivers/staging/fsl_ppfe/pfe_hif_lib.c b/drivers/staging/fsl_ppfe/pfe_hif_lib.c
62
+index 4274a59257fe..d5a5701bf987 100644
63
+--- a/drivers/staging/fsl_ppfe/pfe_hif_lib.c
64
+@@ -512,40 +512,6 @@ void __hif_lib_xmit_pkt(struct hif_client_s *client, unsigned int qno, void
65
+ 	queue->jiffies_last_packet = jiffies;
66
+ }
67
+ 
68
+-/*This function puts the given packet in the specific client queue */
69
+-int hif_lib_xmit_pkt(struct hif_client_s *client, unsigned int qno, void *data,
70
+-		     unsigned int len, u32 client_ctrl, void *client_data)
71
+-{
72
+-	struct hif_client_tx_queue *queue = &client->tx_q[qno];
73
+-	struct tx_queue_desc *desc = queue->base + queue->write_idx;
74
+-
75
+-	if (queue->tx_pending < queue->size) {
76
+-		/*Construct pkt header */
77
+-
78
+-		data -= sizeof(struct hif_hdr);
79
+-		len += sizeof(struct hif_hdr);
80
+-
81
+-		hif_hdr_write(data, client->id, qno, client_ctrl);
82
+-
83
+-		desc->data = client_data;
84
+-		desc->ctrl = CL_DESC_OWN | CL_DESC_FLAGS(HIF_FIRST_BUFFER |
85
+-				HIF_LAST_BUFFER | HIF_DATA_VALID);
86
+-
87
+-		if (hif_xmit_pkt(&pfe->hif, client->id, qno, data, len))
88
+-			return 1;
89
+-
90
+-		inc_cl_idx(queue->write_idx);
91
+-		queue->tx_pending++;
92
+-		queue->jiffies_last_packet = jiffies;
93
+-
94
+-		return 0;
95
+-	}
96
+-
97
+-	pr_debug("%s Tx client %d qno %d is full\n", __func__, client->id,
98
+-		 qno);
99
+-	return 1;
100
+-}
101
+-
102
+ void *hif_lib_tx_get_next_complete(struct hif_client_s *client, int qno,
103
+ 				   unsigned int *flags, int count)
104
+ {
105
+-- 
106
+2.14.2
107
+
0 108
new file mode 100644
... ...
@@ -0,0 +1,91 @@
0
+From 8ae5bb44b311a6fc1425382167e4666ff2a11f8d Mon Sep 17 00:00:00 2001
1
+From: Calvin Johnson <calvin.johnson@nxp.com>
2
+Date: Wed, 18 Oct 2017 18:34:41 +0530
3
+Subject: [PATCH 05/22] staging: fsl_ppfe/eth: fix read/write/ack idx issue
4
+
5
+While fixing checkpatch errors some of the index increments
6
+were commented out. They are enabled.
7
+
8
+Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
9
+
10
+[ Srinidhi Rao : Ported this patch to photon linux from
11
+  qoriq-components linux 'linux-4.14-nxp'
12
+  (https://source.codeaurora.org/external/qoriq/qoriq-components/linux)
13
+]
14
+
15
+Signed-off-by: srinidhira0 <srinidhir@vmware.com>
16
+---
17
+ drivers/staging/fsl_ppfe/pfe_hif.c     | 8 ++++----
18
+ drivers/staging/fsl_ppfe/pfe_hif_lib.c | 9 +++------
19
+ 2 files changed, 7 insertions(+), 10 deletions(-)
20
+
21
+diff --git a/drivers/staging/fsl_ppfe/pfe_hif.c b/drivers/staging/fsl_ppfe/pfe_hif.c
22
+index 61b4d57c8a34..6835e14021a2 100644
23
+--- a/drivers/staging/fsl_ppfe/pfe_hif.c
24
+@@ -511,9 +511,9 @@ static void *client_put_rxpacket(struct hif_rx_queue *queue, void *pkt, u32 len,
25
+ 			 */
26
+ 			smp_wmb();
27
+ 			writel(CL_DESC_BUF_LEN(len) | flags, &desc->ctrl);
28
+-			/* queue->write_idx = (queue->write_idx + 1)
29
+-			 *		       & (queue->size - 1);
30
+-			 */
31
++			queue->write_idx = (queue->write_idx + 1)
32
++					    & (queue->size - 1);
33
++
34
+ 			free_pkt += pfe_pkt_headroom;
35
+ 		}
36
+ 	}
37
+@@ -703,7 +703,7 @@ static int client_ack_txpacket(struct pfe_hif *hif, unsigned int client_id,
38
+ 
39
+ 	if (readl(&desc->ctrl) & CL_DESC_OWN) {
40
+ 		writel((readl(&desc->ctrl) & ~CL_DESC_OWN), &desc->ctrl);
41
+-		/* queue->ack_idx = (queue->ack_idx + 1) & (queue->size - 1); */
42
++		queue->ack_idx = (queue->ack_idx + 1) & (queue->size - 1);
43
+ 
44
+ 		return 0;
45
+ 
46
+diff --git a/drivers/staging/fsl_ppfe/pfe_hif_lib.c b/drivers/staging/fsl_ppfe/pfe_hif_lib.c
47
+index d5a5701bf987..837eaa244ff6 100644
48
+--- a/drivers/staging/fsl_ppfe/pfe_hif_lib.c
49
+@@ -211,9 +211,6 @@ static int hif_lib_client_init_rx_buffers(struct hif_client_s *client, int
50
+ 	return 1;
51
+ }
52
+ 
53
+-#define inc_cl_idx(idxname)					\
54
+-	({ typeof(idxname) idxname_ = (idxname);		\
55
+-	((idxname_) = (idxname_ + 1) & (queue->size - 1)); })
56
+ 
57
+ static void hif_lib_client_cleanup_tx_queue(struct hif_client_tx_queue *queue)
58
+ {
59
+@@ -465,7 +462,7 @@ void *hif_lib_receive_pkt(struct hif_client_s *client, int qno, int *len, int
60
+ 		smp_wmb();
61
+ 
62
+ 		desc->ctrl = CL_DESC_BUF_LEN(pfe_pkt_size) | CL_DESC_OWN;
63
+-		inc_cl_idx(queue->read_idx);
64
++		queue->read_idx = (queue->read_idx + 1) & (queue->size - 1);
65
+ 	}
66
+ 
67
+ 	/*spin_unlock_irqrestore(&client->rx_lock, flags); */
68
+@@ -507,7 +504,7 @@ void __hif_lib_xmit_pkt(struct hif_client_s *client, unsigned int qno, void
69
+ 
70
+ 	__hif_xmit_pkt(&pfe->hif, client->id, qno, data, len, flags);
71
+ 
72
+-	inc_cl_idx(queue->write_idx);
73
++	queue->write_idx = (queue->write_idx + 1) & (queue->size - 1);
74
+ 	queue->tx_pending++;
75
+ 	queue->jiffies_last_packet = jiffies;
76
+ }
77
+@@ -544,7 +541,7 @@ void *hif_lib_tx_get_next_complete(struct hif_client_s *client, int qno,
78
+ 	if (desc->ctrl & CL_DESC_OWN)
79
+ 		return NULL;
80
+ 
81
+-	inc_cl_idx(queue->read_idx);
82
++	queue->read_idx = (queue->read_idx + 1) & (queue->size - 1);
83
+ 	queue->tx_pending--;
84
+ 
85
+ 	*flags = CL_DESC_GET_FLAGS(desc->ctrl);
86
+-- 
87
+2.14.2
88
+
0 89
new file mode 100644
... ...
@@ -0,0 +1,38 @@
0
+From 6a0a4302336e653577ab6819c54e2bba9b2e1ef9 Mon Sep 17 00:00:00 2001
1
+From: Calvin Johnson <calvin.johnson@nxp.com>
2
+Date: Fri, 27 Oct 2017 11:20:47 +0530
3
+Subject: [PATCH 06/22] staging: fsl_ppfe/eth: Make phy_ethtool_ksettings_get
4
+ return void
5
+
6
+Make return value void since function never return meaningful value
7
+
8
+Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
9
+
10
+[ Srinidhi Rao : Ported this patch to photon linux from
11
+  qoriq-components linux 'linux-4.14-nxp'
12
+  (https://source.codeaurora.org/external/qoriq/qoriq-components/linux)
13
+]
14
+
15
+Signed-off-by: srinidhira0 <srinidhir@vmware.com>
16
+---
17
+ drivers/staging/fsl_ppfe/pfe_eth.c | 4 +++-
18
+ 1 file changed, 3 insertions(+), 1 deletion(-)
19
+
20
+diff --git a/drivers/staging/fsl_ppfe/pfe_eth.c b/drivers/staging/fsl_ppfe/pfe_eth.c
21
+index a0171f3e7537..89e60ce424f0 100644
22
+--- a/drivers/staging/fsl_ppfe/pfe_eth.c
23
+@@ -577,7 +577,9 @@ static int pfe_eth_get_settings(struct net_device *ndev,
24
+ 	if (!phydev)
25
+ 		return -ENODEV;
26
+ 
27
+-	return phy_ethtool_ksettings_get(phydev, cmd);
28
++	phy_ethtool_ksettings_get(phydev, cmd);
29
++
30
++	return 0;
31
+ }
32
+ 
33
+ /*
34
+-- 
35
+2.14.2
36
+
0 37
new file mode 100644
... ...
@@ -0,0 +1,83 @@
0
+From 3ad9c8e3f97138e34d03b88a63352d65deb1cef8 Mon Sep 17 00:00:00 2001
1
+From: Calvin Johnson <calvin.johnson@nxp.com>
2
+Date: Wed, 15 Nov 2017 13:45:27 +0530
3
+Subject: [PATCH 07/22] staging: fsl_ppfe/eth: add function to update tmu
4
+ credits
5
+
6
+__hif_lib_update_credit function is used to update the tmu credits.
7
+If tx_qos is set, tmu credit is updated based on the number of packets
8
+transmitted by tmu.
9
+
10
+Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
11
+Signed-off-by: Anjaneyulu Jagarlmudi <anji.jagarlmudi@nxp.com>
12
+
13
+[ Srinidhi Rao : Ported this patch to photon linux from
14
+  qoriq-components linux 'linux-4.14-nxp'
15
+  (https://source.codeaurora.org/external/qoriq/qoriq-components/linux)
16
+]
17
+
18
+Signed-off-by: srinidhira0 <srinidhir@vmware.com>
19
+---
20
+ drivers/staging/fsl_ppfe/pfe_hif_lib.c | 33 +++++++++++++++++++++++++++++++++
21
+ drivers/staging/fsl_ppfe/pfe_hif_lib.h |  1 +
22
+ 2 files changed, 34 insertions(+)
23
+
24
+diff --git a/drivers/staging/fsl_ppfe/pfe_hif_lib.c b/drivers/staging/fsl_ppfe/pfe_hif_lib.c
25
+index 837eaa244ff6..2ec47bf952e0 100644
26
+--- a/drivers/staging/fsl_ppfe/pfe_hif_lib.c
27
+@@ -565,6 +565,39 @@ static void hif_lib_tmu_credit_init(struct pfe *pfe)
28
+ 		}
29
+ }
30
+ 
31
++/* __hif_lib_update_credit
32
++ *
33
++ * @param[in] client	hif client context
34
++ * @param[in] queue	queue number in match with TMU
35
++ */
36
++void __hif_lib_update_credit(struct hif_client_s *client, unsigned int queue)
37
++{
38
++	unsigned int tmu_tx_packets, tmp;
39
++
40
++	if (tx_qos) {
41
++		tmu_tx_packets = be32_to_cpu(pe_dmem_read(TMU0_ID +
42
++			client->id, TMU_DM_TX_TRANS, 4));
43
++
44
++		/* tx_packets counter overflowed */
45
++		if (tmu_tx_packets >
46
++		    pfe->tmu_credit.tx_packets[client->id][queue]) {
47
++			tmp = UINT_MAX - tmu_tx_packets +
48
++			pfe->tmu_credit.tx_packets[client->id][queue];
49
++
50
++			pfe->tmu_credit.tx_credit[client->id][queue] =
51
++			pfe->tmu_credit.tx_credit_max[client->id][queue] - tmp;
52
++		} else {
53
++		/* TMU tx <= pfe_eth tx, normal case or both OF since
54
++		 * last time
55
++		 */
56
++			pfe->tmu_credit.tx_credit[client->id][queue] =
57
++			pfe->tmu_credit.tx_credit_max[client->id][queue] -
58
++			(pfe->tmu_credit.tx_packets[client->id][queue] -
59
++			tmu_tx_packets);
60
++		}
61
++	}
62
++}
63
++
64
+ int pfe_hif_lib_init(struct pfe *pfe)
65
+ {
66
+ 	int rc;
67
+diff --git a/drivers/staging/fsl_ppfe/pfe_hif_lib.h b/drivers/staging/fsl_ppfe/pfe_hif_lib.h
68
+index 49e7b5f1f9c3..d48eb14a29b8 100644
69
+--- a/drivers/staging/fsl_ppfe/pfe_hif_lib.h
70
+@@ -185,6 +185,7 @@ void *hif_lib_tx_get_next_complete(struct hif_client_s *client, int qno,
71
+ void *hif_lib_receive_pkt(struct hif_client_s *client, int qno, int *len, int
72
+ 				*ofst, unsigned int *rx_ctrl,
73
+ 				unsigned int *desc_ctrl, void **priv_data);
74
++void __hif_lib_update_credit(struct hif_client_s *client, unsigned int queue);
75
+ void hif_lib_set_rx_cpu_affinity(struct hif_client_s *client, int cpu_id);
76
+ void hif_lib_set_tx_queue_nocpy(struct hif_client_s *client, int qno, int
77
+ 					enable);
78
+-- 
79
+2.14.2
80
+
0 81
new file mode 100644
... ...
@@ -0,0 +1,101 @@
0
+From 3caccca49ab8a42589d6bffbeba0e4c083118f80 Mon Sep 17 00:00:00 2001
1
+From: Kavi Akhila-B46177 <akhila.kavi@nxp.com>
2
+Date: Thu, 2 Nov 2017 12:05:35 +0530
3
+Subject: [PATCH 08/22] staging: fsl_ppfe/eth: Avoid packet drop at TMU queues
4
+
5
+Added flow control between TMU queues and PFE Linux driver,
6
+based on TMU credits availability.
7
+Added tx_qos module parameter to control this behavior.
8
+Use queue-0 as default queue to transmit packets.
9
+
10
+Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
11
+Signed-off-by: Akhila Kavi <akhila.kavi@nxp.com>
12
+Signed-off-by: Anjaneyulu Jagarlmudi <anji.jagarlmudi@nxp.com>
13
+
14
+[ Srinidhi Rao : Ported this patch to photon linux from
15
+  qoriq-components linux 'linux-4.14-nxp'
16
+  (https://source.codeaurora.org/external/qoriq/qoriq-components/linux)
17
+]
18
+
19
+Signed-off-by: srinidhira0 <srinidhir@vmware.com>
20
+---
21
+ drivers/staging/fsl_ppfe/pfe_eth.c     | 17 +++++++++++++----
22
+ drivers/staging/fsl_ppfe/pfe_hif_lib.c |  7 +++++--
23
+ 2 files changed, 18 insertions(+), 6 deletions(-)
24
+
25
+diff --git a/drivers/staging/fsl_ppfe/pfe_eth.c b/drivers/staging/fsl_ppfe/pfe_eth.c
26
+index 89e60ce424f0..8771ad5c0634 100644
27
+--- a/drivers/staging/fsl_ppfe/pfe_eth.c
28
+@@ -293,10 +293,10 @@ static int pfe_eth_sysfs_init(struct net_device *ndev)
29
+ 	/* Initialize the default values */
30
+ 
31
+ 	/*
32
+-	 * By default, packets without conntrack will use this default high
33
++	 * By default, packets without conntrack will use this default low
34
+ 	 * priority queue
35
+ 	 */
36
+-	priv->default_priority = 15;
37
++	priv->default_priority = 0;
38
+ 
39
+ 	/* Create our sysfs files */
40
+ 	err = device_create_file(&ndev->dev, &dev_attr_default_priority);
41
+@@ -1566,10 +1566,17 @@ static int pfe_eth_might_stop_tx(struct pfe_eth_priv_s *priv, int queuenum,
42
+ 				 unsigned int n_segs)
43
+ {
44
+ 	ktime_t kt;
45
++	int tried = 0;
46
+ 
47
++try_again:
48
+ 	if (unlikely((__hif_tx_avail(&pfe->hif) < n_desc) ||
49
+-		     (hif_lib_tx_avail(&priv->client, queuenum) < n_desc) ||
50
++	(hif_lib_tx_avail(&priv->client, queuenum) < n_desc) ||
51
+ 	(hif_lib_tx_credit_avail(pfe, priv->id, queuenum) < n_segs))) {
52
++		if (!tried) {
53
++			__hif_lib_update_credit(&priv->client, queuenum);
54
++			tried = 1;
55
++			goto try_again;
56
++		}
57
+ #ifdef PFE_ETH_TX_STATS
58
+ 		if (__hif_tx_avail(&pfe->hif) < n_desc) {
59
+ 			priv->stop_queue_hif[queuenum]++;
60
+@@ -1692,8 +1699,10 @@ static void pfe_eth_flush_tx(struct pfe_eth_priv_s *priv)
61
+ 
62
+ 	netif_info(priv, tx_done, priv->ndev, "%s\n", __func__);
63
+ 
64
+-	for (ii = 0; ii < emac_txq_cnt; ii++)
65
++	for (ii = 0; ii < emac_txq_cnt; ii++) {
66
+ 		pfe_eth_flush_txQ(priv, ii, 0, 0);
67
++		__hif_lib_update_credit(&priv->client, ii);
68
++	}
69
+ }
70
+ 
71
+ void pfe_tx_get_req_desc(struct sk_buff *skb, unsigned int *n_desc, unsigned int
72
+diff --git a/drivers/staging/fsl_ppfe/pfe_hif_lib.c b/drivers/staging/fsl_ppfe/pfe_hif_lib.c
73
+index 2ec47bf952e0..eeab4ff3b6b8 100644
74
+--- a/drivers/staging/fsl_ppfe/pfe_hif_lib.c
75
+@@ -34,7 +34,10 @@
76
+ 
77
+ unsigned int lro_mode;
78
+ unsigned int page_mode;
79
+-unsigned int tx_qos;
80
++unsigned int tx_qos = 1;
81
++module_param(tx_qos, uint, 0444);
82
++MODULE_PARM_DESC(tx_qos, "0: disable ,\n"
83
++			 "1: enable (default), guarantee no packet drop at TMU level\n");
84
+ unsigned int pfe_pkt_size;
85
+ unsigned int pfe_pkt_headroom;
86
+ unsigned int emac_txq_cnt;
87
+@@ -576,7 +579,7 @@ void __hif_lib_update_credit(struct hif_client_s *client, unsigned int queue)
88
+ 
89
+ 	if (tx_qos) {
90
+ 		tmu_tx_packets = be32_to_cpu(pe_dmem_read(TMU0_ID +
91
+-			client->id, TMU_DM_TX_TRANS, 4));
92
++			client->id, (TMU_DM_TX_TRANS + (queue * 4)), 4));
93
+ 
94
+ 		/* tx_packets counter overflowed */
95
+ 		if (tmu_tx_packets >
96
+-- 
97
+2.14.2
98
+
0 99
new file mode 100644
... ...
@@ -0,0 +1,89 @@
0
+From a9327228db24a51da3e01cd770690b66fe475e47 Mon Sep 17 00:00:00 2001
1
+From: Bhaskar Upadhaya <Bhaskar.Upadhaya@nxp.com>
2
+Date: Wed, 29 Nov 2017 12:08:00 +0530
3
+Subject: [PATCH 09/22] staging: fsl_ppfe/eth: Enable PFE in clause 45 mode
4
+
5
+when we opearate in clause 45 mode, we need to call
6
+the function get_phy_device() with its 3rd argument as
7
+"true" and then the resultant phy device needs to be
8
+register with phy layer via phy_device_register()
9
+
10
+Signed-off-by: Bhaskar Upadhaya <Bhaskar.Upadhaya@nxp.com>
11
+
12
+[ Srinidhi Rao : Ported this patch to photon linux from
13
+  qoriq-components linux 'linux-4.14-nxp'
14
+  (https://source.codeaurora.org/external/qoriq/qoriq-components/linux)
15
+]
16
+
17
+Signed-off-by: srinidhira0 <srinidhir@vmware.com>
18
+---
19
+ drivers/staging/fsl_ppfe/pfe_eth.c | 32 +++++++++++++++++++++++++++++---
20
+ 1 file changed, 29 insertions(+), 3 deletions(-)
21
+
22
+diff --git a/drivers/staging/fsl_ppfe/pfe_eth.c b/drivers/staging/fsl_ppfe/pfe_eth.c
23
+index 8771ad5c0634..8d2b1da0cc20 100644
24
+--- a/drivers/staging/fsl_ppfe/pfe_eth.c
25
+@@ -923,7 +923,8 @@ static int pfe_eth_mdio_init(struct pfe_eth_priv_s *priv,
26
+ 			     struct ls1012a_mdio_platform_data *minfo)
27
+ {
28
+ 	struct mii_bus *bus;
29
+-	int rc;
30
++	int rc, ii;
31
++	struct phy_device *phydev;
32
+ 
33
+ 	netif_info(priv, drv, priv->ndev, "%s\n", __func__);
34
+ 	pr_info("%s\n", __func__);
35
+@@ -962,6 +963,31 @@ static int pfe_eth_mdio_init(struct pfe_eth_priv_s *priv,
36
+ 	}
37
+ 
38
+ 	priv->mii_bus = bus;
39
++
40
++	/* For clause 45 we need to call get_phy_device() with it's
41
++	 * 3rd argument as true and then register the phy device
42
++	 * via phy_device_register()
43
++	 */
44
++
45
++	if (priv->einfo->mii_config == PHY_INTERFACE_MODE_2500SGMII) {
46
++		for (ii = 0; ii < NUM_GEMAC_SUPPORT; ii++) {
47
++			phydev = get_phy_device(priv->mii_bus,
48
++					priv->einfo->phy_id + ii, true);
49
++			if (!phydev || IS_ERR(phydev)) {
50
++				rc = -EIO;
51
++				netdev_err(priv->ndev, "fail to get device\n");
52
++				goto err1;
53
++			}
54
++			rc = phy_device_register(phydev);
55
++			if (rc) {
56
++				phy_device_free(phydev);
57
++				netdev_err(priv->ndev,
58
++					"phy_device_register() failed\n");
59
++				goto err1;
60
++			}
61
++		}
62
++	}
63
++
64
+ 	pfe_eth_mdio_reset(bus);
65
+ 
66
+ 	return 0;
67
+@@ -1149,7 +1175,7 @@ static void ls1012a_configure_serdes(struct net_device *ndev)
68
+ 	int sgmii_2500 = 0;
69
+ 	struct mii_bus *bus = priv->mii_bus;
70
+ 
71
+-	if (priv->einfo->mii_config == PHY_INTERFACE_MODE_SGMII_2500)
72
++	if (priv->einfo->mii_config == PHY_INTERFACE_MODE_2500SGMII)
73
+ 		sgmii_2500 = 1;
74
+ 
75
+ 	netif_info(priv, drv, ndev, "%s\n", __func__);
76
+@@ -1198,7 +1224,7 @@ static int pfe_phy_init(struct net_device *ndev)
77
+ 	netif_info(priv, drv, ndev, "%s: %s\n", __func__, phy_id);
78
+ 	interface = priv->einfo->mii_config;
79
+ 	if ((interface == PHY_INTERFACE_MODE_SGMII) ||
80
+-	    (interface == PHY_INTERFACE_MODE_SGMII_2500)) {
81
++	    (interface == PHY_INTERFACE_MODE_2500SGMII)) {
82
+ 		/*Configure SGMII PCS */
83
+ 		if (pfe->scfg) {
84
+ 			/*Config MDIO from serdes */
85
+-- 
86
+2.14.2
87
+
0 88
new file mode 100644
... ...
@@ -0,0 +1,55 @@
0
+From 1ba5f5745e480b7d1a5627f396f343e546f6c395 Mon Sep 17 00:00:00 2001
1
+From: Bhaskar Upadhaya <Bhaskar.Upadhaya@nxp.com>
2
+Date: Wed, 29 Nov 2017 12:21:43 +0530
3
+Subject: [PATCH 10/22] staging: fsl_ppfe/eth: Disable autonegotiation for 2.5G
4
+ SGMII
5
+
6
+PCS initialization sequence for 2.5G SGMII interface governs
7
+auto negotiation to be in disabled mode
8
+
9
+Signed-off-by: Bhaskar Upadhaya <Bhaskar.Upadhaya@nxp.com>
10
+
11
+[ Srinidhi Rao : Ported this patch to photon linux from
12
+  qoriq-components linux 'linux-4.14-nxp'
13
+  (https://source.codeaurora.org/external/qoriq/qoriq-components/linux)
14
+]
15
+
16
+Signed-off-by: srinidhira0 <srinidhir@vmware.com>
17
+---
18
+ drivers/staging/fsl_ppfe/pfe_eth.c | 7 +++++--
19
+ 1 file changed, 5 insertions(+), 2 deletions(-)
20
+
21
+diff --git a/drivers/staging/fsl_ppfe/pfe_eth.c b/drivers/staging/fsl_ppfe/pfe_eth.c
22
+index 8d2b1da0cc20..9e8850b28990 100644
23
+--- a/drivers/staging/fsl_ppfe/pfe_eth.c
24
+@@ -1174,6 +1174,7 @@ static void ls1012a_configure_serdes(struct net_device *ndev)
25
+ 	struct pfe_eth_priv_s *priv = pfe->eth.eth_priv[0];
26
+ 	int sgmii_2500 = 0;
27
+ 	struct mii_bus *bus = priv->mii_bus;
28
++	u16 value = 0;
29
+ 
30
+ 	if (priv->einfo->mii_config == PHY_INTERFACE_MODE_2500SGMII)
31
+ 		sgmii_2500 = 1;
32
+@@ -1191,14 +1192,16 @@ static void ls1012a_configure_serdes(struct net_device *ndev)
33
+ 		pfe_eth_mdio_write(bus, 0, 0x4, 0x4001);
34
+ 		pfe_eth_mdio_write(bus, 0, 0x12, 0xa120);
35
+ 		pfe_eth_mdio_write(bus, 0, 0x13, 0x7);
36
++		/* Autonegotiation need to be disabled for 2.5G SGMII mode*/
37
++		value = 0x0140;
38
++		pfe_eth_mdio_write(bus, 0, 0x0, value);
39
+ 	} else {
40
+ 		pfe_eth_mdio_write(bus, 0, 0x14, 0xb);
41
+ 		pfe_eth_mdio_write(bus, 0, 0x4, 0x1a1);
42
+ 		pfe_eth_mdio_write(bus, 0, 0x12, 0x400);
43
+ 		pfe_eth_mdio_write(bus, 0, 0x13, 0x0);
44
++		pfe_eth_mdio_write(bus, 0, 0x0, 0x1140);
45
+ 	}
46
+-
47
+-	pfe_eth_mdio_write(bus, 0, 0x0, 0x1140);
48
+ }
49
+ 
50
+ /*
51
+-- 
52
+2.14.2
53
+
0 54
new file mode 100644
... ...
@@ -0,0 +1,43 @@
0
+From 389086e1ab9c389224f6c6c79b6ab3b764044973 Mon Sep 17 00:00:00 2001
1
+From: Guanhua Gao <guanhua.gao@nxp.com>
2
+Date: Fri, 12 Jan 2018 16:28:20 +0800
3
+Subject: [PATCH 11/22] staging: fsl_ppfe/eth: add missing included header file
4
+MIME-Version: 1.0
5
+Content-Type: text/plain; charset=UTF-8
6
+Content-Transfer-Encoding: 8bit
7
+
8
+ppfe compilation on dash-lts 4.14 reports error:
9
+In file included from drivers/staging/fsl_ppfe/pfe_mod.h:30:0,
10
+		from drivers/staging/fsl_ppfe/pfe_mod.c:20:
11
+drivers/staging/fsl_ppfe/pfe_hif.h:172:24: error: field â_cleanup_taskletâas incomplete type
12
+	struct tasklet_struct tx_cleanup_tasklet;
13
+
14
+The structure tasklet_struct is defined in interrupt.h, add it to fix the compilation error.
15
+
16
+Signed-off-by: Guanhua Gao <guanhua.gao@nxp.com>
17
+
18
+[ Srinidhi Rao : Ported this patch to photon linux from
19
+  qoriq-components linux 'linux-4.14-nxp'
20
+  (https://source.codeaurora.org/external/qoriq/qoriq-components/linux)
21
+]
22
+
23
+Signed-off-by: srinidhira0 <srinidhir@vmware.com>
24
+---
25
+ drivers/staging/fsl_ppfe/pfe_hif.h | 1 +
26
+ 1 file changed, 1 insertion(+)
27
+
28
+diff --git a/drivers/staging/fsl_ppfe/pfe_hif.h b/drivers/staging/fsl_ppfe/pfe_hif.h
29
+index 6e36f0c1f4ff..8281adb12cd7 100644
30
+--- a/drivers/staging/fsl_ppfe/pfe_hif.h
31
+@@ -20,6 +20,7 @@
32
+ #define _PFE_HIF_H_
33
+ 
34
+ #include <linux/netdevice.h>
35
++#include <linux/interrupt.h>
36
+ 
37
+ #define HIF_NAPI_STATS
38
+ 
39
+-- 
40
+2.14.2
41
+
0 42
new file mode 100644
... ...
@@ -0,0 +1,59 @@
0
+From 429966138df2fbc6a81203d587f87d12bb071b05 Mon Sep 17 00:00:00 2001
1
+From: Yangbo Lu <yangbo.lu@nxp.com>
2
+Date: Tue, 30 Jan 2018 20:22:24 +0800
3
+Subject: [PATCH 12/22] staging: fsl_ppfe/eth: clean up
4
+ iounmap(pfe->ddr_baseaddr)
5
+
6
+pfe->ddr_baseaddr was got through phys_to_virt() not ioremap(),
7
+so iounmap() for pfe->ddr_baseaddr should be removed.
8
+
9
+Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
10
+
11
+[ Srinidhi Rao : Ported this patch to photon linux from
12
+  qoriq-components linux 'linux-4.14-nxp'
13
+  (https://source.codeaurora.org/external/qoriq/qoriq-components/linux)
14
+]
15
+
16
+Signed-off-by: srinidhira0 <srinidhir@vmware.com>
17
+---
18
+ drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c | 9 ---------
19
+ 1 file changed, 9 deletions(-)
20
+
21
+diff --git a/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c b/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c
22
+index c579eb58f277..f3eb88de66a4 100644
23
+--- a/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c
24
+@@ -169,13 +169,7 @@ static int pfe_platform_probe(struct platform_device *pdev)
25
+ 
26
+ 	pfe->ddr_phys_baseaddr = res.start;
27
+ 	pfe->ddr_size = resource_size(&res);
28
+-
29
+ 	pfe->ddr_baseaddr = phys_to_virt(res.start);
30
+-	if (!pfe->ddr_baseaddr) {
31
+-		pr_err("ioremap() ddr failed\n");
32
+-		rc = -ENOMEM;
33
+-		goto err_ddr;
34
+-	}
35
+ 
36
+ 	pfe->scfg =
37
+ 		syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
38
+@@ -257,8 +251,6 @@ static int pfe_platform_probe(struct platform_device *pdev)
39
+ 	iounmap(pfe->cbus_baseaddr);
40
+ 
41
+ err_axi:
42
+-	iounmap(pfe->ddr_baseaddr);
43
+-
44
+ err_ddr:
45
+ 	platform_set_drvdata(pdev, NULL);
46
+ 
47
+@@ -281,7 +273,6 @@ static int pfe_platform_remove(struct platform_device *pdev)
48
+ 	rc = pfe_remove(pfe);
49
+ 
50
+ 	iounmap(pfe->cbus_baseaddr);
51
+-	iounmap(pfe->ddr_baseaddr);
52
+ 
53
+ 	platform_set_drvdata(pdev, NULL);
54
+ 
55
+-- 
56
+2.14.2
57
+
0 58
new file mode 100644
... ...
@@ -0,0 +1,42 @@
0
+From 105bded455f8893a6cb7c28b061609d59d5734a7 Mon Sep 17 00:00:00 2001
1
+From: Calvin Johnson <calvin.johnson@nxp.com>
2
+Date: Thu, 8 Mar 2018 13:58:38 +0530
3
+Subject: [PATCH 13/22] staging: fsl_ppfe/eth: calculate PFE_PKT_SIZE with
4
+ SKB_DATA_ALIGN
5
+
6
+pfe packet size was calculated without considering skb data alignment
7
+and this resulted in jumbo frames crashing kernel when the
8
+cacheline size increased from 64 to 128 bytes with
9
+commit 97303480753e ("arm64: Increase the max granular size").
10
+
11
+Modify pfe packet size caclulation to include skb data alignment of
12
+sizeof(struct skb_shared_info).
13
+
14
+Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
15
+
16
+[ Srinidhi Rao : Ported this patch to photon linux from
17
+  qoriq-components linux 'linux-4.14-nxp'
18
+  (https://source.codeaurora.org/external/qoriq/qoriq-components/linux)
19
+]
20
+
21
+Signed-off-by: srinidhira0 <srinidhir@vmware.com>
22
+---
23
+ drivers/staging/fsl_ppfe/pfe_hif_lib.h | 2 +-
24
+ 1 file changed, 1 insertion(+), 1 deletion(-)
25
+
26
+diff --git a/drivers/staging/fsl_ppfe/pfe_hif_lib.h b/drivers/staging/fsl_ppfe/pfe_hif_lib.h
27
+index d48eb14a29b8..08031f1f3117 100644
28
+--- a/drivers/staging/fsl_ppfe/pfe_hif_lib.h
29
+@@ -146,7 +146,7 @@ struct tx_queue_desc {
30
+ #define PFE_BUF_SIZE		2048
31
+ #define PFE_PKT_HEADROOM	128
32
+ 
33
+-#define SKB_SHARED_INFO_SIZE   (sizeof(struct skb_shared_info))
34
++#define SKB_SHARED_INFO_SIZE   SKB_DATA_ALIGN(sizeof(struct skb_shared_info))
35
+ #define PFE_PKT_SIZE		(PFE_BUF_SIZE - PFE_PKT_HEADROOM \
36
+ 				 - SKB_SHARED_INFO_SIZE)
37
+ #define MAX_L2_HDR_SIZE		14	/* Not correct for VLAN/PPPoE */
38
+-- 
39
+2.14.2
40
+
0 41
new file mode 100644
... ...
@@ -0,0 +1,171 @@
0
+From 6425d31ff45a3fd0984ada7fb9440618d785b31b Mon Sep 17 00:00:00 2001
1
+From: Akhil Goyal <akhil.goyal@nxp.com>
2
+Date: Fri, 13 Apr 2018 15:41:28 +0530
3
+Subject: [PATCH 14/22] staging: fsl_ppfe/eth: support for userspace networking
4
+
5
+This patch adds the userspace mode support to fsl_ppfe network driver.
6
+In the new mode, basic hardware initialization is performed in kernel, while
7
+the datapath and HIF handling is the responsibility of the userspace.
8
+
9
+The new command line parameter is added to initialize the ppfe module
10
+in userspace mode. By default the module remains in kernelspace networking
11
+mode.
12
+To enable userspace mode, use "insmod pfe.ko us=1"
13
+
14
+Signed-off-by: Akhil Goyal <akhil.goyal@nxp.com>
15
+Signed-off-by: Gagandeep Singh <g.singh@nxp.com>
16
+
17
+[ Srinidhi Rao : Ported this patch to photon linux from
18
+  qoriq-components linux 'linux-4.14-nxp'
19
+  (https://source.codeaurora.org/external/qoriq/qoriq-components/linux)
20
+]
21
+
22
+Signed-off-by: srinidhira0 <srinidhir@vmware.com>
23
+---
24
+ drivers/staging/fsl_ppfe/pfe_eth.c | 21 +++++++++++++++++++--
25
+ drivers/staging/fsl_ppfe/pfe_mod.c | 15 +++++++++++++++
26
+ drivers/staging/fsl_ppfe/pfe_mod.h |  2 ++
27
+ 3 files changed, 36 insertions(+), 2 deletions(-)
28
+
29
+diff --git a/drivers/staging/fsl_ppfe/pfe_eth.c b/drivers/staging/fsl_ppfe/pfe_eth.c
30
+index 9e8850b28990..297aa01b695a 100644
31
+--- a/drivers/staging/fsl_ppfe/pfe_eth.c
32
+@@ -2296,6 +2296,8 @@ static int pfe_eth_init_one(struct pfe *pfe, int id)
33
+ 		goto err0;
34
+ 	}
35
+ 
36
++	if (us)
37
++		emac_txq_cnt = EMAC_TXQ_CNT;
38
+ 	/* Create an ethernet device instance */
39
+ 	ndev = alloc_etherdev_mq(sizeof(*priv), emac_txq_cnt);
40
+ 
41
+@@ -2342,6 +2344,9 @@ static int pfe_eth_init_one(struct pfe *pfe, int id)
42
+ 		}
43
+ 	}
44
+ 
45
++	if (us)
46
++		goto phy_init;
47
++
48
+ 	ndev->mtu = 1500;
49
+ 
50
+ 	/* Set MTU limits */
51
+@@ -2381,6 +2386,8 @@ static int pfe_eth_init_one(struct pfe *pfe, int id)
52
+ 		netdev_err(ndev, "register_netdev() failed\n");
53
+ 		goto err3;
54
+ 	}
55
++
56
++phy_init:
57
+ 	device_init_wakeup(&ndev->dev, WAKE_MAGIC);
58
+ 
59
+ 	if (!(priv->einfo->phy_flags & GEMAC_NO_PHY)) {
60
+@@ -2392,6 +2399,12 @@ static int pfe_eth_init_one(struct pfe *pfe, int id)
61
+ 		}
62
+ 	}
63
+ 
64
++	if (us) {
65
++		if (priv->phydev)
66
++			phy_start(priv->phydev);
67
++		return 0;
68
++	}
69
++
70
+ 	netif_carrier_on(ndev);
71
+ 
72
+ 	/* Create all the sysfs files */
73
+@@ -2403,6 +2416,8 @@ static int pfe_eth_init_one(struct pfe *pfe, int id)
74
+ 
75
+ 	return 0;
76
+ err4:
77
++	if (us)
78
++		goto err3;
79
+ 	unregister_netdev(ndev);
80
+ err3:
81
+ 	pfe_eth_mdio_exit(priv->mii_bus);
82
+@@ -2449,9 +2464,11 @@ static void pfe_eth_exit_one(struct pfe_eth_priv_s *priv)
83
+ {
84
+ 	netif_info(priv, probe, priv->ndev, "%s\n", __func__);
85
+ 
86
+-	pfe_eth_sysfs_exit(priv->ndev);
87
++	if (!us) {
88
++		pfe_eth_sysfs_exit(priv->ndev);
89
+ 
90
+-	unregister_netdev(priv->ndev);
91
++		unregister_netdev(priv->ndev);
92
++	}
93
+ 
94
+ 	if (!(priv->einfo->phy_flags & GEMAC_NO_PHY))
95
+ 		pfe_phy_exit(priv->ndev);
96
+diff --git a/drivers/staging/fsl_ppfe/pfe_mod.c b/drivers/staging/fsl_ppfe/pfe_mod.c
97
+index d5ba56a3c73f..ca418456c26f 100644
98
+--- a/drivers/staging/fsl_ppfe/pfe_mod.c
99
+@@ -19,6 +19,10 @@
100
+ #include <linux/dma-mapping.h>
101
+ #include "pfe_mod.h"
102
+ 
103
++unsigned int us;
104
++module_param(us, uint, 0444);
105
++MODULE_PARM_DESC(us, "0: module enabled for kernel networking (DEFAULT)\n"
106
++			"1: module enabled for userspace networking\n");
107
+ struct pfe *pfe;
108
+ 
109
+ /*
110
+@@ -56,6 +60,9 @@ int pfe_probe(struct pfe *pfe)
111
+ 	if (rc < 0)
112
+ 		goto err_hw;
113
+ 
114
++	if (us)
115
++		goto firmware_init;
116
++
117
+ 	rc = pfe_hif_lib_init(pfe);
118
+ 	if (rc < 0)
119
+ 		goto err_hif_lib;
120
+@@ -64,6 +71,7 @@ int pfe_probe(struct pfe *pfe)
121
+ 	if (rc < 0)
122
+ 		goto err_hif;
123
+ 
124
++firmware_init:
125
+ 	rc = pfe_firmware_init(pfe);
126
+ 	if (rc < 0)
127
+ 		goto err_firmware;
128
+@@ -99,6 +107,9 @@ int pfe_probe(struct pfe *pfe)
129
+ 	pfe_firmware_exit(pfe);
130
+ 
131
+ err_firmware:
132
++	if (us)
133
++		goto err_hif_lib;
134
++
135
+ 	pfe_hif_exit(pfe);
136
+ 
137
+ err_hif:
138
+@@ -131,10 +142,14 @@ int pfe_remove(struct pfe *pfe)
139
+ #endif
140
+ 	pfe_firmware_exit(pfe);
141
+ 
142
++	if (us)
143
++		goto hw_exit;
144
++
145
+ 	pfe_hif_exit(pfe);
146
+ 
147
+ 	pfe_hif_lib_exit(pfe);
148
+ 
149
++hw_exit:
150
+ 	pfe_hw_exit(pfe);
151
+ 
152
+ 	return 0;
153
+diff --git a/drivers/staging/fsl_ppfe/pfe_mod.h b/drivers/staging/fsl_ppfe/pfe_mod.h
154
+index 3012f17fef31..014ae65ca34a 100644
155
+--- a/drivers/staging/fsl_ppfe/pfe_mod.h
156
+@@ -22,6 +22,8 @@
157
+ #include <linux/device.h>
158
+ #include <linux/elf.h>
159
+ 
160
++extern unsigned int us;
161
++
162
+ struct pfe;
163
+ 
164
+ #include "pfe_hw.h"
165
+-- 
166
+2.14.2
167
+
0 168
new file mode 100644
... ...
@@ -0,0 +1,57 @@
0
+From 09626eade30d9c41ce18fdcc9f566c3aba9ee716 Mon Sep 17 00:00:00 2001
1
+From: Calvin Johnson <calvin.johnson@nxp.com>
2
+Date: Mon, 30 Apr 2018 11:40:01 +0530
3
+Subject: [PATCH 15/22] staging: fsl_ppfe/eth: unregister netdev after
4
+ pfe_phy_exit
5
+
6
+rmmod pfe.ko throws below warning:
7
+
8
+kernfs: can not remove 'phydev', no directory
9
+------------[ cut here ]------------
10
+WARNING: CPU: 0 PID: 2230 at fs/kernfs/dir.c:1481
11
+kernfs_remove_by_name_ns+0x90/0xa0
12
+
13
+This is caused when the unregistered netdev structure is accessed to
14
+disconnect phy.
15
+
16
+Resolve the issue by unregistering netdev after disconnecting phy.
17
+
18
+Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
19
+
20
+[ Srinidhi Rao : Ported this patch to photon linux from
21
+  qoriq-components linux 'linux-4.14-nxp'
22
+  (https://source.codeaurora.org/external/qoriq/qoriq-components/linux)
23
+]
24
+
25
+Signed-off-by: srinidhira0 <srinidhir@vmware.com>
26
+---
27
+ drivers/staging/fsl_ppfe/pfe_eth.c | 8 ++++----
28
+ 1 file changed, 4 insertions(+), 4 deletions(-)
29
+
30
+diff --git a/drivers/staging/fsl_ppfe/pfe_eth.c b/drivers/staging/fsl_ppfe/pfe_eth.c
31
+index 297aa01b695a..265045fcb008 100644
32
+--- a/drivers/staging/fsl_ppfe/pfe_eth.c
33
+@@ -2464,15 +2464,15 @@ static void pfe_eth_exit_one(struct pfe_eth_priv_s *priv)
34
+ {
35
+ 	netif_info(priv, probe, priv->ndev, "%s\n", __func__);
36
+ 
37
+-	if (!us) {
38
++	if (!us)
39
+ 		pfe_eth_sysfs_exit(priv->ndev);
40
+ 
41
+-		unregister_netdev(priv->ndev);
42
+-	}
43
+-
44
+ 	if (!(priv->einfo->phy_flags & GEMAC_NO_PHY))
45
+ 		pfe_phy_exit(priv->ndev);
46
+ 
47
++	if (!us)
48
++		unregister_netdev(priv->ndev);
49
++
50
+ 	if (priv->mii_bus)
51
+ 		pfe_eth_mdio_exit(priv->mii_bus);
52
+ 
53
+-- 
54
+2.14.2
55
+
0 56
new file mode 100644
... ...
@@ -0,0 +1,61 @@
0
+From d799c0372e6bde0f6b8786bb1705de46115b05b6 Mon Sep 17 00:00:00 2001
1
+From: anuj batham <anuj.batham@nxp.com>
2
+Date: Fri, 27 Apr 2018 14:38:09 +0530
3
+Subject: [PATCH 16/22] staging: fsl_ppfe/eth: HW parse results for DPDK
4
+
5
+HW Parse results are included in the packet headroom.
6
+Length and Offset calculation now accommodates parse info size.
7
+
8
+Signed-off-by: Archana Madhavan <archana.madhavan@nxp.com>
9
+
10
+[ Srinidhi Rao : Ported this patch to photon linux from
11
+  qoriq-components linux 'linux-4.14-nxp'
12
+  (https://source.codeaurora.org/external/qoriq/qoriq-components/linux)
13
+]
14
+
15
+Signed-off-by: srinidhira0 <srinidhir@vmware.com>
16
+---
17
+ drivers/staging/fsl_ppfe/pfe_hif_lib.c | 7 +++++--
18
+ drivers/staging/fsl_ppfe/pfe_hif_lib.h | 1 +
19
+ 2 files changed, 6 insertions(+), 2 deletions(-)
20
+
21
+diff --git a/drivers/staging/fsl_ppfe/pfe_hif_lib.c b/drivers/staging/fsl_ppfe/pfe_hif_lib.c
22
+index eeab4ff3b6b8..16fcf2daeef8 100644
23
+--- a/drivers/staging/fsl_ppfe/pfe_hif_lib.c
24
+@@ -435,6 +435,7 @@ void *hif_lib_receive_pkt(struct hif_client_s *client, int qno, int *len, int
25
+ 			u16 size = *rx_ctrl >> HIF_CTRL_RX_OFFSET_OFST;
26
+ 
27
+ 			if (size) {
28
++				size += PFE_PARSE_INFO_SIZE;
29
+ 				*len = CL_DESC_BUF_LEN(desc->ctrl) -
30
+ 						PFE_PKT_HEADER_SZ - size;
31
+ 				*ofst = pfe_pkt_headroom + PFE_PKT_HEADER_SZ
32
+@@ -442,8 +443,10 @@ void *hif_lib_receive_pkt(struct hif_client_s *client, int qno, int *len, int
33
+ 				*priv_data = desc->data + PFE_PKT_HEADER_SZ;
34
+ 			} else {
35
+ 				*len = CL_DESC_BUF_LEN(desc->ctrl) -
36
+-						PFE_PKT_HEADER_SZ;
37
+-				*ofst = pfe_pkt_headroom + PFE_PKT_HEADER_SZ;
38
++				       PFE_PKT_HEADER_SZ - PFE_PARSE_INFO_SIZE;
39
++				*ofst = pfe_pkt_headroom
40
++					+ PFE_PKT_HEADER_SZ
41
++					+ PFE_PARSE_INFO_SIZE;
42
+ 				*priv_data = NULL;
43
+ 			}
44
+ 
45
+diff --git a/drivers/staging/fsl_ppfe/pfe_hif_lib.h b/drivers/staging/fsl_ppfe/pfe_hif_lib.h
46
+index 08031f1f3117..c8334a6b6a13 100644
47
+--- a/drivers/staging/fsl_ppfe/pfe_hif_lib.h
48
+@@ -23,6 +23,7 @@
49
+ 
50
+ #define HIF_CL_REQ_TIMEOUT	10
51
+ #define GFP_DMA_PFE 0
52
++#define PFE_PARSE_INFO_SIZE	16
53
+ 
54
+ enum {
55
+ 	REQUEST_CL_REGISTER = 0,
56
+-- 
57
+2.14.2
58
+
0 59
new file mode 100644
... ...
@@ -0,0 +1,42 @@
0
+From ab625957c7d169031b91bc7dba0d72bbee063fff Mon Sep 17 00:00:00 2001
1
+From: Calvin Johnson <calvin.johnson@nxp.com>
2
+Date: Wed, 20 Jun 2018 10:22:32 +0530
3
+Subject: [PATCH 17/22] staging: fsl_ppfe/eth: reorganize pfe_netdev_ops
4
+
5
+Reorganize members of struct pfe_netdev_ops to match with the order
6
+of members in struct net_device_ops defined in include/linux/netdevice.h
7
+
8
+Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
9
+
10
+[ Srinidhi Rao : Ported this patch to photon linux from
11
+  qoriq-components linux 'linux-4.14-nxp'
12
+  (https://source.codeaurora.org/external/qoriq/qoriq-components/linux)
13
+]
14
+
15
+Signed-off-by: srinidhira0 <srinidhir@vmware.com>
16
+---
17
+ drivers/staging/fsl_ppfe/pfe_eth.c | 6 +++---
18
+ 1 file changed, 3 insertions(+), 3 deletions(-)
19
+
20
+diff --git a/drivers/staging/fsl_ppfe/pfe_eth.c b/drivers/staging/fsl_ppfe/pfe_eth.c
21
+index 265045fcb008..0aa08d251b7c 100644
22
+--- a/drivers/staging/fsl_ppfe/pfe_eth.c
23
+@@ -2243,11 +2243,11 @@ static const struct net_device_ops pfe_netdev_ops = {
24
+ 	.ndo_stop = pfe_eth_close,
25
+ 	.ndo_start_xmit = pfe_eth_send_packet,
26
+ 	.ndo_select_queue = pfe_eth_select_queue,
27
+-	.ndo_get_stats = pfe_eth_get_stats,
28
+-	.ndo_set_mac_address = pfe_eth_set_mac_address,
29
+ 	.ndo_set_rx_mode = pfe_eth_set_multi,
30
+-	.ndo_set_features = pfe_eth_set_features,
31
++	.ndo_set_mac_address = pfe_eth_set_mac_address,
32
+ 	.ndo_validate_addr = eth_validate_addr,
33
++	.ndo_get_stats = pfe_eth_get_stats,
34
++	.ndo_set_features = pfe_eth_set_features,
35
+ };
36
+ 
37
+ /* pfe_eth_init_one
38
+-- 
39
+2.14.2
40
+
0 41
new file mode 100644
... ...
@@ -0,0 +1,58 @@
0
+From 1f2258f3645c6ed5eebda50b4b575b67330ec04e Mon Sep 17 00:00:00 2001
1
+From: Calvin Johnson <calvin.johnson@nxp.com>
2
+Date: Wed, 20 Jun 2018 10:22:50 +0530
3
+Subject: [PATCH 18/22] staging: fsl_ppfe/eth: use mask for rx max frame len
4
+
5
+Define and use PFE_RCR_MAX_FL_MASK to properly set Rx max frame
6
+length of MAC Receive Control Register.
7
+
8
+Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
9
+
10
+[ Srinidhi Rao : Ported this patch to photon linux from
11
+  qoriq-components linux 'linux-4.14-nxp'
12
+  (https://source.codeaurora.org/external/qoriq/qoriq-components/linux)
13
+]
14
+
15
+Signed-off-by: srinidhira0 <srinidhir@vmware.com>
16
+---
17
+ drivers/staging/fsl_ppfe/pfe_hal.c | 10 ++++++----
18
+ 1 file changed, 6 insertions(+), 4 deletions(-)
19
+
20
+diff --git a/drivers/staging/fsl_ppfe/pfe_hal.c b/drivers/staging/fsl_ppfe/pfe_hal.c
21
+index 0915034b281b..7e89606bb40c 100644
22
+--- a/drivers/staging/fsl_ppfe/pfe_hal.c
23
+@@ -19,6 +19,8 @@
24
+ #include "pfe_mod.h"
25
+ #include "pfe/pfe.h"
26
+ 
27
++#define PFE_RCR_MAX_FL_MASK	0xC000FFFF
28
++
29
+ void *cbus_base_addr;
30
+ void *ddr_base_addr;
31
+ unsigned long ddr_phys_base_addr;
32
+@@ -1011,8 +1013,8 @@ void gemac_no_broadcast(void *base)
33
+ void gemac_enable_1536_rx(void *base)
34
+ {
35
+ 	/* Set 1536 as Maximum frame length */
36
+-	writel(readl(base + EMAC_RCNTRL_REG) | (1536 << 16), base +
37
+-		EMAC_RCNTRL_REG);
38
++	writel((readl(base + EMAC_RCNTRL_REG) & PFE_RCR_MAX_FL_MASK)
39
++		| (1536 << 16), base +	EMAC_RCNTRL_REG);
40
+ }
41
+ 
42
+ /* GEMAC enable jumbo function.
43
+@@ -1020,8 +1022,8 @@ void gemac_enable_1536_rx(void *base)
44
+  */
45
+ void gemac_enable_rx_jmb(void *base)
46
+ {
47
+-	writel(readl(base + EMAC_RCNTRL_REG) | (JUMBO_FRAME_SIZE << 16), base
48
+-		+ EMAC_RCNTRL_REG);
49
++	writel((readl(base + EMAC_RCNTRL_REG) & PFE_RCR_MAX_FL_MASK)
50
++		| (JUMBO_FRAME_SIZE << 16), base + EMAC_RCNTRL_REG);
51
+ }
52
+ 
53
+ /* GEMAC enable stacked vlan function.
54
+-- 
55
+2.14.2
56
+
0 57
new file mode 100644
... ...
@@ -0,0 +1,90 @@
0
+From bfd03698e85a6bff663280e538dab2eea4fb90ff Mon Sep 17 00:00:00 2001
1
+From: Calvin Johnson <calvin.johnson@nxp.com>
2
+Date: Wed, 20 Jun 2018 10:23:01 +0530
3
+Subject: [PATCH 19/22] staging: fsl_ppfe/eth: define pfe ndo_change_mtu
4
+ function
5
+
6
+Define ndo_change_mtu function for pfe. This sets the max Rx frame
7
+length to the new mtu.
8
+
9
+Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
10
+
11
+[ Srinidhi Rao : Ported this patch to photon linux from
12
+  qoriq-components linux 'linux-4.14-nxp'
13
+  (https://source.codeaurora.org/external/qoriq/qoriq-components/linux)
14
+]
15
+
16
+Signed-off-by: srinidhira0 <srinidhir@vmware.com>
17
+---
18
+ drivers/staging/fsl_ppfe/include/pfe/pfe.h |  1 +
19
+ drivers/staging/fsl_ppfe/pfe_eth.c         | 12 ++++++++++++
20
+ drivers/staging/fsl_ppfe/pfe_hal.c         | 11 +++++++++++
21
+ 3 files changed, 24 insertions(+)
22
+
23
+diff --git a/drivers/staging/fsl_ppfe/include/pfe/pfe.h b/drivers/staging/fsl_ppfe/include/pfe/pfe.h
24
+index d93ae4c60251..79eeafa60eb6 100644
25
+--- a/drivers/staging/fsl_ppfe/include/pfe/pfe.h
26
+@@ -303,6 +303,7 @@ void gemac_allow_broadcast(void *base);
27
+ void gemac_no_broadcast(void *base);
28
+ void gemac_enable_1536_rx(void *base);
29
+ void gemac_disable_1536_rx(void *base);
30
++void gemac_set_rx_max_fl(void *base, int mtu);
31
+ void gemac_enable_rx_jmb(void *base);
32
+ void gemac_disable_rx_jmb(void *base);
33
+ void gemac_enable_stacked_vlan(void *base);
34
+diff --git a/drivers/staging/fsl_ppfe/pfe_eth.c b/drivers/staging/fsl_ppfe/pfe_eth.c
35
+index 0aa08d251b7c..77d7a7b682c6 100644
36
+--- a/drivers/staging/fsl_ppfe/pfe_eth.c
37
+@@ -1345,6 +1345,17 @@ static int pfe_eth_event_handler(void *data, int event, int qno)
38
+ 	return 0;
39
+ }
40
+ 
41
++static int pfe_eth_change_mtu(struct net_device *ndev, int new_mtu)
42
++{
43
++	struct pfe_eth_priv_s *priv = netdev_priv(ndev);
44
++
45
++	ndev->mtu = new_mtu;
46
++	new_mtu += ETH_HLEN + ETH_FCS_LEN;
47
++	gemac_set_rx_max_fl(priv->EMAC_baseaddr, new_mtu);
48
++
49
++	return 0;
50
++}
51
++
52
+ /* pfe_eth_open
53
+  */
54
+ static int pfe_eth_open(struct net_device *ndev)
55
+@@ -2246,6 +2257,7 @@ static const struct net_device_ops pfe_netdev_ops = {
56
+ 	.ndo_set_rx_mode = pfe_eth_set_multi,
57
+ 	.ndo_set_mac_address = pfe_eth_set_mac_address,
58
+ 	.ndo_validate_addr = eth_validate_addr,
59
++	.ndo_change_mtu = pfe_eth_change_mtu,
60
+ 	.ndo_get_stats = pfe_eth_get_stats,
61
+ 	.ndo_set_features = pfe_eth_set_features,
62
+ };
63
+diff --git a/drivers/staging/fsl_ppfe/pfe_hal.c b/drivers/staging/fsl_ppfe/pfe_hal.c
64
+index 7e89606bb40c..cb8cb9cbd42f 100644
65
+--- a/drivers/staging/fsl_ppfe/pfe_hal.c
66
+@@ -1017,6 +1017,17 @@ void gemac_enable_1536_rx(void *base)
67
+ 		| (1536 << 16), base +	EMAC_RCNTRL_REG);
68
+ }
69
+ 
70
++/* GEMAC set rx Max frame length.
71
++ * @param[in]	base	GEMAC base address
72
++ * @param[in]	mtu	new mtu
73
++ */
74
++void gemac_set_rx_max_fl(void *base, int mtu)
75
++{
76
++	/* Set mtu as Maximum frame length */
77
++	writel((readl(base + EMAC_RCNTRL_REG) & PFE_RCR_MAX_FL_MASK)
78
++		| (mtu << 16), base + EMAC_RCNTRL_REG);
79
++}
80
++
81
+ /* GEMAC enable jumbo function.
82
+  * @param[in]	base	GEMAC base address
83
+  */
84
+-- 
85
+2.14.2
86
+
0 87
new file mode 100644
... ...
@@ -0,0 +1,60 @@
0
+From 26a83eb4f3f492ad5454f6ebec86efe8da7a1641 Mon Sep 17 00:00:00 2001
1
+From: Calvin Johnson <calvin.johnson@nxp.com>
2
+Date: Wed, 20 Jun 2018 10:23:16 +0530
3
+Subject: [PATCH 20/22] staging: fsl_ppfe/eth: remove jumbo frame enable from
4
+ gemac init
5
+
6
+MAC Receive Control Register was configured to allow jumbo frames.
7
+This is removed as jumbo frames can be supported anytime by changing
8
+mtu which will in turn modify MAX_FL field of MAC RCR.
9
+Jumbo frames caused pfe to hang on LS1012A rev 1.0 Silicon due to
10
+erratum A-010897.
11
+
12
+Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
13
+
14
+[ Srinidhi Rao : Ported this patch to photon linux from
15
+  qoriq-components linux 'linux-4.14-nxp'
16
+  (https://source.codeaurora.org/external/qoriq/qoriq-components/linux)
17
+]
18
+
19
+Signed-off-by: srinidhira0 <srinidhir@vmware.com>
20
+---
21
+ drivers/staging/fsl_ppfe/pfe_eth.c | 1 -
22
+ drivers/staging/fsl_ppfe/pfe_hal.c | 9 ---------
23
+ 2 files changed, 10 deletions(-)
24
+
25
+diff --git a/drivers/staging/fsl_ppfe/pfe_eth.c b/drivers/staging/fsl_ppfe/pfe_eth.c
26
+index 77d7a7b682c6..b272e72baf5f 100644
27
+--- a/drivers/staging/fsl_ppfe/pfe_eth.c
28
+@@ -1272,7 +1272,6 @@ static int pfe_gemac_init(struct pfe_eth_priv_s *priv)
29
+ 	gemac_set_config(priv->EMAC_baseaddr, &cfg);
30
+ 	gemac_allow_broadcast(priv->EMAC_baseaddr);
31
+ 	gemac_enable_1536_rx(priv->EMAC_baseaddr);
32
+-	gemac_enable_rx_jmb(priv->EMAC_baseaddr);
33
+ 	gemac_enable_stacked_vlan(priv->EMAC_baseaddr);
34
+ 	gemac_enable_pause_rx(priv->EMAC_baseaddr);
35
+ 	gemac_set_bus_width(priv->EMAC_baseaddr, 64);
36
+diff --git a/drivers/staging/fsl_ppfe/pfe_hal.c b/drivers/staging/fsl_ppfe/pfe_hal.c
37
+index cb8cb9cbd42f..cfd02ccc313a 100644
38
+--- a/drivers/staging/fsl_ppfe/pfe_hal.c
39
+@@ -1028,15 +1028,6 @@ void gemac_set_rx_max_fl(void *base, int mtu)
40
+ 		| (mtu << 16), base + EMAC_RCNTRL_REG);
41
+ }
42
+ 
43
+-/* GEMAC enable jumbo function.
44
+- * @param[in]	base	GEMAC base address
45
+- */
46
+-void gemac_enable_rx_jmb(void *base)
47
+-{
48
+-	writel((readl(base + EMAC_RCNTRL_REG) & PFE_RCR_MAX_FL_MASK)
49
+-		| (JUMBO_FRAME_SIZE << 16), base + EMAC_RCNTRL_REG);
50
+-}
51
+-
52
+ /* GEMAC enable stacked vlan function.
53
+  * @param[in]	base	GEMAC base address
54
+  */
55
+-- 
56
+2.14.2
57
+
0 58
new file mode 100644
... ...
@@ -0,0 +1,40 @@
0
+From 4a57b7304d1200e4e653f3e2b5f4cd61654cd191 Mon Sep 17 00:00:00 2001
1
+From: Calvin Johnson <calvin.johnson@nxp.com>
2
+Date: Wed, 20 Jun 2018 10:23:32 +0530
3
+Subject: [PATCH 21/22] staging: fsl_ppfe/eth: disable CRC removal
4
+
5
+Disable CRC removal from the packet, so that packets are forwarded
6
+as is to Linux.
7
+CRC configuration in MAC will be reflected in the packet received
8
+to Linux.
9
+
10
+Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
11
+
12
+[ Srinidhi Rao : Ported this patch to photon linux from
13
+  qoriq-components linux 'linux-4.14-nxp'
14
+  (https://source.codeaurora.org/external/qoriq/qoriq-components/linux)
15
+]
16
+
17
+Signed-off-by: srinidhira0 <srinidhir@vmware.com>
18
+---
19
+ drivers/staging/fsl_ppfe/pfe_hal.c | 4 ++--
20
+ 1 file changed, 2 insertions(+), 2 deletions(-)
21
+
22
+diff --git a/drivers/staging/fsl_ppfe/pfe_hal.c b/drivers/staging/fsl_ppfe/pfe_hal.c
23
+index cfd02ccc313a..ec7764648c0c 100644
24
+--- a/drivers/staging/fsl_ppfe/pfe_hal.c
25
+@@ -869,8 +869,8 @@ void gemac_set_mode(void *base, int mode)
26
+ 	/*Remove loopbank*/
27
+ 	val &= ~EMAC_RCNTRL_LOOP;
28
+ 
29
+-	/*Enable flow control and MII mode*/
30
+-	val |= (EMAC_RCNTRL_FCE | EMAC_RCNTRL_MII_MODE);
31
++	/* Enable flow control and MII mode and terminate received CRC */
32
++	val |= (EMAC_RCNTRL_FCE | EMAC_RCNTRL_MII_MODE | EMAC_RCNTRL_CRC_FWD);
33
+ 
34
+ 	writel(val, base + EMAC_RCNTRL_REG);
35
+ }
36
+-- 
37
+2.14.2
38
+
0 39
new file mode 100644
... ...
@@ -0,0 +1,123 @@
0
+From 4cd81dcda58bf1533c646d35ceb4decefd565410 Mon Sep 17 00:00:00 2001
1
+From: Calvin Johnson <calvin.johnson@nxp.com>
2
+Date: Wed, 20 Jun 2018 10:23:41 +0530
3
+Subject: [PATCH 22/22] staging: fsl_ppfe/eth: handle ls1012a errata_a010897
4
+
5
+On LS1012A rev 1.0, Jumbo frames are not supported as it causes
6
+the PFE controller to hang. A reset of the entire chip is required
7
+to resume normal operation.
8
+
9
+To handle this errata, frames with length > 1900 are truncated for
10
+rev 1.0 of LS1012A.
11
+
12
+Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
13
+
14
+[ Srinidhi Rao : Ported this patch to photon linux from
15
+  qoriq-components linux 'linux-4.14-nxp'
16
+  (https://source.codeaurora.org/external/qoriq/qoriq-components/linux)
17
+]
18
+
19
+Signed-off-by: srinidhira0 <srinidhir@vmware.com>
20
+---
21
+ drivers/staging/fsl_ppfe/pfe_eth.c | 20 +++++++++++++++++++-
22
+ drivers/staging/fsl_ppfe/pfe_eth.h |  3 ++-
23
+ drivers/staging/fsl_ppfe/pfe_hal.c | 10 +++++++++-
24
+ 3 files changed, 30 insertions(+), 3 deletions(-)
25
+
26
+diff --git a/drivers/staging/fsl_ppfe/pfe_eth.c b/drivers/staging/fsl_ppfe/pfe_eth.c
27
+index b272e72baf5f..dba5a49e180e 100644
28
+--- a/drivers/staging/fsl_ppfe/pfe_eth.c
29
+@@ -44,6 +44,7 @@
30
+ #include <linux/delay.h>
31
+ #include <linux/regmap.h>
32
+ #include <linux/i2c.h>
33
++#include <linux/fsl/guts.h>
34
+ 
35
+ #if defined(CONFIG_NF_CONNTRACK_MARK)
36
+ #include <net/netfilter/nf_conntrack.h>
37
+@@ -52,6 +53,10 @@
38
+ #include "pfe_mod.h"
39
+ #include "pfe_eth.h"
40
+ 
41
++#define LS1012A_REV_1_0		0x87040010
42
++
43
++bool pfe_errata_a010897;
44
++
45
+ static void *cbus_emac_base[3];
46
+ static void *cbus_gpi_base[3];
47
+ 
48
+@@ -2362,7 +2367,15 @@ static int pfe_eth_init_one(struct pfe *pfe, int id)
49
+ 
50
+ 	/* Set MTU limits */
51
+ 	ndev->min_mtu = ETH_MIN_MTU;
52
+-	ndev->max_mtu = JUMBO_FRAME_SIZE;
53
++
54
++/*
55
++ * Jumbo frames are not supported on LS1012A rev-1.0.
56
++ * So max mtu should be restricted to supported frame length.
57
++ */
58
++	if (pfe_errata_a010897)
59
++		ndev->max_mtu = JUMBO_FRAME_SIZE_V1 - ETH_HLEN - ETH_FCS_LEN;
60
++	else
61
++		ndev->max_mtu = JUMBO_FRAME_SIZE_V2 - ETH_HLEN - ETH_FCS_LEN;
62
+ 
63
+ 	/* supported features */
64
+ 	ndev->hw_features = NETIF_F_SG;
65
+@@ -2453,6 +2466,11 @@ int pfe_eth_init(struct pfe *pfe)
66
+ 	cbus_gpi_base[0] = EGPI1_BASE_ADDR;
67
+ 	cbus_gpi_base[1] = EGPI2_BASE_ADDR;
68
+ 
69
++	if (fsl_guts_get_svr() == LS1012A_REV_1_0)
70
++		pfe_errata_a010897 = true;
71
++	else
72
++		pfe_errata_a010897 = false;
73
++
74
+ 	for (ii = 0; ii < NUM_GEMAC_SUPPORT; ii++) {
75
+ 		err = pfe_eth_init_one(pfe, ii);
76
+ 		if (err)
77
+diff --git a/drivers/staging/fsl_ppfe/pfe_eth.h b/drivers/staging/fsl_ppfe/pfe_eth.h
78
+index 721bef3ef53b..051e2d4cee53 100644
79
+--- a/drivers/staging/fsl_ppfe/pfe_eth.h
80
+@@ -85,7 +85,8 @@ struct ls1012a_pfe_platform_data {
81
+ #define EMAC_TXQ_CNT	16
82
+ #define EMAC_TXQ_DEPTH	(HIF_TX_DESC_NT)
83
+ 
84
+-#define JUMBO_FRAME_SIZE	10258
85
++#define JUMBO_FRAME_SIZE_V1	1900
86
++#define JUMBO_FRAME_SIZE_V2	10258
87
+ /*
88
+  * Client Tx queue threshold, for txQ flush condition.
89
+  * It must be smaller than the queue size (in case we ever change it in the
90
+diff --git a/drivers/staging/fsl_ppfe/pfe_hal.c b/drivers/staging/fsl_ppfe/pfe_hal.c
91
+index ec7764648c0c..e55a63f123df 100644
92
+--- a/drivers/staging/fsl_ppfe/pfe_hal.c
93
+@@ -19,6 +19,9 @@
94
+ #include "pfe_mod.h"
95
+ #include "pfe/pfe.h"
96
+ 
97
++/* A-010897: Jumbo frame is not supported */
98
++extern bool pfe_errata_a010897;
99
++
100
+ #define PFE_RCR_MAX_FL_MASK	0xC000FFFF
101
+ 
102
+ void *cbus_base_addr;
103
+@@ -1102,7 +1105,12 @@ void gemac_set_config(void *base, struct gemac_cfg *cfg)
104
+ 	/*GEMAC config taken from VLSI */
105
+ 	writel(0x00000004, base + EMAC_TFWR_STR_FWD);
106
+ 	writel(0x00000005, base + EMAC_RX_SECTION_FULL);
107
+-	writel(0x00003fff, base + EMAC_TRUNC_FL);
108
++
109
++	if (pfe_errata_a010897)
110
++		writel(0x0000076c, base + EMAC_TRUNC_FL);
111
++	else
112
++		writel(0x00003fff, base + EMAC_TRUNC_FL);
113
++
114
+ 	writel(0x00000030, base + EMAC_TX_SECTION_EMPTY);
115
+ 	writel(0x00000000, base + EMAC_MIB_CTRL_STS_REG);
116
+ 
117
+-- 
118
+2.14.2
119
+
0 120
new file mode 100644
... ...
@@ -0,0 +1,375 @@
0
+From f190432842ad8888d09b4ee1a107cf7e0f97b137 Mon Sep 17 00:00:00 2001
1
+From: srinidhira0 <srinidhir@vmware.com>
2
+Date: Fri, 11 Jan 2019 10:38:51 +0000
3
+Subject: [PATCH] staging: fsl_ppfe/eth:  Modify Kconfig to enable pfe driver
4
+
5
+This patch is intended to enable the compilation of
6
+fsl_ppfe driver based on the kernel config file.
7
+This patch aslo adds Device Tree files which has been
8
+ported from qoriq-components/linux git, 'linux-4.14-nxp'
9
+branch
10
+
11
+Signed-off-by: srinidhira0 <srinidhir@vmware.com>
12
+---
13
+ arch/arm64/boot/dts/freescale/Makefile             |   1 +
14
+ arch/arm64/boot/dts/freescale/fsl-ls1012a-frwy.dts | 172 +++++++++++++++++++++
15
+ arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi     |  41 ++++-
16
+ drivers/staging/Kconfig                            |   2 +
17
+ drivers/staging/Makefile                           |   1 +
18
+ drivers/staging/fsl_ppfe/Kconfig                   |   2 +-
19
+ drivers/staging/fsl_ppfe/Makefile                  |   2 +-
20
+ drivers/staging/fsl_ppfe/pfe_eth.c                 |  15 +-
21
+ 8 files changed, 225 insertions(+), 11 deletions(-)
22
+ create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1012a-frwy.dts
23
+
24
+diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
25
+index 86e18adb695a..25a9fb766438 100644
26
+--- a/arch/arm64/boot/dts/freescale/Makefile
27
+@@ -1,5 +1,6 @@
28
+ # SPDX-License-Identifier: GPL-2.0
29
+ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1012a-frdm.dtb
30
++dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1012a-frwy.dtb
31
+ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1012a-qds.dtb
32
+ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1012a-rdb.dtb
33
+ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1043a-qds.dtb
34
+diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1012a-frwy.dts b/arch/arm64/boot/dts/freescale/fsl-ls1012a-frwy.dts
35
+new file mode 100644
36
+index 000000000000..3418bb0a906c
37
+--- /dev/null
38
+@@ -0,0 +1,172 @@
39
++/*
40
++ * Device Tree file for NXP LS1012A FRWY Board.
41
++ *
42
++ * Copyright 2018 NXP
43
++ *
44
++ * This file is dual-licensed: you can use it either under the terms
45
++ * of the GPLv2 or the X11 license, at your option. Note that this dual
46
++ * licensing only applies to this file, and not this project as a
47
++ * whole.
48
++ *
49
++ *  a) This library is free software; you can redistribute it and/or
50
++ *     modify it under the terms of the GNU General Public License as
51
++ *     published by the Free Software Foundation; either version 2 of the
52
++ *     License, or (at your option) any later version.
53
++ *
54
++ *     This library is distributed in the hope that it will be useful,
55
++ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
56
++ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
57
++ *     GNU General Public License for more details.
58
++ *
59
++ * Or, alternatively,
60
++ *
61
++ *  b) Permission is hereby granted, free of charge, to any person
62
++ *     obtaining a copy of this software and associated documentation
63
++ *     files (the "Software"), to deal in the Software without
64
++ *     restriction, including without limitation the rights to use,
65
++ *     copy, modify, merge, publish, distribute, sublicense, and/or
66
++ *     sell copies of the Software, and to permit persons to whom the
67
++ *     Software is furnished to do so, subject to the following
68
++ *     conditions:
69
++ *
70
++ *     The above copyright notice and this permission notice shall be
71
++ *     included in all copies or substantial portions of the Software.
72
++ *
73
++ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
74
++ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
75
++ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
76
++ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
77
++ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
78
++ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
79
++ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
80
++ *     OTHER DEALINGS IN THE SOFTWARE.
81
++ */
82
++/dts-v1/;
83
++
84
++#include "fsl-ls1012a.dtsi"
85
++
86
++/ {
87
++	model = "LS1012A FRWY Board";
88
++	compatible = "fsl,ls1012a-frwy", "fsl,ls1012a";
89
++
90
++	aliases {
91
++		ethernet0 = &pfe_mac0;
92
++		ethernet1 = &pfe_mac1;
93
++	};
94
++
95
++	sys_mclk: clock-mclk {
96
++		compatible = "fixed-clock";
97
++		#clock-cells = <0>;
98
++		clock-frequency = <25000000>;
99
++	};
100
++
101
++	reg_1p8v: regulator-1p8v {
102
++		compatible = "regulator-fixed";
103
++		regulator-name = "1P8V";
104
++		regulator-min-microvolt = <1800000>;
105
++		regulator-max-microvolt = <1800000>;
106
++		regulator-always-on;
107
++	};
108
++
109
++	sound {
110
++		compatible = "simple-audio-card";
111
++		simple-audio-card,format = "i2s";
112
++		simple-audio-card,widgets =
113
++			"Microphone", "Microphone Jack",
114
++			"Headphone", "Headphone Jack",
115
++			"Speaker", "Speaker Ext",
116
++			"Line", "Line In Jack";
117
++		simple-audio-card,routing =
118
++			"MIC_IN", "Microphone Jack",
119
++			"Microphone Jack", "Mic Bias",
120
++			"LINE_IN", "Line In Jack",
121
++			"Headphone Jack", "HP_OUT",
122
++			"Speaker Ext", "LINE_OUT";
123
++
124
++		simple-audio-card,cpu {
125
++			sound-dai = <&sai2>;
126
++			frame-master;
127
++			bitclock-master;
128
++		};
129
++
130
++		simple-audio-card,codec {
131
++			sound-dai = <&codec>;
132
++			frame-master;
133
++			bitclock-master;
134
++			system-clock-frequency = <25000000>;
135
++		};
136
++	};
137
++};
138
++
139
++&pcie {
140
++	status = "okay";
141
++};
142
++
143
++&duart0 {
144
++	status = "okay";
145
++};
146
++
147
++&i2c0 {
148
++	status = "okay";
149
++
150
++	codec: sgtl5000@a {
151
++		compatible = "fsl,sgtl5000";
152
++		#sound-dai-cells = <0>;
153
++		reg = <0xa>;
154
++		VDDA-supply = <&reg_1p8v>;
155
++		VDDIO-supply = <&reg_1p8v>;
156
++		clocks = <&sys_mclk>;
157
++		clock-names = "pfe";
158
++	};
159
++};
160
++
161
++&pfe {
162
++	status = "okay";
163
++	#address-cells = <1>;
164
++	#size-cells = <0>;
165
++
166
++	ethernet@0 {
167
++		compatible = "fsl,pfe-gemac-port";
168
++		#address-cells = <1>;
169
++		#size-cells = <0>;
170
++		reg = <0x0>;	/* GEM_ID */
171
++		fsl,gemac-bus-id = <0x0>;	/* BUS_ID */
172
++		fsl,gemac-phy-id = <0x2>;	/* PHY_ID */
173
++		fsl,mdio-mux-val = <0x0>;
174
++		phy-mode = "sgmii";
175
++		fsl,pfe-phy-if-flags = <0x0>;
176
++		local-mac-address = [ 00 1A 2B 3C 4D 5E ];
177
++		fsl,pfe-gemac-if-name = "eth0";
178
++		fsl,pfe-gemac-mode = <0x1B00>; /* GEMAC_SW_CONF | GEMAC_SW_FULL_DUPLEX |
179
++GEMAC_SW_SPEED_1G */
180
++		mdio@0 {
181
++			reg = <0x1>; /* enabled/disabled */
182
++			fsl,mdio-phy-mask = <0xFFFFFFF9>;
183
++		};
184
++	};
185
++
186
++	ethernet@1 {
187
++		compatible = "fsl,pfe-gemac-port";
188
++		#address-cells = <1>;
189
++		#size-cells = <0>;
190
++		reg = <0x1>;	/* GEM_ID */
191
++		fsl,gemac-bus-id = <0x1>;	/* BUS_ID */
192
++		fsl,gemac-phy-id = <0x1>;	/* PHY_ID */
193
++		fsl,mdio-mux-val = <0x0>;
194
++		local-mac-address = [ 00 AA BB CC DD EE ];
195
++		phy-mode = "rgmii";
196
++		fsl,pfe-gemac-if-name = "eth2";
197
++		fsl,pfe-phy-if-flags = <0x0>;
198
++		fsl,pfe-gemac-mode = <0x1B00>; /* GEMAC_SW_CONF | GEMAC_SW_FULL_DUPLEX |
199
++GEMAC_SW_SPEED_1G */
200
++
201
++		mdio@0 {
202
++			reg = <0x0>; /* enabled/disabled */
203
++			fsl,mdio-phy-mask = <0xFFFFFFF9>;
204
++		};
205
++	};
206
++};
207
++
208
++&sai2 {
209
++	status = "okay";
210
++};
211
+diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi
212
+index 68ac78c4564d..343e3d88b73e 100644
213
+--- a/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi
214
+@@ -474,7 +474,7 @@
215
+ 			interrupts = <0 126 IRQ_TYPE_LEVEL_HIGH>;
216
+ 		};
217
+ 
218
+-		pcie@3400000 {
219
++		pcie: pcie@3400000 {
220
+ 			compatible = "fsl,ls1012a-pcie", "snps,dw-pcie";
221
+ 			reg = <0x00 0x03400000 0x0 0x00100000   /* controller registers */
222
+ 			       0x40 0x00000000 0x0 0x00002000>; /* configuration space */
223
+@@ -497,6 +497,45 @@
224
+ 					<0000 0 0 3 &gic 0 112 IRQ_TYPE_LEVEL_HIGH>,
225
+ 					<0000 0 0 4 &gic 0 113 IRQ_TYPE_LEVEL_HIGH>;
226
+ 		};
227
++		rcpm: rcpm@1ee2000 {
228
++			compatible = "fsl,ls1012a-rcpm", "fsl,qoriq-rcpm-2.1";
229
++			reg = <0x0 0x1ee2000 0x0 0x1000>;
230
++			fsl,#rcpm-wakeup-cells = <1>;
231
++		};
232
++	};
233
++
234
++	reserved-memory {
235
++		#address-cells = <2>;
236
++		#size-cells = <2>;
237
++		ranges;
238
++
239
++		pfe_reserved: packetbuffer@83400000 {
240
++			reg = <0 0x83400000 0 0xc00000>;
241
++		};
242
++	};
243
++
244
++	pfe: pfe@04000000 {
245
++		compatible = "fsl,pfe";
246
++		reg =   <0x0 0x04000000 0x0 0xc00000>,	/* AXI 16M */
247
++			<0x0 0x83400000 0x0 0xc00000>;  /* PFE DDR 12M */
248
++		reg-names = "pfe", "pfe-ddr";
249
++		fsl,pfe-num-interfaces = <0x2>;
250
++		interrupts = <0 172 0x4>,    /* HIF interrupt */
251
++			     <0 173 0x4>,    /*HIF_NOCPY interrupt */
252
++			     <0 174 0x4>;    /* WoL interrupt */
253
++		interrupt-names = "pfe_hif", "pfe_hif_nocpy", "pfe_wol";
254
++		memory-region = <&pfe_reserved>;
255
++		fsl,pfe-scfg = <&scfg 0>;
256
++		fsl,rcpm-wakeup = <&rcpm 0xf0000020>;
257
++		clocks = <&clockgen 4 0>;
258
++		clock-names = "pfe";
259
++
260
++		status = "okay";
261
++		pfe_mac0: ethernet@0 {
262
++		};
263
++
264
++		pfe_mac1: ethernet@1 {
265
++		};
266
+ 	};
267
+ 
268
+ 	firmware {
269
+diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
270
+index 1abf76be2aa8..2744ecad2294 100644
271
+--- a/drivers/staging/Kconfig
272
+@@ -126,4 +126,6 @@ source "drivers/staging/axis-fifo/Kconfig"
273
+ 
274
+ source "drivers/staging/erofs/Kconfig"
275
+ 
276
++source "drivers/staging/fsl_ppfe/Kconfig"
277
++
278
+ endif # STAGING
279
+diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
280
+index ab0cbe8815b1..13bf0fa8a262 100644
281
+--- a/drivers/staging/Makefile
282
+@@ -53,3 +53,4 @@ obj-$(CONFIG_SOC_MT7621)	+= mt7621-dts/
283
+ obj-$(CONFIG_STAGING_GASKET_FRAMEWORK)	+= gasket/
284
+ obj-$(CONFIG_XIL_AXIS_FIFO)	+= axis-fifo/
285
+ obj-$(CONFIG_EROFS_FS)		+= erofs/
286
++obj-$(CONFIG_FSL_PPFE)          += fsl_ppfe/
287
+diff --git a/drivers/staging/fsl_ppfe/Kconfig b/drivers/staging/fsl_ppfe/Kconfig
288
+index e40964354cad..c38c669ed59f 100644
289
+--- a/drivers/staging/fsl_ppfe/Kconfig
290
+@@ -2,7 +2,7 @@
291
+ # Freescale Programmable Packet Forwarding Engine driver
292
+ #
293
+ config FSL_PPFE
294
+-	bool "Freescale PPFE Driver"
295
++	tristate "Freescale PPFE Driver"
296
+ 	default n
297
+ 	---help---
298
+ 	Freescale LS1012A SoC has a Programmable Packet Forwarding Engine.
299
+diff --git a/drivers/staging/fsl_ppfe/Makefile b/drivers/staging/fsl_ppfe/Makefile
300
+index 07cd351b9221..513efefd8ded 100644
301
+--- a/drivers/staging/fsl_ppfe/Makefile
302
+@@ -4,7 +4,7 @@
303
+ 
304
+ ccflags-y +=  -I$(src)/include  -I$(src)
305
+ 
306
+-obj-m += pfe.o
307
++obj-$(CONFIG_FSL_PPFE) += pfe.o
308
+ 
309
+ pfe-y += pfe_mod.o \
310
+ 	pfe_hw.o \
311
+diff --git a/drivers/staging/fsl_ppfe/pfe_eth.c b/drivers/staging/fsl_ppfe/pfe_eth.c
312
+index dba5a49e180e..767c069c517a 100644
313
+--- a/drivers/staging/fsl_ppfe/pfe_eth.c
314
+@@ -974,7 +974,10 @@ static int pfe_eth_mdio_init(struct pfe_eth_priv_s *priv,
315
+ 	 * via phy_device_register()
316
+ 	 */
317
+ 
318
+-	if (priv->einfo->mii_config == PHY_INTERFACE_MODE_2500SGMII) {
319
++	/* Since 4.19 Kernel does not support 2.5GBPS SGMII yet,
320
++	   Disabling the cluse 45 phy register
321
++	 */
322
++	/*if (priv->einfo->mii_config == PHY_INTERFACE_MODE_2500SGMII) {
323
+ 		for (ii = 0; ii < NUM_GEMAC_SUPPORT; ii++) {
324
+ 			phydev = get_phy_device(priv->mii_bus,
325
+ 					priv->einfo->phy_id + ii, true);
326
+@@ -991,7 +994,7 @@ static int pfe_eth_mdio_init(struct pfe_eth_priv_s *priv,
327
+ 				goto err1;
328
+ 			}
329
+ 		}
330
+-	}
331
++	} */
332
+ 
333
+ 	pfe_eth_mdio_reset(bus);
334
+ 
335
+@@ -1181,9 +1184,6 @@ static void ls1012a_configure_serdes(struct net_device *ndev)
336
+ 	struct mii_bus *bus = priv->mii_bus;
337
+ 	u16 value = 0;
338
+ 
339
+-	if (priv->einfo->mii_config == PHY_INTERFACE_MODE_2500SGMII)
340
+-		sgmii_2500 = 1;
341
+-
342
+ 	netif_info(priv, drv, ndev, "%s\n", __func__);
343
+ 	/* PCS configuration done with corresponding GEMAC */
344
+ 
345
+@@ -1231,8 +1231,7 @@ static int pfe_phy_init(struct net_device *ndev)
346
+ 
347
+ 	netif_info(priv, drv, ndev, "%s: %s\n", __func__, phy_id);
348
+ 	interface = priv->einfo->mii_config;
349
+-	if ((interface == PHY_INTERFACE_MODE_SGMII) ||
350
+-	    (interface == PHY_INTERFACE_MODE_2500SGMII)) {
351
++	if ( interface == PHY_INTERFACE_MODE_SGMII ) {
352
+ 		/*Configure SGMII PCS */
353
+ 		if (pfe->scfg) {
354
+ 			/*Config MDIO from serdes */
355
+@@ -1823,7 +1822,7 @@ static int pfe_eth_send_packet(struct sk_buff *skb, struct net_device *ndev)
356
+  *
357
+  */
358
+ static u16 pfe_eth_select_queue(struct net_device *ndev, struct sk_buff *skb,
359
+-				void *accel_priv,
360
++				struct net_device *sb_dev,
361
+ 				select_queue_fallback_t fallback)
362
+ {
363
+ 	struct pfe_eth_priv_s *priv = netdev_priv(ndev);
364
+-- 
365
+2.14.2
366
+
... ...
@@ -8,7 +8,7 @@
8 8
 		},
9 9
     "packagelist_file": "packages_ls1012afrwy.json",
10 10
     "size": {"root": "1", "swap": "0"},
11
-    "boot":"bios",
11
+    "boot":"efi",
12 12
     "public_key":"<ssh-key-here>",
13 13
     "postinstallscripts": ["ls1012afrwy-custom-patch.sh"],
14 14
     "additionalfiles": [
15 15
new file mode 100644
16 16
Binary files /dev/null and b/support/image-builder/ls1012afrwy/esp/bootaa64.efi differ
17 17
Binary files a/support/image-builder/ls1012afrwy/esp/ls1012afrwy_boot.scr and b/support/image-builder/ls1012afrwy/esp/ls1012afrwy_boot.scr differ
... ...
@@ -15,19 +15,17 @@
15 15
 
16 16
 grub_efi_install()
17 17
 {
18
-    BOOT_PARTITION=/dev/mapper/`basename ${HDD}`p2
19
-    mkdir -p $BUILDROOT/boot_temp/
20
-    mount -t ext4 $BOOT_PARTITION $BUILDROOT/boot_temp/
21
-    cp -rfa $BUILDROOT/boot/* $BUILDROOT/boot_temp/
22
-    cp -r $SCRIPT_PATH/esp/ls1012afrwy_boot.scr $BUILDROOT/boot_temp/
23
-    cp -rfa $BUILDROOT/boot_temp/vmlinuz-* $BUILDROOT/boot_temp/Image
24
-    gzip -k $BUILDROOT/boot_temp/Image
25
-    cp -rfa $BUILDROOT/boot_temp/dtb/fsl-ls1012a-frdm.dtb $BUILDROOT/boot_temp/fsl-ls1012a-frwy.dtb
26
-    sync
27
-    umount $BUILDROOT/boot_temp/
28
-    rm -rf $BUILDROOT/boot_temp/
18
+	cp -r $SCRIPT_PATH/esp/ls1012afrwy_boot.scr $BUILDROOT/
19
+	mkdir -p $BUILDROOT/boot/esp/EFI/BOOT/
20
+	cp $SCRIPT_PATH/esp/bootaa64.efi $BUILDROOT/boot/esp/EFI/BOOT/
21
+	mkdir -p $BUILDROOT/boot/esp/boot/grub2
22
+	cat > $BUILDROOT/boot/esp/boot/grub2/grub.cfg << EOF
23
+search -n -u ${BOOT_UUID} -s
24
+configfile ${BOOT_DIRECTORY}grub2/grub.cfg
25
+EOF
29 26
 }
30 27
 
28
+
31 29
 set -o errexit        # exit if error...insurance ;)
32 30
 set -o nounset        # exit if variable not initalized
33 31
 set +h            # disable hashall
... ...
@@ -55,19 +53,23 @@ fi
55 55
 #
56 56
 #    Install grub2.
57 57
 #
58
-BOOT_UUID=$(blkid -s UUID -o value $BOOT_PARTITION_PATH)
58
+BOOT_UUID=$(blkid -s UUID -o value $ROOT_PARTITION_PATH)
59 59
 
60 60
 echo "$ROOT_PARTITION_PATH"
61 61
 echo "$BUILDROOT"
62 62
 
63
+mkdir -p $BUILDROOT/boot/grub2/
64
+ln -sfv grub2 $BUILDROOT/boot/grub
65
+
66
+
67
+grub_efi_install
68
+
63 69
 RFS_PARTITION=/dev/mapper/`basename ${HDD}`p2
64 70
 #umount -f $BUILDROOT
65 71
 #mount -t ext4 $ROOT_PATITION_PATH $BUILDROOT
66 72
 
67
-EXTRA_PARAMS="rootwait rw console=ttyS0,115200n8 console=tty0 cma=256M rootfs=/dev/mmcblk0p3"
68
-
73
+EXTRA_PARAMS="rootwait rw console=ttyS0,115200n8 console=tty0 cma=256M rootfs=/dev/mmcblk0p2"
69 74
 
70
-mkdir -p $BUILDROOT/boot/grub2/
71 75
 
72 76
 cat > $BUILDROOT/boot/grub2/grub.cfg << EOF
73 77
 # Begin /boot/grub2/grub.cfg
... ...
@@ -101,7 +103,12 @@ EOF
101 101
 
102 102
 
103 103
 
104
-mkdir $BUILDROOT/boot/grub
105
-cp -rfa $BUILDROOT/boot/grub2/* $BUILDROOT/boot/grub/
104
+#mkdir $BUILDROOT/boot/grub
105
+#cp -rfa $BUILDROOT/boot/grub2/* $BUILDROOT/boot/grub/
106
+
107
+#grub_efi_install
108
+
109
+#Cleanup the workspace directory
110
+rm -rf "$BUILDROOT"/tools
111
+rm -rf "$BUILDROOT"/RPMS
106 112
 
107
-grub_efi_install